source: src/Parser/ParseNode.h@ 1931bb01

ADT ast-experimental pthread-emulation qualifiedEnum
Last change on this file since 1931bb01 was 9e7236f4, checked in by JiadaL <j82liang@…>, 3 years ago

Resolution of struct enum. The codegen of struct enum will be in the next commit

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