source: src/Parser/ParseNode.h@ 888339e

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 888339e was d48e529, checked in by Rob Schluntz <rschlunt@…>, 8 years ago

Begin to introduce support for yylloc in the parser and extend CodeLocation to include start column and end column/line number information

  • Property mode set to 100644
File size: 19.2 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 : Thu Sep 14 23:09:39 2017
13// Update Count : 815
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 char * yyfilename;
50extern int yylineno;
51extern YYLTYPE yylloc;
52
53class ParseNode {
54 public:
55 ParseNode() {};
56 virtual ~ParseNode() { delete next; delete name; };
57 virtual ParseNode * clone() const = 0;
58
59 ParseNode * get_next() const { return next; }
60 ParseNode * set_next( ParseNode * newlink ) { next = newlink; return this; }
61
62 ParseNode * get_last() {
63 ParseNode * current;
64 for ( current = this; current->get_next() != nullptr; current = current->get_next() );
65 return current;
66 }
67 ParseNode * set_last( ParseNode * newlast ) {
68 if ( newlast != nullptr ) get_last()->set_next( newlast );
69 return this;
70 }
71
72 virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
73 virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
74
75 static int indent_by;
76
77 ParseNode * next = nullptr;
78 std::string * name = nullptr;
79 CodeLocation location = yylloc;
80}; // ParseNode
81
82//##############################################################################
83
84class InitializerNode : public ParseNode {
85 public:
86 InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr );
87 InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
88 ~InitializerNode();
89 virtual InitializerNode * clone() const { assert( false ); return nullptr; }
90
91 ExpressionNode * get_expression() const { return expr; }
92
93 InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
94 ExpressionNode * get_designators() const { return designator; }
95
96 InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
97 bool get_maybeConstructed() const { return maybeConstructed; }
98
99 InitializerNode * next_init() const { return kids; }
100
101 void print( std::ostream &os, int indent = 0 ) const;
102 void printOneLine( std::ostream & ) const;
103
104 virtual Initializer * build() const;
105 private:
106 ExpressionNode * expr;
107 bool aggregate;
108 ExpressionNode * designator; // may be list
109 InitializerNode * kids;
110 bool maybeConstructed;
111}; // InitializerNode
112
113//##############################################################################
114
115class ExpressionNode final : public ParseNode {
116 public:
117 ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
118 virtual ~ExpressionNode() {}
119 virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
120
121 bool get_extension() const { return extension; }
122 ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
123
124 virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
125 void printOneLine( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
126
127 template<typename T>
128 bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
129
130 Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
131 private:
132 bool extension = false;
133 std::unique_ptr<Expression> expr;
134}; // ExpressionNode
135
136template< typename T >
137struct maybeBuild_t< Expression, T > {
138 static inline Expression * doit( const T * orig ) {
139 if ( orig ) {
140 Expression * p = orig->build();
141 p->set_extension( orig->get_extension() );
142 p->location = orig->location;
143 return p;
144 } else {
145 return nullptr;
146 } // if
147 }
148};
149
150// Must harmonize with OperName.
151enum class OperKinds {
152 // diadic
153 SizeOf, AlignOf, OffsetOf, Plus, Minus, Exp, Mul, Div, Mod, Or, And,
154 BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
155 Assign, AtAssn, ExpAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
156 Index, Range,
157 // monadic
158 UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
159 Ctor, Dtor,
160}; // OperKinds
161
162struct LabelNode {
163 std::list< Label > labels;
164};
165
166Expression * build_constantInteger( std::string &str );
167Expression * build_constantFloat( std::string &str );
168Expression * build_constantChar( std::string &str );
169Expression * build_constantStr( std::string &str );
170Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
171Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
172Expression * build_field_name_FLOATINGconstant( const std::string & str );
173Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
174
175NameExpr * build_varref( const std::string * name );
176
177Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
178Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
179Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
180Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
181Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
182Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
183Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
184Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
185Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
186Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
187Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
188Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
189Expression * build_tuple( ExpressionNode * expr_node = nullptr );
190Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
191Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
192
193//##############################################################################
194
195struct TypeData;
196
197class DeclarationNode : public ParseNode {
198 public:
199 enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, NoBasicType };
200 enum ComplexType { Complex, Imaginary, NoComplexType };
201 enum Signedness { Signed, Unsigned, NoSignedness };
202 enum Length { Short, Long, LongLong, NoLength };
203 enum Aggregate { Struct, Union, Trait, Coroutine, Monitor, Thread, NoAggregate };
204 enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
205 enum BuiltinType { Valist, Zero, One, NoBuiltinType };
206
207 static const char * basicTypeNames[];
208 static const char * complexTypeNames[];
209 static const char * signednessNames[];
210 static const char * lengthNames[];
211 static const char * aggregateNames[];
212 static const char * typeClassNames[];
213 static const char * builtinTypeNames[];
214
215 static DeclarationNode * newStorageClass( Type::StorageClasses );
216 static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
217 static DeclarationNode * newTypeQualifier( Type::Qualifiers );
218 static DeclarationNode * newBasicType( BasicType );
219 static DeclarationNode * newComplexType( ComplexType );
220 static DeclarationNode * newSignedNess( Signedness );
221 static DeclarationNode * newLength( Length );
222 static DeclarationNode * newBuiltinType( BuiltinType );
223 static DeclarationNode * newForall( DeclarationNode * );
224 static DeclarationNode * newFromTypedef( std::string * );
225 static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body, bool newStyle = false );
226 static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
227 static DeclarationNode * newEnum( std::string * name, DeclarationNode * constants, bool body );
228 static DeclarationNode * newEnumConstant( std::string * name, ExpressionNode * constant );
229 static DeclarationNode * newName( std::string * );
230 static DeclarationNode * newFromTypeGen( std::string *, ExpressionNode * params );
231 static DeclarationNode * newTypeParam( TypeClass, std::string * );
232 static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
233 static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
234 static DeclarationNode * newTypeDecl( std::string * name, DeclarationNode * typeParams );
235 static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
236 static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
237 static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
238 static DeclarationNode * newBitfield( ExpressionNode * size );
239 static DeclarationNode * newTuple( DeclarationNode * members );
240 static DeclarationNode * newTypeof( ExpressionNode * expr );
241 static DeclarationNode * newAttr( std::string *, ExpressionNode * expr ); // @ attributes
242 static DeclarationNode * newAttr( std::string *, DeclarationNode * type ); // @ attributes
243 static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
244 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
245
246 DeclarationNode();
247 ~DeclarationNode();
248 DeclarationNode * clone() const override;
249
250 DeclarationNode * addQualifiers( DeclarationNode * );
251 void checkQualifiers( const TypeData *, const TypeData * );
252 void checkSpecifiers( DeclarationNode * );
253 DeclarationNode * copySpecifiers( DeclarationNode * );
254 DeclarationNode * addType( DeclarationNode * );
255 DeclarationNode * addTypedef();
256 DeclarationNode * addAssertions( DeclarationNode * );
257 DeclarationNode * addName( std::string * );
258 DeclarationNode * addAsmName( DeclarationNode * );
259 DeclarationNode * addBitfield( ExpressionNode * size );
260 DeclarationNode * addVarArgs();
261 DeclarationNode * addFunctionBody( StatementNode * body );
262 DeclarationNode * addOldDeclList( DeclarationNode * list );
263 DeclarationNode * setBase( TypeData * newType );
264 DeclarationNode * copyAttribute( DeclarationNode * attr );
265 DeclarationNode * addPointer( DeclarationNode * qualifiers );
266 DeclarationNode * addArray( DeclarationNode * array );
267 DeclarationNode * addNewPointer( DeclarationNode * pointer );
268 DeclarationNode * addNewArray( DeclarationNode * array );
269 DeclarationNode * addParamList( DeclarationNode * list );
270 DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
271 DeclarationNode * addInitializer( InitializerNode * init );
272 DeclarationNode * addTypeInitializer( DeclarationNode * 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( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
282 virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) 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 DeclarationNode * initializer;
301 };
302 Variable_t variable;
303
304 struct Attr_t {
305// const std::string * name;
306 ExpressionNode * expr;
307 DeclarationNode * type;
308 };
309 Attr_t attr;
310
311 BuiltinType builtin;
312
313 TypeData * type;
314
315 Type::FuncSpecifiers funcSpecs;
316 Type::StorageClasses storageClasses;
317
318 ExpressionNode * bitfieldWidth;
319 std::unique_ptr<ExpressionNode> enumeratorValue;
320 bool hasEllipsis;
321 LinkageSpec::Spec linkage;
322 Expression *asmName;
323 std::list< Attribute * > attributes;
324 InitializerNode * initializer;
325 bool extension = false;
326 std::string error;
327 StatementNode * asmStmt;
328
329 static UniqueName anonymous;
330}; // DeclarationNode
331
332Type * buildType( TypeData * type );
333
334static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
335 Type * ret = orig ? orig->buildType() : nullptr;
336 delete orig;
337 return ret;
338}
339
340//##############################################################################
341
342class StatementNode final : public ParseNode {
343 public:
344 StatementNode() { stmt = nullptr; }
345 StatementNode( Statement * stmt ) : stmt( stmt ) {}
346 StatementNode( DeclarationNode * decl );
347 virtual ~StatementNode() {}
348
349 virtual StatementNode * clone() const final { assert( false ); return nullptr; }
350 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
351
352 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
353 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
354 delete attr;
355 delete name;
356 return this;
357 }
358
359 virtual StatementNode * append_last_case( StatementNode * );
360
361 virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
362 virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
363 private:
364 std::unique_ptr<Statement> stmt;
365}; // StatementNode
366
367Statement * build_expr( ExpressionNode * ctl );
368
369struct IfCtl {
370 IfCtl( DeclarationNode * decl, ExpressionNode * condition ) :
371 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
372
373 StatementNode * init;
374 ExpressionNode * condition;
375};
376
377struct ForCtl {
378 ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
379 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
380 ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
381 init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
382
383 StatementNode * init;
384 ExpressionNode * condition;
385 ExpressionNode * change;
386};
387
388Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
389Statement * build_switch( ExpressionNode * ctl, StatementNode * stmt );
390Statement * build_case( ExpressionNode * ctl );
391Statement * build_default();
392Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
393Statement * build_for( ForCtl * forctl, StatementNode * stmt );
394Statement * build_branch( BranchStmt::Type kind );
395Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
396Statement * build_computedgoto( ExpressionNode * ctl );
397Statement * build_return( ExpressionNode * ctl );
398Statement * build_throw( ExpressionNode * ctl );
399Statement * build_resume( ExpressionNode * ctl );
400Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
401Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
402Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
403Statement * build_finally( StatementNode * stmt );
404Statement * build_compound( StatementNode * first );
405Statement * build_asmstmt( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
406WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
407WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
408WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
409WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
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 } else {
426 assertf(false, "buildList unknown type");
427 } // if
428 } catch( SemanticError &e ) {
429 e.set_location( cur->location );
430 errors.append( e );
431 } // try
432 cur = dynamic_cast< NodeType * >( cur->get_next() );
433 } // while
434 if ( ! errors.isEmpty() ) {
435 throw errors;
436 } // if
437}
438
439// in DeclarationNode.cc
440void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
441void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
442void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
443
444template< typename SynTreeType, typename NodeType >
445void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
446 buildList( firstNode, outputList );
447 delete firstNode;
448}
449
450// in ParseNode.cc
451std::ostream & operator<<( std::ostream & out, const ParseNode * node );
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.