source: src/Parser/ParseNode.h @ a073d46

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

code generation for external asm statement (declaration)

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