source: src/SynTree/Expression.cc @ 50377a4

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 50377a4 was 50377a4, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Refactor tree print code to use Indenter

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