source: src/Parser/ParseNode.h @ 481115f

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 481115f was 481115f, checked in by Peter A. Buhr <pabuhr@…>, 4 years ago

change semantics of CFA routine-prototype declaration

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