source: src/Parser/ParseNode.h @ 3a5131ed

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

handle KR function declarations

  • Property mode set to 100644
File size: 18.3 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 Feb 16 13:15:55 2017
13// Update Count     : 661
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 { 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        // These must remain in the same order as the corresponding DeclarationNode names.
204
205        // enum StorageClass { Extern, Static, Auto, Register, NoStorageClass };
206        // enum FunctionSpec { Inline, Fortran, Noreturn, NoFunctionSpec };
207        // enum Qualifier { Const, Restrict, Volatile, Lvalue, Atomic, Threadlocal, Mutex, NoQualifier };
208
209        enum StorageClass { Extern, Static, Auto, Register, Inline, Fortran, Noreturn, Threadlocal, NoStorageClass, };
210        enum Qualifier { Const, Restrict, Volatile, Lvalue, Atomic, NoQualifier };
211        enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, NoBasicType };
212        enum ComplexType { Complex, Imaginary, NoComplexType };
213        enum Signedness { Signed, Unsigned, NoSignedness };
214        enum Length { Short, Long, LongLong, NoLength };
215        enum Aggregate { Struct, Union, Trait, NoAggregate };
216        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
217        enum BuiltinType { Valist, Zero, One, NoBuiltinType };
218
219        static const char * storageName[];
220        static const char * qualifierName[];
221        static const char * basicTypeName[];
222        static const char * complexTypeName[];
223        static const char * signednessName[];
224        static const char * lengthName[];
225        static const char * aggregateName[];
226        static const char * typeClassName[];
227        static const char * builtinTypeName[];
228
229        static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body, bool newStyle = false );
230        static DeclarationNode * newQualifier( Qualifier );
231        static DeclarationNode * newForall( DeclarationNode * );
232        static DeclarationNode * newStorageClass( StorageClass );
233        static DeclarationNode * newBasicType( BasicType );
234        static DeclarationNode * newComplexType( ComplexType );
235        static DeclarationNode * newSignedNess( Signedness sn );
236        static DeclarationNode * newLength( Length lnth );
237        static DeclarationNode * newBuiltinType( BuiltinType );
238        static DeclarationNode * newFromTypedef( std::string * );
239        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
240        static DeclarationNode * newEnum( std::string * name, DeclarationNode * constants );
241        static DeclarationNode * newEnumConstant( std::string * name, ExpressionNode * constant );
242        static DeclarationNode * newName( std::string * );
243        static DeclarationNode * newFromTypeGen( std::string *, ExpressionNode * params );
244        static DeclarationNode * newTypeParam( TypeClass, std::string * );
245        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
246        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
247        static DeclarationNode * newTypeDecl( std::string * name, DeclarationNode * typeParams );
248        static DeclarationNode * newPointer( DeclarationNode * qualifiers );
249        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
250        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
251        static DeclarationNode * newBitfield( ExpressionNode * size );
252        static DeclarationNode * newTuple( DeclarationNode * members );
253        static DeclarationNode * newTypeof( ExpressionNode * expr );
254        static DeclarationNode * newAttr( std::string *, ExpressionNode * expr ); // @ attributes
255        static DeclarationNode * newAttr( std::string *, DeclarationNode * type ); // @ attributes
256        static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
257        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
258
259        DeclarationNode();
260        ~DeclarationNode();
261        DeclarationNode * clone() const;
262
263        DeclarationNode * addQualifiers( DeclarationNode * );
264        void checkQualifiers( const TypeData *, const TypeData * );
265        void checkStorageClasses( DeclarationNode * );
266        DeclarationNode * copyStorageClasses( DeclarationNode * );
267        DeclarationNode * addType( DeclarationNode * );
268        DeclarationNode * addTypedef();
269        DeclarationNode * addAssertions( DeclarationNode * );
270        DeclarationNode * addName( std::string * );
271        DeclarationNode * addAsmName( DeclarationNode * );
272        DeclarationNode * addBitfield( ExpressionNode * size );
273        DeclarationNode * addVarArgs();
274        DeclarationNode * addFunctionBody( StatementNode * body );
275        DeclarationNode * addOldDeclList( DeclarationNode * list );
276        DeclarationNode * setBase( TypeData * newType );
277        DeclarationNode * copyAttribute( DeclarationNode * attr );
278        DeclarationNode * addPointer( DeclarationNode * qualifiers );
279        DeclarationNode * addArray( DeclarationNode * array );
280        DeclarationNode * addNewPointer( DeclarationNode * pointer );
281        DeclarationNode * addNewArray( DeclarationNode * array );
282        DeclarationNode * addParamList( DeclarationNode * list );
283        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
284        DeclarationNode * addInitializer( InitializerNode * init );
285
286        DeclarationNode * cloneType( std::string * newName );
287        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
288
289        DeclarationNode * appendList( DeclarationNode * node ) {
290                return (DeclarationNode *)set_last( node );
291        }
292
293        virtual void print( std::ostream &os, int indent = 0 ) const override;
294        virtual void printList( std::ostream &os, int indent = 0 ) const override;
295
296        Declaration * build() const;
297        ::Type * buildType() const;
298
299        bool get_hasEllipsis() const;
300        LinkageSpec::Spec get_linkage() const { return linkage; }
301        DeclarationNode * extractAggregate() const;
302        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
303        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode*>(this)->enumeratorValue.release(); }
304
305        bool get_extension() const { return extension; }
306        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
307  public:
308        struct Variable_t {
309//              const std::string * name;
310                DeclarationNode::TypeClass tyClass;
311                DeclarationNode * assertions;
312        };
313        Variable_t variable;
314
315        struct Attr_t {
316//              const std::string * name;
317                ExpressionNode * expr;
318                DeclarationNode * type;
319        };
320        Attr_t attr;
321
322        BuiltinType builtin;
323
324        TypeData * type;
325        StorageClass storageClass;
326        ExpressionNode * bitfieldWidth;
327        bool isInline, isNoreturn;
328        std::unique_ptr<ExpressionNode> enumeratorValue;
329        bool hasEllipsis;
330        LinkageSpec::Spec linkage;
331        ConstantExpr *asmName;
332        std::list< Attribute * > attributes;
333        InitializerNode * initializer;
334        bool extension = false;
335        std::string error;
336        StatementNode * asmStmt;
337
338        static UniqueName anonymous;
339}; // DeclarationNode
340
341Type * buildType( TypeData * type );
342
343static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
344        Type* ret = orig ? orig->buildType() : nullptr;
345        delete orig;
346        return ret;
347}
348
349//##############################################################################
350
351class StatementNode final : public ParseNode {
352  public:
353        StatementNode() { stmt = nullptr; }
354        StatementNode( Statement * stmt ) : stmt( stmt ) {}
355        StatementNode( DeclarationNode * decl );
356        virtual ~StatementNode() {}
357
358        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
359        Statement * build() const { return const_cast<StatementNode*>(this)->stmt.release(); }
360
361        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
362                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
363                delete attr;
364                delete name;
365                return this;
366        }
367
368        virtual StatementNode * append_last_case( StatementNode * );
369
370        virtual void print( std::ostream &os, int indent = 0 ) const override {}
371        virtual void printList( std::ostream &os, int indent = 0 ) const override {}
372  private:
373        std::unique_ptr<Statement> stmt;
374}; // StatementNode
375
376Statement * build_expr( ExpressionNode * ctl );
377
378struct ForCtl {
379        ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
380                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
381        ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
382                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
383
384        StatementNode * init;
385        ExpressionNode * condition;
386        ExpressionNode * change;
387};
388
389Statement * build_if( ExpressionNode * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
390Statement * build_switch( ExpressionNode * ctl, StatementNode * stmt );
391Statement * build_case( ExpressionNode * ctl );
392Statement * build_default();
393Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
394Statement * build_for( ForCtl * forctl, StatementNode * stmt );
395Statement * build_branch( BranchStmt::Type kind );
396Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
397Statement * build_computedgoto( ExpressionNode * ctl );
398Statement * build_return( ExpressionNode * ctl );
399Statement * build_throw( ExpressionNode * ctl );
400Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
401Statement * build_catch( DeclarationNode * decl, StatementNode * stmt, bool catchAny = false );
402Statement * build_finally( StatementNode * stmt );
403Statement * build_compound( StatementNode * first );
404Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
405
406//##############################################################################
407
408template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
409void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
410        SemanticError errors;
411        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
412        const NodeType * cur = firstNode;
413
414        while ( cur ) {
415                try {
416                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
417                        if ( result ) {
418                                result->location = cur->location;
419                                * out++ = result;
420                        } // if
421                } catch( SemanticError &e ) {
422                        e.set_location( cur->location );
423                        errors.append( e );
424                } // try
425                cur = dynamic_cast< NodeType * >( cur->get_next() );
426        } // while
427        if ( ! errors.isEmpty() ) {
428                throw errors;
429        } // if
430}
431
432// in DeclarationNode.cc
433void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
434void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
435void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
436
437template< typename SynTreeType, typename NodeType >
438void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
439        buildList( firstNode, outputList );
440        delete firstNode;
441}
442
443// in ParseNode.cc
444std::ostream & operator<<( std::ostream & out, const ParseNode * node );
445
446#endif // PARSENODE_H
447
448// Local Variables: //
449// tab-width: 4 //
450// mode: c++ //
451// compile-command: "make install" //
452// End: //
Note: See TracBrowser for help on using the repository browser.