source: src/Parser/ParseNode.h @ 5f61546

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 5f61546 was 6a276a0, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Update parser for new fallthrough semantics

  • Property mode set to 100644
File size: 19.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 22 17:49:31 2018
13// Update Count     : 827
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();
90        virtual InitializerNode * clone() const { assert( false ); return nullptr; }
91
92        ExpressionNode * get_expression() const { return expr; }
93
94        InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
95        ExpressionNode * get_designators() const { return designator; }
96
97        InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
98        bool get_maybeConstructed() const { return maybeConstructed; }
99
100        InitializerNode * next_init() const { return kids; }
101
102        void print( std::ostream &os, int indent = 0 ) const;
103        void printOneLine( std::ostream & ) const;
104
105        virtual Initializer * build() const;
106  private:
107        ExpressionNode * expr;
108        bool aggregate;
109        ExpressionNode * designator;                                            // may be list
110        InitializerNode * kids;
111        bool maybeConstructed;
112}; // InitializerNode
113
114//##############################################################################
115
116class ExpressionNode final : public ParseNode {
117  public:
118        ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
119        virtual ~ExpressionNode() {}
120        virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
121
122        bool get_extension() const { return extension; }
123        ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
124
125        virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
126                os << expr.get() << std::endl;
127        }
128        void printOneLine( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
129
130        template<typename T>
131        bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
132
133        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
134  private:
135        bool extension = false;
136        std::unique_ptr<Expression> expr;
137}; // ExpressionNode
138
139template< typename T >
140struct maybeBuild_t< Expression, T > {
141        static inline Expression * doit( const T * orig ) {
142                if ( orig ) {
143                        Expression * p = orig->build();
144                        p->set_extension( orig->get_extension() );
145                        p->location = orig->location;
146                        return p;
147                } else {
148                        return nullptr;
149                } // if
150        }
151};
152
153// Must harmonize with OperName.
154enum class OperKinds {
155        // diadic
156        SizeOf, AlignOf, OffsetOf, Plus, Minus, Exp, Mul, Div, Mod, Or, And,
157        BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
158        Assign, AtAssn, ExpAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
159        Index, Range,
160        // monadic
161        UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
162        Ctor, Dtor,
163}; // OperKinds
164
165struct LabelNode {
166        std::list< Label > labels;
167};
168
169Expression * build_constantInteger( std::string &str );
170Expression * build_constantFloat( std::string &str );
171Expression * build_constantChar( std::string &str );
172Expression * build_constantStr( std::string &str );
173Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
174Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
175Expression * build_field_name_FLOATINGconstant( const std::string & str );
176Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
177
178NameExpr * build_varref( const std::string * name );
179
180Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
181Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
182Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
183Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
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_tuple( ExpressionNode * expr_node = nullptr );
193Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
194Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
195
196//##############################################################################
197
198struct TypeData;
199
200class DeclarationNode : public ParseNode {
201  public:
202        // These enumerations must harmonize with their names.
203        enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, Int128, Float80, Float128, NoBasicType };
204        static const char * basicTypeNames[];
205        enum ComplexType { Complex, Imaginary, NoComplexType };
206        static const char * complexTypeNames[];
207        enum Signedness { Signed, Unsigned, NoSignedness };
208        static const char * signednessNames[];
209        enum Length { Short, Long, LongLong, NoLength };
210        static const char * lengthNames[];
211        enum Aggregate { Struct, Union, Exception, Trait, Coroutine, Monitor, Thread, NoAggregate };
212        static const char * aggregateNames[];
213        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
214        static const char * typeClassNames[];
215        enum BuiltinType { Valist, Zero, One, NoBuiltinType };
216        static const char * builtinTypeNames[];
217
218        static DeclarationNode * newStorageClass( Type::StorageClasses );
219        static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
220        static DeclarationNode * newTypeQualifier( Type::Qualifiers );
221        static DeclarationNode * newBasicType( BasicType );
222        static DeclarationNode * newComplexType( ComplexType );
223        static DeclarationNode * newSignedNess( Signedness );
224        static DeclarationNode * newLength( Length );
225        static DeclarationNode * newBuiltinType( BuiltinType );
226        static DeclarationNode * newForall( DeclarationNode * );
227        static DeclarationNode * newFromTypedef( std::string * );
228        static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
229        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
230        static DeclarationNode * newEnum( std::string * name, DeclarationNode * constants, bool body );
231        static DeclarationNode * newEnumConstant( std::string * name, ExpressionNode * constant );
232        static DeclarationNode * newName( std::string * );
233        static DeclarationNode * newFromTypeGen( std::string *, ExpressionNode * params );
234        static DeclarationNode * newTypeParam( TypeClass, std::string * );
235        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
236        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
237        static DeclarationNode * newTypeDecl( std::string * name, DeclarationNode * typeParams );
238        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
239        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
240        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
241        static DeclarationNode * newBitfield( ExpressionNode * size );
242        static DeclarationNode * newTuple( DeclarationNode * members );
243        static DeclarationNode * newTypeof( ExpressionNode * expr );
244        static DeclarationNode * newAttr( std::string *, ExpressionNode * expr ); // @ attributes
245        static DeclarationNode * newAttr( std::string *, DeclarationNode * type ); // @ attributes
246        static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
247        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
248
249        DeclarationNode();
250        ~DeclarationNode();
251        DeclarationNode * clone() const override;
252
253        DeclarationNode * addQualifiers( DeclarationNode * );
254        void checkQualifiers( const TypeData *, const TypeData * );
255        void checkSpecifiers( DeclarationNode * );
256        DeclarationNode * copySpecifiers( DeclarationNode * );
257        DeclarationNode * addType( DeclarationNode * );
258        DeclarationNode * addTypedef();
259        DeclarationNode * addAssertions( DeclarationNode * );
260        DeclarationNode * addName( std::string * );
261        DeclarationNode * addAsmName( DeclarationNode * );
262        DeclarationNode * addBitfield( ExpressionNode * size );
263        DeclarationNode * addVarArgs();
264        DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
265        DeclarationNode * addOldDeclList( DeclarationNode * list );
266        DeclarationNode * setBase( TypeData * newType );
267        DeclarationNode * copyAttribute( DeclarationNode * attr );
268        DeclarationNode * addPointer( DeclarationNode * qualifiers );
269        DeclarationNode * addArray( DeclarationNode * array );
270        DeclarationNode * addNewPointer( DeclarationNode * pointer );
271        DeclarationNode * addNewArray( DeclarationNode * array );
272        DeclarationNode * addParamList( DeclarationNode * list );
273        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
274        DeclarationNode * addInitializer( InitializerNode * init );
275        DeclarationNode * addTypeInitializer( DeclarationNode * init );
276
277        DeclarationNode * cloneType( std::string * newName );
278        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
279
280        DeclarationNode * appendList( DeclarationNode * node ) {
281                return (DeclarationNode *)set_last( node );
282        }
283
284        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
285        virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
286
287        Declaration * build() const;
288        Type * buildType() const;
289
290        LinkageSpec::Spec get_linkage() const { return linkage; }
291        DeclarationNode * extractAggregate() const;
292        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
293        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
294
295        bool get_extension() const { return extension; }
296        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
297  public:
298        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
299
300        struct Variable_t {
301//              const std::string * name;
302                DeclarationNode::TypeClass tyClass;
303                DeclarationNode * assertions;
304                DeclarationNode * initializer;
305        };
306        Variable_t variable;
307
308        struct Attr_t {
309//              const std::string * name;
310                ExpressionNode * expr;
311                DeclarationNode * type;
312        };
313        Attr_t attr;
314
315        BuiltinType builtin;
316
317        TypeData * type;
318
319        Type::FuncSpecifiers funcSpecs;
320        Type::StorageClasses storageClasses;
321
322        ExpressionNode * bitfieldWidth;
323        std::unique_ptr<ExpressionNode> enumeratorValue;
324        bool hasEllipsis;
325        LinkageSpec::Spec linkage;
326        Expression *asmName;
327        std::list< Attribute * > attributes;
328        InitializerNode * initializer;
329        bool extension = false;
330        std::string error;
331        StatementNode * asmStmt;
332
333        static UniqueName anonymous;
334}; // DeclarationNode
335
336Type * buildType( TypeData * type );
337
338static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
339        Type * ret = orig ? orig->buildType() : nullptr;
340        delete orig;
341        return ret;
342}
343
344//##############################################################################
345
346class StatementNode final : public ParseNode {
347  public:
348        StatementNode() { stmt = nullptr; }
349        StatementNode( Statement * stmt ) : stmt( stmt ) {}
350        StatementNode( DeclarationNode * decl );
351        virtual ~StatementNode() {}
352
353        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
354        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
355
356        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
357                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
358                delete attr;
359                delete name;
360                return this;
361        }
362
363        virtual StatementNode * append_last_case( StatementNode * );
364
365        virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
366                os << stmt.get() << std::endl;
367        }
368  private:
369        std::unique_ptr<Statement> stmt;
370}; // StatementNode
371
372Statement * build_expr( ExpressionNode * ctl );
373
374struct IfCtl {
375        IfCtl( DeclarationNode * decl, ExpressionNode * condition ) :
376                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
377
378        StatementNode * init;
379        ExpressionNode * condition;
380};
381
382struct ForCtl {
383        ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
384                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
385        ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
386                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
387
388        StatementNode * init;
389        ExpressionNode * condition;
390        ExpressionNode * change;
391};
392
393Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
394Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
395Statement * build_case( ExpressionNode * ctl );
396Statement * build_default();
397Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
398Statement * build_for( ForCtl * forctl, StatementNode * stmt );
399Statement * build_branch( BranchStmt::Type kind );
400Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
401Statement * build_computedgoto( ExpressionNode * ctl );
402Statement * build_return( ExpressionNode * ctl );
403Statement * build_throw( ExpressionNode * ctl );
404Statement * build_resume( ExpressionNode * ctl );
405Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
406Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
407Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
408Statement * build_finally( StatementNode * stmt );
409Statement * build_compound( StatementNode * first );
410Statement * build_asmstmt( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
411WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
412WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
413WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
414WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
415WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
416
417//##############################################################################
418
419template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
420void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
421        SemanticErrorException errors;
422        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
423        const NodeType * cur = firstNode;
424
425        while ( cur ) {
426                try {
427                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
428                        if ( result ) {
429                                result->location = cur->location;
430                                * out++ = result;
431                        } else {
432                                assertf(false, "buildList unknown type");
433                        } // if
434                } catch( SemanticErrorException &e ) {
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.