source: src/Parser/ParseNode.h@ 5509ff4

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr persistent-indexer pthread-emulation qualifiedEnum
Last change on this file since 5509ff4 was e15853c, checked in by Peter A. Buhr <pabuhr@…>, 7 years ago

remove leading underscores in enums for _FloatNN and _Bool

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