source: src/Parser/ExpressionNode.cc@ 04273e9

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor 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 04273e9 was 7bf7fb9, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

more refactoring of parser code

  • Property mode set to 100644
File size: 21.7 KB
RevLine 
[b87a5ed]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//
[0caaa6a]7// ExpressionNode.cc --
8//
[b87a5ed]9// Author : Rodolfo G. Esteves
10// Created On : Sat May 16 13:17:07 2015
[097e2b0]11// Last Modified By : Peter A. Buhr
[7bf7fb9]12// Last Modified On : Sun Aug 7 09:23:12 2016
13// Update Count : 437
[0caaa6a]14//
[b87a5ed]15
[51b73452]16#include <cassert>
17#include <cctype>
[7bf7fb9]18#include <climits>
19#include <cstdio>
[51b73452]20#include <algorithm>
[59db689]21#include <sstream>
[51b73452]22
23#include "ParseNode.h"
[630a82a]24#include "TypeData.h"
[51b73452]25#include "SynTree/Constant.h"
26#include "SynTree/Expression.h"
[630a82a]27#include "SynTree/Declaration.h"
[d3b7937]28#include "Common/UnimplementedError.h"
[51b73452]29#include "parseutility.h"
[d3b7937]30#include "Common/utility.h"
[51b73452]31
32using namespace std;
33
[e04ef3a]34ExpressionNode::ExpressionNode() : ParseNode() {}
[51b73452]35
[e04ef3a]36ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ) {}
[51b73452]37
[e04ef3a]38ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ), extension( other.extension ) {
[b87a5ed]39 if ( other.argName ) {
[7bf7fb9]40 std::cout << "ExpressionNode" << std::endl;
[b87a5ed]41 argName = other.argName->clone();
42 } else {
43 argName = 0;
44 } // if
[51b73452]45}
46
[7f5566b]47ExpressionNode * ExpressionNode::set_argName( const std::string *aName ) {
[b87a5ed]48 argName = new VarRefNode( aName );
49 return this;
[51b73452]50}
51
[7f5566b]52ExpressionNode * ExpressionNode::set_argName( ExpressionNode *aDesignator ) {
[b87a5ed]53 argName = aDesignator;
54 return this;
[51b73452]55}
56
57void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
[b87a5ed]58 if ( argName ) {
[59db689]59 os << string( indent, ' ' ) << "(designated by: ";
[b87a5ed]60 argName->printOneLine( os, indent );
61 os << ")" << std::endl;
62 } // if
[51b73452]63}
64
[cd623a4]65//##############################################################################
66
[3848e0e]67NullExprNode::NullExprNode() {}
[51b73452]68
[3848e0e]69NullExprNode *NullExprNode::clone() const {
[b87a5ed]70 return new NullExprNode();
[51b73452]71}
72
[bdd516a]73void NullExprNode::print( std::ostream & os, int indent ) const {
[b87a5ed]74 printDesignation( os );
75 os << "null expression";
[51b73452]76}
77
[bdd516a]78void NullExprNode::printOneLine( std::ostream & os, int indent ) const {
[b87a5ed]79 printDesignation( os );
80 os << "null";
[51b73452]81}
82
[3848e0e]83Expression *NullExprNode::build() const {
[b87a5ed]84 return 0;
[51b73452]85}
86
[cd623a4]87//##############################################################################
88
[7bf7fb9]89// Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
90//
91// prefix action constant action suffix
92//
93// Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
94//
95// constant BEGIN CONT ...
96// <CONT>(...)? BEGIN 0 ... // possible empty suffix
97//
98// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
99// type.
100
101static Type::Qualifiers emptyQualifiers; // no qualifiers on constants
102
103static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
104static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
105static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
106static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
107static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
108static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
109
110ConstantNode *build_constantInteger( std::string & str ) {
111 static const BasicType::Kind kind[2][3] = {
112 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
113 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
114 };
115 bool dec = true, Unsigned = false; // decimal, unsigned constant
116 int size; // 0 => int, 1 => long, 2 => long long
117 unsigned long long v; // converted integral value
118 size_t last = str.length() - 1; // last character of constant
119
120 if ( str[0] == '0' ) { // octal/hex constant ?
121 dec = false;
122 if ( last != 0 && checkX( str[1] ) ) { // hex constant ?
123 sscanf( (char *)str.c_str(), "%llx", &v );
124 //printf( "%llx %llu\n", v, v );
125 } else { // octal constant
126 sscanf( (char *)str.c_str(), "%llo", &v );
127 //printf( "%llo %llu\n", v, v );
128 } // if
129 } else { // decimal constant ?
130 sscanf( (char *)str.c_str(), "%llu", &v );
131 //printf( "%llu %llu\n", v, v );
132 } // if
133
134 if ( v <= INT_MAX ) { // signed int
135 size = 0;
136 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int
137 size = 0;
138 Unsigned = true; // unsigned
139 } else if ( v <= LONG_MAX ) { // signed long int
140 size = 1;
141 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
142 size = 1;
143 Unsigned = true; // unsigned long int
144 } else if ( v <= LLONG_MAX ) { // signed long long int
145 size = 2;
146 } else { // unsigned long long int
147 size = 2;
148 Unsigned = true; // unsigned long long int
149 } // if
150
151 if ( checkU( str[last] ) ) { // suffix 'u' ?
152 Unsigned = true;
153 if ( last > 0 && checkL( str[last - 1] ) ) { // suffix 'l' ?
154 size = 1;
155 if ( last > 1 && checkL( str[last - 2] ) ) { // suffix 'll' ?
156 size = 2;
157 } // if
158 } // if
159 } else if ( checkL( str[ last ] ) ) { // suffix 'l' ?
160 size = 1;
161 if ( last > 0 && checkL( str[last - 1] ) ) { // suffix 'll' ?
162 size = 2;
163 if ( last > 1 && checkU( str[last - 2] ) ) { // suffix 'u' ?
164 Unsigned = true;
165 } // if
166 } else {
167 if ( last > 0 && checkU( str[last - 1] ) ) { // suffix 'u' ?
168 Unsigned = true;
169 } // if
170 } // if
171 } // if
172
173 return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[Unsigned][size] ), str ) ) );
174} // build_constantInteger
[51b73452]175
[7bf7fb9]176ConstantNode *build_constantFloat( std::string & str ) {
177 static const BasicType::Kind kind[2][3] = {
178 { BasicType::Float, BasicType::Double, BasicType::LongDouble },
179 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
180 };
[59c24b6]181
[7bf7fb9]182 bool complx = false; // real, complex
183 int size = 1; // 0 => float, 1 => double (default), 2 => long double
184 // floating-point constant has minimum of 2 characters: 1. or .1
185 size_t last = str.length() - 1;
[51b73452]186
[7bf7fb9]187 if ( checkI( str[last] ) ) { // imaginary ?
188 complx = true;
189 last -= 1; // backup one character
190 } // if
[0caaa6a]191
[7bf7fb9]192 if ( checkF( str[last] ) ) { // float ?
193 size = 0;
194 } else if ( checkD( str[last] ) ) { // double ?
195 size = 1;
196 } else if ( checkL( str[last] ) ) { // long double ?
197 size = 2;
198 } // if
199 if ( ! complx && checkI( str[last - 1] ) ) { // imaginary ?
200 complx = true;
201 } // if
[51b73452]202
[7bf7fb9]203 return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[complx][size] ), str ) ) );
204} // build_constantFloat
[51b73452]205
[7bf7fb9]206ConstantNode *build_constantChar( std::string & str ) {
207 return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::Char ), str ) ) );
208} // build_constantChar
[51b73452]209
[7bf7fb9]210ConstantNode *build_constantStr( std::string & str ) {
211 // string should probably be a primitive type
212 ArrayType *at = new ArrayType( emptyQualifiers, new BasicType( emptyQualifiers, BasicType::Char ),
213 new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::UnsignedInt ),
214 toString( str.size()+1-2 ) ) ), // +1 for '\0' and -2 for '"'
215 false, false );
216 return new ConstantNode( new ConstantExpr( Constant( at, str ) ) );
217} // build_constantStr
[51b73452]218
[cd623a4]219//##############################################################################
220
[7bf7fb9]221//Expression *build_varref( ExpressionNode expr ) {
222// return new NameExpr( get_name(), maybeBuild<Expression>( get_argName() ) );
223//}
[51b73452]224
[7bf7fb9]225VarRefNode::VarRefNode( const string *name, bool labelp ) : ExpressionNode( name ), isLabel( labelp ) {}
[51b73452]226
[3848e0e]227VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
[51b73452]228}
229
230Expression *VarRefNode::build() const {
[b87a5ed]231 return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
[51b73452]232}
233
[bdd516a]234void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]235 printDesignation( os );
236 os << get_name() << ' ';
[51b73452]237}
238
[bdd516a]239void VarRefNode::print( std::ostream &os, int indent ) const {
[b87a5ed]240 printDesignation( os );
[44b5ca0]241 os << string( indent, ' ' ) << "Referencing: ";
[b87a5ed]242 os << "Variable: " << get_name();
243 os << endl;
[51b73452]244}
245
[cd623a4]246//##############################################################################
247
[51b1202]248DesignatorNode::DesignatorNode( ExpressionNode *expr, bool isArrayIndex ) : isArrayIndex( isArrayIndex ) {
249 set_argName( expr );
[e869d663]250 assert( get_argName() );
251
252 if ( ! isArrayIndex ) {
253 if ( VarRefNode * var = dynamic_cast< VarRefNode * >( expr ) ) {
254
255 stringstream ss( var->get_name() );
256 double value;
257 if ( ss >> value ) {
[7bf7fb9]258 // this is a floating point constant. It MUST be ".0" or ".1", otherwise the program is invalid
[e869d663]259 if ( ! (var->get_name() == ".0" || var->get_name() == ".1") ) {
260 throw SemanticError( "invalid designator name: " + var->get_name() );
261 } // if
262 var->set_name( var->get_name().substr(1) );
263 } // if
264 } // if
265 } // if
[51b1202]266}
267
268DesignatorNode::DesignatorNode( const DesignatorNode &other ) : ExpressionNode( other ), isArrayIndex( other.isArrayIndex ) {
269}
270
[e869d663]271class DesignatorFixer : public Mutator {
272public:
273 virtual Expression* mutate( NameExpr *nameExpr ) {
274 if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
275 Constant val( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nameExpr->get_name() );
276 delete nameExpr;
277 return new ConstantExpr( val );
278 }
279 return nameExpr;
280 }
281};
282
[51b1202]283Expression *DesignatorNode::build() const {
[e04ef3a]284 Expression * ret = maybeBuild<Expression>(get_argName());
[e869d663]285
[51b1202]286 if ( isArrayIndex ) {
[7bf7fb9]287 // need to traverse entire structure and change any instances of 0 or 1 to ConstantExpr
[e869d663]288 DesignatorFixer fixer;
289 ret = ret->acceptMutator( fixer );
[51b1202]290 } // if
[e869d663]291
292 return ret;
[51b1202]293}
294
295void DesignatorNode::printOneLine( std::ostream &os, int indent ) const {
296 if ( get_argName() ) {
297 if ( isArrayIndex ) {
298 os << "[";
299 get_argName()->printOneLine( os, indent );
300 os << "]";
301 } else {
302 os << ".";
303 get_argName()->printOneLine( os, indent );
304 }
305 } // if
306}
307
308void DesignatorNode::print( std::ostream &os, int indent ) const {
309 if ( get_argName() ) {
310 if ( isArrayIndex ) {
311 os << "[";
312 get_argName()->print( os, indent );
313 os << "]";
314 } else {
315 os << ".";
316 get_argName()->print( os, indent );
317 }
318 } // if
319}
320
321//##############################################################################
322
[d9e2280]323static const char *OperName[] = {
[5721a6d]324 // diadic
[7bf7fb9]325 "SizeOf", "AlignOf", "OffsetOf", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
[5721a6d]326 "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
327 "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
[d9e2280]328 "?[?]", "...",
[5721a6d]329 // monadic
330 "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
331};
332
[cd623a4]333//##############################################################################
334
[064e3ff]335Expression *build_cast( TypeValueNode * arg, ExpressionNode *expr_node ) {
336 DeclarationNode *decl_node = arg->get_decl();
337
338 Type *targetType = decl_node->buildType();
339 if ( dynamic_cast< VoidType* >( targetType ) ) {
340 delete targetType;
341 return new CastExpr( maybeBuild<Expression>(expr_node) );
342 } else {
343 return new CastExpr( maybeBuild<Expression>(expr_node), targetType );
344 } // if
345}
346
347Expression *build_fieldSel( ExpressionNode *expr_node, VarRefNode *member ) {
348 NameExpr* memberExpr = dynamic_cast<NameExpr*> ( maybeBuild<Expression>( member) );
349 assert( memberExpr );
350 UntypedMemberExpr *ret = new UntypedMemberExpr( memberExpr->get_name(), maybeBuild<Expression>(expr_node) );
351 delete member;
352 return ret;
353}
354
355Expression *build_pfieldSel( ExpressionNode *expr_node, VarRefNode *member ) {
356 NameExpr* memberExpr = dynamic_cast<NameExpr*> ( maybeBuild<Expression>( member) );
357 assert( memberExpr );
358 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
359 deref->get_args().push_back( maybeBuild<Expression>(expr_node) );
360 UntypedMemberExpr *ret = new UntypedMemberExpr( memberExpr->get_name(), deref );
361 delete member;
362 return ret;
363}
364
365Expression *build_addressOf( ExpressionNode *expr_node ) {
366 return new AddressExpr( maybeBuild<Expression>(expr_node) );
367}
368Expression *build_sizeOf( ExpressionNode *expr_node ) {
369 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr_node ) ) {
370 return new SizeofExpr( arg->get_decl()->buildType() );
371 } else {
372 return new SizeofExpr( maybeBuild<Expression>(expr_node) );
373 } // if
374}
375Expression *build_alignOf( ExpressionNode *expr_node ) {
376 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr_node ) ) {
377 return new AlignofExpr( arg->get_decl()->buildType() );
378 } else {
379 return new AlignofExpr( maybeBuild<Expression>(expr_node) );
380 } // if
381}
382Expression *build_offsetOf( TypeValueNode * arg, VarRefNode *member ) {
383 NameExpr *memberExpr = dynamic_cast<NameExpr *>( maybeBuild<Expression>( member ) );
384 assert( memberExpr );
385 return new UntypedOffsetofExpr( arg->get_decl()->buildType(), memberExpr->get_name() );
386}
387
[51e076e]388Expression *build_and_or( ExpressionNode *expr_node1, ExpressionNode *expr_node2, bool kind ) {
389 return new LogicalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), notZeroExpr( maybeBuild<Expression>(expr_node2) ), kind );
390}
391
[d9e2280]392Expression *build_unary_val( OperKinds op, ExpressionNode *expr_node ) {
[9706554]393 std::list<Expression *> args;
394 args.push_back( maybeBuild<Expression>(expr_node) );
[d9e2280]395 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
[9706554]396}
[d9e2280]397Expression *build_unary_ptr( OperKinds op, ExpressionNode *expr_node ) {
[51e076e]398 std::list<Expression *> args;
399 args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node) ) );
[d9e2280]400 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
[51e076e]401}
[d9e2280]402Expression *build_binary_val( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
[51e076e]403 std::list<Expression *> args;
404 args.push_back( maybeBuild<Expression>(expr_node1) );
405 args.push_back( maybeBuild<Expression>(expr_node2) );
[d9e2280]406 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
[51e076e]407}
[d9e2280]408Expression *build_binary_ptr( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
[9706554]409 std::list<Expression *> args;
410 args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node1) ) );
411 args.push_back( maybeBuild<Expression>(expr_node2) );
[d9e2280]412 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
[9706554]413}
[51e076e]414
415Expression *build_cond( ExpressionNode *expr_node1, ExpressionNode *expr_node2, ExpressionNode *expr_node3 ) {
416 return new ConditionalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), maybeBuild<Expression>(expr_node2), maybeBuild<Expression>(expr_node3) );
417}
418
419Expression *build_comma( ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
420 return new CommaExpr( maybeBuild<Expression>(expr_node1), maybeBuild<Expression>(expr_node2) );
421}
422
[9706554]423Expression *build_attr( VarRefNode *var, ExpressionNode * expr ) {
424 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr ) ) {
425 return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType() );
426 } else {
427 return new AttrExpr( maybeBuild<Expression>(var), maybeBuild<Expression>(expr) );
428 } // if
429}
430
431Expression *build_tuple( ExpressionNode * expr ) {
432 TupleExpr *ret = new TupleExpr();
433 buildList( expr, ret->get_exprs() );
434 return ret;
435}
436
437Expression *build_func( ExpressionNode * function, ExpressionNode * expr ) {
438 std::list<Expression *> args;
439
440 buildList( expr, args );
441 return new UntypedExpr( maybeBuild<Expression>(function), args, nullptr );
442}
443
[d9e2280]444Expression *build_range( ExpressionNode * low, ExpressionNode *high ) {
445 Expression *low_cexpr = maybeBuild<Expression>( low );
446 Expression *high_cexpr = maybeBuild<Expression>( high );
447 return new RangeExpr( low_cexpr, high_cexpr );
[51b73452]448}
449
[cd623a4]450//##############################################################################
451
[7f5566b]452Expression *AsmExprNode::build() const {
[e04ef3a]453 return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) );
[7f5566b]454}
455
456void AsmExprNode::print( std::ostream &os, int indent ) const {
457 os << string( indent, ' ' ) << "Assembler Expression:" << endl;
458 if ( inout ) {
459 os << string( indent, ' ' ) << "inout: " << std::endl;
460 inout->print( os, indent + 2 );
461 } // if
462 if ( constraint ) {
463 os << string( indent, ' ' ) << "constraint: " << std::endl;
464 constraint->print( os, indent + 2 );
465 } // if
466 if ( operand ) {
467 os << string( indent, ' ' ) << "operand: " << std::endl;
468 operand->print( os, indent + 2 );
469 } // if
470}
471
472void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
473 printDesignation( os );
474 os << "( ";
475 if ( inout ) inout->printOneLine( os, indent + 2 );
476 os << ", ";
477 if ( constraint ) constraint->printOneLine( os, indent + 2 );
478 os << ", ";
479 if ( operand ) operand->printOneLine( os, indent + 2 );
480 os << ") ";
481}
482
483//##############################################################################
484
485void LabelNode::print( std::ostream &os, int indent ) const {}
486
487void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
488
489//##############################################################################
490
[bdd516a]491ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
[51b73452]492
[3848e0e]493ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
[51b73452]494}
495
496ValofExprNode::~ValofExprNode() {
[b87a5ed]497 delete body;
[51b73452]498}
499
500void ValofExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]501 printDesignation( os );
[59db689]502 os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
[b87a5ed]503 get_body()->print( os, indent + 4);
[51b73452]504}
505
[3848e0e]506void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]507 assert( false );
[51b73452]508}
509
510Expression *ValofExprNode::build() const {
[e04ef3a]511 return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) );
[3848e0e]512}
513
[cd623a4]514//##############################################################################
515
[bdd516a]516ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
[b87a5ed]517 if ( init_ == 0 )
518 init = 0;
519 else {
520 DeclarationNode *decl;
521 ExpressionNode *exp;
522
[a61fea9a]523 if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
[b87a5ed]524 init = new StatementNode( decl );
525 else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
526 init = new StatementNode( StatementNode::Exp, exp );
527 else
528 throw SemanticError("Error in for control expression");
529 }
[51b73452]530}
531
532ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
[b87a5ed]533 : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
[51b73452]534}
535
[a08ba92]536ForCtlExprNode::~ForCtlExprNode() {
[b87a5ed]537 delete init;
538 delete condition;
539 delete change;
[51b73452]540}
541
542Expression *ForCtlExprNode::build() const {
[b87a5ed]543 // this shouldn't be used!
544 assert( false );
545 return 0;
[51b73452]546}
547
548void ForCtlExprNode::print( std::ostream &os, int indent ) const{
[59db689]549 os << string( indent,' ' ) << "For Control Expression -- :" << endl;
[a61fea9a]550
[59db689]551 os << string( indent + 2, ' ' ) << "initialization:" << endl;
[a61fea9a]552 if ( init != 0 )
553 init->printList( os, indent + 4 );
554
555 os << string( indent + 2, ' ' ) << "condition: " << endl;
556 if ( condition != 0 )
557 condition->print( os, indent + 4 );
[59db689]558 os << string( indent + 2, ' ' ) << "increment: " << endl;
[a61fea9a]559 if ( change != 0 )
560 change->print( os, indent + 4 );
[51b73452]561}
562
[3848e0e]563void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]564 assert( false );
[51b73452]565}
566
[cd623a4]567//##############################################################################
568
569TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
[51b73452]570}
571
[cd623a4]572TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
[51b73452]573}
574
[3848e0e]575Expression *TypeValueNode::build() const {
[b87a5ed]576 return new TypeExpr( decl->buildType() );
[51b73452]577}
578
[bdd516a]579void TypeValueNode::print( std::ostream &os, int indent ) const {
[b87a5ed]580 os << std::string( indent, ' ' ) << "Type:";
581 get_decl()->print( os, indent + 2);
[51b73452]582}
583
[bdd516a]584void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]585 os << "Type:";
586 get_decl()->print( os, indent + 2);
[51b73452]587}
588
[630a82a]589
590CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}
591CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}
592
593CompoundLiteralNode::~CompoundLiteralNode() {
594 delete kids;
595 delete type;
596}
597
598CompoundLiteralNode *CompoundLiteralNode::clone() const {
599 return new CompoundLiteralNode( *this );
600}
601
602void CompoundLiteralNode::print( std::ostream &os, int indent ) const {
603 os << string( indent,' ' ) << "CompoundLiteralNode:" << endl;
604
605 os << string( indent + 2, ' ' ) << "type:" << endl;
606 if ( type != 0 )
607 type->print( os, indent + 4 );
608
609 os << string( indent + 2, ' ' ) << "initialization:" << endl;
610 if ( kids != 0 )
611 kids->printList( os, indent + 4 );
612}
613
614void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const {
615 os << "( ";
616 if ( type ) type->print( os );
617 os << ", ";
618 if ( kids ) kids->printOneLine( os );
619 os << ") ";
620}
621
622Expression *CompoundLiteralNode::build() const {
[e04ef3a]623 Declaration * newDecl = maybeBuild<Declaration>(type); // compound literal type
[630a82a]624 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
[e04ef3a]625 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild<Initializer>(kids) );
[630a82a]626 // these types do not have associated type information
627 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) {
[e04ef3a]628 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeBuild<Initializer>(kids) );
[630a82a]629 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) {
[e04ef3a]630 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeBuild<Initializer>(kids) );
[630a82a]631 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) {
[e04ef3a]632 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeBuild<Initializer>(kids) );
[630a82a]633 } else {
634 assert( false );
635 } // if
636}
637
[b87a5ed]638// Local Variables: //
639// tab-width: 4 //
640// mode: c++ //
641// compile-command: "make install" //
642// End: //
Note: See TracBrowser for help on using the repository browser.