source: src/Parser/ParseNode.h @ def751f

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since def751f was 4e2befe3, checked in by JiadaL <j82liang@…>, 2 years ago

add build_qualified_expr

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