source: src/Parser/ParseNode.h@ 466787a

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

Implement enum Hiding

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