source: src/Parser/ParseNode.h @ e149f77

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 e149f77 was 513e165, checked in by Peter A. Buhr <pabuhr@…>, 7 years ago

generalize types for encoded strings, and fold simple ExpressionNode? build routines into parser

  • Property mode set to 100644
File size: 19.6 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 : Wed Sep 13 12:35:10 2017
13// Update Count     : 807
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_addressOf( ExpressionNode * expr_node );
178Expression * build_sizeOfexpr( ExpressionNode * expr_node );
179Expression * build_sizeOftype( DeclarationNode * decl_node );
180Expression * build_alignOfexpr( ExpressionNode * expr_node );
181Expression * build_alignOftype( DeclarationNode * decl_node );
182Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
183Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
184Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
185Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
186Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
187Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
188Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
189Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
190Expression * build_attrexpr( NameExpr * var, ExpressionNode * expr_node );
191Expression * build_attrtype( NameExpr * var, DeclarationNode * decl_node );
192Expression * build_tuple( ExpressionNode * expr_node = nullptr );
193Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
194Expression * build_range( ExpressionNode * low, ExpressionNode * high );
195Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
196
197//##############################################################################
198
199struct TypeData;
200
201class DeclarationNode : public ParseNode {
202  public:
203        enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, NoBasicType };
204        enum ComplexType { Complex, Imaginary, NoComplexType };
205        enum Signedness { Signed, Unsigned, NoSignedness };
206        enum Length { Short, Long, LongLong, NoLength };
207        enum Aggregate { Struct, Union, Trait, Coroutine, Monitor, Thread, NoAggregate };
208        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
209        enum BuiltinType { Valist, Zero, One, NoBuiltinType };
210
211        static const char * basicTypeNames[];
212        static const char * complexTypeNames[];
213        static const char * signednessNames[];
214        static const char * lengthNames[];
215        static const char * aggregateNames[];
216        static const char * typeClassNames[];
217        static const char * builtinTypeNames[];
218
219        static DeclarationNode * newStorageClass( Type::StorageClasses );
220        static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
221        static DeclarationNode * newTypeQualifier( Type::Qualifiers );
222        static DeclarationNode * newBasicType( BasicType );
223        static DeclarationNode * newComplexType( ComplexType );
224        static DeclarationNode * newSignedNess( Signedness );
225        static DeclarationNode * newLength( Length );
226        static DeclarationNode * newBuiltinType( BuiltinType );
227        static DeclarationNode * newForall( DeclarationNode * );
228        static DeclarationNode * newFromTypedef( std::string * );
229        static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body, bool newStyle = false );
230        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
231        static DeclarationNode * newEnum( std::string * name, DeclarationNode * constants, bool body );
232        static DeclarationNode * newEnumConstant( std::string * name, ExpressionNode * constant );
233        static DeclarationNode * newName( std::string * );
234        static DeclarationNode * newFromTypeGen( std::string *, ExpressionNode * params );
235        static DeclarationNode * newTypeParam( TypeClass, std::string * );
236        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
237        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
238        static DeclarationNode * newTypeDecl( std::string * name, DeclarationNode * typeParams );
239        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
240        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
241        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
242        static DeclarationNode * newBitfield( ExpressionNode * size );
243        static DeclarationNode * newTuple( DeclarationNode * members );
244        static DeclarationNode * newTypeof( ExpressionNode * expr );
245        static DeclarationNode * newAttr( std::string *, ExpressionNode * expr ); // @ attributes
246        static DeclarationNode * newAttr( std::string *, DeclarationNode * type ); // @ attributes
247        static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
248        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
249
250        DeclarationNode();
251        ~DeclarationNode();
252        DeclarationNode * clone() const override;
253
254        DeclarationNode * addQualifiers( DeclarationNode * );
255        void checkQualifiers( const TypeData *, const TypeData * );
256        void checkSpecifiers( DeclarationNode * );
257        DeclarationNode * copySpecifiers( DeclarationNode * );
258        DeclarationNode * addType( DeclarationNode * );
259        DeclarationNode * addTypedef();
260        DeclarationNode * addAssertions( DeclarationNode * );
261        DeclarationNode * addName( std::string * );
262        DeclarationNode * addAsmName( DeclarationNode * );
263        DeclarationNode * addBitfield( ExpressionNode * size );
264        DeclarationNode * addVarArgs();
265        DeclarationNode * addFunctionBody( StatementNode * body );
266        DeclarationNode * addOldDeclList( DeclarationNode * list );
267        DeclarationNode * setBase( TypeData * newType );
268        DeclarationNode * copyAttribute( DeclarationNode * attr );
269        DeclarationNode * addPointer( DeclarationNode * qualifiers );
270        DeclarationNode * addArray( DeclarationNode * array );
271        DeclarationNode * addNewPointer( DeclarationNode * pointer );
272        DeclarationNode * addNewArray( DeclarationNode * array );
273        DeclarationNode * addParamList( DeclarationNode * list );
274        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
275        DeclarationNode * addInitializer( InitializerNode * init );
276        DeclarationNode * addTypeInitializer( DeclarationNode * init );
277
278        DeclarationNode * cloneType( std::string * newName );
279        DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
280
281        DeclarationNode * appendList( DeclarationNode * node ) {
282                return (DeclarationNode *)set_last( node );
283        }
284
285        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
286        virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
287
288        Declaration * build() const;
289        Type * buildType() const;
290
291        bool get_hasEllipsis() const;
292        LinkageSpec::Spec get_linkage() const { return linkage; }
293        DeclarationNode * extractAggregate() const;
294        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
295        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
296
297        bool get_extension() const { return extension; }
298        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
299  public:
300        struct Variable_t {
301//              const std::string * name;
302                DeclarationNode::TypeClass tyClass;
303                DeclarationNode * assertions;
304                DeclarationNode * initializer;
305        };
306        Variable_t variable;
307
308        struct Attr_t {
309//              const std::string * name;
310                ExpressionNode * expr;
311                DeclarationNode * type;
312        };
313        Attr_t attr;
314
315        BuiltinType builtin;
316
317        TypeData * type;
318
319        Type::FuncSpecifiers funcSpecs;
320        Type::StorageClasses storageClasses;
321
322        ExpressionNode * bitfieldWidth;
323        std::unique_ptr<ExpressionNode> enumeratorValue;
324        bool hasEllipsis;
325        LinkageSpec::Spec linkage;
326        Expression *asmName;
327        std::list< Attribute * > attributes;
328        InitializerNode * initializer;
329        bool extension = false;
330        std::string error;
331        StatementNode * asmStmt;
332
333        static UniqueName anonymous;
334}; // DeclarationNode
335
336Type * buildType( TypeData * type );
337
338static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
339        Type * ret = orig ? orig->buildType() : nullptr;
340        delete orig;
341        return ret;
342}
343
344//##############################################################################
345
346class StatementNode final : public ParseNode {
347  public:
348        StatementNode() { stmt = nullptr; }
349        StatementNode( Statement * stmt ) : stmt( stmt ) {}
350        StatementNode( DeclarationNode * decl );
351        virtual ~StatementNode() {}
352
353        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
354        Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
355
356        virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
357                stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
358                delete attr;
359                delete name;
360                return this;
361        }
362
363        virtual StatementNode * append_last_case( StatementNode * );
364
365        virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
366        virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {}
367  private:
368        std::unique_ptr<Statement> stmt;
369}; // StatementNode
370
371Statement * build_expr( ExpressionNode * ctl );
372
373struct IfCtl {
374        IfCtl( DeclarationNode * decl, ExpressionNode * condition ) :
375                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
376
377        StatementNode * init;
378        ExpressionNode * condition;
379};
380
381struct ForCtl {
382        ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
383                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
384        ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
385                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
386
387        StatementNode * init;
388        ExpressionNode * condition;
389        ExpressionNode * change;
390};
391
392Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
393Statement * build_switch( ExpressionNode * ctl, StatementNode * stmt );
394Statement * build_case( ExpressionNode * ctl );
395Statement * build_default();
396Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
397Statement * build_for( ForCtl * forctl, StatementNode * stmt );
398Statement * build_branch( BranchStmt::Type kind );
399Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
400Statement * build_computedgoto( ExpressionNode * ctl );
401Statement * build_return( ExpressionNode * ctl );
402Statement * build_throw( ExpressionNode * ctl );
403Statement * build_resume( ExpressionNode * ctl );
404Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
405Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt );
406Statement * build_catch( CatchStmt::Kind kind, DeclarationNode *decl, ExpressionNode *cond, StatementNode *body );
407Statement * build_finally( StatementNode * stmt );
408Statement * build_compound( StatementNode * first );
409Statement * build_asmstmt( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
410WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
411WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
412WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
413WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
414
415//##############################################################################
416
417template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
418void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
419        SemanticError errors;
420        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
421        const NodeType * cur = firstNode;
422
423        while ( cur ) {
424                try {
425                        SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
426                        if ( result ) {
427                                result->location = cur->location;
428                                * out++ = result;
429                        } else {
430                                assertf(false, "buildList unknown type");
431                        } // if
432                } catch( SemanticError &e ) {
433                        e.set_location( cur->location );
434                        errors.append( e );
435                } // try
436                cur = dynamic_cast< NodeType * >( cur->get_next() );
437        } // while
438        if ( ! errors.isEmpty() ) {
439                throw errors;
440        } // if
441}
442
443// in DeclarationNode.cc
444void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
445void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
446void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
447
448template< typename SynTreeType, typename NodeType >
449void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
450        buildList( firstNode, outputList );
451        delete firstNode;
452}
453
454// in ParseNode.cc
455std::ostream & operator<<( std::ostream & out, const ParseNode * node );
456
457// Local Variables: //
458// tab-width: 4 //
459// mode: c++ //
460// compile-command: "make install" //
461// End: //
Note: See TracBrowser for help on using the repository browser.