source: src/Parser/ParseNode.h@ 633a642

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 633a642 was 5fcba14, checked in by Rob Schluntz <rschlunt@…>, 8 years ago

Implement function declaration's with clause

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