source: src/Parser/ParseNode.h @ 61fc4f6

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

start for cpp directive-statement

  • Property mode set to 100644
File size: 19.7 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 : Sun Apr 29 14:04:05 2018
13// Update Count     : 830
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_keyword_cast( KeywordCastExpr::Target target, ExpressionNode * expr_node );
182Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
183Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
184Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
185Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
186Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
187Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
188Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
189Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
190Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
191Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
192Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
193Expression * build_tuple( ExpressionNode * expr_node = nullptr );
194Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
195Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
196
197//##############################################################################
198
199struct TypeData;
200
201class DeclarationNode : public ParseNode {
202  public:
203        // These enumerations must harmonize with their names.
204        enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, Int128, Float80, Float128, NoBasicType };
205        static const char * basicTypeNames[];
206        enum ComplexType { Complex, Imaginary, NoComplexType };
207        static const char * complexTypeNames[];
208        enum Signedness { Signed, Unsigned, NoSignedness };
209        static const char * signednessNames[];
210        enum Length { Short, Long, LongLong, NoLength };
211        static const char * lengthNames[];
212        enum Aggregate { Struct, Union, Exception, Trait, Coroutine, Monitor, Thread, NoAggregate };
213        static const char * aggregateNames[];
214        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
215        static const char * typeClassNames[];
216        enum BuiltinType { Valist, Zero, One, NoBuiltinType };
217        static const char * builtinTypeNames[];
218
219        static DeclarationNode * newStorageClass( Type::StorageClasses );
220        static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
221        static DeclarationNode * newTypeQualifier( Type::Qualifiers );
222        static DeclarationNode * newBasicType( BasicType );
223        static DeclarationNode * newComplexType( ComplexType );
224        static DeclarationNode * newSignedNess( Signedness );
225        static DeclarationNode * newLength( Length );
226        static DeclarationNode * newBuiltinType( BuiltinType );
227        static DeclarationNode * newForall( DeclarationNode * );
228        static DeclarationNode * newFromTypedef( std::string * );
229        static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
230        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
231        static DeclarationNode * newEnum( std::string * name, DeclarationNode * constants, bool body );
232        static DeclarationNode * newEnumConstant( std::string * name, ExpressionNode * constant );
233        static DeclarationNode * newName( std::string * );
234        static DeclarationNode * newFromTypeGen( std::string *, ExpressionNode * params );
235        static DeclarationNode * newTypeParam( TypeClass, std::string * );
236        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
237        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
238        static DeclarationNode * newTypeDecl( std::string * name, DeclarationNode * typeParams );
239        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
240        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
241        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
242        static DeclarationNode * newBitfield( ExpressionNode * size );
243        static DeclarationNode * newTuple( DeclarationNode * members );
244        static DeclarationNode * newTypeof( ExpressionNode * expr );
245        static DeclarationNode * newAttr( std::string *, ExpressionNode * expr ); // @ attributes
246        static DeclarationNode * newAttr( std::string *, DeclarationNode * type ); // @ attributes
247        static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
248        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
249        static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
250
251        DeclarationNode();
252        ~DeclarationNode();
253        DeclarationNode * clone() const override;
254
255        DeclarationNode * addQualifiers( DeclarationNode * );
256        void checkQualifiers( const TypeData *, const TypeData * );
257        void checkSpecifiers( DeclarationNode * );
258        DeclarationNode * copySpecifiers( DeclarationNode * );
259        DeclarationNode * addType( DeclarationNode * );
260        DeclarationNode * addTypedef();
261        DeclarationNode * addAssertions( DeclarationNode * );
262        DeclarationNode * addName( std::string * );
263        DeclarationNode * addAsmName( DeclarationNode * );
264        DeclarationNode * addBitfield( ExpressionNode * size );
265        DeclarationNode * addVarArgs();
266        DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
267        DeclarationNode * addOldDeclList( DeclarationNode * list );
268        DeclarationNode * setBase( TypeData * newType );
269        DeclarationNode * copyAttribute( DeclarationNode * attr );
270        DeclarationNode * addPointer( DeclarationNode * qualifiers );
271        DeclarationNode * addArray( DeclarationNode * array );
272        DeclarationNode * addNewPointer( DeclarationNode * pointer );
273        DeclarationNode * addNewArray( DeclarationNode * array );
274        DeclarationNode * addParamList( DeclarationNode * list );
275        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
276        DeclarationNode * addInitializer( InitializerNode * init );
277        DeclarationNode * addTypeInitializer( DeclarationNode * init );
278
279        DeclarationNode * cloneType( std::string * newName );
280        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
281
282        DeclarationNode * appendList( DeclarationNode * node ) {
283                return (DeclarationNode *)set_last( node );
284        }
285
286        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
287        virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
288
289        Declaration * build() const;
290        Type * buildType() const;
291
292        LinkageSpec::Spec get_linkage() const { return linkage; }
293        DeclarationNode * extractAggregate() const;
294        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
295        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
296
297        bool get_extension() const { return extension; }
298        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
299  public:
300        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
301
302        struct Variable_t {
303//              const std::string * name;
304                DeclarationNode::TypeClass tyClass;
305                DeclarationNode * assertions;
306                DeclarationNode * initializer;
307        };
308        Variable_t variable;
309
310        struct Attr_t {
311//              const std::string * name;
312                ExpressionNode * expr;
313                DeclarationNode * type;
314        };
315        Attr_t attr;
316
317        struct StaticAssert_t {
318                ExpressionNode * condition;
319                Expression * message;
320        };
321        StaticAssert_t assert;
322
323        BuiltinType builtin;
324
325        TypeData * type;
326
327        Type::FuncSpecifiers funcSpecs;
328        Type::StorageClasses storageClasses;
329
330        ExpressionNode * bitfieldWidth;
331        std::unique_ptr<ExpressionNode> enumeratorValue;
332        bool hasEllipsis;
333        LinkageSpec::Spec linkage;
334        Expression * asmName;
335        std::list< Attribute * > attributes;
336        InitializerNode * initializer;
337        bool extension = false;
338        std::string error;
339        StatementNode * asmStmt;
340
341        static UniqueName anonymous;
342}; // DeclarationNode
343
344Type * buildType( TypeData * type );
345
346static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
347        Type * ret = orig ? orig->buildType() : nullptr;
348        delete orig;
349        return ret;
350}
351
352//##############################################################################
353
354class StatementNode final : public ParseNode {
355  public:
356        StatementNode() { stmt = nullptr; }
357        StatementNode( Statement * stmt ) : stmt( stmt ) {}
358        StatementNode( DeclarationNode * decl );
359        virtual ~StatementNode() {}
360
361        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
362        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
363
364        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
365                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
366                delete attr;
367                delete name;
368                return this;
369        }
370
371        virtual StatementNode * append_last_case( StatementNode * );
372
373        virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
374                os << stmt.get() << std::endl;
375        }
376  private:
377        std::unique_ptr<Statement> stmt;
378}; // StatementNode
379
380Statement * build_expr( ExpressionNode * ctl );
381
382struct IfCtl {
383        IfCtl( DeclarationNode * decl, ExpressionNode * condition ) :
384                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
385
386        StatementNode * init;
387        ExpressionNode * condition;
388};
389
390struct ForCtl {
391        ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
392                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
393        ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
394                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
395
396        StatementNode * init;
397        ExpressionNode * condition;
398        ExpressionNode * change;
399};
400
401Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
402Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
403Statement * build_case( ExpressionNode * ctl );
404Statement * build_default();
405Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
406Statement * build_for( ForCtl * forctl, StatementNode * stmt );
407Statement * build_branch( BranchStmt::Type kind );
408Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
409Statement * build_computedgoto( ExpressionNode * ctl );
410Statement * build_return( ExpressionNode * ctl );
411Statement * build_throw( ExpressionNode * ctl );
412Statement * build_resume( ExpressionNode * ctl );
413Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
414Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
415Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
416Statement * build_finally( StatementNode * stmt );
417Statement * build_compound( StatementNode * first );
418Statement * build_asmstmt( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
419Statement * build_dirstmt( std::string * directive );
420WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
421WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
422WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
423WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
424WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
425
426//##############################################################################
427
428template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
429void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
430        SemanticErrorException errors;
431        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
432        const NodeType * cur = firstNode;
433
434        while ( cur ) {
435                try {
436                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
437                        if ( result ) {
438                                result->location = cur->location;
439                                * out++ = result;
440                        } else {
441                                assertf(false, "buildList unknown type");
442                        } // if
443                } catch( SemanticErrorException &e ) {
444                        errors.append( e );
445                } // try
446                cur = dynamic_cast< NodeType * >( cur->get_next() );
447        } // while
448        if ( ! errors.isEmpty() ) {
449                throw errors;
450        } // if
451}
452
453// in DeclarationNode.cc
454void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
455void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
456void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
457
458template< typename SynTreeType, typename NodeType >
459void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
460        buildList( firstNode, outputList );
461        delete firstNode;
462}
463
464// in ParseNode.cc
465std::ostream & operator<<( std::ostream & out, const ParseNode * node );
466
467// Local Variables: //
468// tab-width: 4 //
469// mode: c++ //
470// compile-command: "make install" //
471// End: //
Note: See TracBrowser for help on using the repository browser.