source: src/Parser/ParseNode.h @ 7a54d67

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 7a54d67 was 1dda8de, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

update chained for-control specifiers

  • Property mode set to 100644
File size: 20.6 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// ParseNode.h --
8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Sat May 16 13:28:16 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Mon Apr 15 14:22:39 2019
13// Update Count     : 874
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        template<typename T>
135        bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
136
137        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
138
139        std::unique_ptr<Expression> expr;                                       // public because of lifetime implications
140  private:
141        bool extension = false;
142}; // ExpressionNode
143
144template< typename T >
145struct maybeBuild_t< Expression, T > {
146        static inline Expression * doit( const T * orig ) {
147                if ( orig ) {
148                        Expression * p = orig->build();
149                        p->set_extension( orig->get_extension() );
150                        p->location = orig->location;
151                        return p;
152                } else {
153                        return nullptr;
154                } // if
155        }
156};
157
158// Must harmonize with OperName.
159enum class OperKinds {
160        // diadic
161        SizeOf, AlignOf, OffsetOf, Plus, Minus, Exp, Mul, Div, Mod, Or, And,
162        BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
163        Assign, AtAssn, ExpAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
164        Index, Range,
165        // monadic
166        UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
167        Ctor, Dtor,
168}; // OperKinds
169
170struct LabelNode {
171        std::list< Label > labels;
172};
173
174Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string
175Expression * build_constantFloat( std::string & str );
176Expression * build_constantChar( std::string & str );
177Expression * build_constantStr( std::string & str );
178Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
179Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
180Expression * build_field_name_FLOATINGconstant( const std::string & str );
181Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
182
183NameExpr * build_varref( const std::string * name );
184
185Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
186Expression * build_keyword_cast( KeywordCastExpr::Target target, ExpressionNode * expr_node );
187Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
188Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
189Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
190Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
191Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
192Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
193Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
194Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
195Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
196Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
197Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
198Expression * build_tuple( ExpressionNode * expr_node = nullptr );
199Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
200Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
201
202//##############################################################################
203
204struct TypeData;
205
206class DeclarationNode : public ParseNode {
207  public:
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 Aggregate { Struct, Union, Exception, Trait, Coroutine, Monitor, Thread, NoAggregate };
220        static const char * aggregateNames[];
221        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
222        static const char * typeClassNames[];
223        enum BuiltinType { Valist, Zero, One, NoBuiltinType };
224        static const char * builtinTypeNames[];
225
226        static DeclarationNode * newStorageClass( Type::StorageClasses );
227        static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
228        static DeclarationNode * newTypeQualifier( Type::Qualifiers );
229        static DeclarationNode * newBasicType( BasicType );
230        static DeclarationNode * newComplexType( ComplexType );
231        static DeclarationNode * newSignedNess( Signedness );
232        static DeclarationNode * newLength( Length );
233        static DeclarationNode * newBuiltinType( BuiltinType );
234        static DeclarationNode * newForall( DeclarationNode * );
235        static DeclarationNode * newFromTypedef( const std::string * );
236        static DeclarationNode * newFromGlobalScope();
237        static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
238        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
239        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
240        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body );
241        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
242        static DeclarationNode * newName( const std::string * );
243        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
244        static DeclarationNode * newTypeParam( TypeClass, 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 * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes
255        static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes
256        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
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 * addAssertions( DeclarationNode * );
271        DeclarationNode * addName( std::string * );
272        DeclarationNode * addAsmName( DeclarationNode * );
273        DeclarationNode * addBitfield( ExpressionNode * size );
274        DeclarationNode * addVarArgs();
275        DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
276        DeclarationNode * addOldDeclList( DeclarationNode * list );
277        DeclarationNode * setBase( TypeData * newType );
278        DeclarationNode * copyAttribute( DeclarationNode * attr );
279        DeclarationNode * addPointer( DeclarationNode * qualifiers );
280        DeclarationNode * addArray( DeclarationNode * array );
281        DeclarationNode * addNewPointer( DeclarationNode * pointer );
282        DeclarationNode * addNewArray( DeclarationNode * array );
283        DeclarationNode * addParamList( DeclarationNode * list );
284        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
285        DeclarationNode * addInitializer( InitializerNode * init );
286        DeclarationNode * addTypeInitializer( DeclarationNode * init );
287
288        DeclarationNode * cloneType( std::string * newName );
289        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
290
291        DeclarationNode * appendList( DeclarationNode * node ) {
292                return (DeclarationNode *)set_last( node );
293        }
294
295        virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
296        virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
297
298        Declaration * build() const;
299        Type * buildType() const;
300
301        LinkageSpec::Spec get_linkage() const { return linkage; }
302        DeclarationNode * extractAggregate() const;
303        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
304        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
305
306        bool get_extension() const { return extension; }
307        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
308
309        bool get_inLine() const { return inLine; }
310        DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
311  public:
312        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
313
314        struct Variable_t {
315//              const std::string * name;
316                DeclarationNode::TypeClass tyClass;
317                DeclarationNode * assertions;
318                DeclarationNode * initializer;
319        };
320        Variable_t variable;
321
322        struct Attr_t {
323//              const std::string * name;
324                ExpressionNode * expr;
325                DeclarationNode * type;
326        };
327        Attr_t attr;
328
329        struct StaticAssert_t {
330                ExpressionNode * condition;
331                Expression * message;
332        };
333        StaticAssert_t assert;
334
335        BuiltinType builtin = NoBuiltinType;
336
337        TypeData * type = nullptr;
338
339        bool inLine = false;
340        Type::FuncSpecifiers funcSpecs;
341        Type::StorageClasses storageClasses;
342
343        ExpressionNode * bitfieldWidth = nullptr;
344        std::unique_ptr<ExpressionNode> enumeratorValue;
345        bool hasEllipsis = false;
346        LinkageSpec::Spec linkage;
347        Expression * asmName = nullptr;
348        std::list< Attribute * > attributes;
349        InitializerNode * initializer = nullptr;
350        bool extension = false;
351        std::string error;
352        StatementNode * asmStmt = nullptr;
353
354        static UniqueName anonymous;
355}; // DeclarationNode
356
357Type * buildType( TypeData * type );
358
359static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
360        Type * ret = orig ? orig->buildType() : nullptr;
361        delete orig;
362        return ret;
363}
364
365//##############################################################################
366
367class StatementNode final : public ParseNode {
368  public:
369        StatementNode() { stmt = nullptr; }
370        StatementNode( Statement * stmt ) : stmt( stmt ) {}
371        StatementNode( DeclarationNode * decl );
372        virtual ~StatementNode() {}
373
374        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
375        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
376
377        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
378                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
379                delete attr;
380                delete name;
381                return this;
382        }
383
384        virtual StatementNode * append_last_case( StatementNode * );
385
386        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
387                os << stmt.get() << std::endl;
388        }
389  private:
390        std::unique_ptr<Statement> stmt;
391}; // StatementNode
392
393Statement * build_expr( ExpressionNode * ctl );
394
395struct IfCtrl {
396        IfCtrl( DeclarationNode * decl, ExpressionNode * condition ) :
397                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
398
399        StatementNode * init;
400        ExpressionNode * condition;
401};
402
403struct ForCtrl {
404        ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
405                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
406        ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
407                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
408
409        StatementNode * init;
410        ExpressionNode * condition;
411        ExpressionNode * change;
412};
413
414Expression * build_if_control( IfCtrl * ctl, std::list< Statement * > & init );
415Statement * build_if( IfCtrl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
416Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
417Statement * build_case( ExpressionNode * ctl );
418Statement * build_default();
419Statement * build_while( IfCtrl * ctl, StatementNode * stmt );
420Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt );
421Statement * build_for( ForCtrl * forctl, StatementNode * stmt );
422Statement * build_branch( BranchStmt::Type kind );
423Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
424Statement * build_computedgoto( ExpressionNode * ctl );
425Statement * build_return( ExpressionNode * ctl );
426Statement * build_throw( ExpressionNode * ctl );
427Statement * build_resume( ExpressionNode * ctl );
428Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
429Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
430Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
431Statement * build_finally( StatementNode * stmt );
432Statement * build_compound( StatementNode * first );
433Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
434Statement * build_directive( std::string * directive );
435WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
436WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
437WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
438WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
439WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
440
441//##############################################################################
442
443template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
444void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
445        SemanticErrorException errors;
446        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
447        const NodeType * cur = firstNode;
448
449        while ( cur ) {
450                try {
451                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
452                        if ( result ) {
453                                result->location = cur->location;
454                                * out++ = result;
455                        } else {
456                                assertf(false, "buildList unknown type");
457                        } // if
458                } catch( SemanticErrorException & e ) {
459                        errors.append( e );
460                } // try
461                cur = dynamic_cast< NodeType * >( cur->get_next() );
462        } // while
463        if ( ! errors.isEmpty() ) {
464                throw errors;
465        } // if
466}
467
468// in DeclarationNode.cc
469void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
470void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
471void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
472
473template< typename SynTreeType, typename NodeType >
474void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
475        buildList( firstNode, outputList );
476        delete firstNode;
477}
478
479// in ParseNode.cc
480std::ostream & operator<<( std::ostream & out, const ParseNode * node );
481
482// Local Variables: //
483// tab-width: 4 //
484// mode: c++ //
485// compile-command: "make install" //
486// End: //
Note: See TracBrowser for help on using the repository browser.