source: src/Parser/ParseNode.h

Last change on this file was e4d7c1c, checked in by JiadaL <j82liang@…>, 2 months ago

Implement enum Hiding

  • 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 : 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, 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
171enum class EnumHiding { Visible, Hide };
172
173struct LabelNode {
174        std::list< Label > labels;
175};
176
177Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string
178Expression * build_constantFloat( std::string & str );
179Expression * build_constantChar( std::string & str );
180Expression * build_constantStr( std::string & str );
181Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
182Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
183Expression * build_field_name_FLOATINGconstant( const std::string & str );
184Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
185
186NameExpr * build_varref( const std::string * name );
187QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name );
188QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl, const NameExpr * name );
189DimensionExpr * build_dimensionref( const std::string * name );
190
191Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
192Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node );
193Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
194Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
195Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
196Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
197Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
198Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
199Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
200Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
201Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
202Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
203Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
204Expression * build_tuple( ExpressionNode * expr_node = nullptr );
205Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
206Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
207
208//##############################################################################
209
210struct TypeData;
211
212struct DeclarationNode : public ParseNode {
213        // These enumerations must harmonize with their names in DeclarationNode.cc.
214        enum BasicType { Void, Bool, Char, Int, Int128,
215                                         Float, Double, LongDouble, uuFloat80, uuFloat128,
216                                         uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x, NoBasicType };
217        static const char * basicTypeNames[];
218        enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
219        static const char * complexTypeNames[];
220        enum Signedness { Signed, Unsigned, NoSignedness };
221        static const char * signednessNames[];
222        enum Length { Short, Long, LongLong, NoLength };
223        static const char * lengthNames[];
224        enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };
225        static const char * builtinTypeNames[];
226
227        static DeclarationNode * newStorageClass( Type::StorageClasses );
228        static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
229        static DeclarationNode * newTypeQualifier( Type::Qualifiers );
230        static DeclarationNode * newBasicType( BasicType );
231        static DeclarationNode * newComplexType( ComplexType );
232        static DeclarationNode * newSignedNess( Signedness );
233        static DeclarationNode * newLength( Length );
234        static DeclarationNode * newBuiltinType( BuiltinType );
235        static DeclarationNode * newForall( DeclarationNode * );
236        static DeclarationNode * newFromTypedef( const std::string * );
237        static DeclarationNode * newFromGlobalScope();
238        static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
239        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
240        static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
241        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible );
242        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
243        static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
244        static DeclarationNode * newEnumInLine( const std::string name );
245        static DeclarationNode * newName( const std::string * );
246        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
247        static DeclarationNode * newTypeParam( TypeDecl::Kind, const std::string * );
248        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
249        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
250        static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
251        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
252        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
253        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
254        static DeclarationNode * newBitfield( ExpressionNode * size );
255        static DeclarationNode * newTuple( DeclarationNode * members );
256        static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
257        static DeclarationNode * newVtableType( DeclarationNode * expr );
258        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
259        static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
260        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
261        static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
262
263        DeclarationNode();
264        ~DeclarationNode();
265        DeclarationNode * clone() const override;
266
267        DeclarationNode * addQualifiers( DeclarationNode * );
268        void checkQualifiers( const TypeData *, const TypeData * );
269        void checkSpecifiers( DeclarationNode * );
270        DeclarationNode * copySpecifiers( DeclarationNode * );
271        DeclarationNode * addType( DeclarationNode * );
272        DeclarationNode * addTypedef();
273        DeclarationNode * addEnumBase( DeclarationNode * );
274        DeclarationNode * addAssertions( DeclarationNode * );
275        DeclarationNode * addName( std::string * );
276        DeclarationNode * addAsmName( DeclarationNode * );
277        DeclarationNode * addBitfield( ExpressionNode * size );
278        DeclarationNode * addVarArgs();
279        DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
280        DeclarationNode * addOldDeclList( DeclarationNode * list );
281        DeclarationNode * setBase( TypeData * newType );
282        DeclarationNode * copyAttribute( DeclarationNode * attr );
283        DeclarationNode * addPointer( DeclarationNode * qualifiers );
284        DeclarationNode * addArray( DeclarationNode * array );
285        DeclarationNode * addNewPointer( DeclarationNode * pointer );
286        DeclarationNode * addNewArray( DeclarationNode * array );
287        DeclarationNode * addParamList( DeclarationNode * list );
288        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
289        DeclarationNode * addInitializer( InitializerNode * init );
290        DeclarationNode * addTypeInitializer( DeclarationNode * init );
291
292        DeclarationNode * cloneType( std::string * newName );
293        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
294
295        DeclarationNode * appendList( DeclarationNode * node ) {
296                return (DeclarationNode *)set_last( node );
297        }
298
299        virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
300        virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
301
302        Declaration * build() const;
303        Type * buildType() const;
304
305        LinkageSpec::Spec get_linkage() const { return linkage; }
306        DeclarationNode * extractAggregate() const;
307        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
308        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
309
310        bool get_extension() const { return extension; }
311        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
312
313        bool get_inLine() const { return inLine; }
314        DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
315
316        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
317
318        struct Variable_t {
319//              const std::string * name;
320                TypeDecl::Kind tyClass;
321                DeclarationNode * assertions;
322                DeclarationNode * initializer;
323        };
324        Variable_t variable;
325
326        struct Attr_t {
327//              const std::string * name;
328                ExpressionNode * expr;
329                DeclarationNode * type;
330        };
331        Attr_t attr;
332
333        struct StaticAssert_t {
334                ExpressionNode * condition;
335                Expression * message;
336        };
337        StaticAssert_t assert;
338
339        BuiltinType builtin = NoBuiltinType;
340
341        TypeData * type = nullptr;
342
343        bool inLine = false;
344        bool enumInLine = false; 
345        Type::FuncSpecifiers funcSpecs;
346        Type::StorageClasses storageClasses;
347
348        ExpressionNode * bitfieldWidth = nullptr;
349        std::unique_ptr<ExpressionNode> enumeratorValue;
350        bool hasEllipsis = false;
351        LinkageSpec::Spec linkage;
352        Expression * asmName = nullptr;
353        std::list< Attribute * > attributes;
354        InitializerNode * initializer = nullptr;
355        bool extension = false;
356        std::string error;
357        StatementNode * asmStmt = nullptr;
358        StatementNode * directiveStmt = nullptr;
359
360        static UniqueName anonymous;
361}; // DeclarationNode
362
363Type * buildType( TypeData * type );
364
365static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
366        Type * ret = orig ? orig->buildType() : nullptr;
367        delete orig;
368        return ret;
369}
370
371//##############################################################################
372
373struct StatementNode final : public ParseNode {
374        StatementNode() { stmt = nullptr; }
375        StatementNode( Statement * stmt ) : stmt( stmt ) {}
376        StatementNode( DeclarationNode * decl );
377        virtual ~StatementNode() {}
378
379        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
380        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
381
382        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
383                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
384                delete attr;
385                delete name;
386                return this;
387        }
388
389        virtual StatementNode * append_last_case( StatementNode * );
390
391        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
392                os << stmt.get() << std::endl;
393        }
394
395        std::unique_ptr<Statement> stmt;
396}; // StatementNode
397
398Statement * build_expr( ExpressionNode * ctl );
399
400struct CondCtl {
401        CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :
402                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
403
404        StatementNode * init;
405        ExpressionNode * condition;
406};
407
408struct ForCtrl {
409        ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
410                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
411        ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
412                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
413
414        StatementNode * init;
415        ExpressionNode * condition;
416        ExpressionNode * change;
417};
418
419Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init );
420Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ );
421Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
422Statement * build_case( ExpressionNode * ctl );
423Statement * build_default();
424Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
425Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
426Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
427Statement * build_branch( BranchStmt::Type kind );
428Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
429Statement * build_computedgoto( ExpressionNode * ctl );
430Statement * build_return( ExpressionNode * ctl );
431Statement * build_throw( ExpressionNode * ctl );
432Statement * build_resume( ExpressionNode * ctl );
433Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
434Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
435Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
436Statement * build_finally( StatementNode * stmt );
437Statement * build_compound( StatementNode * first );
438StatementNode * maybe_build_compound( StatementNode * first );
439Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
440Statement * build_directive( std::string * directive );
441SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None);
442WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
443WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
444WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
445WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
446Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
447Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt );
448
449//##############################################################################
450
451template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
452void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
453        SemanticErrorException errors;
454        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
455        const NodeType * cur = firstNode;
456
457        while ( cur ) {
458                try {
459                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
460                        if ( result ) {
461                                result->location = cur->location;
462                                * out++ = result;
463                        } else {
464                                SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
465                        } // if
466                } catch( SemanticErrorException & e ) {
467                        errors.append( e );
468                } // try
469                const ParseNode * temp = (cur->get_next());
470                cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr
471                if ( ! cur && temp ) {                                                  // non-homogeneous nodes ?
472                        SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
473                } // if
474        } // while
475        if ( ! errors.isEmpty() ) {
476                throw errors;
477        } // if
478}
479
480// in DeclarationNode.cc
481void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
482void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
483void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
484
485template< typename SynTreeType, typename NodeType >
486void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
487        buildList( firstNode, outputList );
488        delete firstNode;
489}
490
491// in ParseNode.cc
492std::ostream & operator<<( std::ostream & out, const ParseNode * node );
493
494// Local Variables: //
495// tab-width: 4 //
496// mode: c++ //
497// compile-command: "make install" //
498// End: //
Note: See TracBrowser for help on using the repository browser.