source: src/Parser/ParseNode.h@ dbae916

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

Preventing NullStmts from being added into ForCtrl ended up being a larger rework as some timing issues caused problems. However, the NullStmts are mostly gone now along with the extra hosting they caused.

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