source: src/Parser/ParseNode.h@ 2988eeb

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

first attempt to create function specifiers

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