source: src/Parser/ParseNode.h @ 936e9f4

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

first attempt, add declarations into "if" conditional

  • Property mode set to 100644
File size: 19.4 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 Aug 16 16:46:48 2017
13// Update Count     : 794
14//
15
16#pragma once
17
18#include <algorithm>               // for move
19#include <cassert>                 // for assert, assertf
20#include <iosfwd>                  // for ostream
21#include <iterator>                // for back_insert_iterator
22#include <list>                    // for list
23#include <memory>                  // for unique_ptr, pointer_traits
24#include <string>                  // for string
25
26#include "Common/SemanticError.h"  // for SemanticError
27#include "Common/UniqueName.h"     // for UniqueName
28#include "Common/utility.h"        // for maybeClone, CodeLocation, maybeBuild
29#include "Parser/LinkageSpec.h"    // for Spec
30#include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
31#include "SynTree/Label.h"         // for Label
32#include "SynTree/Statement.h"     // for Statement, BranchStmt, BranchStmt:...
33#include "SynTree/Type.h"          // for Type, Type::FuncSpecifiers, Type::...
34
35class Attribute;
36class Declaration;
37class DeclarationNode;
38class DeclarationWithType;
39class ExpressionNode;
40class Initializer;
41class StatementNode;
42
43//##############################################################################
44
45extern char * yyfilename;
46extern int yylineno;
47
48class ParseNode {
49  public:
50        ParseNode() {};
51        virtual ~ParseNode() { delete next; delete name; };
52        virtual ParseNode * clone() const = 0;
53
54        ParseNode * get_next() const { return next; }
55        ParseNode * set_next( ParseNode * newlink ) { next = newlink; return this; }
56
57        ParseNode * get_last() {
58                ParseNode * current;
59                for ( current = this; current->get_next() != nullptr; current = current->get_next() );
60                return current;
61        }
62        ParseNode * set_last( ParseNode * newlast ) {
63                if ( newlast != nullptr ) get_last()->set_next( newlast );
64                return this;
65        }
66
67        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
68        virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
69
70        static int indent_by;
71
72        ParseNode * next = nullptr;
73        std::string * name = nullptr;
74        CodeLocation location = { yyfilename, yylineno };
75}; // ParseNode
76
77//##############################################################################
78
79class InitializerNode : public ParseNode {
80  public:
81        InitializerNode( ExpressionNode *, bool aggrp = false,  ExpressionNode * des = nullptr );
82        InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
83        ~InitializerNode();
84        virtual InitializerNode * clone() const { assert( false ); return nullptr; }
85
86        ExpressionNode * get_expression() const { return expr; }
87
88        InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
89        ExpressionNode * get_designators() const { return designator; }
90
91        InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
92        bool get_maybeConstructed() const { return maybeConstructed; }
93
94        InitializerNode * next_init() const { return kids; }
95
96        void print( std::ostream &os, int indent = 0 ) const;
97        void printOneLine( std::ostream & ) const;
98
99        virtual Initializer * build() const;
100  private:
101        ExpressionNode * expr;
102        bool aggregate;
103        ExpressionNode * designator;                                            // may be list
104        InitializerNode * kids;
105        bool maybeConstructed;
106}; // InitializerNode
107
108//##############################################################################
109
110class ExpressionNode final : public ParseNode {
111  public:
112        ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
113        virtual ~ExpressionNode() {}
114        virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
115
116        bool get_extension() const { return extension; }
117        ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
118
119        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
120        void printOneLine( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
121
122        template<typename T>
123        bool isExpressionType() const {
124                return nullptr != dynamic_cast<T>(expr.get());
125        }
126
127        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
128  private:
129        bool extension = false;
130        std::unique_ptr<Expression> expr;
131}; // ExpressionNode
132
133template< typename T >
134struct maybeBuild_t< Expression, T > {
135        static inline Expression * doit( const T * orig ) {
136                if ( orig ) {
137                        Expression * p = orig->build();
138                        p->set_extension( orig->get_extension() );
139                        p->location = orig->location;
140                        return p;
141                } else {
142                        return nullptr;
143                } // if
144        }
145};
146
147// Must harmonize with OperName.
148enum class OperKinds {
149        // diadic
150        SizeOf, AlignOf, OffsetOf, Plus, Minus, Exp, Mul, Div, Mod, Or, And,
151        BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
152        Assign, AtAssn, ExpAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
153        Index, Range,
154        // monadic
155        UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress,
156        Ctor, Dtor,
157}; // OperKinds
158
159struct LabelNode {
160        std::list< Label > labels;
161};
162
163Expression * build_constantInteger( const std::string &str );
164Expression * build_constantFloat( const std::string &str );
165Expression * build_constantChar( const std::string &str );
166ConstantExpr * build_constantStr( const std::string &str );
167Expression * build_field_name_FLOATINGconstant( const std::string & str );
168Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
169Expression * build_field_name_REALFRACTIONconstant( const std::string & str );
170Expression * build_field_name_REALDECIMALconstant( const std::string & str );
171
172NameExpr * build_varref( const std::string * name );
173Expression * build_typevalue( DeclarationNode * decl );
174
175Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
176Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
177Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
178Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
179Expression * build_addressOf( ExpressionNode * expr_node );
180Expression * build_sizeOfexpr( ExpressionNode * expr_node );
181Expression * build_sizeOftype( DeclarationNode * decl_node );
182Expression * build_alignOfexpr( ExpressionNode * expr_node );
183Expression * build_alignOftype( DeclarationNode * decl_node );
184Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
185Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
186Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
187Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
188Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
189Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
190Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
191Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
192Expression * build_comma( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
193Expression * build_attrexpr( NameExpr * var, ExpressionNode * expr_node );
194Expression * build_attrtype( NameExpr * var, DeclarationNode * decl_node );
195Expression * build_tuple( ExpressionNode * expr_node = nullptr );
196Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
197Expression * build_range( ExpressionNode * low, ExpressionNode * high );
198Expression * build_asmexpr( ExpressionNode * inout, ConstantExpr * constraint, ExpressionNode * operand );
199Expression * build_valexpr( StatementNode * s );
200Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
201
202//##############################################################################
203
204struct TypeData;
205
206class DeclarationNode : public ParseNode {
207  public:
208        enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, NoBasicType };
209        enum ComplexType { Complex, Imaginary, NoComplexType };
210        enum Signedness { Signed, Unsigned, NoSignedness };
211        enum Length { Short, Long, LongLong, NoLength };
212        enum Aggregate { Struct, Union, Trait, Coroutine, Monitor, Thread, NoAggregate };
213        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
214        enum BuiltinType { Valist, Zero, One, NoBuiltinType };
215
216        static const char * basicTypeNames[];
217        static const char * complexTypeNames[];
218        static const char * signednessNames[];
219        static const char * lengthNames[];
220        static const char * aggregateNames[];
221        static const char * typeClassNames[];
222        static const char * builtinTypeNames[];
223
224        static DeclarationNode * newStorageClass( Type::StorageClasses );
225        static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
226        static DeclarationNode * newTypeQualifier( Type::Qualifiers );
227        static DeclarationNode * newBasicType( BasicType );
228        static DeclarationNode * newComplexType( ComplexType );
229        static DeclarationNode * newSignedNess( Signedness );
230        static DeclarationNode * newLength( Length );
231        static DeclarationNode * newBuiltinType( BuiltinType );
232        static DeclarationNode * newForall( DeclarationNode * );
233        static DeclarationNode * newFromTypedef( std::string * );
234        static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body, bool newStyle = false );
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, bool body );
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        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
254
255        DeclarationNode();
256        ~DeclarationNode();
257        DeclarationNode * clone() const override;
258
259        DeclarationNode * addQualifiers( DeclarationNode * );
260        void checkQualifiers( const TypeData *, const TypeData * );
261        void checkSpecifiers( DeclarationNode * );
262        DeclarationNode * copySpecifiers( DeclarationNode * );
263        DeclarationNode * addType( DeclarationNode * );
264        DeclarationNode * addTypedef();
265        DeclarationNode * addAssertions( DeclarationNode * );
266        DeclarationNode * addName( std::string * );
267        DeclarationNode * addAsmName( DeclarationNode * );
268        DeclarationNode * addBitfield( ExpressionNode * size );
269        DeclarationNode * addVarArgs();
270        DeclarationNode * addFunctionBody( StatementNode * body );
271        DeclarationNode * addOldDeclList( DeclarationNode * list );
272        DeclarationNode * setBase( TypeData * newType );
273        DeclarationNode * copyAttribute( DeclarationNode * attr );
274        DeclarationNode * addPointer( DeclarationNode * qualifiers );
275        DeclarationNode * addArray( DeclarationNode * array );
276        DeclarationNode * addNewPointer( DeclarationNode * pointer );
277        DeclarationNode * addNewArray( DeclarationNode * array );
278        DeclarationNode * addParamList( DeclarationNode * list );
279        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
280        DeclarationNode * addInitializer( InitializerNode * init );
281        DeclarationNode * addTypeInitializer( DeclarationNode * init );
282
283        DeclarationNode * cloneType( std::string * newName );
284        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
285
286        DeclarationNode * appendList( DeclarationNode * node ) {
287                return (DeclarationNode *)set_last( node );
288        }
289
290        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
291        virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
292
293        Declaration * build() const;
294        Type * buildType() const;
295
296        bool get_hasEllipsis() const;
297        LinkageSpec::Spec get_linkage() const { return linkage; }
298        DeclarationNode * extractAggregate() const;
299        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
300        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
301
302        bool get_extension() const { return extension; }
303        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
304  public:
305        struct Variable_t {
306//              const std::string * name;
307                DeclarationNode::TypeClass tyClass;
308                DeclarationNode * assertions;
309                DeclarationNode * initializer;
310        };
311        Variable_t variable;
312
313        struct Attr_t {
314//              const std::string * name;
315                ExpressionNode * expr;
316                DeclarationNode * type;
317        };
318        Attr_t attr;
319
320        BuiltinType builtin;
321
322        TypeData * type;
323
324        Type::FuncSpecifiers funcSpecs;
325        Type::StorageClasses storageClasses;
326
327        ExpressionNode * bitfieldWidth;
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( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
371        virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
372  private:
373        std::unique_ptr<Statement> stmt;
374}; // StatementNode
375
376Statement * build_expr( ExpressionNode * ctl );
377
378struct IfCtl {
379        IfCtl( DeclarationNode * decl, ExpressionNode * condition ) :
380                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
381
382        StatementNode * init;
383        ExpressionNode * condition;
384};
385
386struct ForCtl {
387        ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
388                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
389        ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
390                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
391
392        StatementNode * init;
393        ExpressionNode * condition;
394        ExpressionNode * change;
395};
396
397Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
398Statement * build_switch( ExpressionNode * ctl, StatementNode * stmt );
399Statement * build_case( ExpressionNode * ctl );
400Statement * build_default();
401Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
402Statement * build_for( ForCtl * forctl, StatementNode * stmt );
403Statement * build_branch( BranchStmt::Type kind );
404Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
405Statement * build_computedgoto( ExpressionNode * ctl );
406Statement * build_return( ExpressionNode * ctl );
407Statement * build_throw( ExpressionNode * ctl );
408Statement * build_resume( ExpressionNode * ctl );
409Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
410Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
411Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
412Statement * build_finally( StatementNode * stmt );
413Statement * build_compound( StatementNode * first );
414Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
415
416//##############################################################################
417
418template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
419void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
420        SemanticError errors;
421        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
422        const NodeType * cur = firstNode;
423
424        while ( cur ) {
425                try {
426                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
427                        if ( result ) {
428                                result->location = cur->location;
429                                * out++ = result;
430                        } else {
431                                assertf(false, "buildList unknown type");
432                        } // if
433                } catch( SemanticError &e ) {
434                        e.set_location( cur->location );
435                        errors.append( e );
436                } // try
437                cur = dynamic_cast< NodeType * >( cur->get_next() );
438        } // while
439        if ( ! errors.isEmpty() ) {
440                throw errors;
441        } // if
442}
443
444// in DeclarationNode.cc
445void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
446void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
447void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
448
449template< typename SynTreeType, typename NodeType >
450void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
451        buildList( firstNode, outputList );
452        delete firstNode;
453}
454
455// in ParseNode.cc
456std::ostream & operator<<( std::ostream & out, const ParseNode * node );
457
458// Local Variables: //
459// tab-width: 4 //
460// mode: c++ //
461// compile-command: "make install" //
462// End: //
Note: See TracBrowser for help on using the repository browser.