source: src/Parser/ParseNode.h @ 374cb117

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since 374cb117 was 374cb117, checked in by JiadaL <j82liang@…>, 22 months ago

Replace the interface for EnumDecl? node construction to support generic enum types

  • Property mode set to 100644
File size: 21.0 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 Feb  2 09:15:49 2022
13// Update Count     : 905
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 "SynTree/LinkageSpec.h"   // for Spec
31#include "SynTree/Declaration.h"   // for Aggregate
32#include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
33#include "SynTree/Label.h"         // for Label
34#include "SynTree/Statement.h"     // for Statement, BranchStmt, BranchStmt:...
35#include "SynTree/Type.h"          // for Type, Type::FuncSpecifiers, Type::...
36
37class Attribute;
38class Declaration;
39struct DeclarationNode;
40class DeclarationWithType;
41class Initializer;
42class ExpressionNode;
43struct StatementNode;
44
45//##############################################################################
46
47typedef CodeLocation YYLTYPE;
48#define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */
49
50extern YYLTYPE yylloc;
51
52class ParseNode {
53  public:
54        ParseNode() {};
55        virtual ~ParseNode() { delete next; delete name; };
56        virtual ParseNode * clone() const = 0;
57
58        ParseNode * get_next() const { return next; }
59        ParseNode * set_next( ParseNode * newlink ) { next = newlink; return this; }
60
61        ParseNode * get_last() {
62                ParseNode * current;
63                for ( current = this; current->get_next() != nullptr; current = current->get_next() );
64                return current;
65        }
66        ParseNode * set_last( ParseNode * newlast ) {
67                if ( newlast != nullptr ) get_last()->set_next( newlast );
68                return this;
69        }
70
71        virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
72        virtual void printList( std::ostream & os, int indent = 0 ) const {
73                print( os, indent );
74                if ( next ) next->print( os, indent );
75        }
76
77        static int indent_by;
78
79        ParseNode * next = nullptr;
80        const std::string * name = nullptr;
81        CodeLocation location = yylloc;
82}; // ParseNode
83
84//##############################################################################
85
86class InitializerNode : public ParseNode {
87  public:
88        InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr );
89        InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
90        InitializerNode( bool isDelete );
91        ~InitializerNode();
92        virtual InitializerNode * clone() const { assert( false ); return nullptr; }
93
94        ExpressionNode * get_expression() const { return expr; }
95
96        InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
97        ExpressionNode * get_designators() const { return designator; }
98
99        InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
100        bool get_maybeConstructed() const { return maybeConstructed; }
101
102        bool get_isDelete() const { return isDelete; }
103
104        InitializerNode * next_init() const { return kids; }
105
106        void print( std::ostream & os, int indent = 0 ) const;
107        void printOneLine( std::ostream & ) const;
108
109        virtual Initializer * build() const;
110  private:
111        ExpressionNode * expr;
112        bool aggregate;
113        ExpressionNode * designator;                                            // may be list
114        InitializerNode * kids;
115        bool maybeConstructed;
116        bool isDelete;
117}; // InitializerNode
118
119//##############################################################################
120
121class ExpressionNode final : public ParseNode {
122  public:
123        ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
124        virtual ~ExpressionNode() {}
125        virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
126
127        bool get_extension() const { return extension; }
128        ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
129
130        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
131                os << expr.get();
132        }
133        void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
134
135        template<typename T>
136        bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
137
138        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
139
140        std::unique_ptr<Expression> expr;                                       // public because of lifetime implications
141  private:
142        bool extension = false;
143}; // ExpressionNode
144
145template< typename T >
146struct maybeBuild_t< Expression, T > {
147        static inline Expression * doit( const T * orig ) {
148                if ( orig ) {
149                        Expression * p = orig->build();
150                        p->set_extension( orig->get_extension() );
151                        p->location = orig->location;
152                        return p;
153                } else {
154                        return nullptr;
155                } // if
156        }
157};
158
159// Must harmonize with OperName.
160enum class OperKinds {
161        // diadic
162        SizeOf, AlignOf, OffsetOf, Plus, Minus, Exp, Mul, Div, Mod, Or, And,
163        BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
164        Assign, AtAssn, ExpAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
165        Index, Range,
166        // monadic
167        UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
168        Ctor, Dtor,
169}; // OperKinds
170
171struct LabelNode {
172        std::list< Label > labels;
173};
174
175Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string
176Expression * build_constantFloat( std::string & str );
177Expression * build_constantChar( std::string & str );
178Expression * build_constantStr( std::string & str );
179Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
180Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
181Expression * build_field_name_FLOATINGconstant( const std::string & str );
182Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
183
184NameExpr * build_varref( const std::string * name );
185DimensionExpr * build_dimensionref( const std::string * name );
186
187Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
188Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node );
189Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
190Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
191Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
192Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
193Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
194Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
195Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
196Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
197Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
198Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
199Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
200Expression * build_tuple( ExpressionNode * expr_node = nullptr );
201Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
202Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
203
204//##############################################################################
205
206struct TypeData;
207
208struct DeclarationNode : public ParseNode {
209        // These enumerations must harmonize with their names in DeclarationNode.cc.
210        enum BasicType { Void, Bool, Char, Int, Int128,
211                                         Float, Double, LongDouble, uuFloat80, uuFloat128,
212                                         uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x, NoBasicType };
213        static const char * basicTypeNames[];
214        enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
215        static const char * complexTypeNames[];
216        enum Signedness { Signed, Unsigned, NoSignedness };
217        static const char * signednessNames[];
218        enum Length { Short, Long, LongLong, NoLength };
219        static const char * lengthNames[];
220        enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };
221        static const char * builtinTypeNames[];
222
223        static DeclarationNode * newStorageClass( Type::StorageClasses );
224        static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
225        static DeclarationNode * newTypeQualifier( Type::Qualifiers );
226        static DeclarationNode * newBasicType( BasicType );
227        static DeclarationNode * newComplexType( ComplexType );
228        static DeclarationNode * newSignedNess( Signedness );
229        static DeclarationNode * newLength( Length );
230        static DeclarationNode * newBuiltinType( BuiltinType );
231        static DeclarationNode * newForall( DeclarationNode * );
232        static DeclarationNode * newFromTypedef( const std::string * );
233        static DeclarationNode * newFromGlobalScope();
234        static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
235        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
236        static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
237        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body );
238        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
239        static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
240        static DeclarationNode * newName( const std::string * );
241        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
242        static DeclarationNode * newTypeParam( TypeDecl::Kind, const std::string * );
243        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
244        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
245        static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
246        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
247        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
248        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
249        static DeclarationNode * newBitfield( ExpressionNode * size );
250        static DeclarationNode * newTuple( DeclarationNode * members );
251        static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
252        static DeclarationNode * newVtableType( DeclarationNode * expr );
253        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
254        static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
255        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
256        static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
257
258        DeclarationNode();
259        ~DeclarationNode();
260        DeclarationNode * clone() const override;
261
262        DeclarationNode * addQualifiers( DeclarationNode * );
263        void checkQualifiers( const TypeData *, const TypeData * );
264        void checkSpecifiers( DeclarationNode * );
265        DeclarationNode * copySpecifiers( DeclarationNode * );
266        DeclarationNode * addType( DeclarationNode * );
267        DeclarationNode * addTypedef();
268        DeclarationNode * addEnumBase( DeclarationNode * );
269        DeclarationNode * addAssertions( DeclarationNode * );
270        DeclarationNode * addName( std::string * );
271        DeclarationNode * addAsmName( DeclarationNode * );
272        DeclarationNode * addBitfield( ExpressionNode * size );
273        DeclarationNode * addVarArgs();
274        DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
275        DeclarationNode * addOldDeclList( DeclarationNode * list );
276        DeclarationNode * setBase( TypeData * newType );
277        DeclarationNode * copyAttribute( DeclarationNode * attr );
278        DeclarationNode * addPointer( DeclarationNode * qualifiers );
279        DeclarationNode * addArray( DeclarationNode * array );
280        DeclarationNode * addNewPointer( DeclarationNode * pointer );
281        DeclarationNode * addNewArray( DeclarationNode * array );
282        DeclarationNode * addParamList( DeclarationNode * list );
283        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
284        DeclarationNode * addInitializer( InitializerNode * init );
285        DeclarationNode * addTypeInitializer( DeclarationNode * 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( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
295        virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
296
297        Declaration * build() const;
298        Type * buildType() const;
299
300        LinkageSpec::Spec get_linkage() const { return linkage; }
301        DeclarationNode * extractAggregate() const;
302        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
303        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
304
305        bool get_extension() const { return extension; }
306        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
307
308        bool get_inLine() const { return inLine; }
309        DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
310
311        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
312
313        struct Variable_t {
314//              const std::string * name;
315                TypeDecl::Kind tyClass;
316                DeclarationNode * assertions;
317                DeclarationNode * initializer;
318        };
319        Variable_t variable;
320
321        struct Attr_t {
322//              const std::string * name;
323                ExpressionNode * expr;
324                DeclarationNode * type;
325        };
326        Attr_t attr;
327
328        struct StaticAssert_t {
329                ExpressionNode * condition;
330                Expression * message;
331        };
332        StaticAssert_t assert;
333
334        BuiltinType builtin = NoBuiltinType;
335
336        TypeData * type = nullptr;
337
338        bool inLine = 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                cur = dynamic_cast< NodeType * >( cur->get_next() );
464        } // while
465        if ( ! errors.isEmpty() ) {
466                throw errors;
467        } // if
468}
469
470// in DeclarationNode.cc
471void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
472void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
473void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
474
475template< typename SynTreeType, typename NodeType >
476void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
477        buildList( firstNode, outputList );
478        delete firstNode;
479}
480
481// in ParseNode.cc
482std::ostream & operator<<( std::ostream & out, const ParseNode * node );
483
484// Local Variables: //
485// tab-width: 4 //
486// mode: c++ //
487// compile-command: "make install" //
488// End: //
Note: See TracBrowser for help on using the repository browser.