source: src/Parser/ParseNode.h @ ee3c93d

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumwith_gc
Last change on this file since ee3c93d was ee3c93d, checked in by Rob Schluntz <rschlunt@…>, 6 years ago

Add support for while loops with control declarations

  • Property mode set to 100644
File size: 19.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 : Mon Apr 30 09:19:17 2018
13// Update Count     : 831
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/CodeLocation.h"   // for CodeLocation
27#include "Common/SemanticError.h"  // for SemanticError
28#include "Common/UniqueName.h"     // for UniqueName
29#include "Common/utility.h"        // for maybeClone, maybeBuild
30#include "Parser/LinkageSpec.h"    // for Spec
31#include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
32#include "SynTree/Label.h"         // for Label
33#include "SynTree/Statement.h"     // for Statement, BranchStmt, BranchStmt:...
34#include "SynTree/Type.h"          // for Type, Type::FuncSpecifiers, Type::...
35
36class Attribute;
37class Declaration;
38class DeclarationNode;
39class DeclarationWithType;
40class ExpressionNode;
41class Initializer;
42class StatementNode;
43
44//##############################################################################
45
46typedef CodeLocation YYLTYPE;
47#define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */
48
49extern YYLTYPE yylloc;
50
51class ParseNode {
52  public:
53        ParseNode() {};
54        virtual ~ParseNode() { delete next; delete name; };
55        virtual ParseNode * clone() const = 0;
56
57        ParseNode * get_next() const { return next; }
58        ParseNode * set_next( ParseNode * newlink ) { next = newlink; return this; }
59
60        ParseNode * get_last() {
61                ParseNode * current;
62                for ( current = this; current->get_next() != nullptr; current = current->get_next() );
63                return current;
64        }
65        ParseNode * set_last( ParseNode * newlast ) {
66                if ( newlast != nullptr ) get_last()->set_next( newlast );
67                return this;
68        }
69
70        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
71        virtual void printList( std::ostream &os, int indent = 0 ) const {
72                print( os, indent );
73                if ( next ) next->print( os, indent );
74        }
75
76        static int indent_by;
77
78        ParseNode * next = nullptr;
79        std::string * name = nullptr;
80        CodeLocation location = yylloc;
81}; // ParseNode
82
83//##############################################################################
84
85class InitializerNode : public ParseNode {
86  public:
87        InitializerNode( ExpressionNode *, bool aggrp = false,  ExpressionNode * des = nullptr );
88        InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
89        InitializerNode( bool isDelete );
90        ~InitializerNode();
91        virtual InitializerNode * clone() const { assert( false ); return nullptr; }
92
93        ExpressionNode * get_expression() const { return expr; }
94
95        InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
96        ExpressionNode * get_designators() const { return designator; }
97
98        InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
99        bool get_maybeConstructed() const { return maybeConstructed; }
100
101        bool get_isDelete() const { return isDelete; }
102
103        InitializerNode * next_init() const { return kids; }
104
105        void print( std::ostream &os, int indent = 0 ) const;
106        void printOneLine( std::ostream & ) const;
107
108        virtual Initializer * build() const;
109  private:
110        ExpressionNode * expr;
111        bool aggregate;
112        ExpressionNode * designator;                                            // may be list
113        InitializerNode * kids;
114        bool maybeConstructed;
115        bool isDelete;
116}; // InitializerNode
117
118//##############################################################################
119
120class ExpressionNode final : public ParseNode {
121  public:
122        ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
123        virtual ~ExpressionNode() {}
124        virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
125
126        bool get_extension() const { return extension; }
127        ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
128
129        virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
130                os << expr.get() << std::endl;
131        }
132        void printOneLine( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
133
134        template<typename T>
135        bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
136
137        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
138  private:
139        bool extension = false;
140        std::unique_ptr<Expression> expr;
141}; // ExpressionNode
142
143template< typename T >
144struct maybeBuild_t< Expression, T > {
145        static inline Expression * doit( const T * orig ) {
146                if ( orig ) {
147                        Expression * p = orig->build();
148                        p->set_extension( orig->get_extension() );
149                        p->location = orig->location;
150                        return p;
151                } else {
152                        return nullptr;
153                } // if
154        }
155};
156
157// Must harmonize with OperName.
158enum class OperKinds {
159        // diadic
160        SizeOf, AlignOf, OffsetOf, Plus, Minus, Exp, Mul, Div, Mod, Or, And,
161        BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
162        Assign, AtAssn, ExpAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
163        Index, Range,
164        // monadic
165        UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
166        Ctor, Dtor,
167}; // OperKinds
168
169struct LabelNode {
170        std::list< Label > labels;
171};
172
173Expression * build_constantInteger( std::string &str );
174Expression * build_constantFloat( std::string &str );
175Expression * build_constantChar( std::string &str );
176Expression * build_constantStr( std::string &str );
177Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
178Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
179Expression * build_field_name_FLOATINGconstant( const std::string & str );
180Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
181
182NameExpr * build_varref( const std::string * name );
183
184Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
185Expression * build_keyword_cast( KeywordCastExpr::Target target, ExpressionNode * expr_node );
186Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
187Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
188Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
189Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
190Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
191Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
192Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
193Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
194Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
195Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
196Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
197Expression * build_tuple( ExpressionNode * expr_node = nullptr );
198Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
199Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
200
201//##############################################################################
202
203struct TypeData;
204
205class DeclarationNode : public ParseNode {
206  public:
207        // These enumerations must harmonize with their names.
208        enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, Int128, Float80, Float128, NoBasicType };
209        static const char * basicTypeNames[];
210        enum ComplexType { Complex, Imaginary, NoComplexType };
211        static const char * complexTypeNames[];
212        enum Signedness { Signed, Unsigned, NoSignedness };
213        static const char * signednessNames[];
214        enum Length { Short, Long, LongLong, NoLength };
215        static const char * lengthNames[];
216        enum Aggregate { Struct, Union, Exception, Trait, Coroutine, Monitor, Thread, NoAggregate };
217        static const char * aggregateNames[];
218        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
219        static const char * typeClassNames[];
220        enum BuiltinType { Valist, Zero, One, NoBuiltinType };
221        static const char * builtinTypeNames[];
222
223        static DeclarationNode * newStorageClass( Type::StorageClasses );
224        static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
225        static DeclarationNode * newTypeQualifier( Type::Qualifiers );
226        static DeclarationNode * newBasicType( BasicType );
227        static DeclarationNode * newComplexType( ComplexType );
228        static DeclarationNode * newSignedNess( Signedness );
229        static DeclarationNode * newLength( Length );
230        static DeclarationNode * newBuiltinType( BuiltinType );
231        static DeclarationNode * newForall( DeclarationNode * );
232        static DeclarationNode * newFromTypedef( std::string * );
233        static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
234        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
235        static DeclarationNode * newEnum( std::string * name, DeclarationNode * constants, bool body );
236        static DeclarationNode * newEnumConstant( std::string * name, ExpressionNode * constant );
237        static DeclarationNode * newName( std::string * );
238        static DeclarationNode * newFromTypeGen( std::string *, ExpressionNode * params );
239        static DeclarationNode * newTypeParam( TypeClass, std::string * );
240        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
241        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
242        static DeclarationNode * newTypeDecl( std::string * name, DeclarationNode * typeParams );
243        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
244        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
245        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
246        static DeclarationNode * newBitfield( ExpressionNode * size );
247        static DeclarationNode * newTuple( DeclarationNode * members );
248        static DeclarationNode * newTypeof( ExpressionNode * expr );
249        static DeclarationNode * newAttr( std::string *, ExpressionNode * expr ); // @ attributes
250        static DeclarationNode * newAttr( std::string *, DeclarationNode * type ); // @ attributes
251        static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
252        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
253        static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
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, ExpressionNode * with = nullptr );
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        LinkageSpec::Spec get_linkage() const { return linkage; }
297        DeclarationNode * extractAggregate() const;
298        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
299        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
300
301        bool get_extension() const { return extension; }
302        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
303  public:
304        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
305
306        struct Variable_t {
307//              const std::string * name;
308                DeclarationNode::TypeClass tyClass;
309                DeclarationNode * assertions;
310                DeclarationNode * initializer;
311        };
312        Variable_t variable;
313
314        struct Attr_t {
315//              const std::string * name;
316                ExpressionNode * expr;
317                DeclarationNode * type;
318        };
319        Attr_t attr;
320
321        struct StaticAssert_t {
322                ExpressionNode * condition;
323                Expression * message;
324        };
325        StaticAssert_t assert;
326
327        BuiltinType builtin;
328
329        TypeData * type;
330
331        Type::FuncSpecifiers funcSpecs;
332        Type::StorageClasses storageClasses;
333
334        ExpressionNode * bitfieldWidth;
335        std::unique_ptr<ExpressionNode> enumeratorValue;
336        bool hasEllipsis;
337        LinkageSpec::Spec linkage;
338        Expression * asmName;
339        std::list< Attribute * > attributes;
340        InitializerNode * initializer;
341        bool extension = false;
342        std::string error;
343        StatementNode * asmStmt;
344
345        static UniqueName anonymous;
346}; // DeclarationNode
347
348Type * buildType( TypeData * type );
349
350static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
351        Type * ret = orig ? orig->buildType() : nullptr;
352        delete orig;
353        return ret;
354}
355
356//##############################################################################
357
358class StatementNode final : public ParseNode {
359  public:
360        StatementNode() { stmt = nullptr; }
361        StatementNode( Statement * stmt ) : stmt( stmt ) {}
362        StatementNode( DeclarationNode * decl );
363        virtual ~StatementNode() {}
364
365        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
366        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
367
368        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
369                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
370                delete attr;
371                delete name;
372                return this;
373        }
374
375        virtual StatementNode * append_last_case( StatementNode * );
376
377        virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
378                os << stmt.get() << std::endl;
379        }
380  private:
381        std::unique_ptr<Statement> stmt;
382}; // StatementNode
383
384Statement * build_expr( ExpressionNode * ctl );
385
386struct IfCtl {
387        IfCtl( DeclarationNode * decl, ExpressionNode * condition ) :
388                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
389
390        StatementNode * init;
391        ExpressionNode * condition;
392};
393
394struct ForCtl {
395        ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
396                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
397        ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
398                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
399
400        StatementNode * init;
401        ExpressionNode * condition;
402        ExpressionNode * change;
403};
404
405Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init );
406Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
407Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
408Statement * build_case( ExpressionNode * ctl );
409Statement * build_default();
410Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
411Statement * build_for( ForCtl * forctl, StatementNode * stmt );
412Statement * build_branch( BranchStmt::Type kind );
413Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
414Statement * build_computedgoto( ExpressionNode * ctl );
415Statement * build_return( ExpressionNode * ctl );
416Statement * build_throw( ExpressionNode * ctl );
417Statement * build_resume( ExpressionNode * ctl );
418Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
419Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
420Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
421Statement * build_finally( StatementNode * stmt );
422Statement * build_compound( StatementNode * first );
423Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
424Statement * build_directive( std::string * directive );
425WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
426WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
427WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
428WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
429WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
430
431//##############################################################################
432
433template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
434void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
435        SemanticErrorException errors;
436        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
437        const NodeType * cur = firstNode;
438
439        while ( cur ) {
440                try {
441                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
442                        if ( result ) {
443                                result->location = cur->location;
444                                * out++ = result;
445                        } else {
446                                assertf(false, "buildList unknown type");
447                        } // if
448                } catch( SemanticErrorException &e ) {
449                        errors.append( e );
450                } // try
451                cur = dynamic_cast< NodeType * >( cur->get_next() );
452        } // while
453        if ( ! errors.isEmpty() ) {
454                throw errors;
455        } // if
456}
457
458// in DeclarationNode.cc
459void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
460void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
461void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
462
463template< typename SynTreeType, typename NodeType >
464void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
465        buildList( firstNode, outputList );
466        delete firstNode;
467}
468
469// in ParseNode.cc
470std::ostream & operator<<( std::ostream & out, const ParseNode * node );
471
472// Local Variables: //
473// tab-width: 4 //
474// mode: c++ //
475// compile-command: "make install" //
476// End: //
Note: See TracBrowser for help on using the repository browser.