source: src/Parser/ParseNode.h @ c2b3243

ADTast-experimental
Last change on this file since c2b3243 was c2b3243, checked in by JiadaL <j82liang@…>, 19 months ago

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

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