source: src/Parser/ParseNode.h @ e464759

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since e464759 was 6eb4398, checked in by Rob Schluntz <rschlunt@…>, 8 years ago

recursively clone expression node lists

  • Property mode set to 100644
File size: 17.9 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 : Fri Mar 17 15:42:18 2017
13// Update Count     : 777
14//
15
16#ifndef PARSENODE_H
17#define PARSENODE_H
18
19#include <string>
20#include <list>
21#include <iterator>
22#include <memory>
23
24#include "Parser/LinkageSpec.h"
25#include "SynTree/Type.h"
26#include "SynTree/Expression.h"
27#include "SynTree/Statement.h"
28#include "SynTree/Label.h"
29#include "Common/utility.h"
30#include "Common/UniqueName.h"
31
32class StatementNode;
33class CompoundStmtNode;
34class DeclarationNode;
35class ExpressionNode;
36class InitializerNode;
37class Attribute;
38
39//##############################################################################
40
41extern char * yyfilename;
42extern int yylineno;
43
44class ParseNode {
45  public:
46        ParseNode() {};
47        virtual ~ParseNode() { delete next; delete name; };
48        virtual ParseNode * clone() const = 0;
49
50        ParseNode * get_next() const { return next; }
51        ParseNode * set_next( ParseNode * newlink ) { next = newlink; return this; }
52
53        ParseNode * get_last() {
54                ParseNode * current;
55                for ( current = this; current->get_next() != nullptr; current = current->get_next() );
56                return current;
57        }
58        ParseNode * set_last( ParseNode * newlast ) {
59                if ( newlast != nullptr ) get_last()->set_next( newlast );
60                return this;
61        }
62
63        virtual void print( std::ostream &os, int indent = 0 ) const {}
64        virtual void printList( std::ostream &os, int indent = 0 ) const {}
65
66        static int indent_by;
67
68        ParseNode * next = nullptr;
69        std::string * name = nullptr;
70        CodeLocation location = { yyfilename, yylineno };
71}; // ParseNode
72
73//##############################################################################
74
75class InitializerNode : public ParseNode {
76  public:
77        InitializerNode( ExpressionNode *, bool aggrp = false,  ExpressionNode * des = nullptr );
78        InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
79        ~InitializerNode();
80        virtual InitializerNode * clone() const { assert( false ); return nullptr; }
81
82        ExpressionNode * get_expression() const { return expr; }
83
84        InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
85        ExpressionNode * get_designators() const { return designator; }
86
87        InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
88        bool get_maybeConstructed() const { return maybeConstructed; }
89
90        InitializerNode * next_init() const { return kids; }
91
92        void print( std::ostream &os, int indent = 0 ) const;
93        void printOneLine( std::ostream & ) const;
94
95        virtual Initializer * build() const;
96  private:
97        ExpressionNode * expr;
98        bool aggregate;
99        ExpressionNode * designator;                                            // may be list
100        InitializerNode * kids;
101        bool maybeConstructed;
102}; // InitializerNode
103
104//##############################################################################
105
106class ExpressionNode final : public ParseNode {
107  public:
108        ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
109        virtual ~ExpressionNode() {}
110        virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
111
112        bool get_extension() const { return extension; }
113        ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
114
115        virtual void print( std::ostream &os, int indent = 0 ) const override {}
116        void printOneLine( std::ostream &os, int indent = 0 ) const {}
117
118        template<typename T>
119        bool isExpressionType() const {
120                return nullptr != dynamic_cast<T>(expr.get());
121        }
122
123        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
124  private:
125        bool extension = false;
126        std::unique_ptr<Expression> expr;
127}; // ExpressionNode
128
129template< typename T >
130struct maybeBuild_t< Expression, T > {
131        static inline Expression * doit( const T * orig ) {
132                if ( orig ) {
133                        Expression * p = orig->build();
134                        p->set_extension( orig->get_extension() );
135                        p->location = orig->location;
136                        return p;
137                } else {
138                        return nullptr;
139                } // if
140        }
141};
142
143enum class OperKinds {
144        // diadic
145        SizeOf, AlignOf, OffsetOf, Plus, Minus, Mul, Div, Mod, Or, And,
146        BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
147        Assign, AtAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
148        Index, Range,
149        // monadic
150        UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress,
151        Ctor, Dtor,
152}; // OperKinds
153
154struct LabelNode {
155        std::list< Label > labels;
156};
157
158Expression * build_constantInteger( const std::string &str );
159Expression * build_constantFloat( const std::string &str );
160Expression * build_constantChar( const std::string &str );
161Expression * build_constantZeroOne( const std::string &str );
162ConstantExpr * build_constantStr( const std::string &str );
163Expression * build_field_name_FLOATINGconstant( const std::string & str );
164Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
165Expression * build_field_name_REALFRACTIONconstant( const std::string & str );
166Expression * build_field_name_REALDECIMALconstant( const std::string & str );
167
168NameExpr * build_varref( const std::string * name, bool labelp = false );
169Expression * build_typevalue( DeclarationNode * decl );
170
171Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
172Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
173Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
174Expression * build_addressOf( ExpressionNode * expr_node );
175Expression * build_sizeOfexpr( ExpressionNode * expr_node );
176Expression * build_sizeOftype( DeclarationNode * decl_node );
177Expression * build_alignOfexpr( ExpressionNode * expr_node );
178Expression * build_alignOftype( DeclarationNode * decl_node );
179Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
180Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
181Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
182Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
183Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
184Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
185Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
186Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
187Expression * build_comma( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
188Expression * build_attrexpr( NameExpr * var, ExpressionNode * expr_node );
189Expression * build_attrtype( NameExpr * var, DeclarationNode * decl_node );
190Expression * build_tuple( ExpressionNode * expr_node = nullptr );
191Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
192Expression * build_range( ExpressionNode * low, ExpressionNode * high );
193Expression * build_asmexpr( ExpressionNode * inout, ConstantExpr * constraint, ExpressionNode * operand );
194Expression * build_valexpr( StatementNode * s );
195Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
196
197//##############################################################################
198
199struct TypeData;
200
201class DeclarationNode : public ParseNode {
202  public:
203        enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, NoBasicType };
204        enum ComplexType { Complex, Imaginary, NoComplexType };
205        enum Signedness { Signed, Unsigned, NoSignedness };
206        enum Length { Short, Long, LongLong, NoLength };
207        enum Aggregate { Struct, Union, Trait, Coroutine, Monitor, Thread, NoAggregate };
208        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
209        enum BuiltinType { Valist, Zero, One, NoBuiltinType };
210
211        static const char * basicTypeNames[];
212        static const char * complexTypeNames[];
213        static const char * signednessNames[];
214        static const char * lengthNames[];
215        static const char * aggregateNames[];
216        static const char * typeClassNames[];
217        static const char * builtinTypeNames[];
218
219        static DeclarationNode * newStorageClass( Type::StorageClasses );
220        static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
221        static DeclarationNode * newTypeQualifier( Type::Qualifiers );
222        static DeclarationNode * newBasicType( BasicType );
223        static DeclarationNode * newComplexType( ComplexType );
224        static DeclarationNode * newSignedNess( Signedness );
225        static DeclarationNode * newLength( Length );
226        static DeclarationNode * newBuiltinType( BuiltinType );
227        static DeclarationNode * newForall( DeclarationNode * );
228        static DeclarationNode * newFromTypedef( std::string * );
229        static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body, bool newStyle = false );
230        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
231        static DeclarationNode * newEnum( std::string * name, DeclarationNode * constants, bool body );
232        static DeclarationNode * newEnumConstant( std::string * name, ExpressionNode * constant );
233        static DeclarationNode * newName( std::string * );
234        static DeclarationNode * newFromTypeGen( std::string *, ExpressionNode * params );
235        static DeclarationNode * newTypeParam( TypeClass, std::string * );
236        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
237        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
238        static DeclarationNode * newTypeDecl( std::string * name, DeclarationNode * typeParams );
239        static DeclarationNode * newPointer( DeclarationNode * qualifiers );
240        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
241        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
242        static DeclarationNode * newBitfield( ExpressionNode * size );
243        static DeclarationNode * newTuple( DeclarationNode * members );
244        static DeclarationNode * newTypeof( ExpressionNode * expr );
245        static DeclarationNode * newAttr( std::string *, ExpressionNode * expr ); // @ attributes
246        static DeclarationNode * newAttr( std::string *, DeclarationNode * type ); // @ attributes
247        static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
248        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
249
250        DeclarationNode();
251        ~DeclarationNode();
252        DeclarationNode * clone() const override;
253
254        DeclarationNode * addQualifiers( DeclarationNode * );
255        void checkQualifiers( const TypeData *, const TypeData * );
256        void checkSpecifiers( DeclarationNode * );
257        DeclarationNode * copySpecifiers( DeclarationNode * );
258        DeclarationNode * addType( DeclarationNode * );
259        DeclarationNode * addTypedef();
260        DeclarationNode * addAssertions( DeclarationNode * );
261        DeclarationNode * addName( std::string * );
262        DeclarationNode * addAsmName( DeclarationNode * );
263        DeclarationNode * addBitfield( ExpressionNode * size );
264        DeclarationNode * addVarArgs();
265        DeclarationNode * addFunctionBody( StatementNode * body );
266        DeclarationNode * addOldDeclList( DeclarationNode * list );
267        DeclarationNode * setBase( TypeData * newType );
268        DeclarationNode * copyAttribute( DeclarationNode * attr );
269        DeclarationNode * addPointer( DeclarationNode * qualifiers );
270        DeclarationNode * addArray( DeclarationNode * array );
271        DeclarationNode * addNewPointer( DeclarationNode * pointer );
272        DeclarationNode * addNewArray( DeclarationNode * array );
273        DeclarationNode * addParamList( DeclarationNode * list );
274        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
275        DeclarationNode * addInitializer( InitializerNode * init );
276
277        DeclarationNode * cloneType( std::string * newName );
278        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
279
280        DeclarationNode * appendList( DeclarationNode * node ) {
281                return (DeclarationNode *)set_last( node );
282        }
283
284        virtual void print( std::ostream &os, int indent = 0 ) const override;
285        virtual void printList( std::ostream &os, int indent = 0 ) const override;
286
287        Declaration * build() const;
288        Type * buildType() const;
289
290        bool get_hasEllipsis() const;
291        LinkageSpec::Spec get_linkage() const { return linkage; }
292        DeclarationNode * extractAggregate() const;
293        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
294        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
295
296        bool get_extension() const { return extension; }
297        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
298  public:
299        struct Variable_t {
300//              const std::string * name;
301                DeclarationNode::TypeClass tyClass;
302                DeclarationNode * assertions;
303        };
304        Variable_t variable;
305
306        struct Attr_t {
307//              const std::string * name;
308                ExpressionNode * expr;
309                DeclarationNode * type;
310        };
311        Attr_t attr;
312
313        BuiltinType builtin;
314
315        TypeData * type;
316
317        Type::FuncSpecifiers funcSpecs;
318        Type::StorageClasses storageClasses;
319
320        ExpressionNode * bitfieldWidth;
321        std::unique_ptr<ExpressionNode> enumeratorValue;
322        bool hasEllipsis;
323        LinkageSpec::Spec linkage;
324        ConstantExpr *asmName;
325        std::list< Attribute * > attributes;
326        InitializerNode * initializer;
327        bool extension = false;
328        std::string error;
329        StatementNode * asmStmt;
330
331        static UniqueName anonymous;
332}; // DeclarationNode
333
334Type * buildType( TypeData * type );
335
336static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
337        Type * ret = orig ? orig->buildType() : nullptr;
338        delete orig;
339        return ret;
340}
341
342//##############################################################################
343
344class StatementNode final : public ParseNode {
345  public:
346        StatementNode() { stmt = nullptr; }
347        StatementNode( Statement * stmt ) : stmt( stmt ) {}
348        StatementNode( DeclarationNode * decl );
349        virtual ~StatementNode() {}
350
351        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
352        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
353
354        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
355                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
356                delete attr;
357                delete name;
358                return this;
359        }
360
361        virtual StatementNode * append_last_case( StatementNode * );
362
363        virtual void print( std::ostream &os, int indent = 0 ) const override {}
364        virtual void printList( std::ostream &os, int indent = 0 ) const override {}
365  private:
366        std::unique_ptr<Statement> stmt;
367}; // StatementNode
368
369Statement * build_expr( ExpressionNode * ctl );
370
371struct ForCtl {
372        ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
373                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
374        ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
375                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
376
377        StatementNode * init;
378        ExpressionNode * condition;
379        ExpressionNode * change;
380};
381
382Statement * build_if( ExpressionNode * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
383Statement * build_switch( ExpressionNode * ctl, StatementNode * stmt );
384Statement * build_case( ExpressionNode * ctl );
385Statement * build_default();
386Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
387Statement * build_for( ForCtl * forctl, StatementNode * stmt );
388Statement * build_branch( BranchStmt::Type kind );
389Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
390Statement * build_computedgoto( ExpressionNode * ctl );
391Statement * build_return( ExpressionNode * ctl );
392Statement * build_throw( ExpressionNode * ctl );
393Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
394Statement * build_catch( DeclarationNode * decl, StatementNode * stmt, bool catchAny = false );
395Statement * build_finally( StatementNode * stmt );
396Statement * build_compound( StatementNode * first );
397Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
398
399//##############################################################################
400
401template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
402void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
403        SemanticError errors;
404        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
405        const NodeType * cur = firstNode;
406
407        while ( cur ) {
408                try {
409                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
410                        if ( result ) {
411                                result->location = cur->location;
412                                * out++ = result;
413                        } // if
414                } catch( SemanticError &e ) {
415                        e.set_location( cur->location );
416                        errors.append( e );
417                } // try
418                cur = dynamic_cast< NodeType * >( cur->get_next() );
419        } // while
420        if ( ! errors.isEmpty() ) {
421                throw errors;
422        } // if
423}
424
425// in DeclarationNode.cc
426void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
427void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
428void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
429
430template< typename SynTreeType, typename NodeType >
431void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
432        buildList( firstNode, outputList );
433        delete firstNode;
434}
435
436// in ParseNode.cc
437std::ostream & operator<<( std::ostream & out, const ParseNode * node );
438
439#endif // PARSENODE_H
440
441// Local Variables: //
442// tab-width: 4 //
443// mode: c++ //
444// compile-command: "make install" //
445// End: //
Note: See TracBrowser for help on using the repository browser.