source: src/Parser/ParseNode.h@ 158b026

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 158b026 was 033ff37, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

remove attribute expression '@'name mechanism

  • Property mode set to 100644
File size: 20.4 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 : Thu Jul 25 22:17:10 2019
13// Update Count : 876
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 template<typename T>
135 bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
136
137 Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
138
139 std::unique_ptr<Expression> expr; // public because of lifetime implications
140 private:
141 bool extension = false;
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, AutoType, 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 * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
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 * addAssertions( DeclarationNode * );
269 DeclarationNode * addName( std::string * );
270 DeclarationNode * addAsmName( DeclarationNode * );
271 DeclarationNode * addBitfield( ExpressionNode * size );
272 DeclarationNode * addVarArgs();
273 DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
274 DeclarationNode * addOldDeclList( DeclarationNode * list );
275 DeclarationNode * setBase( TypeData * newType );
276 DeclarationNode * copyAttribute( DeclarationNode * attr );
277 DeclarationNode * addPointer( DeclarationNode * qualifiers );
278 DeclarationNode * addArray( DeclarationNode * array );
279 DeclarationNode * addNewPointer( DeclarationNode * pointer );
280 DeclarationNode * addNewArray( DeclarationNode * array );
281 DeclarationNode * addParamList( DeclarationNode * list );
282 DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
283 DeclarationNode * addInitializer( InitializerNode * init );
284 DeclarationNode * addTypeInitializer( DeclarationNode * init );
285
286 DeclarationNode * cloneType( std::string * newName );
287 DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
288
289 DeclarationNode * appendList( DeclarationNode * node ) {
290 return (DeclarationNode *)set_last( node );
291 }
292
293 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
294 virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
295
296 Declaration * build() const;
297 Type * buildType() const;
298
299 LinkageSpec::Spec get_linkage() const { return linkage; }
300 DeclarationNode * extractAggregate() const;
301 bool has_enumeratorValue() const { return (bool)enumeratorValue; }
302 ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
303
304 bool get_extension() const { return extension; }
305 DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
306
307 bool get_inLine() const { return inLine; }
308 DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
309 public:
310 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
311
312 struct Variable_t {
313// const std::string * name;
314 DeclarationNode::TypeClass tyClass;
315 DeclarationNode * assertions;
316 DeclarationNode * initializer;
317 };
318 Variable_t variable;
319
320 struct Attr_t {
321// const std::string * name;
322 ExpressionNode * expr;
323 DeclarationNode * type;
324 };
325 Attr_t attr;
326
327 struct StaticAssert_t {
328 ExpressionNode * condition;
329 Expression * message;
330 };
331 StaticAssert_t assert;
332
333 BuiltinType builtin = NoBuiltinType;
334
335 TypeData * type = nullptr;
336
337 bool inLine = false;
338 Type::FuncSpecifiers funcSpecs;
339 Type::StorageClasses storageClasses;
340
341 ExpressionNode * bitfieldWidth = nullptr;
342 std::unique_ptr<ExpressionNode> enumeratorValue;
343 bool hasEllipsis = false;
344 LinkageSpec::Spec linkage;
345 Expression * asmName = nullptr;
346 std::list< Attribute * > attributes;
347 InitializerNode * initializer = nullptr;
348 bool extension = false;
349 std::string error;
350 StatementNode * asmStmt = nullptr;
351
352 static UniqueName anonymous;
353}; // DeclarationNode
354
355Type * buildType( TypeData * type );
356
357static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
358 Type * ret = orig ? orig->buildType() : nullptr;
359 delete orig;
360 return ret;
361}
362
363//##############################################################################
364
365class StatementNode final : public ParseNode {
366 public:
367 StatementNode() { stmt = nullptr; }
368 StatementNode( Statement * stmt ) : stmt( stmt ) {}
369 StatementNode( DeclarationNode * decl );
370 virtual ~StatementNode() {}
371
372 virtual StatementNode * clone() const final { assert( false ); return nullptr; }
373 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
374
375 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
376 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
377 delete attr;
378 delete name;
379 return this;
380 }
381
382 virtual StatementNode * append_last_case( StatementNode * );
383
384 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
385 os << stmt.get() << std::endl;
386 }
387 private:
388 std::unique_ptr<Statement> stmt;
389}; // StatementNode
390
391Statement * build_expr( ExpressionNode * ctl );
392
393struct IfCtrl {
394 IfCtrl( DeclarationNode * decl, ExpressionNode * condition ) :
395 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
396
397 StatementNode * init;
398 ExpressionNode * condition;
399};
400
401struct ForCtrl {
402 ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
403 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
404 ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
405 init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
406
407 StatementNode * init;
408 ExpressionNode * condition;
409 ExpressionNode * change;
410};
411
412Expression * build_if_control( IfCtrl * ctl, std::list< Statement * > & init );
413Statement * build_if( IfCtrl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
414Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
415Statement * build_case( ExpressionNode * ctl );
416Statement * build_default();
417Statement * build_while( IfCtrl * ctl, StatementNode * stmt );
418Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt );
419Statement * build_for( ForCtrl * forctl, StatementNode * stmt );
420Statement * build_branch( BranchStmt::Type kind );
421Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
422Statement * build_computedgoto( ExpressionNode * ctl );
423Statement * build_return( ExpressionNode * ctl );
424Statement * build_throw( ExpressionNode * ctl );
425Statement * build_resume( ExpressionNode * ctl );
426Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
427Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
428Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
429Statement * build_finally( StatementNode * stmt );
430Statement * build_compound( StatementNode * first );
431Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
432Statement * build_directive( std::string * directive );
433WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
434WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
435WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
436WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
437Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
438
439//##############################################################################
440
441template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
442void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
443 SemanticErrorException errors;
444 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
445 const NodeType * cur = firstNode;
446
447 while ( cur ) {
448 try {
449 SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
450 if ( result ) {
451 result->location = cur->location;
452 * out++ = result;
453 } else {
454 assertf(false, "buildList unknown type");
455 } // if
456 } catch( SemanticErrorException & e ) {
457 errors.append( e );
458 } // try
459 cur = dynamic_cast< NodeType * >( cur->get_next() );
460 } // while
461 if ( ! errors.isEmpty() ) {
462 throw errors;
463 } // if
464}
465
466// in DeclarationNode.cc
467void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
468void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
469void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
470
471template< typename SynTreeType, typename NodeType >
472void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
473 buildList( firstNode, outputList );
474 delete firstNode;
475}
476
477// in ParseNode.cc
478std::ostream & operator<<( std::ostream & out, const ParseNode * node );
479
480// Local Variables: //
481// tab-width: 4 //
482// mode: c++ //
483// compile-command: "make install" //
484// End: //
Note: See TracBrowser for help on using the repository browser.