source: src/Parser/ParseNode.h@ e9e4e9ee

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 e9e4e9ee was 44a81853, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

first attempt at gcc attributes

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