source: src/Parser/ParseNode.h @ f271bdd

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprno_listpersistent-indexer
Last change on this file since f271bdd was f271bdd, checked in by Peter A. Buhr <pabuhr@…>, 3 years ago

first attempt at extended for-crtl, name changes

  • Property mode set to 100644
File size: 20.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 : Sat Aug  4 09:39:40 2018
13// Update Count     : 853
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        const 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();
131        }
132        void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
133
134        Expression *get_expr() const { return expr.get(); }
135        template<typename T>
136        bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
137
138        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
139  private:
140        bool extension = false;
141        std::unique_ptr<Expression> expr;
142}; // ExpressionNode
143
144template< typename T >
145struct maybeBuild_t< Expression, T > {
146        static inline Expression * doit( const T * orig ) {
147                if ( orig ) {
148                        Expression * p = orig->build();
149                        p->set_extension( orig->get_extension() );
150                        p->location = orig->location;
151                        return p;
152                } else {
153                        return nullptr;
154                } // if
155        }
156};
157
158// Must harmonize with OperName.
159enum class OperKinds {
160        // diadic
161        SizeOf, AlignOf, OffsetOf, Plus, Minus, Exp, Mul, Div, Mod, Or, And,
162        BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
163        Assign, AtAssn, ExpAssn, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn,
164        Index, Range,
165        // monadic
166        UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
167        Ctor, Dtor,
168}; // OperKinds
169
170struct LabelNode {
171        std::list< Label > labels;
172};
173
174Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string
175Expression * build_constantFloat( std::string & str );
176Expression * build_constantChar( std::string & str );
177Expression * build_constantStr( std::string & str );
178Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
179Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
180Expression * build_field_name_FLOATINGconstant( const std::string & str );
181Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
182
183NameExpr * build_varref( const std::string * name );
184
185Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
186Expression * build_keyword_cast( KeywordCastExpr::Target target, ExpressionNode * expr_node );
187Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
188Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
189Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
190Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
191Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
192Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
193Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
194Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
195Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
196Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
197Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
198Expression * build_tuple( ExpressionNode * expr_node = nullptr );
199Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
200Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
201
202//##############################################################################
203
204struct TypeData;
205
206class DeclarationNode : public ParseNode {
207  public:
208        // These enumerations must harmonize with their names.
209        enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, Int128, Float80, Float128, NoBasicType };
210        static const char * basicTypeNames[];
211        enum ComplexType { Complex, Imaginary, NoComplexType };
212        static const char * complexTypeNames[];
213        enum Signedness { Signed, Unsigned, NoSignedness };
214        static const char * signednessNames[];
215        enum Length { Short, Long, LongLong, NoLength };
216        static const char * lengthNames[];
217        enum Aggregate { Struct, Union, Exception, Trait, Coroutine, Monitor, Thread, NoAggregate };
218        static const char * aggregateNames[];
219        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
220        static const char * typeClassNames[];
221        enum BuiltinType { Valist, Zero, One, NoBuiltinType };
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( const std::string * );
234        static DeclarationNode * newFromGlobalScope();
235        static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
236        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
237        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
238        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body );
239        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
240        static DeclarationNode * newName( const std::string * );
241        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
242        static DeclarationNode * newTypeParam( TypeClass, const std::string * );
243        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
244        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
245        static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
246        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
247        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
248        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
249        static DeclarationNode * newBitfield( ExpressionNode * size );
250        static DeclarationNode * newTuple( DeclarationNode * members );
251        static DeclarationNode * newTypeof( ExpressionNode * expr );
252        static DeclarationNode * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes
253        static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes
254        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
255        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
256        static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
257
258        DeclarationNode();
259        ~DeclarationNode();
260        DeclarationNode * clone() const override;
261
262        DeclarationNode * addQualifiers( DeclarationNode * );
263        void checkQualifiers( const TypeData *, const TypeData * );
264        void checkSpecifiers( DeclarationNode * );
265        DeclarationNode * copySpecifiers( DeclarationNode * );
266        DeclarationNode * addType( DeclarationNode * );
267        DeclarationNode * addTypedef();
268        DeclarationNode * addAssertions( DeclarationNode * );
269        DeclarationNode * addName( std::string * );
270        DeclarationNode * addAsmName( DeclarationNode * );
271        DeclarationNode * addBitfield( ExpressionNode * size );
272        DeclarationNode * addVarArgs();
273        DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
274        DeclarationNode * addOldDeclList( DeclarationNode * list );
275        DeclarationNode * setBase( TypeData * newType );
276        DeclarationNode * copyAttribute( DeclarationNode * attr );
277        DeclarationNode * addPointer( DeclarationNode * qualifiers );
278        DeclarationNode * addArray( DeclarationNode * array );
279        DeclarationNode * addNewPointer( DeclarationNode * pointer );
280        DeclarationNode * addNewArray( DeclarationNode * array );
281        DeclarationNode * addParamList( DeclarationNode * list );
282        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
283        DeclarationNode * addInitializer( InitializerNode * init );
284        DeclarationNode * addTypeInitializer( DeclarationNode * init );
285
286        DeclarationNode * cloneType( std::string * newName );
287        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
288
289        DeclarationNode * appendList( DeclarationNode * node ) {
290                return (DeclarationNode *)set_last( node );
291        }
292
293        virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
294        virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
295
296        Declaration * build() const;
297        Type * buildType() const;
298
299        LinkageSpec::Spec get_linkage() const { return linkage; }
300        DeclarationNode * extractAggregate() const;
301        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
302        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
303
304        bool get_extension() const { return extension; }
305        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
306
307        bool get_inLine() const { return inLine; }
308        DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
309  public:
310        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
311
312        struct Variable_t {
313//              const std::string * name;
314                DeclarationNode::TypeClass tyClass;
315                DeclarationNode * assertions;
316                DeclarationNode * initializer;
317        };
318        Variable_t variable;
319
320        struct Attr_t {
321//              const std::string * name;
322                ExpressionNode * expr;
323                DeclarationNode * type;
324        };
325        Attr_t attr;
326
327        struct StaticAssert_t {
328                ExpressionNode * condition;
329                Expression * message;
330        };
331        StaticAssert_t assert;
332
333        BuiltinType builtin = NoBuiltinType;
334
335        TypeData * type = nullptr;
336
337        bool inLine = false;
338        Type::FuncSpecifiers funcSpecs;
339        Type::StorageClasses storageClasses;
340
341        ExpressionNode * bitfieldWidth = nullptr;
342        std::unique_ptr<ExpressionNode> enumeratorValue;
343        bool hasEllipsis = false;
344        LinkageSpec::Spec linkage;
345        Expression * asmName = nullptr;
346        std::list< Attribute * > attributes;
347        InitializerNode * initializer = nullptr;
348        bool extension = false;
349        std::string error;
350        StatementNode * asmStmt = nullptr;
351
352        static UniqueName anonymous;
353}; // DeclarationNode
354
355Type * buildType( TypeData * type );
356
357static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
358        Type * ret = orig ? orig->buildType() : nullptr;
359        delete orig;
360        return ret;
361}
362
363//##############################################################################
364
365class StatementNode final : public ParseNode {
366  public:
367        StatementNode() { stmt = nullptr; }
368        StatementNode( Statement * stmt ) : stmt( stmt ) {}
369        StatementNode( DeclarationNode * decl );
370        virtual ~StatementNode() {}
371
372        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
373        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
374
375        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
376                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
377                delete attr;
378                delete name;
379                return this;
380        }
381
382        virtual StatementNode * append_last_case( StatementNode * );
383
384        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
385                os << stmt.get() << std::endl;
386        }
387  private:
388        std::unique_ptr<Statement> stmt;
389}; // StatementNode
390
391Statement * build_expr( ExpressionNode * ctl );
392
393struct IfCtrl {
394        IfCtrl( DeclarationNode * decl, ExpressionNode * condition ) :
395                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
396
397        StatementNode * init;
398        ExpressionNode * condition;
399};
400
401struct ForCtrl {
402        ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
403                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
404        ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
405                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
406
407        StatementNode * init;
408        ExpressionNode * condition;
409        ExpressionNode * change;
410};
411
412Expression * build_if_control( IfCtrl * ctl, std::list< Statement * > & init );
413Statement * build_if( IfCtrl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
414Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
415Statement * build_case( ExpressionNode * ctl );
416Statement * build_default();
417Statement * build_while( IfCtrl * ctl, StatementNode * stmt );
418Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt );
419Statement * build_for( ForCtrl * forctl, StatementNode * stmt );
420Statement * build_branch( BranchStmt::Type kind );
421Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
422Statement * build_computedgoto( ExpressionNode * ctl );
423Statement * build_return( ExpressionNode * ctl );
424Statement * build_throw( ExpressionNode * ctl );
425Statement * build_resume( ExpressionNode * ctl );
426Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
427Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
428Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
429Statement * build_finally( StatementNode * stmt );
430Statement * build_compound( StatementNode * first );
431Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
432Statement * build_directive( std::string * directive );
433WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
434WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
435WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
436WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
437WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
438
439//##############################################################################
440
441template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
442void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
443        SemanticErrorException errors;
444        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
445        const NodeType * cur = firstNode;
446
447        while ( cur ) {
448                try {
449                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
450                        if ( result ) {
451                                result->location = cur->location;
452                                * out++ = result;
453                        } else {
454                                assertf(false, "buildList unknown type");
455                        } // if
456                } catch( SemanticErrorException & e ) {
457                        errors.append( e );
458                } // try
459                cur = dynamic_cast< NodeType * >( cur->get_next() );
460        } // while
461        if ( ! errors.isEmpty() ) {
462                throw errors;
463        } // if
464}
465
466// in DeclarationNode.cc
467void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
468void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
469void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
470
471template< typename SynTreeType, typename NodeType >
472void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
473        buildList( firstNode, outputList );
474        delete firstNode;
475}
476
477// in ParseNode.cc
478std::ostream & operator<<( std::ostream & out, const ParseNode * node );
479
480// Local Variables: //
481// tab-width: 4 //
482// mode: c++ //
483// compile-command: "make install" //
484// End: //
Note: See TracBrowser for help on using the repository browser.