source: src/Parser/ParseNode.h @ 67d4e37

arm-ehcleanup-dtorsjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-expr
Last change on this file since 67d4e37 was 67d4e37, checked in by Peter A. Buhr <pabuhr@…>, 3 years ago

add chained for-control specifiers, update loop test and test output

  • Property mode set to 100644
File size: 20.7 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// ParseNode.h --
8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Sat May 16 13:28:16 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sat Apr 13 15:44:20 2019
13// Update Count     : 873
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 "Parser/LinkageSpec.h"    // for Spec
31#include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
32#include "SynTree/Label.h"         // for Label
33#include "SynTree/Statement.h"     // for Statement, BranchStmt, BranchStmt:...
34#include "SynTree/Type.h"          // for Type, Type::FuncSpecifiers, Type::...
35
36class Attribute;
37class Declaration;
38class DeclarationNode;
39class DeclarationWithType;
40class ExpressionNode;
41class Initializer;
42class StatementNode;
43
44//##############################################################################
45
46typedef CodeLocation YYLTYPE;
47#define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */
48
49extern YYLTYPE yylloc;
50
51class ParseNode {
52  public:
53        ParseNode() {};
54        virtual ~ParseNode() { delete next; delete name; };
55        virtual ParseNode * clone() const = 0;
56
57        ParseNode * get_next() const { return next; }
58        ParseNode * set_next( ParseNode * newlink ) { next = newlink; return this; }
59
60        ParseNode * get_last() {
61                ParseNode * current;
62                for ( current = this; current->get_next() != nullptr; current = current->get_next() );
63                return current;
64        }
65        ParseNode * set_last( ParseNode * newlast ) {
66                if ( newlast != nullptr ) get_last()->set_next( newlast );
67                return this;
68        }
69
70        virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
71        virtual void printList( std::ostream & os, int indent = 0 ) const {
72                print( os, indent );
73                if ( next ) next->print( os, indent );
74        }
75
76        static int indent_by;
77
78        ParseNode * next = nullptr;
79        const std::string * name = nullptr;
80        CodeLocation location = yylloc;
81}; // ParseNode
82
83//##############################################################################
84
85class InitializerNode : public ParseNode {
86  public:
87        InitializerNode( ExpressionNode *, bool aggrp = false,  ExpressionNode * des = nullptr );
88        InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
89        InitializerNode( bool isDelete );
90        ~InitializerNode();
91        virtual InitializerNode * clone() const { assert( false ); return nullptr; }
92
93        ExpressionNode * get_expression() const { return expr; }
94
95        InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
96        ExpressionNode * get_designators() const { return designator; }
97
98        InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
99        bool get_maybeConstructed() const { return maybeConstructed; }
100
101        bool get_isDelete() const { return isDelete; }
102
103        InitializerNode * next_init() const { return kids; }
104
105        void print( std::ostream & os, int indent = 0 ) const;
106        void printOneLine( std::ostream & ) const;
107
108        virtual Initializer * build() const;
109  private:
110        ExpressionNode * expr;
111        bool aggregate;
112        ExpressionNode * designator;                                            // may be list
113        InitializerNode * kids;
114        bool maybeConstructed;
115        bool isDelete;
116}; // InitializerNode
117
118//##############################################################################
119
120class ExpressionNode final : public ParseNode {
121  public:
122        ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
123        virtual ~ExpressionNode() {}
124        virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
125
126        bool get_extension() const { return extension; }
127        ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
128
129        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
130                os << expr.get();
131        }
132        void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
133
134        Expression * get_expr() const { return expr.get(); }
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( KeywordCastExpr::Target 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
207class DeclarationNode : public ParseNode {
208  public:
209        // These enumerations must harmonize with their names in DeclarationNode.cc.
210        enum BasicType { Void, Bool, Char, Int, Int128,
211                                         Float, Double, LongDouble, uuFloat80, uuFloat128,
212                                         uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x, NoBasicType };
213        static const char * basicTypeNames[];
214        enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
215        static const char * complexTypeNames[];
216        enum Signedness { Signed, Unsigned, NoSignedness };
217        static const char * signednessNames[];
218        enum Length { Short, Long, LongLong, NoLength };
219        static const char * lengthNames[];
220        enum Aggregate { Struct, Union, Exception, Trait, Coroutine, Monitor, Thread, NoAggregate };
221        static const char * aggregateNames[];
222        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
223        static const char * typeClassNames[];
224        enum BuiltinType { Valist, Zero, One, NoBuiltinType };
225        static const char * builtinTypeNames[];
226
227        static DeclarationNode * newStorageClass( Type::StorageClasses );
228        static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
229        static DeclarationNode * newTypeQualifier( Type::Qualifiers );
230        static DeclarationNode * newBasicType( BasicType );
231        static DeclarationNode * newComplexType( ComplexType );
232        static DeclarationNode * newSignedNess( Signedness );
233        static DeclarationNode * newLength( Length );
234        static DeclarationNode * newBuiltinType( BuiltinType );
235        static DeclarationNode * newForall( DeclarationNode * );
236        static DeclarationNode * newFromTypedef( const std::string * );
237        static DeclarationNode * newFromGlobalScope();
238        static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
239        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
240        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
241        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body );
242        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
243        static DeclarationNode * newName( const std::string * );
244        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
245        static DeclarationNode * newTypeParam( TypeClass, const std::string * );
246        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
247        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
248        static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
249        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
250        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
251        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
252        static DeclarationNode * newBitfield( ExpressionNode * size );
253        static DeclarationNode * newTuple( DeclarationNode * members );
254        static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
255        static DeclarationNode * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes
256        static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes
257        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
258        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
259        static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
260
261        DeclarationNode();
262        ~DeclarationNode();
263        DeclarationNode * clone() const override;
264
265        DeclarationNode * addQualifiers( DeclarationNode * );
266        void checkQualifiers( const TypeData *, const TypeData * );
267        void checkSpecifiers( DeclarationNode * );
268        DeclarationNode * copySpecifiers( DeclarationNode * );
269        DeclarationNode * addType( DeclarationNode * );
270        DeclarationNode * addTypedef();
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  public:
313        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
314
315        struct Variable_t {
316//              const std::string * name;
317                DeclarationNode::TypeClass 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
355        static UniqueName anonymous;
356}; // DeclarationNode
357
358Type * buildType( TypeData * type );
359
360static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
361        Type * ret = orig ? orig->buildType() : nullptr;
362        delete orig;
363        return ret;
364}
365
366//##############################################################################
367
368class StatementNode final : public ParseNode {
369  public:
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  private:
391        std::unique_ptr<Statement> stmt;
392}; // StatementNode
393
394Statement * build_expr( ExpressionNode * ctl );
395
396struct IfCtrl {
397        IfCtrl( 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( IfCtrl * ctl, std::list< Statement * > & init );
416Statement * build_if( IfCtrl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
417Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
418Statement * build_case( ExpressionNode * ctl );
419Statement * build_default();
420Statement * build_while( IfCtrl * ctl, StatementNode * stmt );
421Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt );
422Statement * build_for( ForCtrl * forctl, StatementNode * stmt );
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_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
431Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
432Statement * build_finally( StatementNode * stmt );
433Statement * build_compound( StatementNode * first );
434Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
435Statement * build_directive( std::string * directive );
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 );
440WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
441
442//##############################################################################
443
444template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
445void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
446        SemanticErrorException errors;
447        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
448        const NodeType * cur = firstNode;
449
450        while ( cur ) {
451                try {
452                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
453                        if ( result ) {
454                                result->location = cur->location;
455                                * out++ = result;
456                        } else {
457                                assertf(false, "buildList unknown type");
458                        } // if
459                } catch( SemanticErrorException & e ) {
460                        errors.append( e );
461                } // try
462                cur = dynamic_cast< NodeType * >( cur->get_next() );
463        } // while
464        if ( ! errors.isEmpty() ) {
465                throw errors;
466        } // if
467}
468
469// in DeclarationNode.cc
470void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
471void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
472void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
473
474template< typename SynTreeType, typename NodeType >
475void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
476        buildList( firstNode, outputList );
477        delete firstNode;
478}
479
480// in ParseNode.cc
481std::ostream & operator<<( std::ostream & out, const ParseNode * node );
482
483// Local Variables: //
484// tab-width: 4 //
485// mode: c++ //
486// compile-command: "make install" //
487// End: //
Note: See TracBrowser for help on using the repository browser.