source: src/Parser/ParseNode.h@ c0714bf

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 c0714bf was 513e165, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

generalize types for encoded strings, and fold simple ExpressionNode build routines into parser

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