source: src/Parser/ParseNode.h@ dd16dd5

ADT ast-experimental
Last change on this file since dd16dd5 was 9a533ba, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Remove the unused DeclarationNode::Attr_t type and support.

  • Property mode set to 100644
File size: 21.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 : Sun Feb 19 09:02:37 2023
13// Update Count : 940
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 StaticAssert_t {
328 ExpressionNode * condition;
329 Expression * message;
330 };
331 StaticAssert_t assert;
332
333 BuiltinType builtin = NoBuiltinType;
334
335 TypeData * type = nullptr;
336
337 bool inLine = false;
338 bool enumInLine = false;
339 Type::FuncSpecifiers funcSpecs;
340 Type::StorageClasses storageClasses;
341
342 ExpressionNode * bitfieldWidth = nullptr;
343 std::unique_ptr<ExpressionNode> enumeratorValue;
344 bool hasEllipsis = false;
345 LinkageSpec::Spec linkage;
346 Expression * asmName = nullptr;
347 std::list< Attribute * > attributes;
348 InitializerNode * initializer = nullptr;
349 bool extension = false;
350 std::string error;
351 StatementNode * asmStmt = nullptr;
352 StatementNode * directiveStmt = nullptr;
353
354 static UniqueName anonymous;
355}; // DeclarationNode
356
357Type * buildType( TypeData * type );
358
359static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
360 Type * ret = orig ? orig->buildType() : nullptr;
361 delete orig;
362 return ret;
363}
364
365//##############################################################################
366
367struct StatementNode final : public ParseNode {
368 StatementNode() { stmt = nullptr; }
369 StatementNode( Statement * stmt ) : stmt( stmt ) {}
370 StatementNode( DeclarationNode * decl );
371 virtual ~StatementNode() {}
372
373 virtual StatementNode * clone() const final { assert( false ); return nullptr; }
374 Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
375
376 virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
377 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
378 delete attr;
379 delete name;
380 return this;
381 }
382
383 virtual StatementNode * append_last_case( StatementNode * );
384
385 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
386 os << stmt.get() << std::endl;
387 }
388
389 std::unique_ptr<Statement> stmt;
390}; // StatementNode
391
392Statement * build_expr( ExpressionNode * ctl );
393
394struct CondCtl {
395 CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :
396 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
397
398 StatementNode * init;
399 ExpressionNode * condition;
400};
401
402struct ForCtrl {
403 ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
404 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
405 ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
406 init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
407
408 StatementNode * init;
409 ExpressionNode * condition;
410 ExpressionNode * change;
411};
412
413Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init );
414Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ );
415Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
416Statement * build_case( ExpressionNode * ctl );
417Statement * build_default();
418Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
419Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
420Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
421Statement * build_branch( BranchStmt::Type kind );
422Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
423Statement * build_computedgoto( ExpressionNode * ctl );
424Statement * build_return( ExpressionNode * ctl );
425Statement * build_throw( ExpressionNode * ctl );
426Statement * build_resume( ExpressionNode * ctl );
427Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
428Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
429Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
430Statement * build_finally( StatementNode * stmt );
431Statement * build_compound( StatementNode * first );
432StatementNode * maybe_build_compound( StatementNode * first );
433Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
434Statement * build_directive( std::string * directive );
435SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None);
436WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
437WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
438WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
439WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
440Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
441Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt );
442
443//##############################################################################
444
445template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
446void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
447 SemanticErrorException errors;
448 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
449 const NodeType * cur = firstNode;
450
451 while ( cur ) {
452 try {
453 SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
454 if ( result ) {
455 result->location = cur->location;
456 * out++ = result;
457 } else {
458 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
459 } // if
460 } catch( SemanticErrorException & e ) {
461 errors.append( e );
462 } // try
463 const ParseNode * temp = (cur->get_next());
464 cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr
465 if ( ! cur && temp ) { // non-homogeneous nodes ?
466 SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
467 } // if
468 } // while
469 if ( ! errors.isEmpty() ) {
470 throw errors;
471 } // if
472}
473
474// in DeclarationNode.cc
475void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
476void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
477void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
478
479template< typename SynTreeType, typename NodeType >
480void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
481 buildList( firstNode, outputList );
482 delete firstNode;
483}
484
485// in ParseNode.cc
486std::ostream & operator<<( std::ostream & out, const ParseNode * node );
487
488// Local Variables: //
489// tab-width: 4 //
490// mode: c++ //
491// compile-command: "make install" //
492// End: //
Note: See TracBrowser for help on using the repository browser.