source: src/Parser/ExpressionNode.cc@ a465caff

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 a465caff was dae881f, checked in by Thierry Delisle <tdelisle@…>, 9 years ago

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

  • Property mode set to 100644
File size: 22.8 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
[51e076e]12// Last Modified On : Fri Aug 5 07:56:23 2016
13// Update Count : 375
[0caaa6a]14//
[b87a5ed]15
[51b73452]16#include <cassert>
17#include <cctype>
18#include <algorithm>
[59db689]19#include <sstream>
20#include <cstdio>
[51b73452]21
22#include "ParseNode.h"
[630a82a]23#include "TypeData.h"
[51b73452]24#include "SynTree/Constant.h"
25#include "SynTree/Expression.h"
[630a82a]26#include "SynTree/Declaration.h"
[d3b7937]27#include "Common/UnimplementedError.h"
[51b73452]28#include "parseutility.h"
[d3b7937]29#include "Common/utility.h"
[51b73452]30
31using namespace std;
32
[e04ef3a]33ExpressionNode::ExpressionNode() : ParseNode() {}
[51b73452]34
[e04ef3a]35ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ) {}
[51b73452]36
[e04ef3a]37ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ), extension( other.extension ) {
[b87a5ed]38 if ( other.argName ) {
39 argName = other.argName->clone();
40 } else {
41 argName = 0;
42 } // if
[51b73452]43}
44
[7f5566b]45ExpressionNode * ExpressionNode::set_argName( const std::string *aName ) {
[b87a5ed]46 argName = new VarRefNode( aName );
47 return this;
[51b73452]48}
49
[7f5566b]50ExpressionNode * ExpressionNode::set_argName( ExpressionNode *aDesignator ) {
[b87a5ed]51 argName = aDesignator;
52 return this;
[51b73452]53}
54
55void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
[b87a5ed]56 if ( argName ) {
[59db689]57 os << string( indent, ' ' ) << "(designated by: ";
[b87a5ed]58 argName->printOneLine( os, indent );
59 os << ")" << std::endl;
60 } // if
[51b73452]61}
62
[cd623a4]63//##############################################################################
64
[3848e0e]65NullExprNode::NullExprNode() {}
[51b73452]66
[3848e0e]67NullExprNode *NullExprNode::clone() const {
[b87a5ed]68 return new NullExprNode();
[51b73452]69}
70
[bdd516a]71void NullExprNode::print( std::ostream & os, int indent ) const {
[b87a5ed]72 printDesignation( os );
73 os << "null expression";
[51b73452]74}
75
[bdd516a]76void NullExprNode::printOneLine( std::ostream & os, int indent ) const {
[b87a5ed]77 printDesignation( os );
78 os << "null";
[51b73452]79}
80
[3848e0e]81Expression *NullExprNode::build() const {
[b87a5ed]82 return 0;
[51b73452]83}
84
[00c32e9]85// CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) {
86// return new CommaExprNode( this, exp );
87// }
[51b73452]88
[cd623a4]89//##############################################################################
90
[ca35c51]91ConstantNode::ConstantNode( ConstantExpr *expr ) : expr( expr ) {
[59db689]92} // ConstantNode::ConstantNode
[51b73452]93
[59db689]94ConstantNode *ConstantNode::appendstr( const std::string *newValue ) {
95 assert( newValue != 0 );
[59c24b6]96
[ca35c51]97 string value = expr->get_constant()->get_value();
[51b73452]98
[7f5566b]99 // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string.
[59db689]100 value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) );
[59c24b6]101 expr->get_constant()->set_value( value );
[0caaa6a]102
[cd623a4]103 delete newValue; // allocated by lexer
[b87a5ed]104 return this;
[51b73452]105}
106
[bdd516a]107void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
[ca35c51]108 // os << string( indent, ' ' );
109 // printDesignation( os );
110
111 // switch ( type ) {
112 // case Integer:
113 // case Float:
114 // os << value ;
115 // break;
116 // case Character:
117 // os << "'" << value << "'";
118 // break;
119 // case String:
120 // os << '"' << value << '"';
121 // break;
122 // } // switch
[b87a5ed]123
[ca35c51]124 // os << ' ';
[51b73452]125}
126
[bdd516a]127void ConstantNode::print( std::ostream &os, int indent ) const {
[b87a5ed]128 printOneLine( os, indent );
129 os << endl;
[51b73452]130}
131
132Expression *ConstantNode::build() const {
[ca35c51]133 return expr->clone();
[51b73452]134}
135
[cd623a4]136//##############################################################################
137
[bdd516a]138VarRefNode::VarRefNode() : isLabel( false ) {}
[51b73452]139
[59db689]140VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {}
[51b73452]141
[3848e0e]142VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
[51b73452]143}
144
145Expression *VarRefNode::build() const {
[b87a5ed]146 return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
[51b73452]147}
148
[bdd516a]149void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]150 printDesignation( os );
151 os << get_name() << ' ';
[51b73452]152}
153
[bdd516a]154void VarRefNode::print( std::ostream &os, int indent ) const {
[b87a5ed]155 printDesignation( os );
[44b5ca0]156 os << string( indent, ' ' ) << "Referencing: ";
[b87a5ed]157 os << "Variable: " << get_name();
158 os << endl;
[51b73452]159}
160
[cd623a4]161//##############################################################################
162
[51b1202]163DesignatorNode::DesignatorNode( ExpressionNode *expr, bool isArrayIndex ) : isArrayIndex( isArrayIndex ) {
164 set_argName( expr );
[e869d663]165 assert( get_argName() );
166
167 if ( ! isArrayIndex ) {
168 if ( VarRefNode * var = dynamic_cast< VarRefNode * >( expr ) ) {
169
170 stringstream ss( var->get_name() );
171 double value;
172 if ( ss >> value ) {
173 // this is a floating point constant. It MUST be
174 // ".0" or ".1", otherwise the program is invalid
175 if ( ! (var->get_name() == ".0" || var->get_name() == ".1") ) {
176 throw SemanticError( "invalid designator name: " + var->get_name() );
177 } // if
178 var->set_name( var->get_name().substr(1) );
179 } // if
180 } // if
181 } // if
[51b1202]182}
183
184DesignatorNode::DesignatorNode( const DesignatorNode &other ) : ExpressionNode( other ), isArrayIndex( other.isArrayIndex ) {
185}
186
[e869d663]187class DesignatorFixer : public Mutator {
188public:
189 virtual Expression* mutate( NameExpr *nameExpr ) {
190 if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
191 Constant val( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nameExpr->get_name() );
192 delete nameExpr;
193 return new ConstantExpr( val );
194 }
195 return nameExpr;
196 }
197};
198
[51b1202]199Expression *DesignatorNode::build() const {
[e04ef3a]200 Expression * ret = maybeBuild<Expression>(get_argName());
[e869d663]201
[51b1202]202 if ( isArrayIndex ) {
[0caaa6a]203 // need to traverse entire structure and change any instances of 0 or 1 to
[e869d663]204 // ConstantExpr
205 DesignatorFixer fixer;
206 ret = ret->acceptMutator( fixer );
[51b1202]207 } // if
[e869d663]208
209 return ret;
[51b1202]210}
211
212void DesignatorNode::printOneLine( std::ostream &os, int indent ) const {
213 if ( get_argName() ) {
214 if ( isArrayIndex ) {
215 os << "[";
216 get_argName()->printOneLine( os, indent );
217 os << "]";
218 } else {
219 os << ".";
220 get_argName()->printOneLine( os, indent );
221 }
222 } // if
223}
224
225void DesignatorNode::print( std::ostream &os, int indent ) const {
226 if ( get_argName() ) {
227 if ( isArrayIndex ) {
228 os << "[";
229 get_argName()->print( os, indent );
230 os << "]";
231 } else {
232 os << ".";
233 get_argName()->print( os, indent );
234 }
235 } // if
236}
237
238//##############################################################################
239
[5721a6d]240static const char *opName[] = {
241 "TupleC", "Comma", "TupleFieldSel", // "TuplePFieldSel", // n-adic
242 // triadic
243 "Cond", "NCond",
244 // diadic
[e04ef3a]245 "SizeOf", "AlignOf", "OffsetOf", "Attr", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
[5721a6d]246 "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
247 "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
[8688ce1]248 "?[?]", "FieldSel", "PFieldSel", "...",
[5721a6d]249 // monadic
250 "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
251};
252
[bdd516a]253OperatorNode::OperatorNode( Type t ) : type( t ) {}
[51b73452]254
[3848e0e]255OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
[51b73452]256}
257
258OperatorNode::~OperatorNode() {}
259
[064e3ff]260OperatorNode::Type OperatorNode::get_type( void ) const {
[b87a5ed]261 return type;
[51b73452]262}
263
[3848e0e]264void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]265 printDesignation( os );
[5721a6d]266 os << opName[ type ] << ' ';
[51b73452]267}
268
269void OperatorNode::print( std::ostream &os, int indent ) const{
[b87a5ed]270 printDesignation( os );
[5721a6d]271 os << string( indent, ' ' ) << "Operator: " << opName[type] << endl;
[b87a5ed]272 return;
[51b73452]273}
274
[59db689]275const char *OperatorNode::get_typename( void ) const{
[5721a6d]276 return opName[ type ];
[51b73452]277}
278
[cd623a4]279//##############################################################################
280
[7f5566b]281CompositeExprNode::CompositeExprNode() : ExpressionNode(), function( 0 ), arguments( 0 ) {
[51b73452]282}
283
[59db689]284CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) {
[51b73452]285}
286
[bdd516a]287CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ):
[b87a5ed]288 function( f ), arguments( args ) {
[51b73452]289}
290
[bdd516a]291CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
[097e2b0]292 function( f ), arguments( arg1 ) {
293 arguments->set_link( arg2 );
[51b73452]294}
295
[0caaa6a]296CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ), arguments( 0 ) {
[b87a5ed]297 ParseNode *cur = other.arguments;
298 while ( cur ) {
299 if ( arguments ) {
300 arguments->set_link( cur->clone() );
301 } else {
302 arguments = ( ExpressionNode*)cur->clone();
303 } // if
304 cur = cur->get_link();
305 }
[51b73452]306}
307
[3848e0e]308CompositeExprNode::~CompositeExprNode() {
[b87a5ed]309 delete function;
310 delete arguments;
[51b73452]311}
312
[064e3ff]313
314Expression *build_cast( TypeValueNode * arg, ExpressionNode *expr_node ) {
315 DeclarationNode *decl_node = arg->get_decl();
316
317 Type *targetType = decl_node->buildType();
318 if ( dynamic_cast< VoidType* >( targetType ) ) {
319 delete targetType;
320 return new CastExpr( maybeBuild<Expression>(expr_node) );
321 } else {
322 return new CastExpr( maybeBuild<Expression>(expr_node), targetType );
323 } // if
324}
325
326Expression *build_fieldSel( ExpressionNode *expr_node, VarRefNode *member ) {
327 NameExpr* memberExpr = dynamic_cast<NameExpr*> ( maybeBuild<Expression>( member) );
328 assert( memberExpr );
329 UntypedMemberExpr *ret = new UntypedMemberExpr( memberExpr->get_name(), maybeBuild<Expression>(expr_node) );
330 delete member;
331 return ret;
332}
333
334Expression *build_pfieldSel( ExpressionNode *expr_node, VarRefNode *member ) {
335 NameExpr* memberExpr = dynamic_cast<NameExpr*> ( maybeBuild<Expression>( member) );
336 assert( memberExpr );
337 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
338 deref->get_args().push_back( maybeBuild<Expression>(expr_node) );
339 UntypedMemberExpr *ret = new UntypedMemberExpr( memberExpr->get_name(), deref );
340 delete member;
341 return ret;
342}
343
344Expression *build_addressOf( ExpressionNode *expr_node ) {
345 return new AddressExpr( maybeBuild<Expression>(expr_node) );
346}
347Expression *build_sizeOf( ExpressionNode *expr_node ) {
348 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr_node ) ) {
349 return new SizeofExpr( arg->get_decl()->buildType() );
350 } else {
351 return new SizeofExpr( maybeBuild<Expression>(expr_node) );
352 } // if
353}
354Expression *build_alignOf( ExpressionNode *expr_node ) {
355 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr_node ) ) {
356 return new AlignofExpr( arg->get_decl()->buildType() );
357 } else {
358 return new AlignofExpr( maybeBuild<Expression>(expr_node) );
359 } // if
360}
361Expression *build_offsetOf( TypeValueNode * arg, VarRefNode *member ) {
362 NameExpr *memberExpr = dynamic_cast<NameExpr *>( maybeBuild<Expression>( member ) );
363 assert( memberExpr );
364 return new UntypedOffsetofExpr( arg->get_decl()->buildType(), memberExpr->get_name() );
365}
366
[51e076e]367Expression *build_and_or( ExpressionNode *expr_node1, ExpressionNode *expr_node2, bool kind ) {
368 return new LogicalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), notZeroExpr( maybeBuild<Expression>(expr_node2) ), kind );
369}
370
371Expression *build_opr1( OperatorNode::Type op, ExpressionNode *expr_node ) {
372 std::list<Expression *> args;
373 args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node) ) );
374 return new UntypedExpr( new NameExpr( opName[ op ] ), args );
375}
376Expression *build_opr2( OperatorNode::Type op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
377 std::list<Expression *> args;
378 args.push_back( maybeBuild<Expression>(expr_node1) );
379 args.push_back( maybeBuild<Expression>(expr_node2) );
380 return new UntypedExpr( new NameExpr( opName[ op ] ), args );
381}
382
383Expression *build_cond( ExpressionNode *expr_node1, ExpressionNode *expr_node2, ExpressionNode *expr_node3 ) {
384 return new ConditionalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), maybeBuild<Expression>(expr_node2), maybeBuild<Expression>(expr_node3) );
385}
386
387Expression *build_comma( ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
388 return new CommaExpr( maybeBuild<Expression>(expr_node1), maybeBuild<Expression>(expr_node2) );
389}
390
[064e3ff]391CompositeExprNode2::CompositeExprNode2( Expression *expr ) : expr( expr ) {}
392CompositeExprNode2::CompositeExprNode2( const CompositeExprNode2 &other ) : expr( other.expr->clone() ) {}
393CompositeExprNode2::~CompositeExprNode2() { delete expr; }
394void CompositeExprNode2::print( std::ostream &, int indent ) const { assert( false ); }
395void CompositeExprNode2::printOneLine( std::ostream &, int indent ) const { assert( false ); }
396
[51b73452]397
[3848e0e]398Expression *CompositeExprNode::build() const {
[b87a5ed]399 OperatorNode *op;
400 std::list<Expression *> args;
[51b73452]401
[b87a5ed]402 buildList( get_args(), args );
403
[cd623a4]404 if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator
[e04ef3a]405 return new UntypedExpr( maybeBuild<Expression>(function), args, maybeBuild< Expression >( get_argName() ));
[cd623a4]406 } // if
[b87a5ed]407
[51e076e]408 switch ( op->get_type() ) {
[cd623a4]409 case OperatorNode::Assign:
410 case OperatorNode::MulAssn:
411 case OperatorNode::DivAssn:
412 case OperatorNode::ModAssn:
413 case OperatorNode::PlusAssn:
414 case OperatorNode::MinusAssn:
415 case OperatorNode::LSAssn:
416 case OperatorNode::RSAssn:
417 case OperatorNode::AndAssn:
418 case OperatorNode::ERAssn:
419 case OperatorNode::OrAssn:
420 assert( ! args.empty() );
421 args.front() = new AddressExpr( args.front() );
422 case OperatorNode::UnPlus:
423 case OperatorNode::UnMinus:
424 case OperatorNode::PointTo:
425 case OperatorNode::Neg:
426 case OperatorNode::BitNeg:
427 case OperatorNode::LabelAddress:
[5721a6d]428 return new UntypedExpr( new NameExpr( opName[ op->get_type() ] ), args );
[cd623a4]429
430 case OperatorNode::Attr:
431 {
[51e076e]432 VarRefNode *var = dynamic_cast<VarRefNode *>( get_args() );
[cd623a4]433 assert( var );
434 if ( ! get_args()->get_link() ) {
[e04ef3a]435 return new AttrExpr( maybeBuild<Expression>(var), ( Expression*)0);
[51e076e]436 } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link() ) ) {
437 return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType() );
[cd623a4]438 } else {
[51e076e]439 return new AttrExpr( maybeBuild<Expression>(var), args.back() );
[cd623a4]440 } // if
441 }
442 case OperatorNode::Cond:
443 {
444 assert( args.size() == 3);
[7f5566b]445 std::list< Expression * >::const_iterator i = args.begin();
[cd623a4]446 Expression *arg1 = notZeroExpr( *i++ );
447 Expression *arg2 = *i++;
448 Expression *arg3 = *i++;
449 return new ConditionalExpr( arg1, arg2, arg3 );
450 }
451 case OperatorNode::NCond:
452 throw UnimplementedError( "GNU 2-argument conditional expression" );
453 // Tuples
454 case OperatorNode::TupleC:
455 {
456 TupleExpr *ret = new TupleExpr();
457 std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
458 return ret;
459 }
460 default:
[51e076e]461 assert( ((void)"CompositeExprNode::build", false) );
[cd623a4]462 return 0;
463 } // switch
[51b73452]464}
465
[bdd516a]466void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]467 printDesignation( os );
468 os << "( ";
469 function->printOneLine( os, indent );
470 for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
471 cur->printOneLine( os, indent );
[5721a6d]472 } // for
[b87a5ed]473 os << ") ";
[51b73452]474}
475
[bdd516a]476void CompositeExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]477 printDesignation( os );
[44b5ca0]478 os << string( indent, ' ' ) << "Application of: " << endl;
[b87a5ed]479 function->print( os, indent + ParseNode::indent_by );
[51b73452]480
[44b5ca0]481 os << string( indent, ' ' ) ;
[b87a5ed]482 if ( arguments ) {
483 os << "... on arguments: " << endl;
484 arguments->printList( os, indent + ParseNode::indent_by );
485 } else
486 os << "... on no arguments: " << endl;
[51b73452]487}
488
[a08ba92]489void CompositeExprNode::set_function( ExpressionNode *f ) {
[b87a5ed]490 function = f;
[51b73452]491}
492
[a08ba92]493void CompositeExprNode::set_args( ExpressionNode *args ) {
[b87a5ed]494 arguments = args;
[51b73452]495}
496
[bdd516a]497ExpressionNode *CompositeExprNode::get_function( void ) const {
[b87a5ed]498 return function;
[51b73452]499}
500
[bdd516a]501ExpressionNode *CompositeExprNode::get_args( void ) const {
[b87a5ed]502 return arguments;
[51b73452]503}
504
[a08ba92]505void CompositeExprNode::add_arg( ExpressionNode *arg ) {
[b87a5ed]506 if ( arguments )
507 arguments->set_link( arg );
508 else
509 set_args( arg );
[51b73452]510}
511
[cd623a4]512//##############################################################################
513
[7f5566b]514Expression *AsmExprNode::build() const {
[e04ef3a]515 return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) );
[7f5566b]516}
517
518void AsmExprNode::print( std::ostream &os, int indent ) const {
519 os << string( indent, ' ' ) << "Assembler Expression:" << endl;
520 if ( inout ) {
521 os << string( indent, ' ' ) << "inout: " << std::endl;
522 inout->print( os, indent + 2 );
523 } // if
524 if ( constraint ) {
525 os << string( indent, ' ' ) << "constraint: " << std::endl;
526 constraint->print( os, indent + 2 );
527 } // if
528 if ( operand ) {
529 os << string( indent, ' ' ) << "operand: " << std::endl;
530 operand->print( os, indent + 2 );
531 } // if
532}
533
534void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
535 printDesignation( os );
536 os << "( ";
537 if ( inout ) inout->printOneLine( os, indent + 2 );
538 os << ", ";
539 if ( constraint ) constraint->printOneLine( os, indent + 2 );
540 os << ", ";
541 if ( operand ) operand->printOneLine( os, indent + 2 );
542 os << ") ";
543}
544
545//##############################################################################
546
547void LabelNode::print( std::ostream &os, int indent ) const {}
548
549void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
550
551//##############################################################################
552
[bdd516a]553ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
[51b73452]554
[3848e0e]555ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
[51b73452]556}
557
558ValofExprNode::~ValofExprNode() {
[b87a5ed]559 delete body;
[51b73452]560}
561
562void ValofExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]563 printDesignation( os );
[59db689]564 os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
[b87a5ed]565 get_body()->print( os, indent + 4);
[51b73452]566}
567
[3848e0e]568void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]569 assert( false );
[51b73452]570}
571
572Expression *ValofExprNode::build() const {
[e04ef3a]573 return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) );
[3848e0e]574}
575
[cd623a4]576//##############################################################################
577
[bdd516a]578ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
[b87a5ed]579 if ( init_ == 0 )
580 init = 0;
581 else {
582 DeclarationNode *decl;
583 ExpressionNode *exp;
584
[a61fea9a]585 if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
[b87a5ed]586 init = new StatementNode( decl );
587 else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
588 init = new StatementNode( StatementNode::Exp, exp );
589 else
590 throw SemanticError("Error in for control expression");
591 }
[51b73452]592}
593
594ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
[b87a5ed]595 : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
[51b73452]596}
597
[a08ba92]598ForCtlExprNode::~ForCtlExprNode() {
[b87a5ed]599 delete init;
600 delete condition;
601 delete change;
[51b73452]602}
603
604Expression *ForCtlExprNode::build() const {
[b87a5ed]605 // this shouldn't be used!
606 assert( false );
607 return 0;
[51b73452]608}
609
610void ForCtlExprNode::print( std::ostream &os, int indent ) const{
[59db689]611 os << string( indent,' ' ) << "For Control Expression -- :" << endl;
[a61fea9a]612
[59db689]613 os << string( indent + 2, ' ' ) << "initialization:" << endl;
[a61fea9a]614 if ( init != 0 )
615 init->printList( os, indent + 4 );
616
617 os << string( indent + 2, ' ' ) << "condition: " << endl;
618 if ( condition != 0 )
619 condition->print( os, indent + 4 );
[59db689]620 os << string( indent + 2, ' ' ) << "increment: " << endl;
[a61fea9a]621 if ( change != 0 )
622 change->print( os, indent + 4 );
[51b73452]623}
624
[3848e0e]625void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]626 assert( false );
[51b73452]627}
628
[cd623a4]629//##############################################################################
630
631TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
[51b73452]632}
633
[cd623a4]634TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
[51b73452]635}
636
[3848e0e]637Expression *TypeValueNode::build() const {
[b87a5ed]638 return new TypeExpr( decl->buildType() );
[51b73452]639}
640
[bdd516a]641void TypeValueNode::print( std::ostream &os, int indent ) const {
[b87a5ed]642 os << std::string( indent, ' ' ) << "Type:";
643 get_decl()->print( os, indent + 2);
[51b73452]644}
645
[bdd516a]646void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]647 os << "Type:";
648 get_decl()->print( os, indent + 2);
[51b73452]649}
650
[630a82a]651
652CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}
653CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}
654
655CompoundLiteralNode::~CompoundLiteralNode() {
656 delete kids;
657 delete type;
658}
659
660CompoundLiteralNode *CompoundLiteralNode::clone() const {
661 return new CompoundLiteralNode( *this );
662}
663
664void CompoundLiteralNode::print( std::ostream &os, int indent ) const {
665 os << string( indent,' ' ) << "CompoundLiteralNode:" << endl;
666
667 os << string( indent + 2, ' ' ) << "type:" << endl;
668 if ( type != 0 )
669 type->print( os, indent + 4 );
670
671 os << string( indent + 2, ' ' ) << "initialization:" << endl;
672 if ( kids != 0 )
673 kids->printList( os, indent + 4 );
674}
675
676void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const {
677 os << "( ";
678 if ( type ) type->print( os );
679 os << ", ";
680 if ( kids ) kids->printOneLine( os );
681 os << ") ";
682}
683
684Expression *CompoundLiteralNode::build() const {
[e04ef3a]685 Declaration * newDecl = maybeBuild<Declaration>(type); // compound literal type
[630a82a]686 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
[e04ef3a]687 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild<Initializer>(kids) );
[630a82a]688 // these types do not have associated type information
689 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) {
[e04ef3a]690 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeBuild<Initializer>(kids) );
[630a82a]691 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) {
[e04ef3a]692 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeBuild<Initializer>(kids) );
[630a82a]693 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) {
[e04ef3a]694 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeBuild<Initializer>(kids) );
[630a82a]695 } else {
696 assert( false );
697 } // if
698}
699
[3848e0e]700ExpressionNode *flattenCommas( ExpressionNode *list ) {
[cd623a4]701 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
702 OperatorNode *op;
703 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
704 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
705 composite->add_arg( next );
706 return flattenCommas( composite->get_args() );
707 } // if
708 } // if
[51b73452]709
[b87a5ed]710 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
711 list->set_next( flattenCommas( next ) );
[51b73452]712
[b87a5ed]713 return list;
[51b73452]714}
715
[3848e0e]716ExpressionNode *tupleContents( ExpressionNode *tuple ) {
[b87a5ed]717 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
718 OperatorNode *op = 0;
719 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
720 return composite->get_args();
[cd623a4]721 } // if
[b87a5ed]722 return tuple;
[51b73452]723}
[b87a5ed]724
725// Local Variables: //
726// tab-width: 4 //
727// mode: c++ //
728// compile-command: "make install" //
729// End: //
Note: See TracBrowser for help on using the repository browser.