source: src/Parser/ParseNode.h@ bb7422a

ADT ast-experimental
Last change on this file since bb7422a was bb7422a, checked in by Andrew Beach <ajbeach@…>, 2 years ago

Translated parser to the new ast. This incuded a small fix in the resolver so larger expressions can be used in with statements and some updated tests. errors/declaration just is a formatting update. attributes now actually preserves more attributes (unknown if all versions work).

  • Property mode set to 100644
File size: 22.3 KB
RevLine 
[b87a5ed]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//
[974906e2]7// ParseNode.h --
[b87a5ed]8//
9// Author : Rodolfo G. Esteves
10// Created On : Sat May 16 13:28:16 2015
[bb7422a]11// Last Modified By : Andrew Beach
12// Last Modified On : Mon Apr 3 17:55:00 2023
13// Update Count : 942
[b87a5ed]14//
15
[6b0b624]16#pragma once
[51b73452]17
[d180746]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
[51b73452]25
[bb7422a]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
[21f0aa8]29#include "Common/CodeLocation.h" // for CodeLocation
[d180746]30#include "Common/SemanticError.h" // for SemanticError
[be9288a]31#include "Common/UniqueName.h" // for UniqueName
[4b60b28]32#include "Common/utility.h" // for maybeClone
[bb7422a]33#include "Parser/parserutility.h" // for maybeBuild, maybeCopy
[d180746]34
35class Attribute;
36class Declaration;
[b2e0df3]37struct DeclarationNode;
[d180746]38class DeclarationWithType;
39class Initializer;
[a6e5091]40class ExpressionNode;
[b2e0df3]41struct StatementNode;
[51b73452]42
[7880579]43//##############################################################################
44
[d48e529]45typedef CodeLocation YYLTYPE;
46#define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */
47
48extern YYLTYPE yylloc;
[294647b]49
[51b73452]50class ParseNode {
[bdd516a]51 public:
[99cad3aa]52 ParseNode() {};
[2298f728]53 virtual ~ParseNode() { delete next; delete name; };
[b6424d9]54 virtual ParseNode * clone() const = 0;
[51b73452]55
[b6424d9]56 ParseNode * get_next() const { return next; }
57 ParseNode * set_next( ParseNode * newlink ) { next = newlink; return this; }
[1b772749]58
[b6424d9]59 ParseNode * get_last() {
60 ParseNode * current;
[2298f728]61 for ( current = this; current->get_next() != nullptr; current = current->get_next() );
[99cad3aa]62 return current;
63 }
[b6424d9]64 ParseNode * set_last( ParseNode * newlast ) {
[2298f728]65 if ( newlast != nullptr ) get_last()->set_next( newlast );
[99cad3aa]66 return this;
67 }
[51b73452]68
[f2f512ba]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 {
[e4bc986]71 print( os, indent );
72 if ( next ) next->print( os, indent );
73 }
[1b772749]74
[b87a5ed]75 static int indent_by;
[7880579]76
[b6424d9]77 ParseNode * next = nullptr;
[25bca42]78 const std::string * name = nullptr;
[d48e529]79 CodeLocation location = yylloc;
[7880579]80}; // ParseNode
[51b73452]81
[7bf7fb9]82//##############################################################################
83
[d1625f8]84class InitializerNode : public ParseNode {
85 public:
[82bbaf4]86 InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr );
[2298f728]87 InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
[3ed994e]88 InitializerNode( bool isDelete );
[d1625f8]89 ~InitializerNode();
[a7741435]90 virtual InitializerNode * clone() const { assert( false ); return nullptr; }
[d1625f8]91
[b6424d9]92 ExpressionNode * get_expression() const { return expr; }
[d1625f8]93
[b6424d9]94 InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
95 ExpressionNode * get_designators() const { return designator; }
[d1625f8]96
[b6424d9]97 InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
[d1625f8]98 bool get_maybeConstructed() const { return maybeConstructed; }
99
[3ed994e]100 bool get_isDelete() const { return isDelete; }
101
[b6424d9]102 InitializerNode * next_init() const { return kids; }
[d1625f8]103
[f2f512ba]104 void print( std::ostream & os, int indent = 0 ) const;
[d1625f8]105 void printOneLine( std::ostream & ) const;
106
[bb7422a]107 virtual ast::Init * build() const;
[d1625f8]108 private:
[b6424d9]109 ExpressionNode * expr;
[d1625f8]110 bool aggregate;
[b6424d9]111 ExpressionNode * designator; // may be list
112 InitializerNode * kids;
[d1625f8]113 bool maybeConstructed;
[3ed994e]114 bool isDelete;
[c1c1112]115}; // InitializerNode
[d1625f8]116
117//##############################################################################
118
[ac71a86]119class ExpressionNode final : public ParseNode {
[bdd516a]120 public:
[bb7422a]121 ExpressionNode( ast::Expr * expr = nullptr ) : expr( expr ) {}
[d1625f8]122 virtual ~ExpressionNode() {}
[bb7422a]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 }
[51b73452]128
[e04ef3a]129 bool get_extension() const { return extension; }
[b6424d9]130 ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
[51b73452]131
[f2f512ba]132 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
133 os << expr.get();
[e4bc986]134 }
[f2f512ba]135 void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
[ac71a86]136
137 template<typename T>
[513e165]138 bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
[51b73452]139
[bb7422a]140 ast::Expr * build() const {
141 ast::Expr * node = const_cast<ExpressionNode *>(this)->expr.release();
[702e826]142 node->set_extension( this->get_extension() );
143 node->location = this->location;
144 return node;
145 }
[67d4e37]146
[bb7422a]147 // Public because of lifetime implications (what lifetime implications?)
148 std::unique_ptr<ast::Expr> expr;
[bdd516a]149 private:
[e04ef3a]150 bool extension = false;
[c1c1112]151}; // ExpressionNode
[e04ef3a]152
[e5f2a67]153// Must harmonize with OperName.
[d9e2280]154enum class OperKinds {
155 // diadic
[e5f2a67]156 SizeOf, AlignOf, OffsetOf, Plus, Minus, Exp, Mul, Div, Mod, Or, And,
[d9e2280]157 BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
[e5f2a67]158 Assign, AtAssn, ExpAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
[d9e2280]159 Index, Range,
160 // monadic
[5809461]161 UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
[d9e2280]162 Ctor, Dtor,
[c1c1112]163}; // OperKinds
[51b73452]164
[7cf8006]165enum class EnumHiding { Visible, Hide };
166
[e82aa9df]167struct LabelNode {
[bb7422a]168 std::vector<ast::Label> labels;
[e82aa9df]169};
170
[bb7422a]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 );
[51b73452]201
[7bf7fb9]202//##############################################################################
203
[62e5546]204struct TypeData;
[51b73452]205
[a025ea8]206struct DeclarationNode : public ParseNode {
[ba01b14]207 // These enumerations must harmonize with their names in DeclarationNode.cc.
[702e826]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 };
[dd020c0]214 static const char * basicTypeNames[];
[ba01b14]215 enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
[dd020c0]216 static const char * complexTypeNames[];
[201aeb9]217 enum Signedness { Signed, Unsigned, NoSignedness };
[dd020c0]218 static const char * signednessNames[];
[201aeb9]219 enum Length { Short, Long, LongLong, NoLength };
[dd020c0]220 static const char * lengthNames[];
[f673c13c]221 enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };
[dd020c0]222 static const char * builtinTypeNames[];
[b6424d9]223
[bb7422a]224 static DeclarationNode * newStorageClass( ast::Storage::Classes );
225 static DeclarationNode * newFuncSpecifier( ast::Function::Specs );
226 static DeclarationNode * newTypeQualifier( ast::CV::Qualifiers );
[b6424d9]227 static DeclarationNode * newBasicType( BasicType );
[5b639ee]228 static DeclarationNode * newComplexType( ComplexType );
[dd020c0]229 static DeclarationNode * newSignedNess( Signedness );
230 static DeclarationNode * newLength( Length );
[b6424d9]231 static DeclarationNode * newBuiltinType( BuiltinType );
[dd020c0]232 static DeclarationNode * newForall( DeclarationNode * );
[25bca42]233 static DeclarationNode * newFromTypedef( const std::string * );
[47498bd]234 static DeclarationNode * newFromGlobalScope();
[c5d7701]235 static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
[25bca42]236 static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
[bb7422a]237 static DeclarationNode * newAggregate( ast::AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
[e4d7c1c]238 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible );
[25bca42]239 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
[374cb117]240 static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
[1e30df7]241 static DeclarationNode * newEnumInLine( const std::string name );
[25bca42]242 static DeclarationNode * newName( const std::string * );
243 static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
[bb7422a]244 static DeclarationNode * newTypeParam( ast::TypeDecl::Kind, const std::string * );
[2298f728]245 static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
246 static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
[25bca42]247 static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
[ce8c12f]248 static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
[b6424d9]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 );
[f855545]253 static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
[93bbbc4]254 static DeclarationNode * newVtableType( DeclarationNode * expr );
[25bca42]255 static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
[2d019af]256 static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
[e994912]257 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
[bb7422a]258 static DeclarationNode * newStaticAssert( ExpressionNode * condition, ast::Expr * message );
[b87a5ed]259
[7880579]260 DeclarationNode();
261 ~DeclarationNode();
[6a0d4d61]262 DeclarationNode * clone() const override;
[7880579]263
[2298f728]264 DeclarationNode * addQualifiers( DeclarationNode * );
[413ad05]265 void checkQualifiers( const TypeData *, const TypeData * );
[a7c90d4]266 void checkSpecifiers( DeclarationNode * );
267 DeclarationNode * copySpecifiers( DeclarationNode * );
[2298f728]268 DeclarationNode * addType( DeclarationNode * );
[b6424d9]269 DeclarationNode * addTypedef();
[f135b50]270 DeclarationNode * addEnumBase( DeclarationNode * );
[2298f728]271 DeclarationNode * addAssertions( DeclarationNode * );
272 DeclarationNode * addName( std::string * );
[c0aa336]273 DeclarationNode * addAsmName( DeclarationNode * );
[b6424d9]274 DeclarationNode * addBitfield( ExpressionNode * size );
275 DeclarationNode * addVarArgs();
[c453ac4]276 DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
[b6424d9]277 DeclarationNode * addOldDeclList( DeclarationNode * list );
[c0aa336]278 DeclarationNode * setBase( TypeData * newType );
279 DeclarationNode * copyAttribute( DeclarationNode * attr );
[b6424d9]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 );
[67cf18c]287 DeclarationNode * addTypeInitializer( DeclarationNode * init );
[b6424d9]288
289 DeclarationNode * cloneType( std::string * newName );
290 DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
291
292 DeclarationNode * appendList( DeclarationNode * node ) {
[99cad3aa]293 return (DeclarationNode *)set_last( node );
294 }
[b87a5ed]295
[f2f512ba]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;
[b87a5ed]298
[bb7422a]299 ast::Decl * build() const;
300 ast::Type * buildType() const;
[b87a5ed]301
[bb7422a]302 ast::Linkage::Spec get_linkage() const { return linkage; }
[b6424d9]303 DeclarationNode * extractAggregate() const;
[4f147cc]304 bool has_enumeratorValue() const { return (bool)enumeratorValue; }
[a7c90d4]305 ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
[b87a5ed]306
[7305915]307 bool get_extension() const { return extension; }
[b6424d9]308 DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
[e07caa2]309
310 bool get_inLine() const { return inLine; }
311 DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
[a025ea8]312
[481115f]313 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
314
[28307be]315 struct Variable_t {
[faddbd8]316// const std::string * name;
[bb7422a]317 ast::TypeDecl::Kind tyClass;
[28307be]318 DeclarationNode * assertions;
[67cf18c]319 DeclarationNode * initializer;
[28307be]320 };
321 Variable_t variable;
322
[f6e3e34]323 struct StaticAssert_t {
324 ExpressionNode * condition;
[bb7422a]325 ast::Expr * message;
[f6e3e34]326 };
327 StaticAssert_t assert;
328
[e07caa2]329 BuiltinType builtin = NoBuiltinType;
[8f6f47d7]330
[e07caa2]331 TypeData * type = nullptr;
[dd020c0]332
[e07caa2]333 bool inLine = false;
[44a0ca2]334 bool enumInLine = false;
[bb7422a]335 ast::Function::Specs funcSpecs;
336 ast::Storage::Classes storageClasses;
[dd020c0]337
[e07caa2]338 ExpressionNode * bitfieldWidth = nullptr;
[4f147cc]339 std::unique_ptr<ExpressionNode> enumeratorValue;
[e07caa2]340 bool hasEllipsis = false;
[bb7422a]341 ast::Linkage::Spec linkage;
342 ast::Expr * asmName = nullptr;
343 std::vector<ast::ptr<ast::Attribute>> attributes;
[e07caa2]344 InitializerNode * initializer = nullptr;
[7305915]345 bool extension = false;
[13e3b50]346 std::string error;
[e07caa2]347 StatementNode * asmStmt = nullptr;
[2d019af]348 StatementNode * directiveStmt = nullptr;
[b87a5ed]349
350 static UniqueName anonymous;
[1db21619]351}; // DeclarationNode
[51b73452]352
[bb7422a]353ast::Type * buildType( TypeData * type );
[d1625f8]354
[bb7422a]355static inline ast::Type * maybeMoveBuildType( const DeclarationNode * orig ) {
356 ast::Type * ret = orig ? orig->buildType() : nullptr;
[4f147cc]357 delete orig;
358 return ret;
359}
360
[7bf7fb9]361//##############################################################################
362
[a025ea8]363struct StatementNode final : public ParseNode {
[bb7422a]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 ) {}
[b6424d9]370 StatementNode( DeclarationNode * decl );
[e82aa9df]371 virtual ~StatementNode() {}
[51b73452]372
[b6424d9]373 virtual StatementNode * clone() const final { assert( false ); return nullptr; }
[bb7422a]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>>{} );
[44a81853]384 delete attr;
[ac71a86]385 delete name;
[2f22cc4]386 return this;
387 }
388
[b6424d9]389 virtual StatementNode * append_last_case( StatementNode * );
[1d4580a]390
[f2f512ba]391 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
[e4bc986]392 os << stmt.get() << std::endl;
393 }
[a025ea8]394
[bb7422a]395 std::unique_ptr<ast::Stmt> stmt;
396 std::unique_ptr<ast::StmtClause> clause;
[2f22cc4]397}; // StatementNode
398
[bb7422a]399ast::Stmt * build_expr( CodeLocation const &, ExpressionNode * ctl );
[1d4580a]400
[473d1da0]401struct CondCtl {
402 CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :
[936e9f4]403 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
404
405 StatementNode * init;
406 ExpressionNode * condition;
407};
408
[f271bdd]409struct ForCtrl {
[1cdc052]410 ForCtrl( StatementNode * stmt, ExpressionNode * condition, ExpressionNode * change ) :
411 init( stmt ), condition( condition ), change( change ) {}
[2f22cc4]412
[b6424d9]413 StatementNode * init;
414 ExpressionNode * condition;
415 ExpressionNode * change;
[2f22cc4]416};
417
[bb7422a]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::Type );
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 );
[7f5566b]445
[7bf7fb9]446//##############################################################################
447
[bb7422a]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 ) {
[a16764a6]452 SemanticErrorException errors;
[bb7422a]453 std::back_insert_iterator<Container<ast::ptr<AstType>, Args...>> out( output );
[b6424d9]454 const NodeType * cur = firstNode;
[b87a5ed]455
456 while ( cur ) {
457 try {
[bb7422a]458 if ( auto result = dynamic_cast<AstType *>( maybeBuild( cur ) ) ) {
459 *out++ = result;
[046e04a]460 } else {
[bb7422a]461 assertf(false, __PRETTY_FUNCTION__ );
[3e274ab]462 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
[b87a5ed]463 } // if
[f2f512ba]464 } catch( SemanticErrorException & e ) {
[b87a5ed]465 errors.append( e );
466 } // try
[bb7422a]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 ) {
[82ff4ed1]471 SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
[4678c1ec]472 } // if
[b87a5ed]473 } // while
[a32b204]474 if ( ! errors.isEmpty() ) {
[b87a5ed]475 throw errors;
476 } // if
[51b73452]477}
478
479// in DeclarationNode.cc
[bb7422a]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 );
[7ecbb7e]489 delete firstNode;
490}
491
[c8dfcd3]492// in ParseNode.cc
493std::ostream & operator<<( std::ostream & out, const ParseNode * node );
[7ecbb7e]494
[51b73452]495// Local Variables: //
[b87a5ed]496// tab-width: 4 //
497// mode: c++ //
498// compile-command: "make install" //
[51b73452]499// End: //
Note: See TracBrowser for help on using the repository browser.