source: src/Parser/ParseNode.h @ 82ff4ed1

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

fix bug printing semantic error in buildList

  • Property mode set to 100644
File size: 21.5 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 16:22:15 2022
13// Update Count     : 937
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 * newName( const std::string * );
243        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
244        static DeclarationNode * newTypeParam( TypeDecl::Kind, const std::string * );
245        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
246        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
247        static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
248        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
249        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
250        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
251        static DeclarationNode * newBitfield( ExpressionNode * size );
252        static DeclarationNode * newTuple( DeclarationNode * members );
253        static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
254        static DeclarationNode * newVtableType( DeclarationNode * expr );
255        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
256        static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
257        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
258        static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
259
260        DeclarationNode();
261        ~DeclarationNode();
262        DeclarationNode * clone() const override;
263
264        DeclarationNode * addQualifiers( DeclarationNode * );
265        void checkQualifiers( const TypeData *, const TypeData * );
266        void checkSpecifiers( DeclarationNode * );
267        DeclarationNode * copySpecifiers( DeclarationNode * );
268        DeclarationNode * addType( DeclarationNode * );
269        DeclarationNode * addTypedef();
270        DeclarationNode * addEnumBase( DeclarationNode * );
271        DeclarationNode * addAssertions( DeclarationNode * );
272        DeclarationNode * addName( std::string * );
273        DeclarationNode * addAsmName( DeclarationNode * );
274        DeclarationNode * addBitfield( ExpressionNode * size );
275        DeclarationNode * addVarArgs();
276        DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
277        DeclarationNode * addOldDeclList( DeclarationNode * list );
278        DeclarationNode * setBase( TypeData * newType );
279        DeclarationNode * copyAttribute( DeclarationNode * attr );
280        DeclarationNode * addPointer( DeclarationNode * qualifiers );
281        DeclarationNode * addArray( DeclarationNode * array );
282        DeclarationNode * addNewPointer( DeclarationNode * pointer );
283        DeclarationNode * addNewArray( DeclarationNode * array );
284        DeclarationNode * addParamList( DeclarationNode * list );
285        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
286        DeclarationNode * addInitializer( InitializerNode * init );
287        DeclarationNode * addTypeInitializer( DeclarationNode * init );
288
289        DeclarationNode * cloneType( std::string * newName );
290        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
291
292        DeclarationNode * appendList( DeclarationNode * node ) {
293                return (DeclarationNode *)set_last( node );
294        }
295
296        virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
297        virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
298
299        Declaration * build() const;
300        Type * buildType() const;
301
302        LinkageSpec::Spec get_linkage() const { return linkage; }
303        DeclarationNode * extractAggregate() const;
304        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
305        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
306
307        bool get_extension() const { return extension; }
308        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
309
310        bool get_inLine() const { return inLine; }
311        DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
312
313        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
314
315        struct Variable_t {
316//              const std::string * name;
317                TypeDecl::Kind tyClass;
318                DeclarationNode * assertions;
319                DeclarationNode * initializer;
320        };
321        Variable_t variable;
322
323        struct Attr_t {
324//              const std::string * name;
325                ExpressionNode * expr;
326                DeclarationNode * type;
327        };
328        Attr_t attr;
329
330        struct StaticAssert_t {
331                ExpressionNode * condition;
332                Expression * message;
333        };
334        StaticAssert_t assert;
335
336        BuiltinType builtin = NoBuiltinType;
337
338        TypeData * type = nullptr;
339
340        bool inLine = false;
341        Type::FuncSpecifiers funcSpecs;
342        Type::StorageClasses storageClasses;
343
344        ExpressionNode * bitfieldWidth = nullptr;
345        std::unique_ptr<ExpressionNode> enumeratorValue;
346        bool hasEllipsis = false;
347        LinkageSpec::Spec linkage;
348        Expression * asmName = nullptr;
349        std::list< Attribute * > attributes;
350        InitializerNode * initializer = nullptr;
351        bool extension = false;
352        std::string error;
353        StatementNode * asmStmt = nullptr;
354        StatementNode * directiveStmt = nullptr;
355
356        static UniqueName anonymous;
357}; // DeclarationNode
358
359Type * buildType( TypeData * type );
360
361static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
362        Type * ret = orig ? orig->buildType() : nullptr;
363        delete orig;
364        return ret;
365}
366
367//##############################################################################
368
369struct StatementNode final : public ParseNode {
370        StatementNode() { stmt = nullptr; }
371        StatementNode( Statement * stmt ) : stmt( stmt ) {}
372        StatementNode( DeclarationNode * decl );
373        virtual ~StatementNode() {}
374
375        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
376        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
377
378        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
379                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
380                delete attr;
381                delete name;
382                return this;
383        }
384
385        virtual StatementNode * append_last_case( StatementNode * );
386
387        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
388                os << stmt.get() << std::endl;
389        }
390
391        std::unique_ptr<Statement> stmt;
392}; // StatementNode
393
394Statement * build_expr( ExpressionNode * ctl );
395
396struct CondCtl {
397        CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :
398                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
399
400        StatementNode * init;
401        ExpressionNode * condition;
402};
403
404struct ForCtrl {
405        ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
406                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
407        ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
408                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
409
410        StatementNode * init;
411        ExpressionNode * condition;
412        ExpressionNode * change;
413};
414
415Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init );
416Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ );
417Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
418Statement * build_case( ExpressionNode * ctl );
419Statement * build_default();
420Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
421Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
422Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
423Statement * build_branch( BranchStmt::Type kind );
424Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
425Statement * build_computedgoto( ExpressionNode * ctl );
426Statement * build_return( ExpressionNode * ctl );
427Statement * build_throw( ExpressionNode * ctl );
428Statement * build_resume( ExpressionNode * ctl );
429Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
430Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
431Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
432Statement * build_finally( StatementNode * stmt );
433Statement * build_compound( StatementNode * first );
434StatementNode * maybe_build_compound( StatementNode * first );
435Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
436Statement * build_directive( std::string * directive );
437SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None);
438WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
439WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
440WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
441WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
442Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
443Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt );
444
445//##############################################################################
446
447template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
448void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
449        SemanticErrorException errors;
450        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
451        const NodeType * cur = firstNode;
452
453        while ( cur ) {
454                try {
455                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
456                        if ( result ) {
457                                result->location = cur->location;
458                                * out++ = result;
459                        } else {
460                                SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
461                        } // if
462                } catch( SemanticErrorException & e ) {
463                        errors.append( e );
464                } // try
465                const ParseNode * temp = (cur->get_next());
466                cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr
467                if ( ! cur && temp ) {                                                  // non-homogeneous nodes ?
468                        SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
469                } // if
470        } // while
471        if ( ! errors.isEmpty() ) {
472                throw errors;
473        } // if
474}
475
476// in DeclarationNode.cc
477void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
478void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
479void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
480
481template< typename SynTreeType, typename NodeType >
482void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
483        buildList( firstNode, outputList );
484        delete firstNode;
485}
486
487// in ParseNode.cc
488std::ostream & operator<<( std::ostream & out, const ParseNode * node );
489
490// Local Variables: //
491// tab-width: 4 //
492// mode: c++ //
493// compile-command: "make install" //
494// End: //
Note: See TracBrowser for help on using the repository browser.