source: src/Parser/ParseNode.h @ bf20567

ADTast-experimental
Last change on this file since bf20567 was 9a533ba, checked in by Andrew Beach <ajbeach@…>, 16 months ago

Remove the unused DeclarationNode::Attr_t type and support.

  • 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 : 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 StaticAssert_t {
328                ExpressionNode * condition;
329                Expression * message;
330        };
331        StaticAssert_t assert;
332
333        BuiltinType builtin = NoBuiltinType;
334
335        TypeData * type = nullptr;
336
337        bool inLine = false;
338        bool enumInLine = false;
339        Type::FuncSpecifiers funcSpecs;
340        Type::StorageClasses storageClasses;
341
342        ExpressionNode * bitfieldWidth = nullptr;
343        std::unique_ptr<ExpressionNode> enumeratorValue;
344        bool hasEllipsis = false;
345        LinkageSpec::Spec linkage;
346        Expression * asmName = nullptr;
347        std::list< Attribute * > attributes;
348        InitializerNode * initializer = nullptr;
349        bool extension = false;
350        std::string error;
351        StatementNode * asmStmt = nullptr;
352        StatementNode * directiveStmt = nullptr;
353
354        static UniqueName anonymous;
355}; // DeclarationNode
356
357Type * buildType( TypeData * type );
358
359static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
360        Type * ret = orig ? orig->buildType() : nullptr;
361        delete orig;
362        return ret;
363}
364
365//##############################################################################
366
367struct StatementNode final : public ParseNode {
368        StatementNode() { stmt = nullptr; }
369        StatementNode( Statement * stmt ) : stmt( stmt ) {}
370        StatementNode( DeclarationNode * decl );
371        virtual ~StatementNode() {}
372
373        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
374        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
375
376        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
377                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
378                delete attr;
379                delete name;
380                return this;
381        }
382
383        virtual StatementNode * append_last_case( StatementNode * );
384
385        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
386                os << stmt.get() << std::endl;
387        }
388
389        std::unique_ptr<Statement> stmt;
390}; // StatementNode
391
392Statement * build_expr( ExpressionNode * ctl );
393
394struct CondCtl {
395        CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :
396                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
397
398        StatementNode * init;
399        ExpressionNode * condition;
400};
401
402struct ForCtrl {
403        ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
404                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
405        ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
406                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
407
408        StatementNode * init;
409        ExpressionNode * condition;
410        ExpressionNode * change;
411};
412
413Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init );
414Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ );
415Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
416Statement * build_case( ExpressionNode * ctl );
417Statement * build_default();
418Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
419Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
420Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
421Statement * build_branch( BranchStmt::Type kind );
422Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
423Statement * build_computedgoto( ExpressionNode * ctl );
424Statement * build_return( ExpressionNode * ctl );
425Statement * build_throw( ExpressionNode * ctl );
426Statement * build_resume( ExpressionNode * ctl );
427Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
428Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
429Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
430Statement * build_finally( StatementNode * stmt );
431Statement * build_compound( StatementNode * first );
432StatementNode * maybe_build_compound( StatementNode * first );
433Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
434Statement * build_directive( std::string * directive );
435SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None);
436WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
437WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
438WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
439WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
440Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
441Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt );
442
443//##############################################################################
444
445template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
446void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
447        SemanticErrorException errors;
448        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
449        const NodeType * cur = firstNode;
450
451        while ( cur ) {
452                try {
453                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
454                        if ( result ) {
455                                result->location = cur->location;
456                                * out++ = result;
457                        } else {
458                                SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
459                        } // if
460                } catch( SemanticErrorException & e ) {
461                        errors.append( e );
462                } // try
463                const ParseNode * temp = (cur->get_next());
464                cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr
465                if ( ! cur && temp ) {                                                  // non-homogeneous nodes ?
466                        SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
467                } // if
468        } // while
469        if ( ! errors.isEmpty() ) {
470                throw errors;
471        } // if
472}
473
474// in DeclarationNode.cc
475void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
476void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
477void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
478
479template< typename SynTreeType, typename NodeType >
480void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
481        buildList( firstNode, outputList );
482        delete firstNode;
483}
484
485// in ParseNode.cc
486std::ostream & operator<<( std::ostream & out, const ParseNode * node );
487
488// Local Variables: //
489// tab-width: 4 //
490// mode: c++ //
491// compile-command: "make install" //
492// End: //
Note: See TracBrowser for help on using the repository browser.