source: src/Parser/ParseNode.h @ a2d4d1c

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 a2d4d1c was d48e529, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Begin to introduce support for yylloc in the parser and extend CodeLocation? to include start column and end column/line number information

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