source: src/Parser/ParseNode.h @ 702e826

ADTast-experimental
Last change on this file since 702e826 was 702e826, checked in by Andrew Beach <ajbeach@…>, 14 months ago

Pre-translation pass on the parser. Entirely code readability improvements, no behaviour (on a larger scale) should be effected.

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