source: src/Parser/ParseNode.h@ ca37445

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 ca37445 was f6e3e34, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Add StaticAssertDecl node

  • Property mode set to 100644
File size: 19.5 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 static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
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, ExpressionNode * with = nullptr );
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 DeclarationNode * addTypeInitializer( DeclarationNode * init );
277
278 DeclarationNode * cloneType( std::string * newName );
279 DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
280
281 DeclarationNode * appendList( DeclarationNode * node ) {
282 return (DeclarationNode *)set_last( node );
283 }
284
285 virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
286 virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
287
288 Declaration * build() const;
289 Type * buildType() const;
290
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 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
300
301 struct Variable_t {
302// const std::string * name;
303 DeclarationNode::TypeClass tyClass;
304 DeclarationNode * assertions;
305 DeclarationNode * initializer;
306 };
307 Variable_t variable;
308
309 struct Attr_t {
310// const std::string * name;
311 ExpressionNode * expr;
312 DeclarationNode * type;
313 };
314 Attr_t attr;
315
316 struct StaticAssert_t {
317 ExpressionNode * condition;
318 Expression * message;
319 };
320 StaticAssert_t assert;
321
322 BuiltinType builtin;
323
324 TypeData * type;
325
326 Type::FuncSpecifiers funcSpecs;
327 Type::StorageClasses storageClasses;
328
329 ExpressionNode * bitfieldWidth;
330 std::unique_ptr<ExpressionNode> enumeratorValue;
331 bool hasEllipsis;
332 LinkageSpec::Spec linkage;
333 Expression *asmName;
334 std::list< Attribute * > attributes;
335 InitializerNode * initializer;
336 bool extension = false;
337 std::string error;
338 StatementNode * asmStmt;
339
340 static UniqueName anonymous;
341}; // DeclarationNode
342
343Type * buildType( TypeData * type );
344
345static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
346 Type * ret = orig ? orig->buildType() : nullptr;
347 delete orig;
348 return ret;
349}
350
351//##############################################################################
352
353class StatementNode final : public ParseNode {
354 public:
355 StatementNode() { stmt = nullptr; }
356 StatementNode( Statement * stmt ) : stmt( stmt ) {}
357 StatementNode( DeclarationNode * decl );
358 virtual ~StatementNode() {}
359
360 virtual StatementNode * clone() const final { assert( false ); return nullptr; }
361 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
362
363 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
364 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
365 delete attr;
366 delete name;
367 return this;
368 }
369
370 virtual StatementNode * append_last_case( StatementNode * );
371
372 virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
373 os << stmt.get() << std::endl;
374 }
375 private:
376 std::unique_ptr<Statement> stmt;
377}; // StatementNode
378
379Statement * build_expr( ExpressionNode * ctl );
380
381struct IfCtl {
382 IfCtl( DeclarationNode * decl, ExpressionNode * condition ) :
383 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
384
385 StatementNode * init;
386 ExpressionNode * condition;
387};
388
389struct ForCtl {
390 ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
391 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
392 ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
393 init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
394
395 StatementNode * init;
396 ExpressionNode * condition;
397 ExpressionNode * change;
398};
399
400Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
401Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
402Statement * build_case( ExpressionNode * ctl );
403Statement * build_default();
404Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
405Statement * build_for( ForCtl * forctl, StatementNode * stmt );
406Statement * build_branch( BranchStmt::Type kind );
407Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
408Statement * build_computedgoto( ExpressionNode * ctl );
409Statement * build_return( ExpressionNode * ctl );
410Statement * build_throw( ExpressionNode * ctl );
411Statement * build_resume( ExpressionNode * ctl );
412Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
413Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
414Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
415Statement * build_finally( StatementNode * stmt );
416Statement * build_compound( StatementNode * first );
417Statement * build_asmstmt( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
418WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
419WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
420WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
421WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
422WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
423
424//##############################################################################
425
426template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
427void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
428 SemanticErrorException errors;
429 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
430 const NodeType * cur = firstNode;
431
432 while ( cur ) {
433 try {
434 SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
435 if ( result ) {
436 result->location = cur->location;
437 * out++ = result;
438 } else {
439 assertf(false, "buildList unknown type");
440 } // if
441 } catch( SemanticErrorException &e ) {
442 errors.append( e );
443 } // try
444 cur = dynamic_cast< NodeType * >( cur->get_next() );
445 } // while
446 if ( ! errors.isEmpty() ) {
447 throw errors;
448 } // if
449}
450
451// in DeclarationNode.cc
452void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
453void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
454void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
455
456template< typename SynTreeType, typename NodeType >
457void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
458 buildList( firstNode, outputList );
459 delete firstNode;
460}
461
462// in ParseNode.cc
463std::ostream & operator<<( std::ostream & out, const ParseNode * node );
464
465// Local Variables: //
466// tab-width: 4 //
467// mode: c++ //
468// compile-command: "make install" //
469// End: //
Note: See TracBrowser for help on using the repository browser.