source: src/Parser/ParseNode.h@ db70fe4

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

move code from ExpressionNode into parser

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