source: src/Parser/ParseNode.h@ 47bfefd

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

add chained for-control specifiers, update loop test and test output

  • Property mode set to 100644
File size: 20.7 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 : Sat Apr 13 15:44:20 2019
13// Update Count : 873
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
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( KeywordCastExpr::Target 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
207class DeclarationNode : public ParseNode {
208 public:
209 // These enumerations must harmonize with their names in DeclarationNode.cc.
210 enum BasicType { Void, Bool, Char, Int, Int128,
211 Float, Double, LongDouble, uuFloat80, uuFloat128,
212 uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x, NoBasicType };
213 static const char * basicTypeNames[];
214 enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
215 static const char * complexTypeNames[];
216 enum Signedness { Signed, Unsigned, NoSignedness };
217 static const char * signednessNames[];
218 enum Length { Short, Long, LongLong, NoLength };
219 static const char * lengthNames[];
220 enum Aggregate { Struct, Union, Exception, Trait, Coroutine, Monitor, Thread, NoAggregate };
221 static const char * aggregateNames[];
222 enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
223 static const char * typeClassNames[];
224 enum BuiltinType { Valist, 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( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
241 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body );
242 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
243 static DeclarationNode * newName( const std::string * );
244 static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
245 static DeclarationNode * newTypeParam( TypeClass, 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 * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes
256 static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes
257 static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
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 * addAssertions( DeclarationNode * );
272 DeclarationNode * addName( std::string * );
273 DeclarationNode * addAsmName( DeclarationNode * );
274 DeclarationNode * addBitfield( ExpressionNode * size );
275 DeclarationNode * addVarArgs();
276 DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
277 DeclarationNode * addOldDeclList( DeclarationNode * list );
278 DeclarationNode * setBase( TypeData * newType );
279 DeclarationNode * copyAttribute( DeclarationNode * attr );
280 DeclarationNode * addPointer( DeclarationNode * qualifiers );
281 DeclarationNode * addArray( DeclarationNode * array );
282 DeclarationNode * addNewPointer( DeclarationNode * pointer );
283 DeclarationNode * addNewArray( DeclarationNode * array );
284 DeclarationNode * addParamList( DeclarationNode * list );
285 DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
286 DeclarationNode * addInitializer( InitializerNode * init );
287 DeclarationNode * addTypeInitializer( DeclarationNode * init );
288
289 DeclarationNode * cloneType( std::string * newName );
290 DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
291
292 DeclarationNode * appendList( DeclarationNode * node ) {
293 return (DeclarationNode *)set_last( node );
294 }
295
296 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
297 virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
298
299 Declaration * build() const;
300 Type * buildType() const;
301
302 LinkageSpec::Spec get_linkage() const { return linkage; }
303 DeclarationNode * extractAggregate() const;
304 bool has_enumeratorValue() const { return (bool)enumeratorValue; }
305 ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
306
307 bool get_extension() const { return extension; }
308 DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
309
310 bool get_inLine() const { return inLine; }
311 DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
312 public:
313 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
314
315 struct Variable_t {
316// const std::string * name;
317 DeclarationNode::TypeClass tyClass;
318 DeclarationNode * assertions;
319 DeclarationNode * initializer;
320 };
321 Variable_t variable;
322
323 struct Attr_t {
324// const std::string * name;
325 ExpressionNode * expr;
326 DeclarationNode * type;
327 };
328 Attr_t attr;
329
330 struct StaticAssert_t {
331 ExpressionNode * condition;
332 Expression * message;
333 };
334 StaticAssert_t assert;
335
336 BuiltinType builtin = NoBuiltinType;
337
338 TypeData * type = nullptr;
339
340 bool inLine = false;
341 Type::FuncSpecifiers funcSpecs;
342 Type::StorageClasses storageClasses;
343
344 ExpressionNode * bitfieldWidth = nullptr;
345 std::unique_ptr<ExpressionNode> enumeratorValue;
346 bool hasEllipsis = false;
347 LinkageSpec::Spec linkage;
348 Expression * asmName = nullptr;
349 std::list< Attribute * > attributes;
350 InitializerNode * initializer = nullptr;
351 bool extension = false;
352 std::string error;
353 StatementNode * asmStmt = nullptr;
354
355 static UniqueName anonymous;
356}; // DeclarationNode
357
358Type * buildType( TypeData * type );
359
360static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
361 Type * ret = orig ? orig->buildType() : nullptr;
362 delete orig;
363 return ret;
364}
365
366//##############################################################################
367
368class StatementNode final : public ParseNode {
369 public:
370 StatementNode() { stmt = nullptr; }
371 StatementNode( Statement * stmt ) : stmt( stmt ) {}
372 StatementNode( DeclarationNode * decl );
373 virtual ~StatementNode() {}
374
375 virtual StatementNode * clone() const final { assert( false ); return nullptr; }
376 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
377
378 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
379 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
380 delete attr;
381 delete name;
382 return this;
383 }
384
385 virtual StatementNode * append_last_case( StatementNode * );
386
387 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
388 os << stmt.get() << std::endl;
389 }
390 private:
391 std::unique_ptr<Statement> stmt;
392}; // StatementNode
393
394Statement * build_expr( ExpressionNode * ctl );
395
396struct IfCtrl {
397 IfCtrl( DeclarationNode * decl, ExpressionNode * condition ) :
398 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
399
400 StatementNode * init;
401 ExpressionNode * condition;
402};
403
404struct ForCtrl {
405 ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
406 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
407 ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
408 init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
409
410 StatementNode * init;
411 ExpressionNode * condition;
412 ExpressionNode * change;
413};
414
415Expression * build_if_control( IfCtrl * ctl, std::list< Statement * > & init );
416Statement * build_if( IfCtrl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
417Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
418Statement * build_case( ExpressionNode * ctl );
419Statement * build_default();
420Statement * build_while( IfCtrl * ctl, StatementNode * stmt );
421Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt );
422Statement * build_for( ForCtrl * forctl, StatementNode * stmt );
423Statement * build_branch( BranchStmt::Type kind );
424Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
425Statement * build_computedgoto( ExpressionNode * ctl );
426Statement * build_return( ExpressionNode * ctl );
427Statement * build_throw( ExpressionNode * ctl );
428Statement * build_resume( ExpressionNode * ctl );
429Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
430Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
431Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
432Statement * build_finally( StatementNode * stmt );
433Statement * build_compound( StatementNode * first );
434Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
435Statement * build_directive( std::string * directive );
436WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
437WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
438WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
439WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
440WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
441
442//##############################################################################
443
444template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
445void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
446 SemanticErrorException errors;
447 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
448 const NodeType * cur = firstNode;
449
450 while ( cur ) {
451 try {
452 SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
453 if ( result ) {
454 result->location = cur->location;
455 * out++ = result;
456 } else {
457 assertf(false, "buildList unknown type");
458 } // if
459 } catch( SemanticErrorException & e ) {
460 errors.append( e );
461 } // try
462 cur = dynamic_cast< NodeType * >( cur->get_next() );
463 } // while
464 if ( ! errors.isEmpty() ) {
465 throw errors;
466 } // if
467}
468
469// in DeclarationNode.cc
470void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
471void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
472void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
473
474template< typename SynTreeType, typename NodeType >
475void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
476 buildList( firstNode, outputList );
477 delete firstNode;
478}
479
480// in ParseNode.cc
481std::ostream & operator<<( std::ostream & out, const ParseNode * node );
482
483// Local Variables: //
484// tab-width: 4 //
485// mode: c++ //
486// compile-command: "make install" //
487// End: //
Note: See TracBrowser for help on using the repository browser.