source: src/Parser/ExpressionNode.cc@ ca35c51

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox memory 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 ca35c51 was ca35c51, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

move implementation of ConstantNode to ConstantExpr

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