source: src/Parser/ParseNode.h@ 1ed841f

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 resolv-new with_gc
Last change on this file since 1ed841f was 6eb4398, checked in by Rob Schluntz <rschlunt@…>, 8 years ago

recursively clone expression node lists

  • Property mode set to 100644
File size: 17.9 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 17 15:42:18 2017
13// Update Count : 777
14//
15
16#ifndef PARSENODE_H
17#define PARSENODE_H
18
19#include <string>
20#include <list>
21#include <iterator>
22#include <memory>
23
24#include "Parser/LinkageSpec.h"
25#include "SynTree/Type.h"
26#include "SynTree/Expression.h"
27#include "SynTree/Statement.h"
28#include "SynTree/Label.h"
29#include "Common/utility.h"
30#include "Common/UniqueName.h"
31
32class StatementNode;
33class CompoundStmtNode;
34class DeclarationNode;
35class ExpressionNode;
36class InitializerNode;
37class Attribute;
38
39//##############################################################################
40
41extern char * yyfilename;
42extern int yylineno;
43
44class ParseNode {
45 public:
46 ParseNode() {};
47 virtual ~ParseNode() { delete next; delete name; };
48 virtual ParseNode * clone() const = 0;
49
50 ParseNode * get_next() const { return next; }
51 ParseNode * set_next( ParseNode * newlink ) { next = newlink; return this; }
52
53 ParseNode * get_last() {
54 ParseNode * current;
55 for ( current = this; current->get_next() != nullptr; current = current->get_next() );
56 return current;
57 }
58 ParseNode * set_last( ParseNode * newlast ) {
59 if ( newlast != nullptr ) get_last()->set_next( newlast );
60 return this;
61 }
62
63 virtual void print( std::ostream &os, int indent = 0 ) const {}
64 virtual void printList( std::ostream &os, int indent = 0 ) const {}
65
66 static int indent_by;
67
68 ParseNode * next = nullptr;
69 std::string * name = nullptr;
70 CodeLocation location = { yyfilename, yylineno };
71}; // ParseNode
72
73//##############################################################################
74
75class InitializerNode : public ParseNode {
76 public:
77 InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr );
78 InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
79 ~InitializerNode();
80 virtual InitializerNode * clone() const { assert( false ); return nullptr; }
81
82 ExpressionNode * get_expression() const { return expr; }
83
84 InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
85 ExpressionNode * get_designators() const { return designator; }
86
87 InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
88 bool get_maybeConstructed() const { return maybeConstructed; }
89
90 InitializerNode * next_init() const { return kids; }
91
92 void print( std::ostream &os, int indent = 0 ) const;
93 void printOneLine( std::ostream & ) const;
94
95 virtual Initializer * build() const;
96 private:
97 ExpressionNode * expr;
98 bool aggregate;
99 ExpressionNode * designator; // may be list
100 InitializerNode * kids;
101 bool maybeConstructed;
102}; // InitializerNode
103
104//##############################################################################
105
106class ExpressionNode final : public ParseNode {
107 public:
108 ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
109 virtual ~ExpressionNode() {}
110 virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
111
112 bool get_extension() const { return extension; }
113 ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
114
115 virtual void print( std::ostream &os, int indent = 0 ) const override {}
116 void printOneLine( std::ostream &os, int indent = 0 ) const {}
117
118 template<typename T>
119 bool isExpressionType() const {
120 return nullptr != dynamic_cast<T>(expr.get());
121 }
122
123 Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
124 private:
125 bool extension = false;
126 std::unique_ptr<Expression> expr;
127}; // ExpressionNode
128
129template< typename T >
130struct maybeBuild_t< Expression, T > {
131 static inline Expression * doit( const T * orig ) {
132 if ( orig ) {
133 Expression * p = orig->build();
134 p->set_extension( orig->get_extension() );
135 p->location = orig->location;
136 return p;
137 } else {
138 return nullptr;
139 } // if
140 }
141};
142
143enum class OperKinds {
144 // diadic
145 SizeOf, AlignOf, OffsetOf, Plus, Minus, Mul, Div, Mod, Or, And,
146 BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
147 Assign, AtAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
148 Index, Range,
149 // monadic
150 UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress,
151 Ctor, Dtor,
152}; // OperKinds
153
154struct LabelNode {
155 std::list< Label > labels;
156};
157
158Expression * build_constantInteger( const std::string &str );
159Expression * build_constantFloat( const std::string &str );
160Expression * build_constantChar( const std::string &str );
161Expression * build_constantZeroOne( const std::string &str );
162ConstantExpr * build_constantStr( const std::string &str );
163Expression * build_field_name_FLOATINGconstant( const std::string & str );
164Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
165Expression * build_field_name_REALFRACTIONconstant( const std::string & str );
166Expression * build_field_name_REALDECIMALconstant( const std::string & str );
167
168NameExpr * build_varref( const std::string * name, bool labelp = false );
169Expression * build_typevalue( DeclarationNode * decl );
170
171Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
172Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
173Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
174Expression * build_addressOf( ExpressionNode * expr_node );
175Expression * build_sizeOfexpr( ExpressionNode * expr_node );
176Expression * build_sizeOftype( DeclarationNode * decl_node );
177Expression * build_alignOfexpr( ExpressionNode * expr_node );
178Expression * build_alignOftype( DeclarationNode * decl_node );
179Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
180Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
181Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
182Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
183Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
184Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
185Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
186Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
187Expression * build_comma( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
188Expression * build_attrexpr( NameExpr * var, ExpressionNode * expr_node );
189Expression * build_attrtype( NameExpr * var, DeclarationNode * decl_node );
190Expression * build_tuple( ExpressionNode * expr_node = nullptr );
191Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
192Expression * build_range( ExpressionNode * low, ExpressionNode * high );
193Expression * build_asmexpr( ExpressionNode * inout, ConstantExpr * constraint, ExpressionNode * operand );
194Expression * build_valexpr( StatementNode * s );
195Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
196
197//##############################################################################
198
199struct TypeData;
200
201class DeclarationNode : public ParseNode {
202 public:
203 enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, NoBasicType };
204 enum ComplexType { Complex, Imaginary, NoComplexType };
205 enum Signedness { Signed, Unsigned, NoSignedness };
206 enum Length { Short, Long, LongLong, NoLength };
207 enum Aggregate { Struct, Union, Trait, Coroutine, Monitor, Thread, NoAggregate };
208 enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
209 enum BuiltinType { Valist, Zero, One, NoBuiltinType };
210
211 static const char * basicTypeNames[];
212 static const char * complexTypeNames[];
213 static const char * signednessNames[];
214 static const char * lengthNames[];
215 static const char * aggregateNames[];
216 static const char * typeClassNames[];
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, bool newStyle = false );
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 );
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
250 DeclarationNode();
251 ~DeclarationNode();
252 DeclarationNode * clone() const override;
253
254 DeclarationNode * addQualifiers( DeclarationNode * );
255 void checkQualifiers( const TypeData *, const TypeData * );
256 void checkSpecifiers( DeclarationNode * );
257 DeclarationNode * copySpecifiers( DeclarationNode * );
258 DeclarationNode * addType( DeclarationNode * );
259 DeclarationNode * addTypedef();
260 DeclarationNode * addAssertions( DeclarationNode * );
261 DeclarationNode * addName( std::string * );
262 DeclarationNode * addAsmName( DeclarationNode * );
263 DeclarationNode * addBitfield( ExpressionNode * size );
264 DeclarationNode * addVarArgs();
265 DeclarationNode * addFunctionBody( StatementNode * body );
266 DeclarationNode * addOldDeclList( DeclarationNode * list );
267 DeclarationNode * setBase( TypeData * newType );
268 DeclarationNode * copyAttribute( DeclarationNode * attr );
269 DeclarationNode * addPointer( DeclarationNode * qualifiers );
270 DeclarationNode * addArray( DeclarationNode * array );
271 DeclarationNode * addNewPointer( DeclarationNode * pointer );
272 DeclarationNode * addNewArray( DeclarationNode * array );
273 DeclarationNode * addParamList( DeclarationNode * list );
274 DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
275 DeclarationNode * addInitializer( InitializerNode * init );
276
277 DeclarationNode * cloneType( std::string * newName );
278 DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
279
280 DeclarationNode * appendList( DeclarationNode * node ) {
281 return (DeclarationNode *)set_last( node );
282 }
283
284 virtual void print( std::ostream &os, int indent = 0 ) const override;
285 virtual void printList( std::ostream &os, int indent = 0 ) const override;
286
287 Declaration * build() const;
288 Type * buildType() const;
289
290 bool get_hasEllipsis() const;
291 LinkageSpec::Spec get_linkage() const { return linkage; }
292 DeclarationNode * extractAggregate() const;
293 bool has_enumeratorValue() const { return (bool)enumeratorValue; }
294 ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
295
296 bool get_extension() const { return extension; }
297 DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
298 public:
299 struct Variable_t {
300// const std::string * name;
301 DeclarationNode::TypeClass tyClass;
302 DeclarationNode * assertions;
303 };
304 Variable_t variable;
305
306 struct Attr_t {
307// const std::string * name;
308 ExpressionNode * expr;
309 DeclarationNode * type;
310 };
311 Attr_t attr;
312
313 BuiltinType builtin;
314
315 TypeData * type;
316
317 Type::FuncSpecifiers funcSpecs;
318 Type::StorageClasses storageClasses;
319
320 ExpressionNode * bitfieldWidth;
321 std::unique_ptr<ExpressionNode> enumeratorValue;
322 bool hasEllipsis;
323 LinkageSpec::Spec linkage;
324 ConstantExpr *asmName;
325 std::list< Attribute * > attributes;
326 InitializerNode * initializer;
327 bool extension = false;
328 std::string error;
329 StatementNode * asmStmt;
330
331 static UniqueName anonymous;
332}; // DeclarationNode
333
334Type * buildType( TypeData * type );
335
336static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
337 Type * ret = orig ? orig->buildType() : nullptr;
338 delete orig;
339 return ret;
340}
341
342//##############################################################################
343
344class StatementNode final : public ParseNode {
345 public:
346 StatementNode() { stmt = nullptr; }
347 StatementNode( Statement * stmt ) : stmt( stmt ) {}
348 StatementNode( DeclarationNode * decl );
349 virtual ~StatementNode() {}
350
351 virtual StatementNode * clone() const final { assert( false ); return nullptr; }
352 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
353
354 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
355 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
356 delete attr;
357 delete name;
358 return this;
359 }
360
361 virtual StatementNode * append_last_case( StatementNode * );
362
363 virtual void print( std::ostream &os, int indent = 0 ) const override {}
364 virtual void printList( std::ostream &os, int indent = 0 ) const override {}
365 private:
366 std::unique_ptr<Statement> stmt;
367}; // StatementNode
368
369Statement * build_expr( ExpressionNode * ctl );
370
371struct ForCtl {
372 ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
373 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
374 ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
375 init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
376
377 StatementNode * init;
378 ExpressionNode * condition;
379 ExpressionNode * change;
380};
381
382Statement * build_if( ExpressionNode * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
383Statement * build_switch( ExpressionNode * ctl, StatementNode * stmt );
384Statement * build_case( ExpressionNode * ctl );
385Statement * build_default();
386Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
387Statement * build_for( ForCtl * forctl, StatementNode * stmt );
388Statement * build_branch( BranchStmt::Type kind );
389Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
390Statement * build_computedgoto( ExpressionNode * ctl );
391Statement * build_return( ExpressionNode * ctl );
392Statement * build_throw( ExpressionNode * ctl );
393Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
394Statement * build_catch( DeclarationNode * decl, StatementNode * stmt, bool catchAny = false );
395Statement * build_finally( StatementNode * stmt );
396Statement * build_compound( StatementNode * first );
397Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
398
399//##############################################################################
400
401template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
402void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
403 SemanticError errors;
404 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
405 const NodeType * cur = firstNode;
406
407 while ( cur ) {
408 try {
409 SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
410 if ( result ) {
411 result->location = cur->location;
412 * out++ = result;
413 } // if
414 } catch( SemanticError &e ) {
415 e.set_location( cur->location );
416 errors.append( e );
417 } // try
418 cur = dynamic_cast< NodeType * >( cur->get_next() );
419 } // while
420 if ( ! errors.isEmpty() ) {
421 throw errors;
422 } // if
423}
424
425// in DeclarationNode.cc
426void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
427void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
428void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
429
430template< typename SynTreeType, typename NodeType >
431void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
432 buildList( firstNode, outputList );
433 delete firstNode;
434}
435
436// in ParseNode.cc
437std::ostream & operator<<( std::ostream & out, const ParseNode * node );
438
439#endif // PARSENODE_H
440
441// Local Variables: //
442// tab-width: 4 //
443// mode: c++ //
444// compile-command: "make install" //
445// End: //
Note: See TracBrowser for help on using the repository browser.