source: src/Parser/ParseNode.h@ 0a2168f

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 0a2168f was a16764a6, checked in by Thierry Delisle <tdelisle@…>, 8 years ago

Changed warning system to prepare for toggling warnings

  • Property mode set to 100644
File size: 19.3 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 Feb 22 17:49:31 2018
13// Update Count : 827
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_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
182Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
183Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
184Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
185Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
186Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
187Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
188Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
189Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
190Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
191Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
192Expression * build_tuple( ExpressionNode * expr_node = nullptr );
193Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
194Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
195
196//##############################################################################
197
198struct TypeData;
199
200class DeclarationNode : public ParseNode {
201 public:
202 // These enumerations must harmonize with their names.
203 enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, Int128, Float80, Float128, NoBasicType };
204 static const char * basicTypeNames[];
205 enum ComplexType { Complex, Imaginary, NoComplexType };
206 static const char * complexTypeNames[];
207 enum Signedness { Signed, Unsigned, NoSignedness };
208 static const char * signednessNames[];
209 enum Length { Short, Long, LongLong, NoLength };
210 static const char * lengthNames[];
211 enum Aggregate { Struct, Union, Exception, Trait, Coroutine, Monitor, Thread, NoAggregate };
212 static const char * aggregateNames[];
213 enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
214 static const char * typeClassNames[];
215 enum BuiltinType { Valist, Zero, One, NoBuiltinType };
216 static const char * builtinTypeNames[];
217
218 static DeclarationNode * newStorageClass( Type::StorageClasses );
219 static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
220 static DeclarationNode * newTypeQualifier( Type::Qualifiers );
221 static DeclarationNode * newBasicType( BasicType );
222 static DeclarationNode * newComplexType( ComplexType );
223 static DeclarationNode * newSignedNess( Signedness );
224 static DeclarationNode * newLength( Length );
225 static DeclarationNode * newBuiltinType( BuiltinType );
226 static DeclarationNode * newForall( DeclarationNode * );
227 static DeclarationNode * newFromTypedef( std::string * );
228 static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
229 static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
230 static DeclarationNode * newEnum( std::string * name, DeclarationNode * constants, bool body );
231 static DeclarationNode * newEnumConstant( std::string * name, ExpressionNode * constant );
232 static DeclarationNode * newName( std::string * );
233 static DeclarationNode * newFromTypeGen( std::string *, ExpressionNode * params );
234 static DeclarationNode * newTypeParam( TypeClass, std::string * );
235 static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
236 static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
237 static DeclarationNode * newTypeDecl( std::string * name, DeclarationNode * typeParams );
238 static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
239 static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
240 static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
241 static DeclarationNode * newBitfield( ExpressionNode * size );
242 static DeclarationNode * newTuple( DeclarationNode * members );
243 static DeclarationNode * newTypeof( ExpressionNode * expr );
244 static DeclarationNode * newAttr( std::string *, ExpressionNode * expr ); // @ attributes
245 static DeclarationNode * newAttr( std::string *, DeclarationNode * type ); // @ attributes
246 static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
247 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
248
249 DeclarationNode();
250 ~DeclarationNode();
251 DeclarationNode * clone() const override;
252
253 DeclarationNode * addQualifiers( DeclarationNode * );
254 void checkQualifiers( const TypeData *, const TypeData * );
255 void checkSpecifiers( DeclarationNode * );
256 DeclarationNode * copySpecifiers( DeclarationNode * );
257 DeclarationNode * addType( DeclarationNode * );
258 DeclarationNode * addTypedef();
259 DeclarationNode * addAssertions( DeclarationNode * );
260 DeclarationNode * addName( std::string * );
261 DeclarationNode * addAsmName( DeclarationNode * );
262 DeclarationNode * addBitfield( ExpressionNode * size );
263 DeclarationNode * addVarArgs();
264 DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
265 DeclarationNode * addOldDeclList( DeclarationNode * list );
266 DeclarationNode * setBase( TypeData * newType );
267 DeclarationNode * copyAttribute( DeclarationNode * attr );
268 DeclarationNode * addPointer( DeclarationNode * qualifiers );
269 DeclarationNode * addArray( DeclarationNode * array );
270 DeclarationNode * addNewPointer( DeclarationNode * pointer );
271 DeclarationNode * addNewArray( DeclarationNode * array );
272 DeclarationNode * addParamList( DeclarationNode * list );
273 DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
274 DeclarationNode * addInitializer( InitializerNode * init );
275 DeclarationNode * addTypeInitializer( DeclarationNode * 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( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
285 virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
286
287 Declaration * build() const;
288 Type * buildType() const;
289
290 LinkageSpec::Spec get_linkage() const { return linkage; }
291 DeclarationNode * extractAggregate() const;
292 bool has_enumeratorValue() const { return (bool)enumeratorValue; }
293 ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
294
295 bool get_extension() const { return extension; }
296 DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
297 public:
298 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
299
300 struct Variable_t {
301// const std::string * name;
302 DeclarationNode::TypeClass tyClass;
303 DeclarationNode * assertions;
304 DeclarationNode * initializer;
305 };
306 Variable_t variable;
307
308 struct Attr_t {
309// const std::string * name;
310 ExpressionNode * expr;
311 DeclarationNode * type;
312 };
313 Attr_t attr;
314
315 BuiltinType builtin;
316
317 TypeData * type;
318
319 Type::FuncSpecifiers funcSpecs;
320 Type::StorageClasses storageClasses;
321
322 ExpressionNode * bitfieldWidth;
323 std::unique_ptr<ExpressionNode> enumeratorValue;
324 bool hasEllipsis;
325 LinkageSpec::Spec linkage;
326 Expression *asmName;
327 std::list< Attribute * > attributes;
328 InitializerNode * initializer;
329 bool extension = false;
330 std::string error;
331 StatementNode * asmStmt;
332
333 static UniqueName anonymous;
334}; // DeclarationNode
335
336Type * buildType( TypeData * type );
337
338static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
339 Type * ret = orig ? orig->buildType() : nullptr;
340 delete orig;
341 return ret;
342}
343
344//##############################################################################
345
346class StatementNode final : public ParseNode {
347 public:
348 StatementNode() { stmt = nullptr; }
349 StatementNode( Statement * stmt ) : stmt( stmt ) {}
350 StatementNode( DeclarationNode * decl );
351 virtual ~StatementNode() {}
352
353 virtual StatementNode * clone() const final { assert( false ); return nullptr; }
354 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
355
356 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
357 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
358 delete attr;
359 delete name;
360 return this;
361 }
362
363 virtual StatementNode * append_last_case( StatementNode * );
364
365 virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
366 os << stmt.get() << std::endl;
367 }
368 private:
369 std::unique_ptr<Statement> stmt;
370}; // StatementNode
371
372Statement * build_expr( ExpressionNode * ctl );
373
374struct IfCtl {
375 IfCtl( DeclarationNode * decl, ExpressionNode * condition ) :
376 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
377
378 StatementNode * init;
379 ExpressionNode * condition;
380};
381
382struct ForCtl {
383 ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
384 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
385 ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
386 init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
387
388 StatementNode * init;
389 ExpressionNode * condition;
390 ExpressionNode * change;
391};
392
393Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
394Statement * build_switch( ExpressionNode * ctl, StatementNode * stmt );
395Statement * build_case( ExpressionNode * ctl );
396Statement * build_default();
397Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
398Statement * build_for( ForCtl * forctl, StatementNode * stmt );
399Statement * build_branch( BranchStmt::Type kind );
400Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
401Statement * build_computedgoto( ExpressionNode * ctl );
402Statement * build_return( ExpressionNode * ctl );
403Statement * build_throw( ExpressionNode * ctl );
404Statement * build_resume( ExpressionNode * ctl );
405Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
406Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
407Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
408Statement * build_finally( StatementNode * stmt );
409Statement * build_compound( StatementNode * first );
410Statement * build_asmstmt( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
411WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
412WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
413WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
414WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
415WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
416
417//##############################################################################
418
419template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
420void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
421 SemanticErrorException errors;
422 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
423 const NodeType * cur = firstNode;
424
425 while ( cur ) {
426 try {
427 SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
428 if ( result ) {
429 result->location = cur->location;
430 * out++ = result;
431 } else {
432 assertf(false, "buildList unknown type");
433 } // if
434 } catch( SemanticErrorException &e ) {
435 errors.append( e );
436 } // try
437 cur = dynamic_cast< NodeType * >( cur->get_next() );
438 } // while
439 if ( ! errors.isEmpty() ) {
440 throw errors;
441 } // if
442}
443
444// in DeclarationNode.cc
445void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
446void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
447void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
448
449template< typename SynTreeType, typename NodeType >
450void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
451 buildList( firstNode, outputList );
452 delete firstNode;
453}
454
455// in ParseNode.cc
456std::ostream & operator<<( std::ostream & out, const ParseNode * node );
457
458// Local Variables: //
459// tab-width: 4 //
460// mode: c++ //
461// compile-command: "make install" //
462// End: //
Note: See TracBrowser for help on using the repository browser.