source: src/Parser/ParseNode.h @ db70fe4

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

move code from ExpressionNode? into parser

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