source: src/Parser/ExpressionNode.cc @ dae881f

aaron-thesisarm-ehcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since dae881f was dae881f, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

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

  • Property mode set to 100644
File size: 22.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 : Fri Aug  5 07:56:23 2016
13// Update Count     : 375
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
85// CommaExprNode *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
367Expression *build_and_or( ExpressionNode *expr_node1, ExpressionNode *expr_node2, bool kind ) {
368        return new LogicalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), notZeroExpr( maybeBuild<Expression>(expr_node2) ), kind );
369}
370
371Expression *build_opr1( OperatorNode::Type op, ExpressionNode *expr_node ) {
372        std::list<Expression *> args;
373        args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node) ) );
374        return new UntypedExpr( new NameExpr( opName[ op ] ), args );
375}
376Expression *build_opr2( OperatorNode::Type op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
377        std::list<Expression *> args;
378        args.push_back( maybeBuild<Expression>(expr_node1) );
379        args.push_back( maybeBuild<Expression>(expr_node2) );
380        return new UntypedExpr( new NameExpr( opName[ op ] ), args );
381}
382
383Expression *build_cond( ExpressionNode *expr_node1, ExpressionNode *expr_node2, ExpressionNode *expr_node3 ) {
384        return new ConditionalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), maybeBuild<Expression>(expr_node2), maybeBuild<Expression>(expr_node3) );
385}
386
387Expression *build_comma( ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
388        return new CommaExpr( maybeBuild<Expression>(expr_node1), maybeBuild<Expression>(expr_node2) );
389}
390
391CompositeExprNode2::CompositeExprNode2( Expression *expr ) : expr( expr ) {}
392CompositeExprNode2::CompositeExprNode2( const CompositeExprNode2 &other ) : expr( other.expr->clone() ) {}
393CompositeExprNode2::~CompositeExprNode2() { delete expr; }
394void CompositeExprNode2::print( std::ostream &, int indent ) const { assert( false ); }
395void CompositeExprNode2::printOneLine( std::ostream &, int indent ) const { assert( false ); }
396
397
398Expression *CompositeExprNode::build() const {
399        OperatorNode *op;
400        std::list<Expression *> args;
401
402        buildList( get_args(), args );
403
404        if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator
405                return new UntypedExpr( maybeBuild<Expression>(function), args, maybeBuild< Expression >( get_argName() ));
406        } // if
407
408        switch ( op->get_type() ) {
409          case OperatorNode::Assign:
410          case OperatorNode::MulAssn:
411          case OperatorNode::DivAssn:
412          case OperatorNode::ModAssn:
413          case OperatorNode::PlusAssn:
414          case OperatorNode::MinusAssn:
415          case OperatorNode::LSAssn:
416          case OperatorNode::RSAssn:
417          case OperatorNode::AndAssn:
418          case OperatorNode::ERAssn:
419          case OperatorNode::OrAssn:
420                assert( ! args.empty() );
421                args.front() = new AddressExpr( args.front() );
422          case OperatorNode::UnPlus:
423          case OperatorNode::UnMinus:
424          case OperatorNode::PointTo:
425          case OperatorNode::Neg:
426          case OperatorNode::BitNeg:
427          case OperatorNode::LabelAddress:
428                return new UntypedExpr( new NameExpr( opName[ op->get_type() ] ), args );
429
430          case OperatorNode::Attr:
431                {
432                        VarRefNode *var = dynamic_cast<VarRefNode *>( get_args() );
433                        assert( var );
434                        if ( ! get_args()->get_link() ) {
435                                return new AttrExpr( maybeBuild<Expression>(var), ( Expression*)0);
436                        } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link() ) ) {
437                                return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType() );
438                        } else {
439                                return new AttrExpr( maybeBuild<Expression>(var), args.back() );
440                        } // if
441                }
442          case OperatorNode::Cond:
443                {
444                        assert( args.size() == 3);
445                        std::list< Expression * >::const_iterator i = args.begin();
446                        Expression *arg1 = notZeroExpr( *i++ );
447                        Expression *arg2 = *i++;
448                        Expression *arg3 = *i++;
449                        return new ConditionalExpr( arg1, arg2, arg3 );
450                }
451          case OperatorNode::NCond:
452                throw UnimplementedError( "GNU 2-argument conditional expression" );
453                // Tuples
454          case OperatorNode::TupleC:
455                {
456                        TupleExpr *ret = new TupleExpr();
457                        std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
458                        return ret;
459                }
460          default:
461                assert( ((void)"CompositeExprNode::build", false) );
462                return 0;
463        } // switch
464}
465
466void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
467        printDesignation( os );
468        os << "( ";
469        function->printOneLine( os, indent );
470        for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
471                cur->printOneLine( os, indent );
472        } // for
473        os << ") ";
474}
475
476void CompositeExprNode::print( std::ostream &os, int indent ) const {
477        printDesignation( os );
478        os << string( indent, ' ' ) << "Application of: " << endl;
479        function->print( os, indent + ParseNode::indent_by );
480
481        os << string( indent, ' ' ) ;
482        if ( arguments ) {
483                os << "... on arguments: " << endl;
484                arguments->printList( os, indent + ParseNode::indent_by );
485        } else
486                os << "... on no arguments: " << endl;
487}
488
489void CompositeExprNode::set_function( ExpressionNode *f ) {
490        function = f;
491}
492
493void CompositeExprNode::set_args( ExpressionNode *args ) {
494        arguments = args;
495}
496
497ExpressionNode *CompositeExprNode::get_function( void ) const {
498        return function;
499}
500
501ExpressionNode *CompositeExprNode::get_args( void ) const {
502        return arguments;
503}
504
505void CompositeExprNode::add_arg( ExpressionNode *arg ) {
506        if ( arguments )
507                arguments->set_link( arg );
508        else
509                set_args( arg );
510}
511
512//##############################################################################
513
514Expression *AsmExprNode::build() const {
515        return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) );
516}
517
518void AsmExprNode::print( std::ostream &os, int indent ) const {
519        os << string( indent, ' ' ) << "Assembler Expression:" << endl;
520        if ( inout ) {
521                os << string( indent, ' ' ) << "inout: " << std::endl;
522                inout->print( os, indent + 2 );
523        } // if
524        if ( constraint ) {
525                os << string( indent, ' ' ) << "constraint: " << std::endl;
526                constraint->print( os, indent + 2 );
527        } // if
528        if ( operand ) {
529                os << string( indent, ' ' ) << "operand: " << std::endl;
530                operand->print( os, indent + 2 );
531        } // if
532}
533
534void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
535        printDesignation( os );
536        os << "( ";
537        if ( inout ) inout->printOneLine( os, indent + 2 );
538        os << ", ";
539        if ( constraint ) constraint->printOneLine( os, indent + 2 );
540        os << ", ";
541        if ( operand ) operand->printOneLine( os, indent + 2 );
542        os << ") ";
543}
544
545//##############################################################################
546
547void LabelNode::print( std::ostream &os, int indent ) const {}
548
549void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
550
551//##############################################################################
552
553ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
554
555ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
556}
557
558ValofExprNode::~ValofExprNode() {
559        delete body;
560}
561
562void ValofExprNode::print( std::ostream &os, int indent ) const {
563        printDesignation( os );
564        os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
565        get_body()->print( os, indent + 4);
566}
567
568void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
569        assert( false );
570}
571
572Expression *ValofExprNode::build() const {
573        return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) );
574}
575
576//##############################################################################
577
578ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
579        if ( init_ == 0 )
580                init = 0;
581        else {
582                DeclarationNode *decl;
583                ExpressionNode *exp;
584
585                if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
586                        init = new StatementNode( decl );
587                else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
588                        init = new StatementNode( StatementNode::Exp, exp );
589                else
590                        throw SemanticError("Error in for control expression");
591        }
592}
593
594ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
595        : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
596}
597
598ForCtlExprNode::~ForCtlExprNode() {
599        delete init;
600        delete condition;
601        delete change;
602}
603
604Expression *ForCtlExprNode::build() const {
605        // this shouldn't be used!
606        assert( false );
607        return 0;
608}
609
610void ForCtlExprNode::print( std::ostream &os, int indent ) const{
611        os << string( indent,' ' ) << "For Control Expression -- :" << endl;
612
613        os << string( indent + 2, ' ' ) << "initialization:" << endl;
614        if ( init != 0 )
615                init->printList( os, indent + 4 );
616
617        os << string( indent + 2, ' ' ) << "condition: " << endl;
618        if ( condition != 0 )
619                condition->print( os, indent + 4 );
620        os << string( indent + 2, ' ' ) << "increment: " << endl;
621        if ( change != 0 )
622                change->print( os, indent + 4 );
623}
624
625void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
626        assert( false );
627}
628
629//##############################################################################
630
631TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
632}
633
634TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
635}
636
637Expression *TypeValueNode::build() const {
638        return new TypeExpr( decl->buildType() );
639}
640
641void TypeValueNode::print( std::ostream &os, int indent ) const {
642        os << std::string( indent, ' ' ) << "Type:";
643        get_decl()->print( os, indent + 2);
644}
645
646void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
647        os << "Type:";
648        get_decl()->print( os, indent + 2);
649}
650
651
652CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}
653CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}
654
655CompoundLiteralNode::~CompoundLiteralNode() {
656        delete kids;
657        delete type;
658}
659
660CompoundLiteralNode *CompoundLiteralNode::clone() const {
661        return new CompoundLiteralNode( *this );
662}
663
664void CompoundLiteralNode::print( std::ostream &os, int indent ) const {
665        os << string( indent,' ' ) << "CompoundLiteralNode:" << endl;
666
667        os << string( indent + 2, ' ' ) << "type:" << endl;
668        if ( type != 0 )
669                type->print( os, indent + 4 );
670
671        os << string( indent + 2, ' ' ) << "initialization:" << endl;
672        if ( kids != 0 )
673                kids->printList( os, indent + 4 );
674}
675
676void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const {
677        os << "( ";
678        if ( type ) type->print( os );
679        os << ", ";
680        if ( kids ) kids->printOneLine( os );
681        os << ") ";
682}
683
684Expression *CompoundLiteralNode::build() const {
685        Declaration * newDecl = maybeBuild<Declaration>(type); // compound literal type
686        if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
687                return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild<Initializer>(kids) );
688        // these types do not have associated type information
689        } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl )  ) {
690                return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeBuild<Initializer>(kids) );
691        } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl )  ) {
692                return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeBuild<Initializer>(kids) );
693        } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl )  ) {
694                return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeBuild<Initializer>(kids) );
695        } else {
696                assert( false );
697        } // if
698}
699
700ExpressionNode *flattenCommas( ExpressionNode *list ) {
701        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
702                OperatorNode *op;
703                if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
704                        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
705                                composite->add_arg( next );
706                        return flattenCommas( composite->get_args() );
707                } // if
708        } // if
709
710        if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
711                list->set_next( flattenCommas( next ) );
712
713        return list;
714}
715
716ExpressionNode *tupleContents( ExpressionNode *tuple ) {
717        if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
718                OperatorNode *op = 0;
719                if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
720                        return composite->get_args();
721        } // if
722        return tuple;
723}
724
725// Local Variables: //
726// tab-width: 4 //
727// mode: c++ //
728// compile-command: "make install" //
729// End: //
Note: See TracBrowser for help on using the repository browser.