source: src/Parser/ExpressionNode.cc@ 7bf7fb9

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 7bf7fb9 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
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 : Sun Aug 7 09:23:12 2016
13// Update Count : 437
14//
15
16#include <cassert>
17#include <cctype>
18#include <climits>
19#include <cstdio>
20#include <algorithm>
21#include <sstream>
22
23#include "ParseNode.h"
24#include "TypeData.h"
25#include "SynTree/Constant.h"
26#include "SynTree/Expression.h"
27#include "SynTree/Declaration.h"
28#include "Common/UnimplementedError.h"
29#include "parseutility.h"
30#include "Common/utility.h"
31
32using namespace std;
33
34ExpressionNode::ExpressionNode() : ParseNode() {}
35
36ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ) {}
37
38ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ), extension( other.extension ) {
39 if ( other.argName ) {
40 std::cout << "ExpressionNode" << std::endl;
41 argName = other.argName->clone();
42 } else {
43 argName = 0;
44 } // if
45}
46
47ExpressionNode * ExpressionNode::set_argName( const std::string *aName ) {
48 argName = new VarRefNode( aName );
49 return this;
50}
51
52ExpressionNode * ExpressionNode::set_argName( ExpressionNode *aDesignator ) {
53 argName = aDesignator;
54 return this;
55}
56
57void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
58 if ( argName ) {
59 os << string( indent, ' ' ) << "(designated by: ";
60 argName->printOneLine( os, indent );
61 os << ")" << std::endl;
62 } // if
63}
64
65//##############################################################################
66
67NullExprNode::NullExprNode() {}
68
69NullExprNode *NullExprNode::clone() const {
70 return new NullExprNode();
71}
72
73void NullExprNode::print( std::ostream & os, int indent ) const {
74 printDesignation( os );
75 os << "null expression";
76}
77
78void NullExprNode::printOneLine( std::ostream & os, int indent ) const {
79 printDesignation( os );
80 os << "null";
81}
82
83Expression *NullExprNode::build() const {
84 return 0;
85}
86
87//##############################################################################
88
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
175
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 };
181
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;
186
187 if ( checkI( str[last] ) ) { // imaginary ?
188 complx = true;
189 last -= 1; // backup one character
190 } // if
191
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
202
203 return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[complx][size] ), str ) ) );
204} // build_constantFloat
205
206ConstantNode *build_constantChar( std::string & str ) {
207 return new ConstantNode( new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::Char ), str ) ) );
208} // build_constantChar
209
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
218
219//##############################################################################
220
221//Expression *build_varref( ExpressionNode expr ) {
222// return new NameExpr( get_name(), maybeBuild<Expression>( get_argName() ) );
223//}
224
225VarRefNode::VarRefNode( const string *name, bool labelp ) : ExpressionNode( name ), isLabel( labelp ) {}
226
227VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
228}
229
230Expression *VarRefNode::build() const {
231 return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
232}
233
234void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
235 printDesignation( os );
236 os << get_name() << ' ';
237}
238
239void VarRefNode::print( std::ostream &os, int indent ) const {
240 printDesignation( os );
241 os << string( indent, ' ' ) << "Referencing: ";
242 os << "Variable: " << get_name();
243 os << endl;
244}
245
246//##############################################################################
247
248DesignatorNode::DesignatorNode( ExpressionNode *expr, bool isArrayIndex ) : isArrayIndex( isArrayIndex ) {
249 set_argName( expr );
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 ) {
258 // this is a floating point constant. It MUST be ".0" or ".1", otherwise the program is invalid
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
266}
267
268DesignatorNode::DesignatorNode( const DesignatorNode &other ) : ExpressionNode( other ), isArrayIndex( other.isArrayIndex ) {
269}
270
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
283Expression *DesignatorNode::build() const {
284 Expression * ret = maybeBuild<Expression>(get_argName());
285
286 if ( isArrayIndex ) {
287 // need to traverse entire structure and change any instances of 0 or 1 to ConstantExpr
288 DesignatorFixer fixer;
289 ret = ret->acceptMutator( fixer );
290 } // if
291
292 return ret;
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
323static const char *OperName[] = {
324 // diadic
325 "SizeOf", "AlignOf", "OffsetOf", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
326 "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
327 "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
328 "?[?]", "...",
329 // monadic
330 "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
331};
332
333//##############################################################################
334
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
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
392Expression *build_unary_val( OperKinds op, ExpressionNode *expr_node ) {
393 std::list<Expression *> args;
394 args.push_back( maybeBuild<Expression>(expr_node) );
395 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
396}
397Expression *build_unary_ptr( OperKinds op, ExpressionNode *expr_node ) {
398 std::list<Expression *> args;
399 args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node) ) );
400 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
401}
402Expression *build_binary_val( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
403 std::list<Expression *> args;
404 args.push_back( maybeBuild<Expression>(expr_node1) );
405 args.push_back( maybeBuild<Expression>(expr_node2) );
406 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
407}
408Expression *build_binary_ptr( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
409 std::list<Expression *> args;
410 args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node1) ) );
411 args.push_back( maybeBuild<Expression>(expr_node2) );
412 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
413}
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
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
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 );
448}
449
450//##############################################################################
451
452Expression *AsmExprNode::build() const {
453 return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) );
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
491ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
492
493ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
494}
495
496ValofExprNode::~ValofExprNode() {
497 delete body;
498}
499
500void ValofExprNode::print( std::ostream &os, int indent ) const {
501 printDesignation( os );
502 os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
503 get_body()->print( os, indent + 4);
504}
505
506void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
507 assert( false );
508}
509
510Expression *ValofExprNode::build() const {
511 return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) );
512}
513
514//##############################################################################
515
516ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
517 if ( init_ == 0 )
518 init = 0;
519 else {
520 DeclarationNode *decl;
521 ExpressionNode *exp;
522
523 if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
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 }
530}
531
532ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
533 : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
534}
535
536ForCtlExprNode::~ForCtlExprNode() {
537 delete init;
538 delete condition;
539 delete change;
540}
541
542Expression *ForCtlExprNode::build() const {
543 // this shouldn't be used!
544 assert( false );
545 return 0;
546}
547
548void ForCtlExprNode::print( std::ostream &os, int indent ) const{
549 os << string( indent,' ' ) << "For Control Expression -- :" << endl;
550
551 os << string( indent + 2, ' ' ) << "initialization:" << endl;
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 );
558 os << string( indent + 2, ' ' ) << "increment: " << endl;
559 if ( change != 0 )
560 change->print( os, indent + 4 );
561}
562
563void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
564 assert( false );
565}
566
567//##############################################################################
568
569TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
570}
571
572TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
573}
574
575Expression *TypeValueNode::build() const {
576 return new TypeExpr( decl->buildType() );
577}
578
579void TypeValueNode::print( std::ostream &os, int indent ) const {
580 os << std::string( indent, ' ' ) << "Type:";
581 get_decl()->print( os, indent + 2);
582}
583
584void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
585 os << "Type:";
586 get_decl()->print( os, indent + 2);
587}
588
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 {
623 Declaration * newDecl = maybeBuild<Declaration>(type); // compound literal type
624 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
625 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild<Initializer>(kids) );
626 // these types do not have associated type information
627 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) {
628 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeBuild<Initializer>(kids) );
629 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) {
630 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeBuild<Initializer>(kids) );
631 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) {
632 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeBuild<Initializer>(kids) );
633 } else {
634 assert( false );
635 } // if
636}
637
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.