source: src/Parser/ParseNode.h @ be53b87

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since be53b87 was 033ff37, checked in by Peter A. Buhr <pabuhr@…>, 5 years ago

remove attribute expression '@'name mechanism

  • 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 : Thu Jul 25 22:17:10 2019
13// Update Count     : 876
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, AutoType, 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 * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
255        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
256        static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
257
258        DeclarationNode();
259        ~DeclarationNode();
260        DeclarationNode * clone() const override;
261
262        DeclarationNode * addQualifiers( DeclarationNode * );
263        void checkQualifiers( const TypeData *, const TypeData * );
264        void checkSpecifiers( DeclarationNode * );
265        DeclarationNode * copySpecifiers( DeclarationNode * );
266        DeclarationNode * addType( DeclarationNode * );
267        DeclarationNode * addTypedef();
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  public:
310        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
311
312        struct Variable_t {
313//              const std::string * name;
314                DeclarationNode::TypeClass tyClass;
315                DeclarationNode * assertions;
316                DeclarationNode * initializer;
317        };
318        Variable_t variable;
319
320        struct Attr_t {
321//              const std::string * name;
322                ExpressionNode * expr;
323                DeclarationNode * type;
324        };
325        Attr_t attr;
326
327        struct StaticAssert_t {
328                ExpressionNode * condition;
329                Expression * message;
330        };
331        StaticAssert_t assert;
332
333        BuiltinType builtin = NoBuiltinType;
334
335        TypeData * type = nullptr;
336
337        bool inLine = false;
338        Type::FuncSpecifiers funcSpecs;
339        Type::StorageClasses storageClasses;
340
341        ExpressionNode * bitfieldWidth = nullptr;
342        std::unique_ptr<ExpressionNode> enumeratorValue;
343        bool hasEllipsis = false;
344        LinkageSpec::Spec linkage;
345        Expression * asmName = nullptr;
346        std::list< Attribute * > attributes;
347        InitializerNode * initializer = nullptr;
348        bool extension = false;
349        std::string error;
350        StatementNode * asmStmt = nullptr;
351
352        static UniqueName anonymous;
353}; // DeclarationNode
354
355Type * buildType( TypeData * type );
356
357static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
358        Type * ret = orig ? orig->buildType() : nullptr;
359        delete orig;
360        return ret;
361}
362
363//##############################################################################
364
365class StatementNode final : public ParseNode {
366  public:
367        StatementNode() { stmt = nullptr; }
368        StatementNode( Statement * stmt ) : stmt( stmt ) {}
369        StatementNode( DeclarationNode * decl );
370        virtual ~StatementNode() {}
371
372        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
373        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
374
375        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
376                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
377                delete attr;
378                delete name;
379                return this;
380        }
381
382        virtual StatementNode * append_last_case( StatementNode * );
383
384        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
385                os << stmt.get() << std::endl;
386        }
387  private:
388        std::unique_ptr<Statement> stmt;
389}; // StatementNode
390
391Statement * build_expr( ExpressionNode * ctl );
392
393struct IfCtrl {
394        IfCtrl( DeclarationNode * decl, ExpressionNode * condition ) :
395                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
396
397        StatementNode * init;
398        ExpressionNode * condition;
399};
400
401struct ForCtrl {
402        ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
403                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
404        ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
405                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
406
407        StatementNode * init;
408        ExpressionNode * condition;
409        ExpressionNode * change;
410};
411
412Expression * build_if_control( IfCtrl * ctl, std::list< Statement * > & init );
413Statement * build_if( IfCtrl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
414Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
415Statement * build_case( ExpressionNode * ctl );
416Statement * build_default();
417Statement * build_while( IfCtrl * ctl, StatementNode * stmt );
418Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt );
419Statement * build_for( ForCtrl * forctl, StatementNode * stmt );
420Statement * build_branch( BranchStmt::Type kind );
421Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
422Statement * build_computedgoto( ExpressionNode * ctl );
423Statement * build_return( ExpressionNode * ctl );
424Statement * build_throw( ExpressionNode * ctl );
425Statement * build_resume( ExpressionNode * ctl );
426Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
427Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
428Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
429Statement * build_finally( StatementNode * stmt );
430Statement * build_compound( StatementNode * first );
431Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
432Statement * build_directive( std::string * directive );
433WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
434WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
435WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
436WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
437Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
438
439//##############################################################################
440
441template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
442void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
443        SemanticErrorException errors;
444        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
445        const NodeType * cur = firstNode;
446
447        while ( cur ) {
448                try {
449                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
450                        if ( result ) {
451                                result->location = cur->location;
452                                * out++ = result;
453                        } else {
454                                assertf(false, "buildList unknown type");
455                        } // if
456                } catch( SemanticErrorException & e ) {
457                        errors.append( e );
458                } // try
459                cur = dynamic_cast< NodeType * >( cur->get_next() );
460        } // while
461        if ( ! errors.isEmpty() ) {
462                throw errors;
463        } // if
464}
465
466// in DeclarationNode.cc
467void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
468void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
469void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
470
471template< typename SynTreeType, typename NodeType >
472void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
473        buildList( firstNode, outputList );
474        delete firstNode;
475}
476
477// in ParseNode.cc
478std::ostream & operator<<( std::ostream & out, const ParseNode * node );
479
480// Local Variables: //
481// tab-width: 4 //
482// mode: c++ //
483// compile-command: "make install" //
484// End: //
Note: See TracBrowser for help on using the repository browser.