source: src/Parser/ParseNode.h @ e612146c

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

third attempt at user-defined literals

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