source: src/Parser/ParseNode.h@ cb4bbb6

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 cb4bbb6 was 6d539f83, checked in by Peter A. Buhr <pabuhr@…>, 7 years ago

rename functions

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