source: src/Parser/ParseNode.h @ f923b5f

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 f923b5f was c0aa336, checked in by Peter A. Buhr <pabuhr@…>, 7 years ago

third attempt at gcc attributes

  • Property mode set to 100644
File size: 18.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 : Mon Feb  6 15:52:21 2017
13// Update Count     : 657
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
201        // enum StorageClass { Extern, Static, Auto, Register, NoStorageClass };
202        // enum FunctionSpec { Inline, Fortran, Noreturn, NoFunctionSpec };
203        // enum Qualifier { Const, Restrict, Volatile, Lvalue, Atomic, Threadlocal, Mutex, NoQualifier };
204
205        enum StorageClass { Extern, Static, Auto, Register, Inline, Fortran, Noreturn, Threadlocal, NoStorageClass, };
206        enum Qualifier { Const, Restrict, Volatile, Lvalue, Atomic, NoQualifier };
207        enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, NoBasicType };
208        enum ComplexType { Complex, Imaginary, NoComplexType };
209        enum Signedness { Signed, Unsigned, NoSignedness };
210        enum Length { Short, Long, LongLong, NoLength };
211        enum Aggregate { Struct, Union, Trait, NoAggregate };
212        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
213        enum BuiltinType { Valist, Zero, One, NoBuiltinType };
214
215        static const char * storageName[];
216        static const char * qualifierName[];
217        static const char * basicTypeName[];
218        static const char * complexTypeName[];
219        static const char * signednessName[];
220        static const char * lengthName[];
221        static const char * aggregateName[];
222        static const char * typeClassName[];
223        static const char * builtinTypeName[];
224
225        static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body, bool newStyle = false );
226        static DeclarationNode * newQualifier( Qualifier );
227        static DeclarationNode * newForall( DeclarationNode * );
228        static DeclarationNode * newStorageClass( StorageClass );
229        static DeclarationNode * newBasicType( BasicType );
230        static DeclarationNode * newComplexType( ComplexType );
231        static DeclarationNode * newSignedNess( Signedness sn );
232        static DeclarationNode * newLength( Length lnth );
233        static DeclarationNode * newBuiltinType( BuiltinType );
234        static DeclarationNode * newFromTypedef( std::string * );
235        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
236        static DeclarationNode * newEnum( std::string * name, DeclarationNode * constants );
237        static DeclarationNode * newEnumConstant( std::string * name, ExpressionNode * constant );
238        static DeclarationNode * newName( std::string * );
239        static DeclarationNode * newFromTypeGen( std::string *, ExpressionNode * params );
240        static DeclarationNode * newTypeParam( TypeClass, 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( std::string * name, DeclarationNode * typeParams );
244        static DeclarationNode * newPointer( DeclarationNode * qualifiers );
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( std::string *, ExpressionNode * expr ); // @ attributes
251        static DeclarationNode * newAttr( std::string *, DeclarationNode * type ); // @ attributes
252        static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
253
254        DeclarationNode();
255        ~DeclarationNode();
256        DeclarationNode * clone() const;
257
258        DeclarationNode * addQualifiers( DeclarationNode * );
259        void checkQualifiers( const TypeData *, const TypeData * );
260        void checkStorageClasses( DeclarationNode * );
261        DeclarationNode * copyStorageClasses( DeclarationNode * );
262        DeclarationNode * addType( DeclarationNode * );
263        DeclarationNode * addTypedef();
264        DeclarationNode * addAssertions( DeclarationNode * );
265        DeclarationNode * addName( std::string * );
266        DeclarationNode * addAsmName( DeclarationNode * );
267        DeclarationNode * addBitfield( ExpressionNode * size );
268        DeclarationNode * addVarArgs();
269        DeclarationNode * addFunctionBody( StatementNode * body );
270        DeclarationNode * addOldDeclList( DeclarationNode * list );
271        DeclarationNode * setBase( TypeData * newType );
272        DeclarationNode * copyAttribute( DeclarationNode * attr );
273        DeclarationNode * addPointer( DeclarationNode * qualifiers );
274        DeclarationNode * addArray( DeclarationNode * array );
275        DeclarationNode * addNewPointer( DeclarationNode * pointer );
276        DeclarationNode * addNewArray( DeclarationNode * array );
277        DeclarationNode * addParamList( DeclarationNode * list );
278        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
279        DeclarationNode * addInitializer( InitializerNode * 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( std::ostream &os, int indent = 0 ) const override;
289        virtual void printList( std::ostream &os, 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        };
308        Variable_t variable;
309
310        struct Attr_t {
311//              const std::string * name;
312                ExpressionNode * expr;
313                DeclarationNode * type;
314        };
315        Attr_t attr;
316
317        BuiltinType builtin;
318
319        TypeData * type;
320        StorageClass storageClass;
321        ExpressionNode * bitfieldWidth;
322        bool isInline, isNoreturn;
323        std::unique_ptr<ExpressionNode> enumeratorValue;
324        bool hasEllipsis;
325        LinkageSpec::Spec linkage;
326        ConstantExpr *asmName;
327        std::list< Attribute * > attributes;
328        InitializerNode * initializer;
329        bool extension = false;
330        std::string error;
331
332        static UniqueName anonymous;
333}; // DeclarationNode
334
335Type * buildType( TypeData * type );
336
337static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
338        Type* ret = orig ? orig->buildType() : nullptr;
339        delete orig;
340        return ret;
341}
342
343//##############################################################################
344
345class StatementNode final : public ParseNode {
346  public:
347        StatementNode() { stmt = nullptr; }
348        StatementNode( Statement * stmt ) : stmt( stmt ) {}
349        StatementNode( DeclarationNode * decl );
350        virtual ~StatementNode() {}
351
352        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
353        Statement * build() const { return const_cast<StatementNode*>(this)->stmt.release(); }
354
355        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
356                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
357                delete attr;
358                delete name;
359                return this;
360        }
361
362        virtual StatementNode * append_last_case( StatementNode * );
363
364        virtual void print( std::ostream &os, int indent = 0 ) const override {}
365        virtual void printList( std::ostream &os, int indent = 0 ) const override {}
366  private:
367        std::unique_ptr<Statement> stmt;
368}; // StatementNode
369
370Statement * build_expr( ExpressionNode * ctl );
371
372struct ForCtl {
373        ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
374                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
375        ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
376                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
377
378        StatementNode * init;
379        ExpressionNode * condition;
380        ExpressionNode * change;
381};
382
383Statement * build_if( ExpressionNode * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
384Statement * build_switch( ExpressionNode * ctl, StatementNode * stmt );
385Statement * build_case( ExpressionNode * ctl );
386Statement * build_default();
387Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
388Statement * build_for( ForCtl * forctl, StatementNode * stmt );
389Statement * build_branch( BranchStmt::Type kind );
390Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
391Statement * build_computedgoto( ExpressionNode * ctl );
392Statement * build_return( ExpressionNode * ctl );
393Statement * build_throw( ExpressionNode * ctl );
394Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
395Statement * build_catch( DeclarationNode * decl, StatementNode * stmt, bool catchAny = false );
396Statement * build_finally( StatementNode * stmt );
397Statement * build_compound( StatementNode * first );
398Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
399
400//##############################################################################
401
402template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
403void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
404        SemanticError errors;
405        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
406        const NodeType * cur = firstNode;
407
408        while ( cur ) {
409                try {
410//                      SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::result_of< decltype(&NodeType::build)(NodeType)>::type >( cur ) );
411                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
412                        if ( result ) {
413                                * out++ = result;
414                        } // if
415                } catch( SemanticError &e ) {
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.