source: src/Parser/ParseNode.h @ c6e6333

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 c6e6333 was 201aeb9, checked in by Peter A. Buhr <pabuhr@…>, 7 years ago

first attempt at new basic-type int128, and length suffix with explicit size

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