source: src/Parser/ParseNode.h @ 60ba456

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumwith_gc
Last change on this file since 60ba456 was f6e3e34, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Add StaticAssertDecl? node

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