source: src/Parser/ParseNode.h @ c5d7701

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprno_listpersistent-indexerpthread-emulationqualifiedEnum
Last change on this file since c5d7701 was c5d7701, checked in by Rob Schluntz <rschlunt@…>, 6 years ago

Add QualifiedType? node

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