source: src/Parser/ParseNode.h @ 44a0ca2

ADTast-experimental
Last change on this file since 44a0ca2 was 44a0ca2, checked in by Peter A. Buhr <pabuhr@…>, 14 months ago

formatting

  • Property mode set to 100644
File size: 21.7 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// ParseNode.h --
8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Sat May 16 13:28:16 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sun Feb 19 09:02:37 2023
13// Update Count     : 940
14//
15
16#pragma once
17
18#include <algorithm>               // for move
19#include <cassert>                 // for assert, assertf
20#include <iosfwd>                  // for ostream
21#include <iterator>                // for back_insert_iterator
22#include <list>                    // for list
23#include <memory>                  // for unique_ptr, pointer_traits
24#include <string>                  // for string
25
26#include "Common/CodeLocation.h"   // for CodeLocation
27#include "Common/SemanticError.h"  // for SemanticError
28#include "Common/UniqueName.h"     // for UniqueName
29#include "Common/utility.h"        // for maybeClone
30#include "Parser/parserutility.h"  // for maybeBuild
31#include "SynTree/LinkageSpec.h"   // for Spec
32#include "SynTree/Declaration.h"   // for Aggregate
33#include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
34#include "SynTree/Label.h"         // for Label
35#include "SynTree/Statement.h"     // for Statement, BranchStmt, BranchStmt:...
36#include "SynTree/Type.h"          // for Type, Type::FuncSpecifiers, Type::...
37
38class Attribute;
39class Declaration;
40struct DeclarationNode;
41class DeclarationWithType;
42class Initializer;
43class ExpressionNode;
44struct StatementNode;
45
46//##############################################################################
47
48typedef CodeLocation YYLTYPE;
49#define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */
50
51extern YYLTYPE yylloc;
52
53class ParseNode {
54  public:
55        ParseNode() {};
56        virtual ~ParseNode() { delete next; delete name; };
57        virtual ParseNode * clone() const = 0;
58
59        ParseNode * get_next() const { return next; }
60        ParseNode * set_next( ParseNode * newlink ) { next = newlink; return this; }
61
62        ParseNode * get_last() {
63                ParseNode * current;
64                for ( current = this; current->get_next() != nullptr; current = current->get_next() );
65                return current;
66        }
67        ParseNode * set_last( ParseNode * newlast ) {
68                if ( newlast != nullptr ) get_last()->set_next( newlast );
69                return this;
70        }
71
72        virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
73        virtual void printList( std::ostream & os, int indent = 0 ) const {
74                print( os, indent );
75                if ( next ) next->print( os, indent );
76        }
77
78        static int indent_by;
79
80        ParseNode * next = nullptr;
81        const std::string * name = nullptr;
82        CodeLocation location = yylloc;
83}; // ParseNode
84
85//##############################################################################
86
87class InitializerNode : public ParseNode {
88  public:
89        InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr );
90        InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
91        InitializerNode( bool isDelete );
92        ~InitializerNode();
93        virtual InitializerNode * clone() const { assert( false ); return nullptr; }
94
95        ExpressionNode * get_expression() const { return expr; }
96
97        InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
98        ExpressionNode * get_designators() const { return designator; }
99
100        InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
101        bool get_maybeConstructed() const { return maybeConstructed; }
102
103        bool get_isDelete() const { return isDelete; }
104
105        InitializerNode * next_init() const { return kids; }
106
107        void print( std::ostream & os, int indent = 0 ) const;
108        void printOneLine( std::ostream & ) const;
109
110        virtual Initializer * build() const;
111  private:
112        ExpressionNode * expr;
113        bool aggregate;
114        ExpressionNode * designator;                                            // may be list
115        InitializerNode * kids;
116        bool maybeConstructed;
117        bool isDelete;
118}; // InitializerNode
119
120//##############################################################################
121
122class ExpressionNode final : public ParseNode {
123  public:
124        ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
125        virtual ~ExpressionNode() {}
126        virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
127
128        bool get_extension() const { return extension; }
129        ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
130
131        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
132                os << expr.get();
133        }
134        void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
135
136        template<typename T>
137        bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
138
139        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
140
141        std::unique_ptr<Expression> expr;                                       // public because of lifetime implications
142  private:
143        bool extension = false;
144}; // ExpressionNode
145
146template< typename T >
147struct maybeBuild_t< Expression, T > {
148        static inline Expression * doit( const T * orig ) {
149                if ( orig ) {
150                        Expression * p = orig->build();
151                        p->set_extension( orig->get_extension() );
152                        p->location = orig->location;
153                        return p;
154                } else {
155                        return nullptr;
156                } // if
157        }
158};
159
160// Must harmonize with OperName.
161enum class OperKinds {
162        // diadic
163        SizeOf, AlignOf, OffsetOf, Plus, Minus, Exp, Mul, Div, Mod, Or, And,
164        BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
165        Assign, AtAssn, ExpAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
166        Index, Range,
167        // monadic
168        UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
169        Ctor, Dtor,
170}; // OperKinds
171
172enum class EnumHiding { Visible, Hide };
173
174struct LabelNode {
175        std::list< Label > labels;
176};
177
178Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string
179Expression * build_constantFloat( std::string & str );
180Expression * build_constantChar( std::string & str );
181Expression * build_constantStr( std::string & str );
182Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
183Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
184Expression * build_field_name_FLOATINGconstant( const std::string & str );
185Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
186
187NameExpr * build_varref( const std::string * name );
188QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name );
189QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl, const NameExpr * name );
190DimensionExpr * build_dimensionref( const std::string * name );
191
192Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
193Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node );
194Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
195Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
196Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
197Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
198Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
199Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
200Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
201Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
202Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
203Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
204Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
205Expression * build_tuple( ExpressionNode * expr_node = nullptr );
206Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
207Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
208
209//##############################################################################
210
211struct TypeData;
212
213struct DeclarationNode : public ParseNode {
214        // These enumerations must harmonize with their names in DeclarationNode.cc.
215        enum BasicType { Void, Bool, Char, Int, Int128,
216                                         Float, Double, LongDouble, uuFloat80, uuFloat128,
217                                         uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x, NoBasicType };
218        static const char * basicTypeNames[];
219        enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
220        static const char * complexTypeNames[];
221        enum Signedness { Signed, Unsigned, NoSignedness };
222        static const char * signednessNames[];
223        enum Length { Short, Long, LongLong, NoLength };
224        static const char * lengthNames[];
225        enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };
226        static const char * builtinTypeNames[];
227
228        static DeclarationNode * newStorageClass( Type::StorageClasses );
229        static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
230        static DeclarationNode * newTypeQualifier( Type::Qualifiers );
231        static DeclarationNode * newBasicType( BasicType );
232        static DeclarationNode * newComplexType( ComplexType );
233        static DeclarationNode * newSignedNess( Signedness );
234        static DeclarationNode * newLength( Length );
235        static DeclarationNode * newBuiltinType( BuiltinType );
236        static DeclarationNode * newForall( DeclarationNode * );
237        static DeclarationNode * newFromTypedef( const std::string * );
238        static DeclarationNode * newFromGlobalScope();
239        static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
240        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
241        static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
242        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible );
243        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
244        static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
245        static DeclarationNode * newEnumInLine( const std::string name );
246        static DeclarationNode * newName( const std::string * );
247        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
248        static DeclarationNode * newTypeParam( TypeDecl::Kind, const std::string * );
249        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
250        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
251        static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
252        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
253        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
254        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
255        static DeclarationNode * newBitfield( ExpressionNode * size );
256        static DeclarationNode * newTuple( DeclarationNode * members );
257        static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
258        static DeclarationNode * newVtableType( DeclarationNode * expr );
259        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
260        static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
261        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
262        static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
263
264        DeclarationNode();
265        ~DeclarationNode();
266        DeclarationNode * clone() const override;
267
268        DeclarationNode * addQualifiers( DeclarationNode * );
269        void checkQualifiers( const TypeData *, const TypeData * );
270        void checkSpecifiers( DeclarationNode * );
271        DeclarationNode * copySpecifiers( DeclarationNode * );
272        DeclarationNode * addType( DeclarationNode * );
273        DeclarationNode * addTypedef();
274        DeclarationNode * addEnumBase( DeclarationNode * );
275        DeclarationNode * addAssertions( DeclarationNode * );
276        DeclarationNode * addName( std::string * );
277        DeclarationNode * addAsmName( DeclarationNode * );
278        DeclarationNode * addBitfield( ExpressionNode * size );
279        DeclarationNode * addVarArgs();
280        DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
281        DeclarationNode * addOldDeclList( DeclarationNode * list );
282        DeclarationNode * setBase( TypeData * newType );
283        DeclarationNode * copyAttribute( DeclarationNode * attr );
284        DeclarationNode * addPointer( DeclarationNode * qualifiers );
285        DeclarationNode * addArray( DeclarationNode * array );
286        DeclarationNode * addNewPointer( DeclarationNode * pointer );
287        DeclarationNode * addNewArray( DeclarationNode * array );
288        DeclarationNode * addParamList( DeclarationNode * list );
289        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
290        DeclarationNode * addInitializer( InitializerNode * init );
291        DeclarationNode * addTypeInitializer( DeclarationNode * init );
292
293        DeclarationNode * cloneType( std::string * newName );
294        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
295
296        DeclarationNode * appendList( DeclarationNode * node ) {
297                return (DeclarationNode *)set_last( node );
298        }
299
300        virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
301        virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
302
303        Declaration * build() const;
304        Type * buildType() const;
305
306        LinkageSpec::Spec get_linkage() const { return linkage; }
307        DeclarationNode * extractAggregate() const;
308        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
309        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
310
311        bool get_extension() const { return extension; }
312        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
313
314        bool get_inLine() const { return inLine; }
315        DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
316
317        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
318
319        struct Variable_t {
320//              const std::string * name;
321                TypeDecl::Kind tyClass;
322                DeclarationNode * assertions;
323                DeclarationNode * initializer;
324        };
325        Variable_t variable;
326
327        struct Attr_t {
328//              const std::string * name;
329                ExpressionNode * expr;
330                DeclarationNode * type;
331        };
332        Attr_t attr;
333
334        struct StaticAssert_t {
335                ExpressionNode * condition;
336                Expression * message;
337        };
338        StaticAssert_t assert;
339
340        BuiltinType builtin = NoBuiltinType;
341
342        TypeData * type = nullptr;
343
344        bool inLine = false;
345        bool enumInLine = false;
346        Type::FuncSpecifiers funcSpecs;
347        Type::StorageClasses storageClasses;
348
349        ExpressionNode * bitfieldWidth = nullptr;
350        std::unique_ptr<ExpressionNode> enumeratorValue;
351        bool hasEllipsis = false;
352        LinkageSpec::Spec linkage;
353        Expression * asmName = nullptr;
354        std::list< Attribute * > attributes;
355        InitializerNode * initializer = nullptr;
356        bool extension = false;
357        std::string error;
358        StatementNode * asmStmt = nullptr;
359        StatementNode * directiveStmt = nullptr;
360
361        static UniqueName anonymous;
362}; // DeclarationNode
363
364Type * buildType( TypeData * type );
365
366static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
367        Type * ret = orig ? orig->buildType() : nullptr;
368        delete orig;
369        return ret;
370}
371
372//##############################################################################
373
374struct StatementNode final : public ParseNode {
375        StatementNode() { stmt = nullptr; }
376        StatementNode( Statement * stmt ) : stmt( stmt ) {}
377        StatementNode( DeclarationNode * decl );
378        virtual ~StatementNode() {}
379
380        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
381        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
382
383        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
384                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
385                delete attr;
386                delete name;
387                return this;
388        }
389
390        virtual StatementNode * append_last_case( StatementNode * );
391
392        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
393                os << stmt.get() << std::endl;
394        }
395
396        std::unique_ptr<Statement> stmt;
397}; // StatementNode
398
399Statement * build_expr( ExpressionNode * ctl );
400
401struct CondCtl {
402        CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :
403                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
404
405        StatementNode * init;
406        ExpressionNode * condition;
407};
408
409struct ForCtrl {
410        ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
411                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
412        ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
413                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
414
415        StatementNode * init;
416        ExpressionNode * condition;
417        ExpressionNode * change;
418};
419
420Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init );
421Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ );
422Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
423Statement * build_case( ExpressionNode * ctl );
424Statement * build_default();
425Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
426Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
427Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
428Statement * build_branch( BranchStmt::Type kind );
429Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
430Statement * build_computedgoto( ExpressionNode * ctl );
431Statement * build_return( ExpressionNode * ctl );
432Statement * build_throw( ExpressionNode * ctl );
433Statement * build_resume( ExpressionNode * ctl );
434Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
435Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
436Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
437Statement * build_finally( StatementNode * stmt );
438Statement * build_compound( StatementNode * first );
439StatementNode * maybe_build_compound( StatementNode * first );
440Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
441Statement * build_directive( std::string * directive );
442SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None);
443WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
444WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
445WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
446WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
447Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
448Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt );
449
450//##############################################################################
451
452template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
453void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
454        SemanticErrorException errors;
455        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
456        const NodeType * cur = firstNode;
457
458        while ( cur ) {
459                try {
460                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
461                        if ( result ) {
462                                result->location = cur->location;
463                                * out++ = result;
464                        } else {
465                                SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
466                        } // if
467                } catch( SemanticErrorException & e ) {
468                        errors.append( e );
469                } // try
470                const ParseNode * temp = (cur->get_next());
471                cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr
472                if ( ! cur && temp ) {                                                  // non-homogeneous nodes ?
473                        SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
474                } // if
475        } // while
476        if ( ! errors.isEmpty() ) {
477                throw errors;
478        } // if
479}
480
481// in DeclarationNode.cc
482void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
483void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
484void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
485
486template< typename SynTreeType, typename NodeType >
487void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
488        buildList( firstNode, outputList );
489        delete firstNode;
490}
491
492// in ParseNode.cc
493std::ostream & operator<<( std::ostream & out, const ParseNode * node );
494
495// Local Variables: //
496// tab-width: 4 //
497// mode: c++ //
498// compile-command: "make install" //
499// End: //
Note: See TracBrowser for help on using the repository browser.