source: src/Parser/ParseNode.h@ 679e644

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 no_list persistent-indexer pthread-emulation qualifiedEnum
Last change on this file since 679e644 was 679e644, checked in by Peter A. Buhr <pabuhr@…>, 7 years ago

extend plan 9, anonymous declarations, change token for default argument

  • Property mode set to 100644
File size: 20.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 : Wed Jul 18 17:35:55 2018
13// Update Count : 844
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() << 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 ); // these 4 routines modify the string
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( const std::string * );
233 static DeclarationNode * newFromGlobalScope();
234 static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
235 static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
236 static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
237 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body );
238 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
239 static DeclarationNode * newName( const std::string * );
240 static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
241 static DeclarationNode * newTypeParam( TypeClass, const std::string * );
242 static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
243 static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
244 static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
245 static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
246 static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
247 static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
248 static DeclarationNode * newBitfield( ExpressionNode * size );
249 static DeclarationNode * newTuple( DeclarationNode * members );
250 static DeclarationNode * newTypeof( ExpressionNode * expr );
251 static DeclarationNode * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes
252 static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes
253 static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
254 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
255 static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
256
257 DeclarationNode();
258 ~DeclarationNode();
259 DeclarationNode * clone() const override;
260
261 DeclarationNode * addQualifiers( DeclarationNode * );
262 void checkQualifiers( const TypeData *, const TypeData * );
263 void checkSpecifiers( DeclarationNode * );
264 DeclarationNode * copySpecifiers( DeclarationNode * );
265 DeclarationNode * addType( DeclarationNode * );
266 DeclarationNode * addTypedef();
267 DeclarationNode * addAssertions( DeclarationNode * );
268 DeclarationNode * addName( std::string * );
269 DeclarationNode * addAsmName( DeclarationNode * );
270 DeclarationNode * addBitfield( ExpressionNode * size );
271 DeclarationNode * addVarArgs();
272 DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
273 DeclarationNode * addOldDeclList( DeclarationNode * list );
274 DeclarationNode * setBase( TypeData * newType );
275 DeclarationNode * copyAttribute( DeclarationNode * attr );
276 DeclarationNode * addPointer( DeclarationNode * qualifiers );
277 DeclarationNode * addArray( DeclarationNode * array );
278 DeclarationNode * addNewPointer( DeclarationNode * pointer );
279 DeclarationNode * addNewArray( DeclarationNode * array );
280 DeclarationNode * addParamList( DeclarationNode * list );
281 DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
282 DeclarationNode * addInitializer( InitializerNode * init );
283 DeclarationNode * addTypeInitializer( DeclarationNode * init );
284
285 DeclarationNode * cloneType( std::string * newName );
286 DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
287
288 DeclarationNode * appendList( DeclarationNode * node ) {
289 return (DeclarationNode *)set_last( node );
290 }
291
292 virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
293 virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
294
295 Declaration * build() const;
296 Type * buildType() const;
297
298 LinkageSpec::Spec get_linkage() const { return linkage; }
299 DeclarationNode * extractAggregate() const;
300 bool has_enumeratorValue() const { return (bool)enumeratorValue; }
301 ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
302
303 bool get_extension() const { return extension; }
304 DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
305 public:
306 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
307
308 struct Variable_t {
309// const std::string * name;
310 DeclarationNode::TypeClass tyClass;
311 DeclarationNode * assertions;
312 DeclarationNode * initializer;
313 };
314 Variable_t variable;
315
316 struct Attr_t {
317// const std::string * name;
318 ExpressionNode * expr;
319 DeclarationNode * type;
320 };
321 Attr_t attr;
322
323 struct StaticAssert_t {
324 ExpressionNode * condition;
325 Expression * message;
326 };
327 StaticAssert_t assert;
328
329 BuiltinType builtin;
330
331 TypeData * type;
332
333 bool inLine;
334 Type::FuncSpecifiers funcSpecs;
335 Type::StorageClasses storageClasses;
336
337 ExpressionNode * bitfieldWidth;
338 std::unique_ptr<ExpressionNode> enumeratorValue;
339 bool hasEllipsis;
340 LinkageSpec::Spec linkage;
341 Expression * asmName;
342 std::list< Attribute * > attributes;
343 InitializerNode * initializer;
344 bool extension = false;
345 std::string error;
346 StatementNode * asmStmt;
347
348 static UniqueName anonymous;
349}; // DeclarationNode
350
351Type * buildType( TypeData * type );
352
353static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
354 Type * ret = orig ? orig->buildType() : nullptr;
355 delete orig;
356 return ret;
357}
358
359//##############################################################################
360
361class StatementNode final : public ParseNode {
362 public:
363 StatementNode() { stmt = nullptr; }
364 StatementNode( Statement * stmt ) : stmt( stmt ) {}
365 StatementNode( DeclarationNode * decl );
366 virtual ~StatementNode() {}
367
368 virtual StatementNode * clone() const final { assert( false ); return nullptr; }
369 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
370
371 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
372 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
373 delete attr;
374 delete name;
375 return this;
376 }
377
378 virtual StatementNode * append_last_case( StatementNode * );
379
380 virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
381 os << stmt.get() << std::endl;
382 }
383 private:
384 std::unique_ptr<Statement> stmt;
385}; // StatementNode
386
387Statement * build_expr( ExpressionNode * ctl );
388
389struct IfCtl {
390 IfCtl( DeclarationNode * decl, ExpressionNode * condition ) :
391 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
392
393 StatementNode * init;
394 ExpressionNode * condition;
395};
396
397struct ForCtl {
398 ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
399 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
400 ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
401 init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
402
403 StatementNode * init;
404 ExpressionNode * condition;
405 ExpressionNode * change;
406};
407
408Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init );
409Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
410Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
411Statement * build_case( ExpressionNode * ctl );
412Statement * build_default();
413Statement * build_while( IfCtl * ctl, StatementNode * stmt );
414Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt );
415Statement * build_for( ForCtl * forctl, StatementNode * stmt );
416Statement * build_branch( BranchStmt::Type kind );
417Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
418Statement * build_computedgoto( ExpressionNode * ctl );
419Statement * build_return( ExpressionNode * ctl );
420Statement * build_throw( ExpressionNode * ctl );
421Statement * build_resume( ExpressionNode * ctl );
422Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
423Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
424Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
425Statement * build_finally( StatementNode * stmt );
426Statement * build_compound( StatementNode * first );
427Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
428Statement * build_directive( std::string * directive );
429WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
430WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
431WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
432WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
433WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
434
435//##############################################################################
436
437template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
438void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
439 SemanticErrorException errors;
440 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
441 const NodeType * cur = firstNode;
442
443 while ( cur ) {
444 try {
445 SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
446 if ( result ) {
447 result->location = cur->location;
448 * out++ = result;
449 } else {
450 assertf(false, "buildList unknown type");
451 } // if
452 } catch( SemanticErrorException &e ) {
453 errors.append( e );
454 } // try
455 cur = dynamic_cast< NodeType * >( cur->get_next() );
456 } // while
457 if ( ! errors.isEmpty() ) {
458 throw errors;
459 } // if
460}
461
462// in DeclarationNode.cc
463void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
464void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
465void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
466
467template< typename SynTreeType, typename NodeType >
468void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
469 buildList( firstNode, outputList );
470 delete firstNode;
471}
472
473// in ParseNode.cc
474std::ostream & operator<<( std::ostream & out, const ParseNode * node );
475
476// Local Variables: //
477// tab-width: 4 //
478// mode: c++ //
479// compile-command: "make install" //
480// End: //
Note: See TracBrowser for help on using the repository browser.