source: src/Parser/ParseNode.h @ 08d5507b

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

change type of function specifier and storage class to bit fields

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