source: src/Parser/ParseNode.h@ eed5e48

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since eed5e48 was e994912, checked in by Peter A. Buhr <pabuhr@…>, 9 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.