source: src/Parser/ParseNode.h @ be9288a

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since be9288a was be9288a, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Fixed errors made by the clean-up tool

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