source: src/Parser/ParseNode.h@ 692c1cc

ADT ast-experimental
Last change on this file since 692c1cc was 4b60b28, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Moved parser utility from common utility file to the parserutility file.

  • Property mode set to 100644
File size: 21.7 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 Nov 2 21:27:07 2022
13// Update Count : 939
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
30#include "Parser/parserutility.h" // for maybeBuild
31#include "SynTree/LinkageSpec.h" // for Spec
32#include "SynTree/Declaration.h" // for Aggregate
33#include "SynTree/Expression.h" // for Expression, ConstantExpr (ptr only)
34#include "SynTree/Label.h" // for Label
35#include "SynTree/Statement.h" // for Statement, BranchStmt, BranchStmt:...
36#include "SynTree/Type.h" // for Type, Type::FuncSpecifiers, Type::...
37
38class Attribute;
39class Declaration;
40struct DeclarationNode;
41class DeclarationWithType;
42class Initializer;
43class ExpressionNode;
44struct StatementNode;
45
46//##############################################################################
47
48typedef CodeLocation YYLTYPE;
49#define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */
50
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( std::ostream & os, int indent = 0 ) const {
74 print( os, indent );
75 if ( next ) next->print( os, indent );
76 }
77
78 static int indent_by;
79
80 ParseNode * next = nullptr;
81 const std::string * name = nullptr;
82 CodeLocation location = yylloc;
83}; // ParseNode
84
85//##############################################################################
86
87class InitializerNode : public ParseNode {
88 public:
89 InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr );
90 InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
91 InitializerNode( bool isDelete );
92 ~InitializerNode();
93 virtual InitializerNode * clone() const { assert( false ); return nullptr; }
94
95 ExpressionNode * get_expression() const { return expr; }
96
97 InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
98 ExpressionNode * get_designators() const { return designator; }
99
100 InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
101 bool get_maybeConstructed() const { return maybeConstructed; }
102
103 bool get_isDelete() const { return isDelete; }
104
105 InitializerNode * next_init() const { return kids; }
106
107 void print( std::ostream & os, int indent = 0 ) const;
108 void printOneLine( std::ostream & ) const;
109
110 virtual Initializer * build() const;
111 private:
112 ExpressionNode * expr;
113 bool aggregate;
114 ExpressionNode * designator; // may be list
115 InitializerNode * kids;
116 bool maybeConstructed;
117 bool isDelete;
118}; // InitializerNode
119
120//##############################################################################
121
122class ExpressionNode final : public ParseNode {
123 public:
124 ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
125 virtual ~ExpressionNode() {}
126 virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
127
128 bool get_extension() const { return extension; }
129 ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
130
131 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
132 os << expr.get();
133 }
134 void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
135
136 template<typename T>
137 bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
138
139 Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
140
141 std::unique_ptr<Expression> expr; // public because of lifetime implications
142 private:
143 bool extension = false;
144}; // ExpressionNode
145
146template< typename T >
147struct maybeBuild_t< Expression, T > {
148 static inline Expression * doit( const T * orig ) {
149 if ( orig ) {
150 Expression * p = orig->build();
151 p->set_extension( orig->get_extension() );
152 p->location = orig->location;
153 return p;
154 } else {
155 return nullptr;
156 } // if
157 }
158};
159
160// Must harmonize with OperName.
161enum class OperKinds {
162 // diadic
163 SizeOf, AlignOf, OffsetOf, Plus, Minus, Exp, Mul, Div, Mod, Or, And,
164 BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
165 Assign, AtAssn, ExpAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
166 Index, Range,
167 // monadic
168 UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
169 Ctor, Dtor,
170}; // OperKinds
171
172enum class EnumHiding { Visible, Hide };
173
174struct LabelNode {
175 std::list< Label > labels;
176};
177
178Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string
179Expression * build_constantFloat( std::string & str );
180Expression * build_constantChar( std::string & str );
181Expression * build_constantStr( std::string & str );
182Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
183Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
184Expression * build_field_name_FLOATINGconstant( const std::string & str );
185Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
186
187NameExpr * build_varref( const std::string * name );
188QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name );
189QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl, const NameExpr * name );
190DimensionExpr * build_dimensionref( const std::string * name );
191
192Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
193Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node );
194Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
195Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
196Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
197Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
198Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
199Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
200Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
201Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
202Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
203Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
204Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
205Expression * build_tuple( ExpressionNode * expr_node = nullptr );
206Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
207Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
208
209//##############################################################################
210
211struct TypeData;
212
213struct DeclarationNode : public ParseNode {
214 // These enumerations must harmonize with their names in DeclarationNode.cc.
215 enum BasicType { Void, Bool, Char, Int, Int128,
216 Float, Double, LongDouble, uuFloat80, uuFloat128,
217 uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x, NoBasicType };
218 static const char * basicTypeNames[];
219 enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
220 static const char * complexTypeNames[];
221 enum Signedness { Signed, Unsigned, NoSignedness };
222 static const char * signednessNames[];
223 enum Length { Short, Long, LongLong, NoLength };
224 static const char * lengthNames[];
225 enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };
226 static const char * builtinTypeNames[];
227
228 static DeclarationNode * newStorageClass( Type::StorageClasses );
229 static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
230 static DeclarationNode * newTypeQualifier( Type::Qualifiers );
231 static DeclarationNode * newBasicType( BasicType );
232 static DeclarationNode * newComplexType( ComplexType );
233 static DeclarationNode * newSignedNess( Signedness );
234 static DeclarationNode * newLength( Length );
235 static DeclarationNode * newBuiltinType( BuiltinType );
236 static DeclarationNode * newForall( DeclarationNode * );
237 static DeclarationNode * newFromTypedef( const std::string * );
238 static DeclarationNode * newFromGlobalScope();
239 static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
240 static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
241 static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
242 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible );
243 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
244 static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
245 static DeclarationNode * newEnumInLine( const std::string name );
246 static DeclarationNode * newName( const std::string * );
247 static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
248 static DeclarationNode * newTypeParam( TypeDecl::Kind, const std::string * );
249 static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
250 static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
251 static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
252 static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
253 static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
254 static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
255 static DeclarationNode * newBitfield( ExpressionNode * size );
256 static DeclarationNode * newTuple( DeclarationNode * members );
257 static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
258 static DeclarationNode * newVtableType( DeclarationNode * expr );
259 static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
260 static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
261 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
262 static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
263
264 DeclarationNode();
265 ~DeclarationNode();
266 DeclarationNode * clone() const override;
267
268 DeclarationNode * addQualifiers( DeclarationNode * );
269 void checkQualifiers( const TypeData *, const TypeData * );
270 void checkSpecifiers( DeclarationNode * );
271 DeclarationNode * copySpecifiers( DeclarationNode * );
272 DeclarationNode * addType( DeclarationNode * );
273 DeclarationNode * addTypedef();
274 DeclarationNode * addEnumBase( DeclarationNode * );
275 DeclarationNode * addAssertions( DeclarationNode * );
276 DeclarationNode * addName( std::string * );
277 DeclarationNode * addAsmName( DeclarationNode * );
278 DeclarationNode * addBitfield( ExpressionNode * size );
279 DeclarationNode * addVarArgs();
280 DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
281 DeclarationNode * addOldDeclList( DeclarationNode * list );
282 DeclarationNode * setBase( TypeData * newType );
283 DeclarationNode * copyAttribute( DeclarationNode * attr );
284 DeclarationNode * addPointer( DeclarationNode * qualifiers );
285 DeclarationNode * addArray( DeclarationNode * array );
286 DeclarationNode * addNewPointer( DeclarationNode * pointer );
287 DeclarationNode * addNewArray( DeclarationNode * array );
288 DeclarationNode * addParamList( DeclarationNode * list );
289 DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
290 DeclarationNode * addInitializer( InitializerNode * init );
291 DeclarationNode * addTypeInitializer( DeclarationNode * init );
292
293 DeclarationNode * cloneType( std::string * newName );
294 DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
295
296 DeclarationNode * appendList( DeclarationNode * node ) {
297 return (DeclarationNode *)set_last( node );
298 }
299
300 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
301 virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
302
303 Declaration * build() const;
304 Type * buildType() const;
305
306 LinkageSpec::Spec get_linkage() const { return linkage; }
307 DeclarationNode * extractAggregate() const;
308 bool has_enumeratorValue() const { return (bool)enumeratorValue; }
309 ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
310
311 bool get_extension() const { return extension; }
312 DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
313
314 bool get_inLine() const { return inLine; }
315 DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
316
317 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
318
319 struct Variable_t {
320// const std::string * name;
321 TypeDecl::Kind tyClass;
322 DeclarationNode * assertions;
323 DeclarationNode * initializer;
324 };
325 Variable_t variable;
326
327 struct Attr_t {
328// const std::string * name;
329 ExpressionNode * expr;
330 DeclarationNode * type;
331 };
332 Attr_t attr;
333
334 struct StaticAssert_t {
335 ExpressionNode * condition;
336 Expression * message;
337 };
338 StaticAssert_t assert;
339
340 BuiltinType builtin = NoBuiltinType;
341
342 TypeData * type = nullptr;
343
344 bool inLine = false;
345 bool enumInLine = false;
346 Type::FuncSpecifiers funcSpecs;
347 Type::StorageClasses storageClasses;
348
349 ExpressionNode * bitfieldWidth = nullptr;
350 std::unique_ptr<ExpressionNode> enumeratorValue;
351 bool hasEllipsis = false;
352 LinkageSpec::Spec linkage;
353 Expression * asmName = nullptr;
354 std::list< Attribute * > attributes;
355 InitializerNode * initializer = nullptr;
356 bool extension = false;
357 std::string error;
358 StatementNode * asmStmt = nullptr;
359 StatementNode * directiveStmt = nullptr;
360
361 static UniqueName anonymous;
362}; // DeclarationNode
363
364Type * buildType( TypeData * type );
365
366static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
367 Type * ret = orig ? orig->buildType() : nullptr;
368 delete orig;
369 return ret;
370}
371
372//##############################################################################
373
374struct StatementNode final : public ParseNode {
375 StatementNode() { stmt = nullptr; }
376 StatementNode( Statement * stmt ) : stmt( stmt ) {}
377 StatementNode( DeclarationNode * decl );
378 virtual ~StatementNode() {}
379
380 virtual StatementNode * clone() const final { assert( false ); return nullptr; }
381 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
382
383 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
384 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
385 delete attr;
386 delete name;
387 return this;
388 }
389
390 virtual StatementNode * append_last_case( StatementNode * );
391
392 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
393 os << stmt.get() << std::endl;
394 }
395
396 std::unique_ptr<Statement> stmt;
397}; // StatementNode
398
399Statement * build_expr( ExpressionNode * ctl );
400
401struct CondCtl {
402 CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :
403 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
404
405 StatementNode * init;
406 ExpressionNode * condition;
407};
408
409struct ForCtrl {
410 ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
411 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
412 ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
413 init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
414
415 StatementNode * init;
416 ExpressionNode * condition;
417 ExpressionNode * change;
418};
419
420Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init );
421Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ );
422Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
423Statement * build_case( ExpressionNode * ctl );
424Statement * build_default();
425Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
426Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
427Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
428Statement * build_branch( BranchStmt::Type kind );
429Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
430Statement * build_computedgoto( ExpressionNode * ctl );
431Statement * build_return( ExpressionNode * ctl );
432Statement * build_throw( ExpressionNode * ctl );
433Statement * build_resume( ExpressionNode * ctl );
434Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
435Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
436Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
437Statement * build_finally( StatementNode * stmt );
438Statement * build_compound( StatementNode * first );
439StatementNode * maybe_build_compound( StatementNode * first );
440Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
441Statement * build_directive( std::string * directive );
442SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None);
443WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
444WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
445WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
446WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
447Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
448Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt );
449
450//##############################################################################
451
452template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
453void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
454 SemanticErrorException errors;
455 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
456 const NodeType * cur = firstNode;
457
458 while ( cur ) {
459 try {
460 SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
461 if ( result ) {
462 result->location = cur->location;
463 * out++ = result;
464 } else {
465 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
466 } // if
467 } catch( SemanticErrorException & e ) {
468 errors.append( e );
469 } // try
470 const ParseNode * temp = (cur->get_next());
471 cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr
472 if ( ! cur && temp ) { // non-homogeneous nodes ?
473 SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
474 } // if
475 } // while
476 if ( ! errors.isEmpty() ) {
477 throw errors;
478 } // if
479}
480
481// in DeclarationNode.cc
482void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
483void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
484void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
485
486template< typename SynTreeType, typename NodeType >
487void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
488 buildList( firstNode, outputList );
489 delete firstNode;
490}
491
492// in ParseNode.cc
493std::ostream & operator<<( std::ostream & out, const ParseNode * node );
494
495// Local Variables: //
496// tab-width: 4 //
497// mode: c++ //
498// compile-command: "make install" //
499// End: //
Note: See TracBrowser for help on using the repository browser.