source: src/Parser/ParseNode.h @ 9236060

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 9236060 was 9236060, checked in by Rob Schluntz <rschlunt@…>, 4 years ago

Merge branch 'master' into references

  • Property mode set to 100644
File size: 18.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 : Thu Jul 27 12:08:08 2017
13// Update Count     : 788
14//
15
16#pragma once
17
18#include <string>
19#include <list>
20#include <iterator>
21#include <memory>
22
23#include "Parser/LinkageSpec.h"
24#include "SynTree/Type.h"
25#include "SynTree/Expression.h"
26#include "SynTree/Statement.h"
27#include "SynTree/Label.h"
28#include "Common/utility.h"
29#include "Common/UniqueName.h"
30
31class StatementNode;
32class CompoundStmtNode;
33class DeclarationNode;
34class ExpressionNode;
35class InitializerNode;
36class Attribute;
37
38//##############################################################################
39
40extern char * yyfilename;
41extern int yylineno;
42
43class ParseNode {
44  public:
45        ParseNode() {};
46        virtual ~ParseNode() { delete next; delete name; };
47        virtual ParseNode * clone() const = 0;
48
49        ParseNode * get_next() const { return next; }
50        ParseNode * set_next( ParseNode * newlink ) { next = newlink; return this; }
51
52        ParseNode * get_last() {
53                ParseNode * current;
54                for ( current = this; current->get_next() != nullptr; current = current->get_next() );
55                return current;
56        }
57        ParseNode * set_last( ParseNode * newlast ) {
58                if ( newlast != nullptr ) get_last()->set_next( newlast );
59                return this;
60        }
61
62        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
63        virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
64
65        static int indent_by;
66
67        ParseNode * next = nullptr;
68        std::string * name = nullptr;
69        CodeLocation location = { yyfilename, yylineno };
70}; // ParseNode
71
72//##############################################################################
73
74class InitializerNode : public ParseNode {
75  public:
76        InitializerNode( ExpressionNode *, bool aggrp = false,  ExpressionNode * des = nullptr );
77        InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
78        ~InitializerNode();
79        virtual InitializerNode * clone() const { assert( false ); return nullptr; }
80
81        ExpressionNode * get_expression() const { return expr; }
82
83        InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
84        ExpressionNode * get_designators() const { return designator; }
85
86        InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
87        bool get_maybeConstructed() const { return maybeConstructed; }
88
89        InitializerNode * next_init() const { return kids; }
90
91        void print( std::ostream &os, int indent = 0 ) const;
92        void printOneLine( std::ostream & ) const;
93
94        virtual Initializer * build() const;
95  private:
96        ExpressionNode * expr;
97        bool aggregate;
98        ExpressionNode * designator;                                            // may be list
99        InitializerNode * kids;
100        bool maybeConstructed;
101}; // InitializerNode
102
103//##############################################################################
104
105class ExpressionNode final : public ParseNode {
106  public:
107        ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
108        virtual ~ExpressionNode() {}
109        virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
110
111        bool get_extension() const { return extension; }
112        ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
113
114        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
115        void printOneLine( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
116
117        template<typename T>
118        bool isExpressionType() const {
119                return nullptr != dynamic_cast<T>(expr.get());
120        }
121
122        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
123  private:
124        bool extension = false;
125        std::unique_ptr<Expression> expr;
126}; // ExpressionNode
127
128template< typename T >
129struct maybeBuild_t< Expression, T > {
130        static inline Expression * doit( const T * orig ) {
131                if ( orig ) {
132                        Expression * p = orig->build();
133                        p->set_extension( orig->get_extension() );
134                        p->location = orig->location;
135                        return p;
136                } else {
137                        return nullptr;
138                } // if
139        }
140};
141
142// Must harmonize with OperName.
143enum class OperKinds {
144        // diadic
145        SizeOf, AlignOf, OffsetOf, Plus, Minus, Exp, Mul, Div, Mod, Or, And,
146        BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
147        Assign, AtAssn, ExpAssn, 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 );
161ConstantExpr * build_constantStr( const std::string &str );
162Expression * build_field_name_FLOATINGconstant( const std::string & str );
163Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
164Expression * build_field_name_REALFRACTIONconstant( const std::string & str );
165Expression * build_field_name_REALDECIMALconstant( const std::string & str );
166
167NameExpr * build_varref( const std::string * name );
168Expression * build_typevalue( DeclarationNode * decl );
169
170Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
171Expression * build_virtual_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, OperKinds kind );
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        // Perhaps this would best fold into newAggragate.
251        static DeclarationNode * newTreeStruct( Aggregate kind, const std::string * name, const std::string * parent, ExpressionNode * actuals, DeclarationNode * fields, bool body );
252
253        DeclarationNode();
254        ~DeclarationNode();
255        DeclarationNode * clone() const override;
256
257        DeclarationNode * addQualifiers( DeclarationNode * );
258        void checkQualifiers( const TypeData *, const TypeData * );
259        void checkSpecifiers( DeclarationNode * );
260        DeclarationNode * copySpecifiers( DeclarationNode * );
261        DeclarationNode * addType( DeclarationNode * );
262        DeclarationNode * addTypedef();
263        DeclarationNode * addAssertions( DeclarationNode * );
264        DeclarationNode * addName( std::string * );
265        DeclarationNode * addAsmName( DeclarationNode * );
266        DeclarationNode * addBitfield( ExpressionNode * size );
267        DeclarationNode * addVarArgs();
268        DeclarationNode * addFunctionBody( StatementNode * body );
269        DeclarationNode * addOldDeclList( DeclarationNode * list );
270        DeclarationNode * setBase( TypeData * newType );
271        DeclarationNode * copyAttribute( DeclarationNode * attr );
272        DeclarationNode * addPointer( DeclarationNode * qualifiers );
273        DeclarationNode * addArray( DeclarationNode * array );
274        DeclarationNode * addNewPointer( DeclarationNode * pointer );
275        DeclarationNode * addNewArray( DeclarationNode * array );
276        DeclarationNode * addParamList( DeclarationNode * list );
277        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
278        DeclarationNode * addInitializer( InitializerNode * init );
279        DeclarationNode * addTypeInitializer( DeclarationNode * init );
280
281        DeclarationNode * cloneType( std::string * newName );
282        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
283
284        DeclarationNode * appendList( DeclarationNode * node ) {
285                return (DeclarationNode *)set_last( node );
286        }
287
288        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
289        virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
290
291        Declaration * build() const;
292        Type * buildType() const;
293
294        bool get_hasEllipsis() const;
295        LinkageSpec::Spec get_linkage() const { return linkage; }
296        DeclarationNode * extractAggregate() const;
297        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
298        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
299
300        bool get_extension() const { return extension; }
301        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
302  public:
303        struct Variable_t {
304//              const std::string * name;
305                DeclarationNode::TypeClass tyClass;
306                DeclarationNode * assertions;
307                DeclarationNode * initializer;
308        };
309        Variable_t variable;
310
311        struct Attr_t {
312//              const std::string * name;
313                ExpressionNode * expr;
314                DeclarationNode * type;
315        };
316        Attr_t attr;
317
318        BuiltinType builtin;
319
320        TypeData * type;
321
322        Type::FuncSpecifiers funcSpecs;
323        Type::StorageClasses storageClasses;
324
325        ExpressionNode * bitfieldWidth;
326        std::unique_ptr<ExpressionNode> enumeratorValue;
327        bool hasEllipsis;
328        LinkageSpec::Spec linkage;
329        ConstantExpr *asmName;
330        std::list< Attribute * > attributes;
331        InitializerNode * initializer;
332        bool extension = false;
333        std::string error;
334        StatementNode * asmStmt;
335
336        static UniqueName anonymous;
337
338        // Temp to test TreeStruct
339        const std::string * parent_name;
340}; // DeclarationNode
341
342Type * buildType( TypeData * type );
343
344static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
345        Type * ret = orig ? orig->buildType() : nullptr;
346        delete orig;
347        return ret;
348}
349
350//##############################################################################
351
352class StatementNode final : public ParseNode {
353  public:
354        StatementNode() { stmt = nullptr; }
355        StatementNode( Statement * stmt ) : stmt( stmt ) {}
356        StatementNode( DeclarationNode * decl );
357        virtual ~StatementNode() {}
358
359        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
360        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
361
362        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
363                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
364                delete attr;
365                delete name;
366                return this;
367        }
368
369        virtual StatementNode * append_last_case( StatementNode * );
370
371        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
372        virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
373  private:
374        std::unique_ptr<Statement> stmt;
375}; // StatementNode
376
377Statement * build_expr( ExpressionNode * ctl );
378
379struct ForCtl {
380        ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
381                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
382        ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
383                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
384
385        StatementNode * init;
386        ExpressionNode * condition;
387        ExpressionNode * change;
388};
389
390Statement * build_if( ExpressionNode * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
391Statement * build_switch( ExpressionNode * ctl, StatementNode * stmt );
392Statement * build_case( ExpressionNode * ctl );
393Statement * build_default();
394Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
395Statement * build_for( ForCtl * forctl, StatementNode * stmt );
396Statement * build_branch( BranchStmt::Type kind );
397Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
398Statement * build_computedgoto( ExpressionNode * ctl );
399Statement * build_return( ExpressionNode * ctl );
400Statement * build_throw( ExpressionNode * ctl );
401Statement * build_resume( ExpressionNode * ctl );
402Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
403Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
404Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
405Statement * build_finally( StatementNode * stmt );
406Statement * build_compound( StatementNode * first );
407Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
408
409//##############################################################################
410
411template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
412void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
413        SemanticError errors;
414        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
415        const NodeType * cur = firstNode;
416
417        while ( cur ) {
418                try {
419                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
420                        if ( result ) {
421                                result->location = cur->location;
422                                * out++ = result;
423                        } else {
424                                assertf(false, "buildList unknown type");
425                        } // if
426                } catch( SemanticError &e ) {
427                        e.set_location( cur->location );
428                        errors.append( e );
429                } // try
430                cur = dynamic_cast< NodeType * >( cur->get_next() );
431        } // while
432        if ( ! errors.isEmpty() ) {
433                throw errors;
434        } // if
435}
436
437// in DeclarationNode.cc
438void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
439void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
440void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
441
442template< typename SynTreeType, typename NodeType >
443void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
444        buildList( firstNode, outputList );
445        delete firstNode;
446}
447
448// in ParseNode.cc
449std::ostream & operator<<( std::ostream & out, const ParseNode * node );
450
451// Local Variables: //
452// tab-width: 4 //
453// mode: c++ //
454// compile-command: "make install" //
455// End: //
Note: See TracBrowser for help on using the repository browser.