source: src/Parser/ParseNode.h @ 497282e

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 497282e was e4bc986, checked in by Rob Schluntz <rschlunt@…>, 6 years ago

Add ParseNode? print code and update declarationErrors test

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