source: src/Parser/ParseNode.h @ 26ba208

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 26ba208 was 68fe077a, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

move type StorageClasses? from DeclarationNode? to Type

  • Property mode set to 100644
File size: 18.5 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 Mar 16 07:46:33 2017
13// Update Count     : 772
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        ExpressionNode( const ExpressionNode &other );
110        virtual ~ExpressionNode() {}
111        virtual ExpressionNode * clone() const override { return expr ? new ExpressionNode( expr->clone() ) : nullptr; }
112
113        bool get_extension() const { return extension; }
114        ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
115
116        virtual void print( std::ostream &os, int indent = 0 ) const override {}
117        void printOneLine( std::ostream &os, int indent = 0 ) const {}
118
119        template<typename T>
120        bool isExpressionType() const {
121                return nullptr != dynamic_cast<T>(expr.get());
122        }
123
124        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
125  private:
126        bool extension = false;
127        std::unique_ptr<Expression> expr;
128}; // ExpressionNode
129
130template< typename T >
131struct maybeBuild_t< Expression, T > {
132        static inline Expression * doit( const T * orig ) {
133                if ( orig ) {
134                        Expression * p = orig->build();
135                        p->set_extension( orig->get_extension() );
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 { Inline = 1 << 0, Noreturn = 1 << 1, Fortran = 1 << 2, NumFuncSpecifier = 3 };
204        union FuncSpecifiers {
205                static const char * Names[];
206                unsigned int val;
207                struct {
208                        bool is_inline : 1;
209                        bool is_noreturn : 1;
210                        bool is_fortran : 1;
211                };
212                FuncSpecifiers() : val( 0 ) {}
213                FuncSpecifiers( unsigned int val ) : val( val ) {}
214                bool operator[]( unsigned int i ) const { return val & (1 << i); }
215                bool any() const { return val != 0; }
216                void print( std::ostream & os ) const {
217                        if ( (*this).any() ) {                                          // any function specifiers ?
218                                for ( unsigned int i = 0; i < NumFuncSpecifier; i += 1 ) {
219                                        if ( (*this)[i] ) {
220                                                os << FuncSpecifiers::Names[i] << ' ';
221                                        } // if
222                                } // for
223                        } // if
224                }
225        }; // FuncSpecifiers
226
227        enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, NoBasicType };
228        enum ComplexType { Complex, Imaginary, NoComplexType };
229        enum Signedness { Signed, Unsigned, NoSignedness };
230        enum Length { Short, Long, LongLong, NoLength };
231        enum Aggregate { Struct, Union, Trait, NoAggregate };
232        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
233        enum BuiltinType { Valist, Zero, One, NoBuiltinType };
234
235        static const char * basicTypeNames[];
236        static const char * complexTypeNames[];
237        static const char * signednessNames[];
238        static const char * lengthNames[];
239        static const char * aggregateNames[];
240        static const char * typeClassNames[];
241        static const char * builtinTypeNames[];
242
243        static DeclarationNode * newStorageClass( Type::StorageClasses );
244        static DeclarationNode * newFuncSpecifier( FuncSpecifiers );
245        static DeclarationNode * newTypeQualifier( Type::Qualifiers );
246        static DeclarationNode * newBasicType( BasicType );
247        static DeclarationNode * newComplexType( ComplexType );
248        static DeclarationNode * newSignedNess( Signedness );
249        static DeclarationNode * newLength( Length );
250        static DeclarationNode * newBuiltinType( BuiltinType );
251        static DeclarationNode * newForall( DeclarationNode * );
252        static DeclarationNode * newFromTypedef( std::string * );
253        static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body, bool newStyle = false );
254        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
255        static DeclarationNode * newEnum( std::string * name, DeclarationNode * constants, bool body );
256        static DeclarationNode * newEnumConstant( std::string * name, ExpressionNode * constant );
257        static DeclarationNode * newName( std::string * );
258        static DeclarationNode * newFromTypeGen( std::string *, ExpressionNode * params );
259        static DeclarationNode * newTypeParam( TypeClass, std::string * );
260        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
261        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
262        static DeclarationNode * newTypeDecl( std::string * name, DeclarationNode * typeParams );
263        static DeclarationNode * newPointer( DeclarationNode * qualifiers );
264        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
265        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
266        static DeclarationNode * newBitfield( ExpressionNode * size );
267        static DeclarationNode * newTuple( DeclarationNode * members );
268        static DeclarationNode * newTypeof( ExpressionNode * expr );
269        static DeclarationNode * newAttr( std::string *, ExpressionNode * expr ); // @ attributes
270        static DeclarationNode * newAttr( std::string *, DeclarationNode * type ); // @ attributes
271        static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
272        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
273
274        DeclarationNode();
275        ~DeclarationNode();
276        DeclarationNode * clone() const override;
277
278        DeclarationNode * addQualifiers( DeclarationNode * );
279        void checkQualifiers( const TypeData *, const TypeData * );
280        void checkSpecifiers( DeclarationNode * );
281        DeclarationNode * copySpecifiers( DeclarationNode * );
282        DeclarationNode * addType( DeclarationNode * );
283        DeclarationNode * addTypedef();
284        DeclarationNode * addAssertions( DeclarationNode * );
285        DeclarationNode * addName( std::string * );
286        DeclarationNode * addAsmName( DeclarationNode * );
287        DeclarationNode * addBitfield( ExpressionNode * size );
288        DeclarationNode * addVarArgs();
289        DeclarationNode * addFunctionBody( StatementNode * body );
290        DeclarationNode * addOldDeclList( DeclarationNode * list );
291        DeclarationNode * setBase( TypeData * newType );
292        DeclarationNode * copyAttribute( DeclarationNode * attr );
293        DeclarationNode * addPointer( DeclarationNode * qualifiers );
294        DeclarationNode * addArray( DeclarationNode * array );
295        DeclarationNode * addNewPointer( DeclarationNode * pointer );
296        DeclarationNode * addNewArray( DeclarationNode * array );
297        DeclarationNode * addParamList( DeclarationNode * list );
298        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
299        DeclarationNode * addInitializer( InitializerNode * init );
300
301        DeclarationNode * cloneType( std::string * newName );
302        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
303
304        DeclarationNode * appendList( DeclarationNode * node ) {
305                return (DeclarationNode *)set_last( node );
306        }
307
308        virtual void print( std::ostream &os, int indent = 0 ) const override;
309        virtual void printList( std::ostream &os, int indent = 0 ) const override;
310
311        Declaration * build() const;
312        Type * buildType() const;
313
314        bool get_hasEllipsis() const;
315        LinkageSpec::Spec get_linkage() const { return linkage; }
316        DeclarationNode * extractAggregate() const;
317        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
318        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
319
320        bool get_extension() const { return extension; }
321        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
322  public:
323        struct Variable_t {
324//              const std::string * name;
325                DeclarationNode::TypeClass tyClass;
326                DeclarationNode * assertions;
327        };
328        Variable_t variable;
329
330        struct Attr_t {
331//              const std::string * name;
332                ExpressionNode * expr;
333                DeclarationNode * type;
334        };
335        Attr_t attr;
336
337        BuiltinType builtin;
338
339        TypeData * type;
340
341        Type::StorageClasses storageClasses;
342        FuncSpecifiers funcSpecs;
343
344        ExpressionNode * bitfieldWidth;
345        std::unique_ptr<ExpressionNode> enumeratorValue;
346        bool hasEllipsis;
347        LinkageSpec::Spec linkage;
348        ConstantExpr *asmName;
349        std::list< Attribute * > attributes;
350        InitializerNode * initializer;
351        bool extension = false;
352        std::string error;
353        StatementNode * asmStmt;
354
355        static UniqueName anonymous;
356}; // DeclarationNode
357
358Type * buildType( TypeData * type );
359
360static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
361        Type * ret = orig ? orig->buildType() : nullptr;
362        delete orig;
363        return ret;
364}
365
366//##############################################################################
367
368class StatementNode final : public ParseNode {
369  public:
370        StatementNode() { stmt = nullptr; }
371        StatementNode( Statement * stmt ) : stmt( stmt ) {}
372        StatementNode( DeclarationNode * decl );
373        virtual ~StatementNode() {}
374
375        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
376        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
377
378        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
379                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
380                delete attr;
381                delete name;
382                return this;
383        }
384
385        virtual StatementNode * append_last_case( StatementNode * );
386
387        virtual void print( std::ostream &os, int indent = 0 ) const override {}
388        virtual void printList( std::ostream &os, int indent = 0 ) const override {}
389  private:
390        std::unique_ptr<Statement> stmt;
391}; // StatementNode
392
393Statement * build_expr( ExpressionNode * ctl );
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
406Statement * build_if( ExpressionNode * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
407Statement * build_switch( ExpressionNode * ctl, StatementNode * stmt );
408Statement * build_case( ExpressionNode * ctl );
409Statement * build_default();
410Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
411Statement * build_for( ForCtl * forctl, StatementNode * stmt );
412Statement * build_branch( BranchStmt::Type kind );
413Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
414Statement * build_computedgoto( ExpressionNode * ctl );
415Statement * build_return( ExpressionNode * ctl );
416Statement * build_throw( ExpressionNode * ctl );
417Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
418Statement * build_catch( DeclarationNode * decl, StatementNode * stmt, bool catchAny = false );
419Statement * build_finally( StatementNode * stmt );
420Statement * build_compound( StatementNode * first );
421Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
422
423//##############################################################################
424
425template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
426void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
427        SemanticError errors;
428        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
429        const NodeType * cur = firstNode;
430
431        while ( cur ) {
432                try {
433                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
434                        if ( result ) {
435                                result->location = cur->location;
436                                * out++ = result;
437                        } // if
438                } catch( SemanticError &e ) {
439                        e.set_location( cur->location );
440                        errors.append( e );
441                } // try
442                cur = dynamic_cast< NodeType * >( cur->get_next() );
443        } // while
444        if ( ! errors.isEmpty() ) {
445                throw errors;
446        } // if
447}
448
449// in DeclarationNode.cc
450void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
451void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
452void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
453
454template< typename SynTreeType, typename NodeType >
455void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
456        buildList( firstNode, outputList );
457        delete firstNode;
458}
459
460// in ParseNode.cc
461std::ostream & operator<<( std::ostream & out, const ParseNode * node );
462
463#endif // PARSENODE_H
464
465// Local Variables: //
466// tab-width: 4 //
467// mode: c++ //
468// compile-command: "make install" //
469// End: //
Note: See TracBrowser for help on using the repository browser.