source: src/Parser/ParseNode.h@ 77de429

ADT ast-experimental
Last change on this file since 77de429 was c2b3243, checked in by JiadaL <j82liang@…>, 3 years ago

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

  • Property mode set to 100644
File size: 21.6 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 : Tue Oct 18 14:15:37 2022
13// Update Count : 936
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 );
185QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name );
186QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl, const NameExpr * name );
187DimensionExpr * build_dimensionref( const std::string * name );
188
189Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
190Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node );
191Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
192Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
193Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
194Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
195Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
196Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
197Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
198Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
199Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
200Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
201Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
202Expression * build_tuple( ExpressionNode * expr_node = nullptr );
203Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
204Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
205
206//##############################################################################
207
208struct TypeData;
209
210struct DeclarationNode : public ParseNode {
211 // These enumerations must harmonize with their names in DeclarationNode.cc.
212 enum BasicType { Void, Bool, Char, Int, Int128,
213 Float, Double, LongDouble, uuFloat80, uuFloat128,
214 uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x, NoBasicType };
215 static const char * basicTypeNames[];
216 enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
217 static const char * complexTypeNames[];
218 enum Signedness { Signed, Unsigned, NoSignedness };
219 static const char * signednessNames[];
220 enum Length { Short, Long, LongLong, NoLength };
221 static const char * lengthNames[];
222 enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };
223 static const char * builtinTypeNames[];
224
225 static DeclarationNode * newStorageClass( Type::StorageClasses );
226 static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
227 static DeclarationNode * newTypeQualifier( Type::Qualifiers );
228 static DeclarationNode * newBasicType( BasicType );
229 static DeclarationNode * newComplexType( ComplexType );
230 static DeclarationNode * newSignedNess( Signedness );
231 static DeclarationNode * newLength( Length );
232 static DeclarationNode * newBuiltinType( BuiltinType );
233 static DeclarationNode * newForall( DeclarationNode * );
234 static DeclarationNode * newFromTypedef( const std::string * );
235 static DeclarationNode * newFromGlobalScope();
236 static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
237 static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
238 static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
239 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr );
240 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
241 static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
242 static DeclarationNode * newEnumInLine( const std::string name );
243 static DeclarationNode * newName( const std::string * );
244 static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
245 static DeclarationNode * newTypeParam( TypeDecl::Kind, const std::string * );
246 static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
247 static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
248 static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
249 static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
250 static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
251 static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
252 static DeclarationNode * newBitfield( ExpressionNode * size );
253 static DeclarationNode * newTuple( DeclarationNode * members );
254 static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
255 static DeclarationNode * newVtableType( DeclarationNode * expr );
256 static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
257 static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
258 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
259 static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
260
261 DeclarationNode();
262 ~DeclarationNode();
263 DeclarationNode * clone() const override;
264
265 DeclarationNode * addQualifiers( DeclarationNode * );
266 void checkQualifiers( const TypeData *, const TypeData * );
267 void checkSpecifiers( DeclarationNode * );
268 DeclarationNode * copySpecifiers( DeclarationNode * );
269 DeclarationNode * addType( DeclarationNode * );
270 DeclarationNode * addTypedef();
271 DeclarationNode * addEnumBase( DeclarationNode * );
272 DeclarationNode * addAssertions( DeclarationNode * );
273 DeclarationNode * addName( std::string * );
274 DeclarationNode * addAsmName( DeclarationNode * );
275 DeclarationNode * addBitfield( ExpressionNode * size );
276 DeclarationNode * addVarArgs();
277 DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
278 DeclarationNode * addOldDeclList( DeclarationNode * list );
279 DeclarationNode * setBase( TypeData * newType );
280 DeclarationNode * copyAttribute( DeclarationNode * attr );
281 DeclarationNode * addPointer( DeclarationNode * qualifiers );
282 DeclarationNode * addArray( DeclarationNode * array );
283 DeclarationNode * addNewPointer( DeclarationNode * pointer );
284 DeclarationNode * addNewArray( DeclarationNode * array );
285 DeclarationNode * addParamList( DeclarationNode * list );
286 DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
287 DeclarationNode * addInitializer( InitializerNode * init );
288 DeclarationNode * addTypeInitializer( DeclarationNode * init );
289
290 DeclarationNode * cloneType( std::string * newName );
291 DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
292
293 DeclarationNode * appendList( DeclarationNode * node ) {
294 return (DeclarationNode *)set_last( node );
295 }
296
297 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
298 virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
299
300 Declaration * build() const;
301 Type * buildType() const;
302
303 LinkageSpec::Spec get_linkage() const { return linkage; }
304 DeclarationNode * extractAggregate() const;
305 bool has_enumeratorValue() const { return (bool)enumeratorValue; }
306 ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
307
308 bool get_extension() const { return extension; }
309 DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
310
311 bool get_inLine() const { return inLine; }
312 DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
313
314 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
315
316 struct Variable_t {
317// const std::string * name;
318 TypeDecl::Kind tyClass;
319 DeclarationNode * assertions;
320 DeclarationNode * initializer;
321 };
322 Variable_t variable;
323
324 struct Attr_t {
325// const std::string * name;
326 ExpressionNode * expr;
327 DeclarationNode * type;
328 };
329 Attr_t attr;
330
331 struct StaticAssert_t {
332 ExpressionNode * condition;
333 Expression * message;
334 };
335 StaticAssert_t assert;
336
337 BuiltinType builtin = NoBuiltinType;
338
339 TypeData * type = nullptr;
340
341 bool inLine = false;
342 bool enumInLine = false;
343 Type::FuncSpecifiers funcSpecs;
344 Type::StorageClasses storageClasses;
345
346 ExpressionNode * bitfieldWidth = nullptr;
347 std::unique_ptr<ExpressionNode> enumeratorValue;
348 bool hasEllipsis = false;
349 LinkageSpec::Spec linkage;
350 Expression * asmName = nullptr;
351 std::list< Attribute * > attributes;
352 InitializerNode * initializer = nullptr;
353 bool extension = false;
354 std::string error;
355 StatementNode * asmStmt = nullptr;
356 StatementNode * directiveStmt = nullptr;
357
358 static UniqueName anonymous;
359}; // DeclarationNode
360
361Type * buildType( TypeData * type );
362
363static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
364 Type * ret = orig ? orig->buildType() : nullptr;
365 delete orig;
366 return ret;
367}
368
369//##############################################################################
370
371struct StatementNode final : public ParseNode {
372 StatementNode() { stmt = nullptr; }
373 StatementNode( Statement * stmt ) : stmt( stmt ) {}
374 StatementNode( DeclarationNode * decl );
375 virtual ~StatementNode() {}
376
377 virtual StatementNode * clone() const final { assert( false ); return nullptr; }
378 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
379
380 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
381 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
382 delete attr;
383 delete name;
384 return this;
385 }
386
387 virtual StatementNode * append_last_case( StatementNode * );
388
389 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
390 os << stmt.get() << std::endl;
391 }
392
393 std::unique_ptr<Statement> stmt;
394}; // StatementNode
395
396Statement * build_expr( ExpressionNode * ctl );
397
398struct CondCtl {
399 CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :
400 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
401
402 StatementNode * init;
403 ExpressionNode * condition;
404};
405
406struct ForCtrl {
407 ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
408 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
409 ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
410 init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
411
412 StatementNode * init;
413 ExpressionNode * condition;
414 ExpressionNode * change;
415};
416
417Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init );
418Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ );
419Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
420Statement * build_case( ExpressionNode * ctl );
421Statement * build_default();
422Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
423Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
424Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
425Statement * build_branch( BranchStmt::Type kind );
426Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
427Statement * build_computedgoto( ExpressionNode * ctl );
428Statement * build_return( ExpressionNode * ctl );
429Statement * build_throw( ExpressionNode * ctl );
430Statement * build_resume( ExpressionNode * ctl );
431Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
432Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
433Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
434Statement * build_finally( StatementNode * stmt );
435Statement * build_compound( StatementNode * first );
436StatementNode * maybe_build_compound( StatementNode * first );
437Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
438Statement * build_directive( std::string * directive );
439SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None);
440WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
441WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
442WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
443WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
444Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
445Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt );
446
447//##############################################################################
448
449template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
450void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
451 SemanticErrorException errors;
452 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
453 const NodeType * cur = firstNode;
454
455 while ( cur ) {
456 try {
457 SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
458 if ( result ) {
459 result->location = cur->location;
460 * out++ = result;
461 } else {
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 cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr
469 if ( ! cur && temp ) { // non-homogeneous nodes ?
470 SemanticError( cur->location, "internal error, non-homogeneous nodes founds in buildList processing." );
471 } // if
472 } // while
473 if ( ! errors.isEmpty() ) {
474 throw errors;
475 } // if
476}
477
478// in DeclarationNode.cc
479void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
480void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
481void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
482
483template< typename SynTreeType, typename NodeType >
484void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
485 buildList( firstNode, outputList );
486 delete firstNode;
487}
488
489// in ParseNode.cc
490std::ostream & operator<<( std::ostream & out, const ParseNode * node );
491
492// Local Variables: //
493// tab-width: 4 //
494// mode: c++ //
495// compile-command: "make install" //
496// End: //
Note: See TracBrowser for help on using the repository browser.