source: src/Parser/ParseNode.h @ 1b77274

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

more refactoring of parser code

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