source: src/Parser/ParseNode.h @ 8f49a54

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 8f49a54 was 44a81853, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

first attempt at gcc attributes

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