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

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 7bf7fb9 was 7bf7fb9, checked in by Peter A. Buhr <pabuhr@…>, 8 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.