source: src/Parser/ParseNode.h@ d2fadeb

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since d2fadeb was 2d019af, checked in by Peter A. Buhr <pabuhr@…>, 5 years ago

parser global pragmas, fixes #241

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