source: src/Parser/ParseNode.h @ 835d6e8

ADTast-experimental
Last change on this file since 835d6e8 was 835d6e8, checked in by Andrew Beach <ajbeach@…>, 13 months ago

ast::SuspendStmt::Type -> ::Kind, this fits the new convention where Type is limited for actual compiler types.

  • Property mode set to 100644
File size: 22.3 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// ParseNode.h --
8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Sat May 16 13:28:16 2015
11// Last Modified By : Andrew Beach
12// Last Modified On : Mon Apr  3 17:55:00 2023
13// Update Count     : 942
14//
15
16#pragma once
17
18#include <algorithm>               // for move
19#include <cassert>                 // for assert, assertf
20#include <iosfwd>                  // for ostream
21#include <iterator>                // for back_insert_iterator
22#include <list>                    // for list
23#include <memory>                  // for unique_ptr, pointer_traits
24#include <string>                  // for string
25
26#include "AST/Expr.hpp"            // for Expr, NameExpr LogicalFlag
27#include "AST/Fwd.hpp"             // for ptr, Decl, DeclWithType,
28#include "AST/Stmt.hpp"            // for Stmt
29#include "Common/CodeLocation.h"   // for CodeLocation
30#include "Common/SemanticError.h"  // for SemanticError
31#include "Common/UniqueName.h"     // for UniqueName
32#include "Common/utility.h"        // for maybeClone
33#include "Parser/parserutility.h"  // for maybeBuild, maybeCopy
34
35class Attribute;
36class Declaration;
37struct DeclarationNode;
38class DeclarationWithType;
39class Initializer;
40class ExpressionNode;
41struct StatementNode;
42
43//##############################################################################
44
45typedef CodeLocation YYLTYPE;
46#define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */
47
48extern YYLTYPE yylloc;
49
50class ParseNode {
51  public:
52        ParseNode() {};
53        virtual ~ParseNode() { delete next; delete name; };
54        virtual ParseNode * clone() const = 0;
55
56        ParseNode * get_next() const { return next; }
57        ParseNode * set_next( ParseNode * newlink ) { next = newlink; return this; }
58
59        ParseNode * get_last() {
60                ParseNode * current;
61                for ( current = this; current->get_next() != nullptr; current = current->get_next() );
62                return current;
63        }
64        ParseNode * set_last( ParseNode * newlast ) {
65                if ( newlast != nullptr ) get_last()->set_next( newlast );
66                return this;
67        }
68
69        virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
70        virtual void printList( std::ostream & os, int indent = 0 ) const {
71                print( os, indent );
72                if ( next ) next->print( os, indent );
73        }
74
75        static int indent_by;
76
77        ParseNode * next = nullptr;
78        const std::string * name = nullptr;
79        CodeLocation location = yylloc;
80}; // ParseNode
81
82//##############################################################################
83
84class InitializerNode : public ParseNode {
85  public:
86        InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr );
87        InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
88        InitializerNode( bool isDelete );
89        ~InitializerNode();
90        virtual InitializerNode * clone() const { assert( false ); return nullptr; }
91
92        ExpressionNode * get_expression() const { return expr; }
93
94        InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
95        ExpressionNode * get_designators() const { return designator; }
96
97        InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
98        bool get_maybeConstructed() const { return maybeConstructed; }
99
100        bool get_isDelete() const { return isDelete; }
101
102        InitializerNode * next_init() const { return kids; }
103
104        void print( std::ostream & os, int indent = 0 ) const;
105        void printOneLine( std::ostream & ) const;
106
107        virtual ast::Init * build() const;
108  private:
109        ExpressionNode * expr;
110        bool aggregate;
111        ExpressionNode * designator;                                            // may be list
112        InitializerNode * kids;
113        bool maybeConstructed;
114        bool isDelete;
115}; // InitializerNode
116
117//##############################################################################
118
119class ExpressionNode final : public ParseNode {
120  public:
121        ExpressionNode( ast::Expr * expr = nullptr ) : expr( expr ) {}
122        virtual ~ExpressionNode() {}
123        virtual ExpressionNode * clone() const override {
124                if ( nullptr == expr ) return nullptr;
125                return static_cast<ExpressionNode*>(
126                        (new ExpressionNode( ast::shallowCopy( expr.get() ) ))->set_next( maybeCopy( get_next() ) ));
127        }
128
129        bool get_extension() const { return extension; }
130        ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
131
132        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
133                os << expr.get();
134        }
135        void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
136
137        template<typename T>
138        bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
139
140        ast::Expr * build() const {
141                ast::Expr * node = const_cast<ExpressionNode *>(this)->expr.release();
142                node->set_extension( this->get_extension() );
143                node->location = this->location;
144                return node;
145        }
146
147        // Public because of lifetime implications (what lifetime implications?)
148        std::unique_ptr<ast::Expr> expr;
149  private:
150        bool extension = false;
151}; // ExpressionNode
152
153// Must harmonize with OperName.
154enum class OperKinds {
155        // diadic
156        SizeOf, AlignOf, OffsetOf, Plus, Minus, Exp, Mul, Div, Mod, Or, And,
157        BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
158        Assign, AtAssn, ExpAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
159        Index, Range,
160        // monadic
161        UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
162        Ctor, Dtor,
163}; // OperKinds
164
165enum class EnumHiding { Visible, Hide };
166
167struct LabelNode {
168        std::vector<ast::Label> labels;
169};
170
171// These 4 routines modify the string:
172ast::Expr * build_constantInteger( const CodeLocation &, std::string & );
173ast::Expr * build_constantFloat( const CodeLocation &, std::string & );
174ast::Expr * build_constantChar( const CodeLocation &, std::string & );
175ast::Expr * build_constantStr( const CodeLocation &, std::string & );
176ast::Expr * build_field_name_FLOATING_FRACTIONconstant( const CodeLocation &, const std::string & str );
177ast::Expr * build_field_name_FLOATING_DECIMALconstant( const CodeLocation &, const std::string & str );
178ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation &, const std::string & str );
179ast::Expr * build_field_name_fraction_constants( const CodeLocation &, ast::Expr * fieldName, ExpressionNode * fracts );
180
181ast::NameExpr * build_varref( const CodeLocation &, const std::string * name );
182ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const DeclarationNode * decl_node, const ast::NameExpr * name );
183ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const ast::EnumDecl * decl, const ast::NameExpr * name );
184ast::DimensionExpr * build_dimensionref( const CodeLocation &, const std::string * name );
185
186ast::Expr * build_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node );
187ast::Expr * build_keyword_cast( const CodeLocation &, ast::AggregateDecl::Aggregate target, ExpressionNode * expr_node );
188ast::Expr * build_virtual_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node );
189ast::Expr * build_fieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member );
190ast::Expr * build_pfieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member );
191ast::Expr * build_offsetOf( const CodeLocation &, DeclarationNode * decl_node, ast::NameExpr * member );
192ast::Expr * build_and( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
193ast::Expr * build_and_or( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ast::LogicalFlag flag );
194ast::Expr * build_unary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node );
195ast::Expr * build_binary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
196ast::Expr * build_binary_ptr( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
197ast::Expr * build_cond( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
198ast::Expr * build_tuple( const CodeLocation &, ExpressionNode * expr_node = nullptr );
199ast::Expr * build_func( const CodeLocation &, ExpressionNode * function, ExpressionNode * expr_node );
200ast::Expr * build_compoundLiteral( const CodeLocation &, DeclarationNode * decl_node, InitializerNode * kids );
201
202//##############################################################################
203
204struct TypeData;
205
206struct DeclarationNode : public ParseNode {
207        // These enumerations must harmonize with their names in DeclarationNode.cc.
208        enum BasicType {
209                Void, Bool, Char, Int, Int128,
210                Float, Double, LongDouble, uuFloat80, uuFloat128,
211                uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x,
212                NoBasicType
213        };
214        static const char * basicTypeNames[];
215        enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
216        static const char * complexTypeNames[];
217        enum Signedness { Signed, Unsigned, NoSignedness };
218        static const char * signednessNames[];
219        enum Length { Short, Long, LongLong, NoLength };
220        static const char * lengthNames[];
221        enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };
222        static const char * builtinTypeNames[];
223
224        static DeclarationNode * newStorageClass( ast::Storage::Classes );
225        static DeclarationNode * newFuncSpecifier( ast::Function::Specs );
226        static DeclarationNode * newTypeQualifier( ast::CV::Qualifiers );
227        static DeclarationNode * newBasicType( BasicType );
228        static DeclarationNode * newComplexType( ComplexType );
229        static DeclarationNode * newSignedNess( Signedness );
230        static DeclarationNode * newLength( Length );
231        static DeclarationNode * newBuiltinType( BuiltinType );
232        static DeclarationNode * newForall( DeclarationNode * );
233        static DeclarationNode * newFromTypedef( const std::string * );
234        static DeclarationNode * newFromGlobalScope();
235        static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
236        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
237        static DeclarationNode * newAggregate( ast::AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
238        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible );
239        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
240        static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
241        static DeclarationNode * newEnumInLine( const std::string name );
242        static DeclarationNode * newName( const std::string * );
243        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
244        static DeclarationNode * newTypeParam( ast::TypeDecl::Kind, const std::string * );
245        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
246        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
247        static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
248        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
249        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
250        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
251        static DeclarationNode * newBitfield( ExpressionNode * size );
252        static DeclarationNode * newTuple( DeclarationNode * members );
253        static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
254        static DeclarationNode * newVtableType( DeclarationNode * expr );
255        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
256        static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
257        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
258        static DeclarationNode * newStaticAssert( ExpressionNode * condition, ast::Expr * message );
259
260        DeclarationNode();
261        ~DeclarationNode();
262        DeclarationNode * clone() const override;
263
264        DeclarationNode * addQualifiers( DeclarationNode * );
265        void checkQualifiers( const TypeData *, const TypeData * );
266        void checkSpecifiers( DeclarationNode * );
267        DeclarationNode * copySpecifiers( DeclarationNode * );
268        DeclarationNode * addType( DeclarationNode * );
269        DeclarationNode * addTypedef();
270        DeclarationNode * addEnumBase( DeclarationNode * );
271        DeclarationNode * addAssertions( DeclarationNode * );
272        DeclarationNode * addName( std::string * );
273        DeclarationNode * addAsmName( DeclarationNode * );
274        DeclarationNode * addBitfield( ExpressionNode * size );
275        DeclarationNode * addVarArgs();
276        DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
277        DeclarationNode * addOldDeclList( DeclarationNode * list );
278        DeclarationNode * setBase( TypeData * newType );
279        DeclarationNode * copyAttribute( DeclarationNode * attr );
280        DeclarationNode * addPointer( DeclarationNode * qualifiers );
281        DeclarationNode * addArray( DeclarationNode * array );
282        DeclarationNode * addNewPointer( DeclarationNode * pointer );
283        DeclarationNode * addNewArray( DeclarationNode * array );
284        DeclarationNode * addParamList( DeclarationNode * list );
285        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
286        DeclarationNode * addInitializer( InitializerNode * init );
287        DeclarationNode * addTypeInitializer( DeclarationNode * init );
288
289        DeclarationNode * cloneType( std::string * newName );
290        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
291
292        DeclarationNode * appendList( DeclarationNode * node ) {
293                return (DeclarationNode *)set_last( node );
294        }
295
296        virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
297        virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
298
299        ast::Decl * build() const;
300        ast::Type * buildType() const;
301
302        ast::Linkage::Spec get_linkage() const { return linkage; }
303        DeclarationNode * extractAggregate() const;
304        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
305        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
306
307        bool get_extension() const { return extension; }
308        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
309
310        bool get_inLine() const { return inLine; }
311        DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
312
313        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
314
315        struct Variable_t {
316//              const std::string * name;
317                ast::TypeDecl::Kind tyClass;
318                DeclarationNode * assertions;
319                DeclarationNode * initializer;
320        };
321        Variable_t variable;
322
323        struct StaticAssert_t {
324                ExpressionNode * condition;
325                ast::Expr * message;
326        };
327        StaticAssert_t assert;
328
329        BuiltinType builtin = NoBuiltinType;
330
331        TypeData * type = nullptr;
332
333        bool inLine = false;
334        bool enumInLine = false;
335        ast::Function::Specs funcSpecs;
336        ast::Storage::Classes storageClasses;
337
338        ExpressionNode * bitfieldWidth = nullptr;
339        std::unique_ptr<ExpressionNode> enumeratorValue;
340        bool hasEllipsis = false;
341        ast::Linkage::Spec linkage;
342        ast::Expr * asmName = nullptr;
343        std::vector<ast::ptr<ast::Attribute>> attributes;
344        InitializerNode * initializer = nullptr;
345        bool extension = false;
346        std::string error;
347        StatementNode * asmStmt = nullptr;
348        StatementNode * directiveStmt = nullptr;
349
350        static UniqueName anonymous;
351}; // DeclarationNode
352
353ast::Type * buildType( TypeData * type );
354
355static inline ast::Type * maybeMoveBuildType( const DeclarationNode * orig ) {
356        ast::Type * ret = orig ? orig->buildType() : nullptr;
357        delete orig;
358        return ret;
359}
360
361//##############################################################################
362
363struct StatementNode final : public ParseNode {
364        StatementNode() :
365                stmt( nullptr ), clause( nullptr ) {}
366        StatementNode( ast::Stmt * stmt ) :
367                stmt( stmt ), clause( nullptr ) {}
368        StatementNode( ast::StmtClause * clause ) :
369                stmt( nullptr ), clause( clause ) {}
370        StatementNode( DeclarationNode * decl );
371        virtual ~StatementNode() {}
372
373        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
374        ast::Stmt * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
375
376        virtual StatementNode * add_label(
377                        const CodeLocation & location,
378                        const std::string * name,
379                        DeclarationNode * attr = nullptr ) {
380                stmt->labels.emplace_back( location,
381                        *name,
382                        attr ? std::move( attr->attributes )
383                                : std::vector<ast::ptr<ast::Attribute>>{} );
384                delete attr;
385                delete name;
386                return this;
387        }
388
389        virtual StatementNode * append_last_case( StatementNode * );
390
391        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
392                os << stmt.get() << std::endl;
393        }
394
395        std::unique_ptr<ast::Stmt> stmt;
396        std::unique_ptr<ast::StmtClause> clause;
397}; // StatementNode
398
399ast::Stmt * build_expr( CodeLocation const &, ExpressionNode * ctl );
400
401struct CondCtl {
402        CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :
403                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
404
405        StatementNode * init;
406        ExpressionNode * condition;
407};
408
409struct ForCtrl {
410        ForCtrl( StatementNode * stmt, ExpressionNode * condition, ExpressionNode * change ) :
411                init( stmt ), condition( condition ), change( change ) {}
412
413        StatementNode * init;
414        ExpressionNode * condition;
415        ExpressionNode * change;
416};
417
418ast::Stmt * build_if( const CodeLocation &, CondCtl * ctl, StatementNode * then, StatementNode * else_ );
419ast::Stmt * build_switch( const CodeLocation &, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
420ast::CaseClause * build_case( ExpressionNode * ctl );
421ast::CaseClause * build_default( const CodeLocation & );
422ast::Stmt * build_while( const CodeLocation &, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
423ast::Stmt * build_do_while( const CodeLocation &, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
424ast::Stmt * build_for( const CodeLocation &, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
425ast::Stmt * build_branch( const CodeLocation &, ast::BranchStmt::Kind kind );
426ast::Stmt * build_branch( const CodeLocation &, std::string * identifier, ast::BranchStmt::Kind kind );
427ast::Stmt * build_computedgoto( ExpressionNode * ctl );
428ast::Stmt * build_return( const CodeLocation &, ExpressionNode * ctl );
429ast::Stmt * build_throw( const CodeLocation &, ExpressionNode * ctl );
430ast::Stmt * build_resume( const CodeLocation &, ExpressionNode * ctl );
431ast::Stmt * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
432ast::Stmt * build_try( const CodeLocation &, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
433ast::CatchClause * build_catch( const CodeLocation &, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
434ast::FinallyClause * build_finally( const CodeLocation &, StatementNode * stmt );
435ast::Stmt * build_compound( const CodeLocation &, StatementNode * first );
436StatementNode * maybe_build_compound( const CodeLocation &, StatementNode * first );
437ast::Stmt * build_asm( const CodeLocation &, bool voltile, ast::Expr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
438ast::Stmt * build_directive( const CodeLocation &, std::string * directive );
439ast::SuspendStmt * build_suspend( const CodeLocation &, StatementNode *, ast::SuspendStmt::Kind );
440ast::WaitForStmt * build_waitfor( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt );
441ast::WaitForStmt * build_waitfor_else( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt );
442ast::WaitForStmt * build_waitfor_timeout( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt );
443ast::Stmt * build_with( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
444ast::Stmt * build_mutex( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
445
446//##############################################################################
447
448template<typename AstType, typename NodeType,
449        template<typename, typename...> class Container, typename... Args>
450void buildList( const NodeType * firstNode,
451                Container<ast::ptr<AstType>, Args...> & output ) {
452        SemanticErrorException errors;
453        std::back_insert_iterator<Container<ast::ptr<AstType>, Args...>> out( output );
454        const NodeType * cur = firstNode;
455
456        while ( cur ) {
457                try {
458                        if ( auto result = dynamic_cast<AstType *>( maybeBuild( cur ) ) ) {
459                                *out++ = result;
460                        } else {
461                                assertf(false, __PRETTY_FUNCTION__ );
462                                SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
463                        } // if
464                } catch( SemanticErrorException & e ) {
465                        errors.append( e );
466                } // try
467                const ParseNode * temp = cur->get_next();
468                // Should not return nullptr, then it is non-homogeneous:
469                cur = dynamic_cast<const NodeType *>( temp );
470                if ( !cur && temp ) {
471                        SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
472                } // if
473        } // while
474        if ( ! errors.isEmpty() ) {
475                throw errors;
476        } // if
477}
478
479// in DeclarationNode.cc
480void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Decl>> & outputList );
481void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList );
482void buildTypeList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Type>> & outputList );
483
484template<typename AstType, typename NodeType,
485        template<typename, typename...> class Container, typename... Args>
486void buildMoveList( const NodeType * firstNode,
487                Container<ast::ptr<AstType>, Args...> & output ) {
488        buildList<AstType, NodeType, Container, Args...>( firstNode, output );
489        delete firstNode;
490}
491
492// in ParseNode.cc
493std::ostream & operator<<( std::ostream & out, const ParseNode * node );
494
495// Local Variables: //
496// tab-width: 4 //
497// mode: c++ //
498// compile-command: "make install" //
499// End: //
Note: See TracBrowser for help on using the repository browser.