source: src/Parser/ParseNode.h@ ee3c93d

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum with_gc
Last change on this file since ee3c93d was ee3c93d, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Add support for while loops with control declarations

  • Property mode set to 100644
File size: 19.8 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 : Mon Apr 30 09:19:17 2018
13// Update Count : 831
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 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() << std::endl;
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 private:
139 bool extension = false;
140 std::unique_ptr<Expression> expr;
141}; // ExpressionNode
142
143template< typename T >
144struct maybeBuild_t< Expression, T > {
145 static inline Expression * doit( const T * orig ) {
146 if ( orig ) {
147 Expression * p = orig->build();
148 p->set_extension( orig->get_extension() );
149 p->location = orig->location;
150 return p;
151 } else {
152 return nullptr;
153 } // if
154 }
155};
156
157// Must harmonize with OperName.
158enum class OperKinds {
159 // diadic
160 SizeOf, AlignOf, OffsetOf, Plus, Minus, Exp, Mul, Div, Mod, Or, And,
161 BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
162 Assign, AtAssn, ExpAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
163 Index, Range,
164 // monadic
165 UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
166 Ctor, Dtor,
167}; // OperKinds
168
169struct LabelNode {
170 std::list< Label > labels;
171};
172
173Expression * build_constantInteger( std::string &str );
174Expression * build_constantFloat( std::string &str );
175Expression * build_constantChar( std::string &str );
176Expression * build_constantStr( std::string &str );
177Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
178Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
179Expression * build_field_name_FLOATINGconstant( const std::string & str );
180Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
181
182NameExpr * build_varref( const std::string * name );
183
184Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
185Expression * build_keyword_cast( KeywordCastExpr::Target target, ExpressionNode * expr_node );
186Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
187Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
188Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
189Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
190Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
191Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
192Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
193Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
194Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
195Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
196Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
197Expression * build_tuple( ExpressionNode * expr_node = nullptr );
198Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
199Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
200
201//##############################################################################
202
203struct TypeData;
204
205class DeclarationNode : public ParseNode {
206 public:
207 // These enumerations must harmonize with their names.
208 enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, Int128, Float80, Float128, NoBasicType };
209 static const char * basicTypeNames[];
210 enum ComplexType { Complex, Imaginary, NoComplexType };
211 static const char * complexTypeNames[];
212 enum Signedness { Signed, Unsigned, NoSignedness };
213 static const char * signednessNames[];
214 enum Length { Short, Long, LongLong, NoLength };
215 static const char * lengthNames[];
216 enum Aggregate { Struct, Union, Exception, Trait, Coroutine, Monitor, Thread, NoAggregate };
217 static const char * aggregateNames[];
218 enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
219 static const char * typeClassNames[];
220 enum BuiltinType { Valist, Zero, One, NoBuiltinType };
221 static const char * builtinTypeNames[];
222
223 static DeclarationNode * newStorageClass( Type::StorageClasses );
224 static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
225 static DeclarationNode * newTypeQualifier( Type::Qualifiers );
226 static DeclarationNode * newBasicType( BasicType );
227 static DeclarationNode * newComplexType( ComplexType );
228 static DeclarationNode * newSignedNess( Signedness );
229 static DeclarationNode * newLength( Length );
230 static DeclarationNode * newBuiltinType( BuiltinType );
231 static DeclarationNode * newForall( DeclarationNode * );
232 static DeclarationNode * newFromTypedef( std::string * );
233 static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
234 static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
235 static DeclarationNode * newEnum( std::string * name, DeclarationNode * constants, bool body );
236 static DeclarationNode * newEnumConstant( std::string * name, ExpressionNode * constant );
237 static DeclarationNode * newName( std::string * );
238 static DeclarationNode * newFromTypeGen( std::string *, ExpressionNode * params );
239 static DeclarationNode * newTypeParam( TypeClass, std::string * );
240 static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
241 static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
242 static DeclarationNode * newTypeDecl( std::string * name, DeclarationNode * typeParams );
243 static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
244 static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
245 static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
246 static DeclarationNode * newBitfield( ExpressionNode * size );
247 static DeclarationNode * newTuple( DeclarationNode * members );
248 static DeclarationNode * newTypeof( ExpressionNode * expr );
249 static DeclarationNode * newAttr( std::string *, ExpressionNode * expr ); // @ attributes
250 static DeclarationNode * newAttr( std::string *, DeclarationNode * type ); // @ attributes
251 static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
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 public:
304 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
305
306 struct Variable_t {
307// const std::string * name;
308 DeclarationNode::TypeClass tyClass;
309 DeclarationNode * assertions;
310 DeclarationNode * initializer;
311 };
312 Variable_t variable;
313
314 struct Attr_t {
315// const std::string * name;
316 ExpressionNode * expr;
317 DeclarationNode * type;
318 };
319 Attr_t attr;
320
321 struct StaticAssert_t {
322 ExpressionNode * condition;
323 Expression * message;
324 };
325 StaticAssert_t assert;
326
327 BuiltinType builtin;
328
329 TypeData * type;
330
331 Type::FuncSpecifiers funcSpecs;
332 Type::StorageClasses storageClasses;
333
334 ExpressionNode * bitfieldWidth;
335 std::unique_ptr<ExpressionNode> enumeratorValue;
336 bool hasEllipsis;
337 LinkageSpec::Spec linkage;
338 Expression * asmName;
339 std::list< Attribute * > attributes;
340 InitializerNode * initializer;
341 bool extension = false;
342 std::string error;
343 StatementNode * asmStmt;
344
345 static UniqueName anonymous;
346}; // DeclarationNode
347
348Type * buildType( TypeData * type );
349
350static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
351 Type * ret = orig ? orig->buildType() : nullptr;
352 delete orig;
353 return ret;
354}
355
356//##############################################################################
357
358class StatementNode final : public ParseNode {
359 public:
360 StatementNode() { stmt = nullptr; }
361 StatementNode( Statement * stmt ) : stmt( stmt ) {}
362 StatementNode( DeclarationNode * decl );
363 virtual ~StatementNode() {}
364
365 virtual StatementNode * clone() const final { assert( false ); return nullptr; }
366 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
367
368 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
369 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
370 delete attr;
371 delete name;
372 return this;
373 }
374
375 virtual StatementNode * append_last_case( StatementNode * );
376
377 virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
378 os << stmt.get() << std::endl;
379 }
380 private:
381 std::unique_ptr<Statement> stmt;
382}; // StatementNode
383
384Statement * build_expr( ExpressionNode * ctl );
385
386struct IfCtl {
387 IfCtl( DeclarationNode * decl, ExpressionNode * condition ) :
388 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
389
390 StatementNode * init;
391 ExpressionNode * condition;
392};
393
394struct ForCtl {
395 ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
396 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
397 ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
398 init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
399
400 StatementNode * init;
401 ExpressionNode * condition;
402 ExpressionNode * change;
403};
404
405Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init );
406Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
407Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
408Statement * build_case( ExpressionNode * ctl );
409Statement * build_default();
410Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
411Statement * build_for( ForCtl * forctl, StatementNode * stmt );
412Statement * build_branch( BranchStmt::Type kind );
413Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
414Statement * build_computedgoto( ExpressionNode * ctl );
415Statement * build_return( ExpressionNode * ctl );
416Statement * build_throw( ExpressionNode * ctl );
417Statement * build_resume( ExpressionNode * ctl );
418Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
419Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
420Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
421Statement * build_finally( StatementNode * stmt );
422Statement * build_compound( StatementNode * first );
423Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
424Statement * build_directive( std::string * directive );
425WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
426WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
427WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
428WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
429WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
430
431//##############################################################################
432
433template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
434void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
435 SemanticErrorException errors;
436 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
437 const NodeType * cur = firstNode;
438
439 while ( cur ) {
440 try {
441 SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
442 if ( result ) {
443 result->location = cur->location;
444 * out++ = result;
445 } else {
446 assertf(false, "buildList unknown type");
447 } // if
448 } catch( SemanticErrorException &e ) {
449 errors.append( e );
450 } // try
451 cur = dynamic_cast< NodeType * >( cur->get_next() );
452 } // while
453 if ( ! errors.isEmpty() ) {
454 throw errors;
455 } // if
456}
457
458// in DeclarationNode.cc
459void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
460void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
461void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
462
463template< typename SynTreeType, typename NodeType >
464void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
465 buildList( firstNode, outputList );
466 delete firstNode;
467}
468
469// in ParseNode.cc
470std::ostream & operator<<( std::ostream & out, const ParseNode * node );
471
472// Local Variables: //
473// tab-width: 4 //
474// mode: c++ //
475// compile-command: "make install" //
476// End: //
Note: See TracBrowser for help on using the repository browser.