source: src/Parser/ExpressionNode.cc@ 064e3ff

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

add new type for ranges and refactor parser code

  • Property mode set to 100644
File size: 23.8 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 Aug 4 16:11:23 2016
13// Update Count : 338
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
97 string value = expr->get_constant()->get_value();
98
99 // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string.
100 value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) );
101 expr->get_constant()->set_value( value );
102
103 delete newValue; // allocated by lexer
104 return this;
105}
106
107void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
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
123
124 // os << ' ';
125}
126
127void ConstantNode::print( std::ostream &os, int indent ) const {
128 printOneLine( os, indent );
129 os << endl;
130}
131
132Expression *ConstantNode::build() const {
133 return expr->clone();
134}
135
136//##############################################################################
137
138VarRefNode::VarRefNode() : isLabel( false ) {}
139
140VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {}
141
142VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
143}
144
145Expression *VarRefNode::build() const {
146 return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
147}
148
149void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
150 printDesignation( os );
151 os << get_name() << ' ';
152}
153
154void VarRefNode::print( std::ostream &os, int indent ) const {
155 printDesignation( os );
156 os << string( indent, ' ' ) << "Referencing: ";
157 os << "Variable: " << get_name();
158 os << endl;
159}
160
161//##############################################################################
162
163DesignatorNode::DesignatorNode( ExpressionNode *expr, bool isArrayIndex ) : isArrayIndex( isArrayIndex ) {
164 set_argName( expr );
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
182}
183
184DesignatorNode::DesignatorNode( const DesignatorNode &other ) : ExpressionNode( other ), isArrayIndex( other.isArrayIndex ) {
185}
186
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
199Expression *DesignatorNode::build() const {
200 Expression * ret = maybeBuild<Expression>(get_argName());
201
202 if ( isArrayIndex ) {
203 // need to traverse entire structure and change any instances of 0 or 1 to
204 // ConstantExpr
205 DesignatorFixer fixer;
206 ret = ret->acceptMutator( fixer );
207 } // if
208
209 return ret;
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
240static const char *opName[] = {
241 "TupleC", "Comma", "TupleFieldSel", // "TuplePFieldSel", // n-adic
242 // triadic
243 "Cond", "NCond",
244 // diadic
245 "SizeOf", "AlignOf", "OffsetOf", "Attr", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
246 "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
247 "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
248 "?[?]", "FieldSel", "PFieldSel", "...",
249 // monadic
250 "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
251};
252
253OperatorNode::OperatorNode( Type t ) : type( t ) {}
254
255OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
256}
257
258OperatorNode::~OperatorNode() {}
259
260OperatorNode::Type OperatorNode::get_type( void ) const {
261 return type;
262}
263
264void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
265 printDesignation( os );
266 os << opName[ type ] << ' ';
267}
268
269void OperatorNode::print( std::ostream &os, int indent ) const{
270 printDesignation( os );
271 os << string( indent, ' ' ) << "Operator: " << opName[type] << endl;
272 return;
273}
274
275const char *OperatorNode::get_typename( void ) const{
276 return opName[ type ];
277}
278
279//##############################################################################
280
281CompositeExprNode::CompositeExprNode() : ExpressionNode(), function( 0 ), arguments( 0 ) {
282}
283
284CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) {
285}
286
287CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ):
288 function( f ), arguments( args ) {
289}
290
291CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
292 function( f ), arguments( arg1 ) {
293 arguments->set_link( arg2 );
294}
295
296CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ), arguments( 0 ) {
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 }
306}
307
308CompositeExprNode::~CompositeExprNode() {
309 delete function;
310 delete arguments;
311}
312
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
367CompositeExprNode2::CompositeExprNode2( Expression *expr ) : expr( expr ) {}
368CompositeExprNode2::CompositeExprNode2( const CompositeExprNode2 &other ) : expr( other.expr->clone() ) {}
369CompositeExprNode2::~CompositeExprNode2() { delete expr; }
370void CompositeExprNode2::print( std::ostream &, int indent ) const { assert( false ); }
371void CompositeExprNode2::printOneLine( std::ostream &, int indent ) const { assert( false ); }
372
373
374Expression *CompositeExprNode::build() const {
375 OperatorNode *op;
376 std::list<Expression *> args;
377
378 buildList( get_args(), args );
379
380 if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator
381 return new UntypedExpr( maybeBuild<Expression>(function), args, maybeBuild< Expression >( get_argName() ));
382 } // if
383
384 switch ( op->get_type()) {
385 case OperatorNode::Incr:
386 case OperatorNode::Decr:
387 case OperatorNode::IncrPost:
388 case OperatorNode::DecrPost:
389 case OperatorNode::Assign:
390 case OperatorNode::MulAssn:
391 case OperatorNode::DivAssn:
392 case OperatorNode::ModAssn:
393 case OperatorNode::PlusAssn:
394 case OperatorNode::MinusAssn:
395 case OperatorNode::LSAssn:
396 case OperatorNode::RSAssn:
397 case OperatorNode::AndAssn:
398 case OperatorNode::ERAssn:
399 case OperatorNode::OrAssn:
400 // the rewrite rules for these expressions specify that the first argument has its address taken
401 assert( ! args.empty() );
402 args.front() = new AddressExpr( args.front() );
403 break;
404 default: // do nothing
405 ;
406 } // switch
407
408 switch ( op->get_type() ) {
409 case OperatorNode::Incr:
410 case OperatorNode::Decr:
411 case OperatorNode::IncrPost:
412 case OperatorNode::DecrPost:
413 case OperatorNode::Assign:
414 case OperatorNode::MulAssn:
415 case OperatorNode::DivAssn:
416 case OperatorNode::ModAssn:
417 case OperatorNode::PlusAssn:
418 case OperatorNode::MinusAssn:
419 case OperatorNode::LSAssn:
420 case OperatorNode::RSAssn:
421 case OperatorNode::AndAssn:
422 case OperatorNode::ERAssn:
423 case OperatorNode::OrAssn:
424 case OperatorNode::Plus:
425 case OperatorNode::Minus:
426 case OperatorNode::Mul:
427 case OperatorNode::Div:
428 case OperatorNode::Mod:
429 case OperatorNode::BitOr:
430 case OperatorNode::BitAnd:
431 case OperatorNode::Xor:
432 case OperatorNode::LShift:
433 case OperatorNode::RShift:
434 case OperatorNode::LThan:
435 case OperatorNode::GThan:
436 case OperatorNode::LEThan:
437 case OperatorNode::GEThan:
438 case OperatorNode::Eq:
439 case OperatorNode::Neq:
440 case OperatorNode::Index:
441 case OperatorNode::Range:
442 case OperatorNode::UnPlus:
443 case OperatorNode::UnMinus:
444 case OperatorNode::PointTo:
445 case OperatorNode::Neg:
446 case OperatorNode::BitNeg:
447 case OperatorNode::LabelAddress:
448 return new UntypedExpr( new NameExpr( opName[ op->get_type() ] ), args );
449 case OperatorNode::Attr:
450 {
451 VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
452 assert( var );
453 if ( ! get_args()->get_link() ) {
454 return new AttrExpr( maybeBuild<Expression>(var), ( Expression*)0);
455 } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
456 return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType());
457 } else {
458 return new AttrExpr( maybeBuild<Expression>(var), args.back());
459 } // if
460 }
461 case OperatorNode::Or:
462 case OperatorNode::And:
463 assert( args.size() == 2);
464 return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
465 case OperatorNode::Cond:
466 {
467 assert( args.size() == 3);
468 std::list< Expression * >::const_iterator i = args.begin();
469 Expression *arg1 = notZeroExpr( *i++ );
470 Expression *arg2 = *i++;
471 Expression *arg3 = *i++;
472 return new ConditionalExpr( arg1, arg2, arg3 );
473 }
474 case OperatorNode::NCond:
475 throw UnimplementedError( "GNU 2-argument conditional expression" );
476 case OperatorNode::Comma:
477 {
478 assert( args.size() == 2);
479 std::list< Expression * >::const_iterator i = args.begin();
480 Expression *ret = *i++;
481 while ( i != args.end() ) {
482 ret = new CommaExpr( ret, *i++ );
483 }
484 return ret;
485 }
486 // Tuples
487 case OperatorNode::TupleC:
488 {
489 TupleExpr *ret = new TupleExpr();
490 std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
491 return ret;
492 }
493 default:
494 // shouldn't happen
495 assert( false );
496 return 0;
497 } // switch
498}
499
500void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
501 printDesignation( os );
502 os << "( ";
503 function->printOneLine( os, indent );
504 for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
505 cur->printOneLine( os, indent );
506 } // for
507 os << ") ";
508}
509
510void CompositeExprNode::print( std::ostream &os, int indent ) const {
511 printDesignation( os );
512 os << string( indent, ' ' ) << "Application of: " << endl;
513 function->print( os, indent + ParseNode::indent_by );
514
515 os << string( indent, ' ' ) ;
516 if ( arguments ) {
517 os << "... on arguments: " << endl;
518 arguments->printList( os, indent + ParseNode::indent_by );
519 } else
520 os << "... on no arguments: " << endl;
521}
522
523void CompositeExprNode::set_function( ExpressionNode *f ) {
524 function = f;
525}
526
527void CompositeExprNode::set_args( ExpressionNode *args ) {
528 arguments = args;
529}
530
531ExpressionNode *CompositeExprNode::get_function( void ) const {
532 return function;
533}
534
535ExpressionNode *CompositeExprNode::get_args( void ) const {
536 return arguments;
537}
538
539void CompositeExprNode::add_arg( ExpressionNode *arg ) {
540 if ( arguments )
541 arguments->set_link( arg );
542 else
543 set_args( arg );
544}
545
546//##############################################################################
547
548Expression *AsmExprNode::build() const {
549 return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) );
550}
551
552void AsmExprNode::print( std::ostream &os, int indent ) const {
553 os << string( indent, ' ' ) << "Assembler Expression:" << endl;
554 if ( inout ) {
555 os << string( indent, ' ' ) << "inout: " << std::endl;
556 inout->print( os, indent + 2 );
557 } // if
558 if ( constraint ) {
559 os << string( indent, ' ' ) << "constraint: " << std::endl;
560 constraint->print( os, indent + 2 );
561 } // if
562 if ( operand ) {
563 os << string( indent, ' ' ) << "operand: " << std::endl;
564 operand->print( os, indent + 2 );
565 } // if
566}
567
568void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
569 printDesignation( os );
570 os << "( ";
571 if ( inout ) inout->printOneLine( os, indent + 2 );
572 os << ", ";
573 if ( constraint ) constraint->printOneLine( os, indent + 2 );
574 os << ", ";
575 if ( operand ) operand->printOneLine( os, indent + 2 );
576 os << ") ";
577}
578
579//##############################################################################
580
581void LabelNode::print( std::ostream &os, int indent ) const {}
582
583void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
584
585//##############################################################################
586
587CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
588
589CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
590}
591
592CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
593}
594
595CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
596 add_arg( exp );
597
598 return this;
599}
600
601CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
602}
603
604//##############################################################################
605
606ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
607
608ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
609}
610
611ValofExprNode::~ValofExprNode() {
612 delete body;
613}
614
615void ValofExprNode::print( std::ostream &os, int indent ) const {
616 printDesignation( os );
617 os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
618 get_body()->print( os, indent + 4);
619}
620
621void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
622 assert( false );
623}
624
625Expression *ValofExprNode::build() const {
626 return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) );
627}
628
629//##############################################################################
630
631ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
632 if ( init_ == 0 )
633 init = 0;
634 else {
635 DeclarationNode *decl;
636 ExpressionNode *exp;
637
638 if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
639 init = new StatementNode( decl );
640 else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
641 init = new StatementNode( StatementNode::Exp, exp );
642 else
643 throw SemanticError("Error in for control expression");
644 }
645}
646
647ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
648 : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
649}
650
651ForCtlExprNode::~ForCtlExprNode() {
652 delete init;
653 delete condition;
654 delete change;
655}
656
657Expression *ForCtlExprNode::build() const {
658 // this shouldn't be used!
659 assert( false );
660 return 0;
661}
662
663void ForCtlExprNode::print( std::ostream &os, int indent ) const{
664 os << string( indent,' ' ) << "For Control Expression -- :" << endl;
665
666 os << string( indent + 2, ' ' ) << "initialization:" << endl;
667 if ( init != 0 )
668 init->printList( os, indent + 4 );
669
670 os << string( indent + 2, ' ' ) << "condition: " << endl;
671 if ( condition != 0 )
672 condition->print( os, indent + 4 );
673 os << string( indent + 2, ' ' ) << "increment: " << endl;
674 if ( change != 0 )
675 change->print( os, indent + 4 );
676}
677
678void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
679 assert( false );
680}
681
682//##############################################################################
683
684TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
685}
686
687TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
688}
689
690Expression *TypeValueNode::build() const {
691 return new TypeExpr( decl->buildType() );
692}
693
694void TypeValueNode::print( std::ostream &os, int indent ) const {
695 os << std::string( indent, ' ' ) << "Type:";
696 get_decl()->print( os, indent + 2);
697}
698
699void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
700 os << "Type:";
701 get_decl()->print( os, indent + 2);
702}
703
704
705CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}
706CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}
707
708CompoundLiteralNode::~CompoundLiteralNode() {
709 delete kids;
710 delete type;
711}
712
713CompoundLiteralNode *CompoundLiteralNode::clone() const {
714 return new CompoundLiteralNode( *this );
715}
716
717void CompoundLiteralNode::print( std::ostream &os, int indent ) const {
718 os << string( indent,' ' ) << "CompoundLiteralNode:" << endl;
719
720 os << string( indent + 2, ' ' ) << "type:" << endl;
721 if ( type != 0 )
722 type->print( os, indent + 4 );
723
724 os << string( indent + 2, ' ' ) << "initialization:" << endl;
725 if ( kids != 0 )
726 kids->printList( os, indent + 4 );
727}
728
729void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const {
730 os << "( ";
731 if ( type ) type->print( os );
732 os << ", ";
733 if ( kids ) kids->printOneLine( os );
734 os << ") ";
735}
736
737Expression *CompoundLiteralNode::build() const {
738 Declaration * newDecl = maybeBuild<Declaration>(type); // compound literal type
739 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
740 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild<Initializer>(kids) );
741 // these types do not have associated type information
742 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) {
743 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeBuild<Initializer>(kids) );
744 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) {
745 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeBuild<Initializer>(kids) );
746 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) {
747 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeBuild<Initializer>(kids) );
748 } else {
749 assert( false );
750 } // if
751}
752
753ExpressionNode *flattenCommas( ExpressionNode *list ) {
754 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
755 OperatorNode *op;
756 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
757 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
758 composite->add_arg( next );
759 return flattenCommas( composite->get_args() );
760 } // if
761 } // if
762
763 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
764 list->set_next( flattenCommas( next ) );
765
766 return list;
767}
768
769ExpressionNode *tupleContents( ExpressionNode *tuple ) {
770 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
771 OperatorNode *op = 0;
772 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
773 return composite->get_args();
774 } // if
775 return tuple;
776}
777
778// Local Variables: //
779// tab-width: 4 //
780// mode: c++ //
781// compile-command: "make install" //
782// End: //
Note: See TracBrowser for help on using the repository browser.