source: src/SynTree/Expression.cc @ e1e8408

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since e1e8408 was bf4b4cf, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Remove argName from Expression.

If named arguments are ever considered again, they should be added in UntypedExpr? (and maybe also ApplicationExpr?) to avoid unnecessary fields in every Expression. Like designators on initializers, it should be much easier to work with argument names at the call expression level.

  • Property mode set to 100644
File size: 21.9 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// Expression.cc --
8//
9// Author           : Richard C. Bilson
10// Created On       : Mon May 18 07:44:20 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Tue Jul 25 14:15:47 2017
13// Update Count     : 54
14//
15
16#include "SynTree/Expression.h"
17
18#include <cassert>                   // for assert, assertf
19#include <iostream>                  // for ostream, operator<<, basic_ostream
20#include <list>                      // for list, _List_iterator, list<>::co...
21
22#include "Common/utility.h"          // for maybeClone, cloneAll, deleteAll
23#include "Declaration.h"             // for ObjectDecl, DeclarationWithType
24#include "Expression.h"              // for Expression, ImplicitCopyCtorExpr
25#include "InitTweak/InitTweak.h"     // for getCallArg, getPointerBase
26#include "Initializer.h"             // for Designation, Initializer
27#include "Statement.h"               // for CompoundStmt, ExprStmt, Statement
28#include "SynTree/BaseSyntaxNode.h"  // for BaseSyntaxNode
29#include "SynTree/Constant.h"        // for Constant
30#include "Type.h"                    // for Type, BasicType, Type::Qualifiers
31#include "TypeSubstitution.h"        // for TypeSubstitution
32
33#include "GenPoly/Lvalue.h"
34
35Expression::Expression() : result( 0 ), env( 0 ) {}
36
37Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), extension( other.extension ) {
38}
39
40Expression::~Expression() {
41        delete env;
42        delete result;
43}
44
45void Expression::print( std::ostream &os, Indenter indent ) const {
46        if ( env ) {
47                os << std::endl << indent << "... with environment:" << std::endl;
48                env->print( os, indent+1 );
49        } // if
50
51        if ( extension ) {
52                os << std::endl << indent << "... with extension:";
53        } // if
54}
55
56ConstantExpr::ConstantExpr( Constant _c ) : Expression(), constant( _c ) {
57        set_result( constant.get_type()->clone() );
58}
59
60ConstantExpr::ConstantExpr( const ConstantExpr &other) : Expression( other ), constant( other.constant ) {
61}
62
63ConstantExpr::~ConstantExpr() {}
64
65void ConstantExpr::print( std::ostream &os, Indenter indent ) const {
66        os << "constant expression " ;
67        constant.print( os );
68        Expression::print( os, indent );
69}
70
71VariableExpr::VariableExpr( DeclarationWithType *_var ) : Expression(), var( _var ) {
72        assert( var );
73        assert( var->get_type() );
74        Type * type = var->get_type()->clone();
75        type->set_lvalue( true );
76        set_result( type );
77}
78
79VariableExpr::VariableExpr( const VariableExpr &other ) : Expression( other ), var( other.var ) {
80}
81
82VariableExpr::~VariableExpr() {
83        // don't delete the declaration, since it points somewhere else in the tree
84}
85
86VariableExpr * VariableExpr::functionPointer( FunctionDecl * func ) {
87        VariableExpr * funcExpr = new VariableExpr( func );
88        funcExpr->set_result( new PointerType( Type::Qualifiers(), funcExpr->get_result() ) );
89        return funcExpr;
90}
91
92void VariableExpr::print( std::ostream &os, Indenter indent ) const {
93        os << "Variable Expression: ";
94        var->printShort(os, indent);
95        Expression::print( os, indent );
96}
97
98SizeofExpr::SizeofExpr( Expression *expr_ ) :
99                Expression(), expr(expr_), type(0), isType(false) {
100        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
101}
102
103SizeofExpr::SizeofExpr( Type *type_ ) :
104                Expression(), expr(0), type(type_), isType(true) {
105        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
106}
107
108SizeofExpr::SizeofExpr( const SizeofExpr &other ) :
109        Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
110}
111
112SizeofExpr::~SizeofExpr() {
113        delete expr;
114        delete type;
115}
116
117void SizeofExpr::print( std::ostream &os, Indenter indent) const {
118        os << "Sizeof Expression on: ";
119        if (isType) type->print(os, indent+1);
120        else expr->print(os, indent+1);
121        Expression::print( os, indent );
122}
123
124AlignofExpr::AlignofExpr( Expression *expr_ ) :
125                Expression(), expr(expr_), type(0), isType(false) {
126        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
127}
128
129AlignofExpr::AlignofExpr( Type *type_ ) :
130                Expression(), expr(0), type(type_), isType(true) {
131        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
132}
133
134AlignofExpr::AlignofExpr( const AlignofExpr &other ) :
135        Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
136}
137
138AlignofExpr::~AlignofExpr() {
139        delete expr;
140        delete type;
141}
142
143void AlignofExpr::print( std::ostream &os, Indenter indent) const {
144        os << "Alignof Expression on: ";
145        if (isType) type->print(os, indent+1);
146        else expr->print(os, indent+1);
147        Expression::print( os, indent );
148}
149
150UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type, const std::string &member ) :
151                Expression(), type(type), member(member) {
152        assert( type );
153        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
154}
155
156UntypedOffsetofExpr::UntypedOffsetofExpr( const UntypedOffsetofExpr &other ) :
157        Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {}
158
159UntypedOffsetofExpr::~UntypedOffsetofExpr() {
160        delete type;
161}
162
163void UntypedOffsetofExpr::print( std::ostream &os, Indenter indent) const {
164        os << "Untyped Offsetof Expression on member " << member << " of ";
165        type->print(os, indent+1);
166        Expression::print( os, indent );
167}
168
169OffsetofExpr::OffsetofExpr( Type *type, DeclarationWithType *member ) :
170                Expression(), type(type), member(member) {
171        assert( member );
172        assert( type );
173        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
174}
175
176OffsetofExpr::OffsetofExpr( const OffsetofExpr &other ) :
177        Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {}
178
179OffsetofExpr::~OffsetofExpr() {
180        delete type;
181}
182
183void OffsetofExpr::print( std::ostream &os, Indenter indent) const {
184        os << "Offsetof Expression on member " << member->name << " of ";
185        type->print(os, indent+1);
186        Expression::print( os, indent );
187}
188
189OffsetPackExpr::OffsetPackExpr( StructInstType *type ) : Expression(), type( type ) {
190        assert( type );
191        set_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) );
192}
193
194OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr &other ) : Expression( other ), type( maybeClone( other.type ) ) {}
195
196OffsetPackExpr::~OffsetPackExpr() { delete type; }
197
198void OffsetPackExpr::print( std::ostream &os, Indenter indent ) const {
199        os << "Offset pack expression on ";
200        type->print(os, indent+1);
201        Expression::print( os, indent );
202}
203
204AttrExpr::AttrExpr( Expression *attr, Expression *expr_ ) :
205                Expression(), attr( attr ), expr(expr_), type(0), isType(false) {
206}
207
208AttrExpr::AttrExpr( Expression *attr, Type *type_ ) :
209                Expression(), attr( attr ), expr(0), type(type_), isType(true) {
210}
211
212AttrExpr::AttrExpr( const AttrExpr &other ) :
213                Expression( other ), attr( maybeClone( other.attr ) ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
214}
215
216AttrExpr::~AttrExpr() {
217        delete attr;
218        delete expr;
219        delete type;
220}
221
222void AttrExpr::print( std::ostream &os, Indenter indent) const {
223        os << "Attr ";
224        attr->print( os, indent+1);
225        if ( isType || expr ) {
226                os << "applied to: ";
227                if (isType) type->print(os, indent+1);
228                else expr->print(os, indent+1);
229        } // if
230        Expression::print( os, indent );
231}
232
233CastExpr::CastExpr( Expression *arg_, Type *toType ) : Expression(), arg(arg_) {
234        set_result(toType);
235}
236
237CastExpr::CastExpr( Expression *arg_ ) : Expression(), arg(arg_) {
238        set_result( new VoidType( Type::Qualifiers() ) );
239}
240
241CastExpr::CastExpr( const CastExpr &other ) : Expression( other ), arg( maybeClone( other.arg ) ) {
242}
243
244CastExpr::~CastExpr() {
245        delete arg;
246}
247
248void CastExpr::print( std::ostream &os, Indenter indent ) const {
249        os << "Cast of:" << std::endl << indent+1;
250        arg->print(os, indent+1);
251        os << std::endl << indent << "... to:";
252        if ( result->isVoid() ) {
253                os << " nothing";
254        } else {
255                os << std::endl << indent+1;
256                result->print( os, indent+1 );
257        } // if
258        Expression::print( os, indent );
259}
260
261VirtualCastExpr::VirtualCastExpr( Expression *arg_, Type *toType ) : Expression(), arg(arg_) {
262        set_result(toType);
263}
264
265VirtualCastExpr::VirtualCastExpr( const VirtualCastExpr &other ) : Expression( other ), arg( maybeClone( other.arg ) ) {
266}
267
268VirtualCastExpr::~VirtualCastExpr() {
269        delete arg;
270}
271
272void VirtualCastExpr::print( std::ostream &os, Indenter indent ) const {
273        os << "Virtual Cast of:" << std::endl << indent+1;
274        arg->print(os, indent+1);
275        os << std::endl << indent << "... to:";
276        if ( ! result ) {
277                os << " unknown";
278        } else {
279                os << std::endl << indent+1;
280                result->print( os, indent+1 );
281        } // if
282        Expression::print( os, indent );
283}
284
285UntypedMemberExpr::UntypedMemberExpr( Expression * member, Expression *aggregate ) :
286                Expression(), member(member), aggregate(aggregate) {
287        assert( aggregate );
288}
289
290UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr &other ) :
291                Expression( other ), member( maybeClone( other.member ) ), aggregate( maybeClone( other.aggregate ) ) {
292}
293
294UntypedMemberExpr::~UntypedMemberExpr() {
295        delete aggregate;
296        delete member;
297}
298
299void UntypedMemberExpr::print( std::ostream &os, Indenter indent ) const {
300        os << "Untyped Member Expression, with field: " << std::endl << indent+1;
301        member->print(os, indent+1 );
302        os << indent << "... from aggregate: " << std::endl << indent+1;
303        aggregate->print(os, indent+1);
304        Expression::print( os, indent );
305}
306
307namespace {
308        TypeSubstitution makeSub( Type * t ) {
309                if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( t ) ) {
310                        return makeSub( refType->get_base() );
311                } else if ( StructInstType * aggInst = dynamic_cast< StructInstType * >( t ) ) {
312                        return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->get_parameters().begin() );
313                } else if ( UnionInstType * aggInst = dynamic_cast< UnionInstType * >( t ) ) {
314                        return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->get_parameters().begin() );
315                } else {
316                        assertf( false, "makeSub expects struct or union type for aggregate, but got: %s", toString( t ).c_str() );
317                }
318        }
319}
320
321
322MemberExpr::MemberExpr( DeclarationWithType *member, Expression *aggregate ) :
323                Expression(), member(member), aggregate(aggregate) {
324        assert( member );
325        assert( aggregate );
326
327        TypeSubstitution sub( makeSub( aggregate->get_result() ) );
328        Type * res = member->get_type()->clone();
329        sub.apply( res );
330        set_result( res );
331        get_result()->set_lvalue( true );
332}
333
334MemberExpr::MemberExpr( const MemberExpr &other ) :
335                Expression( other ), member( other.member ), aggregate( maybeClone( other.aggregate ) ) {
336}
337
338MemberExpr::~MemberExpr() {
339        // don't delete the member declaration, since it points somewhere else in the tree
340        delete aggregate;
341}
342
343void MemberExpr::print( std::ostream &os, Indenter indent ) const {
344        os << "Member Expression, with field: " << std::endl;
345        os << indent+1;
346        member->print( os, indent+1 );
347        os << std::endl << indent << "... from aggregate: " << std::endl << indent+1;
348        aggregate->print(os, indent + 1);
349        Expression::print( os, indent );
350}
351
352UntypedExpr::UntypedExpr( Expression *function, const std::list<Expression *> &args ) :
353                Expression(), function(function), args(args) {}
354
355UntypedExpr::UntypedExpr( const UntypedExpr &other ) :
356                Expression( other ), function( maybeClone( other.function ) ) {
357        cloneAll( other.args, args );
358}
359
360UntypedExpr::~UntypedExpr() {
361        delete function;
362        deleteAll( args );
363}
364
365UntypedExpr * UntypedExpr::createDeref( Expression * expr ) {
366        UntypedExpr * ret = new UntypedExpr( new NameExpr("*?"), std::list< Expression * >{ expr } );
367        if ( Type * type = expr->get_result() ) {
368                Type * base = InitTweak::getPointerBase( type );
369                assertf( base, "expected pointer type in dereference (type was %s)", toString( type ).c_str() );
370                ret->set_result( base->clone() );
371                if ( GenPoly::referencesPermissable() ) {
372                        // if references are still allowed in the AST, dereference returns a reference
373                        ret->set_result( new ReferenceType( Type::Qualifiers(), ret->get_result() ) );
374                } else {
375                        // references have been removed, in which case dereference returns an lvalue of the base type.
376                        ret->get_result()->set_lvalue( true );
377                }
378        }
379        return ret;
380}
381
382UntypedExpr * UntypedExpr::createAssign( Expression * arg1, Expression * arg2 ) {
383        assert( arg1 && arg2 );
384        UntypedExpr * ret = new UntypedExpr( new NameExpr( "?=?" ), std::list< Expression * >{ arg1, arg2 } );
385        if ( arg1->get_result() && arg2->get_result() ) {
386                // if both expressions are typed, assumes that this assignment is a C bitwise assignment,
387                // so the result is the type of the RHS
388                ret->set_result( arg2->get_result()->clone() );
389        }
390        return ret;
391}
392
393
394void UntypedExpr::print( std::ostream &os, Indenter indent ) const {
395        os << "Applying untyped: " << std::endl;
396        os << indent+1;
397        function->print(os, indent+1);
398        os << std::endl << indent << "...to: " << std::endl;
399        printAll(args, os, indent+1);
400        Expression::print( os, indent );
401}
402
403NameExpr::NameExpr( std::string name ) : Expression(), name(name) {
404        assertf(name != "0", "Zero is not a valid name");
405        assertf(name != "1", "One is not a valid name");
406}
407
408NameExpr::NameExpr( const NameExpr &other ) : Expression( other ), name( other.name ) {
409}
410
411NameExpr::~NameExpr() {}
412
413void NameExpr::print( std::ostream &os, Indenter indent ) const {
414        os << "Name: " << get_name();
415        Expression::print( os, indent );
416}
417
418LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp ) :
419                Expression(), arg1(arg1_), arg2(arg2_), isAnd(andp) {
420        set_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
421}
422
423LogicalExpr::LogicalExpr( const LogicalExpr &other ) :
424                Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), isAnd( other.isAnd ) {
425}
426
427LogicalExpr::~LogicalExpr() {
428        delete arg1;
429        delete arg2;
430}
431
432void LogicalExpr::print( std::ostream &os, Indenter indent )const {
433        os << "Short-circuited operation (" << (isAnd ? "and" : "or") << ") on: ";
434        arg1->print(os);
435        os << " and ";
436        arg2->print(os);
437        Expression::print( os, indent );
438}
439
440ConditionalExpr::ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3 ) :
441                Expression(), arg1(arg1), arg2(arg2), arg3(arg3) {}
442
443ConditionalExpr::ConditionalExpr( const ConditionalExpr &other ) :
444                Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), arg3( maybeClone( other.arg3 ) ) {
445}
446
447ConditionalExpr::~ConditionalExpr() {
448        delete arg1;
449        delete arg2;
450        delete arg3;
451}
452
453void ConditionalExpr::print( std::ostream &os, Indenter indent ) const {
454        os << "Conditional expression on: " << std::endl << indent+1;
455        arg1->print( os, indent+1 );
456        os << indent << "First alternative:" << std::endl << indent+1;
457        arg2->print( os, indent+1 );
458        os << indent << "Second alternative:" << std::endl << indent+1;
459        arg3->print( os, indent+1 );
460        Expression::print( os, indent );
461}
462
463AsmExpr::AsmExpr( const AsmExpr & other ) : Expression( other ), inout( maybeClone( other.inout ) ), constraint( maybeClone( other.constraint ) ), operand( maybeClone( other.operand ) ) {}
464
465
466void AsmExpr::print( std::ostream &os, Indenter indent ) const {
467        os << "Asm Expression: " << std::endl;
468        if ( inout ) inout->print( os, indent+1 );
469        if ( constraint ) constraint->print( os, indent+1 );
470        if ( operand ) operand->print( os, indent+1 );
471}
472
473
474ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( ApplicationExpr * callExpr ) : callExpr( callExpr ) {
475        assert( callExpr );
476        assert( callExpr->result );
477        set_result( callExpr->get_result()->clone() );
478}
479
480ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( const ImplicitCopyCtorExpr & other ) : Expression( other ), callExpr( maybeClone( other.callExpr ) ) {
481        cloneAll( other.tempDecls, tempDecls );
482        cloneAll( other.returnDecls, returnDecls );
483        cloneAll( other.dtors, dtors );
484}
485
486ImplicitCopyCtorExpr::~ImplicitCopyCtorExpr() {
487        set_env( nullptr ); // ImplicitCopyCtorExpr does not take ownership of an environment
488        delete callExpr;
489        deleteAll( tempDecls );
490        deleteAll( returnDecls );
491        deleteAll( dtors );
492}
493
494void ImplicitCopyCtorExpr::print( std::ostream &os, Indenter indent ) const {
495        os <<  "Implicit Copy Constructor Expression: " << std::endl << indent+1;
496        callExpr->print( os, indent+1 );
497        os << std::endl << indent << "... with temporaries:" << std::endl;
498        printAll( tempDecls, os, indent+1 );
499        os << std::endl << indent << "... with return temporaries:" << std::endl;
500        printAll( returnDecls, os, indent+1 );
501        Expression::print( os, indent );
502}
503
504
505ConstructorExpr::ConstructorExpr( Expression * callExpr ) : callExpr( callExpr ) {
506        // allow resolver to type a constructor used as an expression as if it has the same type as its first argument
507        assert( callExpr );
508        Expression * arg = InitTweak::getCallArg( callExpr, 0 );
509        assert( arg );
510        set_result( maybeClone( arg->result ) );
511}
512
513ConstructorExpr::ConstructorExpr( const ConstructorExpr & other ) : Expression( other ), callExpr( maybeClone( other.callExpr ) ) {
514}
515
516ConstructorExpr::~ConstructorExpr() {
517        delete callExpr;
518}
519
520void ConstructorExpr::print( std::ostream &os, Indenter indent ) const {
521        os <<  "Constructor Expression: " << std::endl << indent+1;
522        callExpr->print( os, indent + 2 );
523        Expression::print( os, indent );
524}
525
526
527CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : initializer( initializer ) {
528        assert( type && initializer );
529        type->set_lvalue( true );
530        set_result( type );
531}
532
533CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), initializer( other.initializer->clone() ) {}
534
535CompoundLiteralExpr::~CompoundLiteralExpr() {
536        delete initializer;
537}
538
539void CompoundLiteralExpr::print( std::ostream &os, Indenter indent ) const {
540        os << "Compound Literal Expression: " << std::endl << indent+1;
541        result->print( os, indent+1 );
542        os << indent+1;
543        initializer->print( os, indent+1 );
544        Expression::print( os, indent );
545}
546
547RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {}
548RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {}
549void RangeExpr::print( std::ostream &os, Indenter indent ) const {
550        os << "Range Expression: ";
551        low->print( os, indent );
552        os << " ... ";
553        high->print( os, indent );
554        Expression::print( os, indent );
555}
556
557StmtExpr::StmtExpr( CompoundStmt *statements ) : statements( statements ) {
558        assert( statements );
559        std::list< Statement * > & body = statements->get_kids();
560        if ( ! body.empty() ) {
561                if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( body.back() ) ) {
562                        set_result( maybeClone( exprStmt->get_expr()->get_result() ) );
563                }
564        }
565        // ensure that StmtExpr has a result type
566        if ( ! result ) {
567                set_result( new VoidType( Type::Qualifiers() ) );
568        }
569}
570StmtExpr::StmtExpr( const StmtExpr &other ) : Expression( other ), statements( other.statements->clone() ) {
571        cloneAll( other.returnDecls, returnDecls );
572        cloneAll( other.dtors, dtors );
573}
574StmtExpr::~StmtExpr() {
575        delete statements;
576        deleteAll( dtors );
577        deleteAll( returnDecls );
578}
579void StmtExpr::print( std::ostream &os, Indenter indent ) const {
580        os << "Statement Expression: " << std::endl << indent+1;
581        statements->print( os, indent+1 );
582        if ( ! returnDecls.empty() ) {
583                os << indent+1 << "... with returnDecls: ";
584                printAll( returnDecls, os, indent+1 );
585        }
586        if ( ! dtors.empty() ) {
587                os << indent+1 << "... with dtors: ";
588                printAll( dtors, os, indent+1 );
589        }
590        Expression::print( os, indent );
591}
592
593
594long long UniqueExpr::count = 0;
595UniqueExpr::UniqueExpr( Expression *expr, long long idVal ) : expr( expr ), object( nullptr ), var( nullptr ), id( idVal ) {
596        assert( expr );
597        assert( count != -1 );
598        if ( id == -1 ) id = count++;
599        if ( expr->get_result() ) {
600                set_result( expr->get_result()->clone() );
601        }
602}
603UniqueExpr::UniqueExpr( const UniqueExpr &other ) : Expression( other ), expr( maybeClone( other.expr ) ), object( maybeClone( other.object ) ), var( maybeClone( other.var ) ), id( other.id ) {
604}
605UniqueExpr::~UniqueExpr() {
606        delete expr;
607        delete object;
608        delete var;
609}
610void UniqueExpr::print( std::ostream &os, Indenter indent ) const {
611        os << "Unique Expression with id:" << id << std::endl << indent+1;
612        expr->print( os, indent+1 );
613        if ( object ) {
614                os << indent << "... with decl: ";
615                get_object()->printShort( os, indent+1 );
616        }
617        Expression::print( os, indent );
618}
619
620InitAlternative::InitAlternative( Type * type, Designation * designation ) : type( type ), designation( designation ) {}
621InitAlternative::InitAlternative( const InitAlternative & other ) : type( maybeClone( other.type ) ), designation( maybeClone( other.designation ) ) {}
622InitAlternative::~InitAlternative() {
623        delete type;
624        delete designation;
625}
626
627UntypedInitExpr::UntypedInitExpr( Expression * expr, const std::list<InitAlternative> & initAlts ) : expr( expr ), initAlts( initAlts ) {}
628UntypedInitExpr::UntypedInitExpr( const UntypedInitExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), initAlts( other.initAlts ) {}
629UntypedInitExpr::~UntypedInitExpr() {
630        delete expr;
631}
632
633void UntypedInitExpr::print( std::ostream & os, Indenter indent ) const {
634        os << "Untyped Init Expression" << std::endl << indent+1;
635        expr->print( os, indent+1 );
636        if ( ! initAlts.empty() ) {
637                for ( const InitAlternative & alt : initAlts ) {
638                        os << indent+1 <<  "InitAlternative: ";
639                        alt.type->print( os, indent+1 );
640                        alt.designation->print( os, indent+1 );
641                }
642        }
643}
644
645InitExpr::InitExpr( Expression * expr, Designation * designation ) : expr( expr ), designation( designation ) {
646        set_result( expr->get_result()->clone() );
647}
648InitExpr::InitExpr( const InitExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), designation( maybeClone( other.designation) ) {}
649InitExpr::~InitExpr() {
650        delete expr;
651        delete designation;
652}
653
654void InitExpr::print( std::ostream & os, Indenter indent ) const {
655        os << "Init Expression" << std::endl << indent+1;
656        expr->print( os, indent+1 );
657        os << indent+1 << "... with designation: ";
658        designation->print( os, indent+1 );
659}
660
661// Local Variables: //
662// tab-width: 4 //
663// mode: c++ //
664// compile-command: "make install" //
665// End: //
Note: See TracBrowser for help on using the repository browser.