source: src/Parser/ParseNode.h @ 679e644

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprno_listpersistent-indexerpthread-emulationqualifiedEnum
Last change on this file since 679e644 was 679e644, checked in by Peter A. Buhr <pabuhr@…>, 5 years ago

extend plan 9, anonymous declarations, change token for default argument

  • Property mode set to 100644
File size: 20.1 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// ParseNode.h --
8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Sat May 16 13:28:16 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Wed Jul 18 17:35:55 2018
13// Update Count     : 844
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() << 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 ); // these 4 routines modify the string
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( const std::string * );
233        static DeclarationNode * newFromGlobalScope();
234        static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
235        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
236        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
237        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body );
238        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
239        static DeclarationNode * newName( const std::string * );
240        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
241        static DeclarationNode * newTypeParam( TypeClass, const std::string * );
242        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
243        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
244        static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
245        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
246        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
247        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
248        static DeclarationNode * newBitfield( ExpressionNode * size );
249        static DeclarationNode * newTuple( DeclarationNode * members );
250        static DeclarationNode * newTypeof( ExpressionNode * expr );
251        static DeclarationNode * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes
252        static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes
253        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
254        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
255        static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
256
257        DeclarationNode();
258        ~DeclarationNode();
259        DeclarationNode * clone() const override;
260
261        DeclarationNode * addQualifiers( DeclarationNode * );
262        void checkQualifiers( const TypeData *, const TypeData * );
263        void checkSpecifiers( DeclarationNode * );
264        DeclarationNode * copySpecifiers( DeclarationNode * );
265        DeclarationNode * addType( DeclarationNode * );
266        DeclarationNode * addTypedef();
267        DeclarationNode * addAssertions( DeclarationNode * );
268        DeclarationNode * addName( std::string * );
269        DeclarationNode * addAsmName( DeclarationNode * );
270        DeclarationNode * addBitfield( ExpressionNode * size );
271        DeclarationNode * addVarArgs();
272        DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
273        DeclarationNode * addOldDeclList( DeclarationNode * list );
274        DeclarationNode * setBase( TypeData * newType );
275        DeclarationNode * copyAttribute( DeclarationNode * attr );
276        DeclarationNode * addPointer( DeclarationNode * qualifiers );
277        DeclarationNode * addArray( DeclarationNode * array );
278        DeclarationNode * addNewPointer( DeclarationNode * pointer );
279        DeclarationNode * addNewArray( DeclarationNode * array );
280        DeclarationNode * addParamList( DeclarationNode * list );
281        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
282        DeclarationNode * addInitializer( InitializerNode * init );
283        DeclarationNode * addTypeInitializer( DeclarationNode * init );
284
285        DeclarationNode * cloneType( std::string * newName );
286        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
287
288        DeclarationNode * appendList( DeclarationNode * node ) {
289                return (DeclarationNode *)set_last( node );
290        }
291
292        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
293        virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
294
295        Declaration * build() const;
296        Type * buildType() const;
297
298        LinkageSpec::Spec get_linkage() const { return linkage; }
299        DeclarationNode * extractAggregate() const;
300        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
301        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
302
303        bool get_extension() const { return extension; }
304        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
305  public:
306        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
307
308        struct Variable_t {
309//              const std::string * name;
310                DeclarationNode::TypeClass tyClass;
311                DeclarationNode * assertions;
312                DeclarationNode * initializer;
313        };
314        Variable_t variable;
315
316        struct Attr_t {
317//              const std::string * name;
318                ExpressionNode * expr;
319                DeclarationNode * type;
320        };
321        Attr_t attr;
322
323        struct StaticAssert_t {
324                ExpressionNode * condition;
325                Expression * message;
326        };
327        StaticAssert_t assert;
328
329        BuiltinType builtin;
330
331        TypeData * type;
332
333        bool inLine;
334        Type::FuncSpecifiers funcSpecs;
335        Type::StorageClasses storageClasses;
336
337        ExpressionNode * bitfieldWidth;
338        std::unique_ptr<ExpressionNode> enumeratorValue;
339        bool hasEllipsis;
340        LinkageSpec::Spec linkage;
341        Expression * asmName;
342        std::list< Attribute * > attributes;
343        InitializerNode * initializer;
344        bool extension = false;
345        std::string error;
346        StatementNode * asmStmt;
347
348        static UniqueName anonymous;
349}; // DeclarationNode
350
351Type * buildType( TypeData * type );
352
353static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
354        Type * ret = orig ? orig->buildType() : nullptr;
355        delete orig;
356        return ret;
357}
358
359//##############################################################################
360
361class StatementNode final : public ParseNode {
362  public:
363        StatementNode() { stmt = nullptr; }
364        StatementNode( Statement * stmt ) : stmt( stmt ) {}
365        StatementNode( DeclarationNode * decl );
366        virtual ~StatementNode() {}
367
368        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
369        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
370
371        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
372                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
373                delete attr;
374                delete name;
375                return this;
376        }
377
378        virtual StatementNode * append_last_case( StatementNode * );
379
380        virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
381                os << stmt.get() << std::endl;
382        }
383  private:
384        std::unique_ptr<Statement> stmt;
385}; // StatementNode
386
387Statement * build_expr( ExpressionNode * ctl );
388
389struct IfCtl {
390        IfCtl( DeclarationNode * decl, ExpressionNode * condition ) :
391                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
392
393        StatementNode * init;
394        ExpressionNode * condition;
395};
396
397struct ForCtl {
398        ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
399                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
400        ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
401                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
402
403        StatementNode * init;
404        ExpressionNode * condition;
405        ExpressionNode * change;
406};
407
408Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init );
409Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
410Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
411Statement * build_case( ExpressionNode * ctl );
412Statement * build_default();
413Statement * build_while( IfCtl * ctl, StatementNode * stmt );
414Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt );
415Statement * build_for( ForCtl * forctl, StatementNode * stmt );
416Statement * build_branch( BranchStmt::Type kind );
417Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
418Statement * build_computedgoto( ExpressionNode * ctl );
419Statement * build_return( ExpressionNode * ctl );
420Statement * build_throw( ExpressionNode * ctl );
421Statement * build_resume( ExpressionNode * ctl );
422Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
423Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
424Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
425Statement * build_finally( StatementNode * stmt );
426Statement * build_compound( StatementNode * first );
427Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
428Statement * build_directive( std::string * directive );
429WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
430WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
431WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
432WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
433WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
434
435//##############################################################################
436
437template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
438void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
439        SemanticErrorException errors;
440        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
441        const NodeType * cur = firstNode;
442
443        while ( cur ) {
444                try {
445                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
446                        if ( result ) {
447                                result->location = cur->location;
448                                * out++ = result;
449                        } else {
450                                assertf(false, "buildList unknown type");
451                        } // if
452                } catch( SemanticErrorException &e ) {
453                        errors.append( e );
454                } // try
455                cur = dynamic_cast< NodeType * >( cur->get_next() );
456        } // while
457        if ( ! errors.isEmpty() ) {
458                throw errors;
459        } // if
460}
461
462// in DeclarationNode.cc
463void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
464void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
465void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
466
467template< typename SynTreeType, typename NodeType >
468void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
469        buildList( firstNode, outputList );
470        delete firstNode;
471}
472
473// in ParseNode.cc
474std::ostream & operator<<( std::ostream & out, const ParseNode * node );
475
476// Local Variables: //
477// tab-width: 4 //
478// mode: c++ //
479// compile-command: "make install" //
480// End: //
Note: See TracBrowser for help on using the repository browser.