source: src/Parser/ParseNode.h@ 6e8bd43

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 stuck-waitfor-destruct with_gc
Last change on this file since 6e8bd43 was 6e8bd43, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

cleanup interface to qualifiers/specifiers

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