source: src/Parser/ParseNode.h@ 1b772749

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

more refactoring of parser code

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