source: src/Parser/ParseNode.h @ a025ea8

arm-ehjacob/cs343-translationnew-ast-unique-expr
Last change on this file since a025ea8 was a025ea8, checked in by Peter A. Buhr <pabuhr@…>, 13 months ago

add maybe_build_compound to always build a compound statement for control structures with a single statement

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