source: src/SynTree/Expression.cc @ df626eb

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

Move inferred parameters to Exception base class

  • Property mode set to 100644
File size: 21.9 KB
RevLine 
[0dd3a2f]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//
[3be261a]7// Expression.cc --
[0dd3a2f]8//
9// Author           : Richard C. Bilson
10// Created On       : Mon May 18 07:44:20 2015
[e04ef3a]11// Last Modified By : Peter A. Buhr
[a5f0529]12// Last Modified On : Tue Jul 25 14:15:47 2017
13// Update Count     : 54
[0dd3a2f]14//
15
[ea6332d]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
[51b7345]32
[b0440b7]33#include "GenPoly/Lvalue.h"
[51b7345]34
[bf4b4cf]35Expression::Expression() : result( 0 ), env( 0 ) {}
[0dd3a2f]36
[df626eb]37Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), extension( other.extension ), inferParams( other.inferParams ) {
[0dd3a2f]38}
39
40Expression::~Expression() {
41        delete env;
[906e24d]42        delete result;
[51b7345]43}
44
[50377a4]45void Expression::print( std::ostream &os, Indenter indent ) const {
[0dd3a2f]46        if ( env ) {
[50377a4]47                os << std::endl << indent << "... with environment:" << std::endl;
48                env->print( os, indent+1 );
[0dd3a2f]49        } // if
[e04ef3a]50
51        if ( extension ) {
[50377a4]52                os << std::endl << indent << "... with extension:";
[e04ef3a]53        } // if
[51b7345]54}
55
[bf4b4cf]56ConstantExpr::ConstantExpr( Constant _c ) : Expression(), constant( _c ) {
[906e24d]57        set_result( constant.get_type()->clone() );
[51b7345]58}
59
[0dd3a2f]60ConstantExpr::ConstantExpr( const ConstantExpr &other) : Expression( other ), constant( other.constant ) {
61}
[51b7345]62
63ConstantExpr::~ConstantExpr() {}
64
[50377a4]65void ConstantExpr::print( std::ostream &os, Indenter indent ) const {
[60089f4]66        os << "constant expression " ;
[cf0941d]67        constant.print( os );
[0dd3a2f]68        Expression::print( os, indent );
[51b7345]69}
70
[bf4b4cf]71VariableExpr::VariableExpr( DeclarationWithType *_var ) : Expression(), var( _var ) {
[db4ecc5]72        assert( var );
73        assert( var->get_type() );
[906e24d]74        Type * type = var->get_type()->clone();
[615a096]75        type->set_lvalue( true );
[906e24d]76        set_result( type );
[51b7345]77}
78
[0dd3a2f]79VariableExpr::VariableExpr( const VariableExpr &other ) : Expression( other ), var( other.var ) {
[51b7345]80}
81
[0dd3a2f]82VariableExpr::~VariableExpr() {
83        // don't delete the declaration, since it points somewhere else in the tree
[51b7345]84}
85
[8a6cf7e]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
[50377a4]92void VariableExpr::print( std::ostream &os, Indenter indent ) const {
[89231bc]93        os << "Variable Expression: ";
[50377a4]94        var->printShort(os, indent);
[0dd3a2f]95        Expression::print( os, indent );
[51b7345]96}
97
[bf4b4cf]98SizeofExpr::SizeofExpr( Expression *expr_ ) :
99                Expression(), expr(expr_), type(0), isType(false) {
[906e24d]100        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
[51b7345]101}
102
[bf4b4cf]103SizeofExpr::SizeofExpr( Type *type_ ) :
104                Expression(), expr(0), type(type_), isType(true) {
[906e24d]105        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
[51b7345]106}
107
[0dd3a2f]108SizeofExpr::SizeofExpr( const SizeofExpr &other ) :
109        Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
[51b7345]110}
111
[0dd3a2f]112SizeofExpr::~SizeofExpr() {
113        delete expr;
114        delete type;
[51b7345]115}
116
[50377a4]117void SizeofExpr::print( std::ostream &os, Indenter indent) const {
[89231bc]118        os << "Sizeof Expression on: ";
[50377a4]119        if (isType) type->print(os, indent+1);
120        else expr->print(os, indent+1);
[47534159]121        Expression::print( os, indent );
122}
123
[bf4b4cf]124AlignofExpr::AlignofExpr( Expression *expr_ ) :
125                Expression(), expr(expr_), type(0), isType(false) {
[906e24d]126        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
[47534159]127}
128
[bf4b4cf]129AlignofExpr::AlignofExpr( Type *type_ ) :
130                Expression(), expr(0), type(type_), isType(true) {
[906e24d]131        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
[47534159]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
[50377a4]143void AlignofExpr::print( std::ostream &os, Indenter indent) const {
[f19339e]144        os << "Alignof Expression on: ";
[50377a4]145        if (isType) type->print(os, indent+1);
146        else expr->print(os, indent+1);
[0dd3a2f]147        Expression::print( os, indent );
[51b7345]148}
149
[bf4b4cf]150UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type, const std::string &member ) :
151                Expression(), type(type), member(member) {
[50377a4]152        assert( type );
[906e24d]153        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
[2a4b088]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
[50377a4]163void UntypedOffsetofExpr::print( std::ostream &os, Indenter indent) const {
164        os << "Untyped Offsetof Expression on member " << member << " of ";
165        type->print(os, indent+1);
[2a4b088]166        Expression::print( os, indent );
167}
168
[bf4b4cf]169OffsetofExpr::OffsetofExpr( Type *type, DeclarationWithType *member ) :
170                Expression(), type(type), member(member) {
[50377a4]171        assert( member );
172        assert( type );
[906e24d]173        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
[25a054f]174}
175
176OffsetofExpr::OffsetofExpr( const OffsetofExpr &other ) :
[79970ed]177        Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {}
[25a054f]178
179OffsetofExpr::~OffsetofExpr() {
180        delete type;
181}
182
[50377a4]183void OffsetofExpr::print( std::ostream &os, Indenter indent) const {
184        os << "Offsetof Expression on member " << member->name << " of ";
185        type->print(os, indent+1);
[25a054f]186        Expression::print( os, indent );
187}
188
[bf4b4cf]189OffsetPackExpr::OffsetPackExpr( StructInstType *type ) : Expression(), type( type ) {
[50377a4]190        assert( type );
[906e24d]191        set_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) );
[afc1045]192}
193
194OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr &other ) : Expression( other ), type( maybeClone( other.type ) ) {}
195
196OffsetPackExpr::~OffsetPackExpr() { delete type; }
197
[50377a4]198void OffsetPackExpr::print( std::ostream &os, Indenter indent ) const {
199        os << "Offset pack expression on ";
200        type->print(os, indent+1);
[25a054f]201        Expression::print( os, indent );
202}
203
[bf4b4cf]204AttrExpr::AttrExpr( Expression *attr, Expression *expr_ ) :
205                Expression(), attr( attr ), expr(expr_), type(0), isType(false) {
[51b7345]206}
207
[bf4b4cf]208AttrExpr::AttrExpr( Expression *attr, Type *type_ ) :
209                Expression(), attr( attr ), expr(0), type(type_), isType(true) {
[51b7345]210}
211
[0dd3a2f]212AttrExpr::AttrExpr( const AttrExpr &other ) :
213                Expression( other ), attr( maybeClone( other.attr ) ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
[51b7345]214}
215
[0dd3a2f]216AttrExpr::~AttrExpr() {
217        delete attr;
218        delete expr;
219        delete type;
[51b7345]220}
221
[50377a4]222void AttrExpr::print( std::ostream &os, Indenter indent) const {
[f19339e]223        os << "Attr ";
[50377a4]224        attr->print( os, indent+1);
[0dd3a2f]225        if ( isType || expr ) {
226                os << "applied to: ";
[50377a4]227                if (isType) type->print(os, indent+1);
228                else expr->print(os, indent+1);
[0dd3a2f]229        } // if
230        Expression::print( os, indent );
[51b7345]231}
232
[bf4b4cf]233CastExpr::CastExpr( Expression *arg_, Type *toType ) : Expression(), arg(arg_) {
[906e24d]234        set_result(toType);
[51b7345]235}
236
[bf4b4cf]237CastExpr::CastExpr( Expression *arg_ ) : Expression(), arg(arg_) {
[906e24d]238        set_result( new VoidType( Type::Qualifiers() ) );
[51b7345]239}
240
[0dd3a2f]241CastExpr::CastExpr( const CastExpr &other ) : Expression( other ), arg( maybeClone( other.arg ) ) {
[51b7345]242}
243
244CastExpr::~CastExpr() {
[0dd3a2f]245        delete arg;
[51b7345]246}
247
[50377a4]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:";
[906e24d]252        if ( result->isVoid() ) {
[50377a4]253                os << " nothing";
[0dd3a2f]254        } else {
[50377a4]255                os << std::endl << indent+1;
256                result->print( os, indent+1 );
[0dd3a2f]257        } // if
258        Expression::print( os, indent );
259}
260
[a5f0529]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
[50377a4]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:";
[a5f0529]276        if ( ! result ) {
[50377a4]277                os << " unknown";
[a5f0529]278        } else {
[50377a4]279                os << std::endl << indent+1;
280                result->print( os, indent+1 );
[a5f0529]281        } // if
282        Expression::print( os, indent );
283}
284
[bf4b4cf]285UntypedMemberExpr::UntypedMemberExpr( Expression * member, Expression *aggregate ) :
286                Expression(), member(member), aggregate(aggregate) {
[50377a4]287        assert( aggregate );
288}
[51b7345]289
[0dd3a2f]290UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr &other ) :
[3b58d91]291                Expression( other ), member( maybeClone( other.member ) ), aggregate( maybeClone( other.aggregate ) ) {
[51b7345]292}
293
294UntypedMemberExpr::~UntypedMemberExpr() {
[0dd3a2f]295        delete aggregate;
[3b58d91]296        delete member;
[51b7345]297}
298
[50377a4]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);
[0dd3a2f]304        Expression::print( os, indent );
[51b7345]305}
306
[d9fa60a]307namespace {
308        TypeSubstitution makeSub( Type * t ) {
[0698aa1]309                if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( t ) ) {
310                        return makeSub( refType->get_base() );
311                } else if ( StructInstType * aggInst = dynamic_cast< StructInstType * >( t ) ) {
[d9fa60a]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 {
[4b0f997]316                        assertf( false, "makeSub expects struct or union type for aggregate, but got: %s", toString( t ).c_str() );
[d9fa60a]317                }
318        }
319}
320
[51b7345]321
[bf4b4cf]322MemberExpr::MemberExpr( DeclarationWithType *member, Expression *aggregate ) :
323                Expression(), member(member), aggregate(aggregate) {
[50377a4]324        assert( member );
325        assert( aggregate );
[d9fa60a]326
327        TypeSubstitution sub( makeSub( aggregate->get_result() ) );
328        Type * res = member->get_type()->clone();
329        sub.apply( res );
330        set_result( res );
[615a096]331        get_result()->set_lvalue( true );
[51b7345]332}
333
[0dd3a2f]334MemberExpr::MemberExpr( const MemberExpr &other ) :
[39f84a4]335                Expression( other ), member( other.member ), aggregate( maybeClone( other.aggregate ) ) {
[51b7345]336}
337
338MemberExpr::~MemberExpr() {
[4551a6e]339        // don't delete the member declaration, since it points somewhere else in the tree
[0dd3a2f]340        delete aggregate;
[51b7345]341}
342
[50377a4]343void MemberExpr::print( std::ostream &os, Indenter indent ) const {
[89231bc]344        os << "Member Expression, with field: " << std::endl;
[50377a4]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);
[0dd3a2f]349        Expression::print( os, indent );
[51b7345]350}
351
[bf4b4cf]352UntypedExpr::UntypedExpr( Expression *function, const std::list<Expression *> &args ) :
353                Expression(), function(function), args(args) {}
[51b7345]354
[0dd3a2f]355UntypedExpr::UntypedExpr( const UntypedExpr &other ) :
356                Expression( other ), function( maybeClone( other.function ) ) {
357        cloneAll( other.args, args );
[51b7345]358}
359
[ac71a86]360UntypedExpr::~UntypedExpr() {
361        delete function;
[03b812d2]362        deleteAll( args );
[ac71a86]363}
[51b7345]364
[b3b2077]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 );
[0698aa1]369                assertf( base, "expected pointer type in dereference (type was %s)", toString( type ).c_str() );
[b0440b7]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                }
[b3b2077]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
[50377a4]394void UntypedExpr::print( std::ostream &os, Indenter indent ) const {
[89231bc]395        os << "Applying untyped: " << std::endl;
[50377a4]396        os << indent+1;
397        function->print(os, indent+1);
398        os << std::endl << indent << "...to: " << std::endl;
399        printAll(args, os, indent+1);
[0dd3a2f]400        Expression::print( os, indent );
[51b7345]401}
402
[bf4b4cf]403NameExpr::NameExpr( std::string name ) : Expression(), name(name) {
[50377a4]404        assertf(name != "0", "Zero is not a valid name");
405        assertf(name != "1", "One is not a valid name");
[4cb935e]406}
[51b7345]407
[0dd3a2f]408NameExpr::NameExpr( const NameExpr &other ) : Expression( other ), name( other.name ) {
[51b7345]409}
410
411NameExpr::~NameExpr() {}
412
[50377a4]413void NameExpr::print( std::ostream &os, Indenter indent ) const {
414        os << "Name: " << get_name();
[0dd3a2f]415        Expression::print( os, indent );
[51b7345]416}
417
[bf4b4cf]418LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp ) :
419                Expression(), arg1(arg1_), arg2(arg2_), isAnd(andp) {
[906e24d]420        set_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
[51b7345]421}
422
[0dd3a2f]423LogicalExpr::LogicalExpr( const LogicalExpr &other ) :
424                Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), isAnd( other.isAnd ) {
[51b7345]425}
426
[a08ba92]427LogicalExpr::~LogicalExpr() {
[0dd3a2f]428        delete arg1;
429        delete arg2;
[51b7345]430}
431
[50377a4]432void LogicalExpr::print( std::ostream &os, Indenter indent )const {
433        os << "Short-circuited operation (" << (isAnd ? "and" : "or") << ") on: ";
[0dd3a2f]434        arg1->print(os);
435        os << " and ";
436        arg2->print(os);
437        Expression::print( os, indent );
[51b7345]438}
439
[bf4b4cf]440ConditionalExpr::ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3 ) :
441                Expression(), arg1(arg1), arg2(arg2), arg3(arg3) {}
[51b7345]442
[0dd3a2f]443ConditionalExpr::ConditionalExpr( const ConditionalExpr &other ) :
444                Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), arg3( maybeClone( other.arg3 ) ) {
445}
[51b7345]446
447ConditionalExpr::~ConditionalExpr() {
[0dd3a2f]448        delete arg1;
449        delete arg2;
450        delete arg3;
[51b7345]451}
452
[50377a4]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 );
[0dd3a2f]460        Expression::print( os, indent );
461}
462
[e6cee92]463AsmExpr::AsmExpr( const AsmExpr & other ) : Expression( other ), inout( maybeClone( other.inout ) ), constraint( maybeClone( other.constraint ) ), operand( maybeClone( other.operand ) ) {}
[3be261a]464
465
[50377a4]466void AsmExpr::print( std::ostream &os, Indenter indent ) const {
[7f5566b]467        os << "Asm Expression: " << std::endl;
[50377a4]468        if ( inout ) inout->print( os, indent+1 );
469        if ( constraint ) constraint->print( os, indent+1 );
470        if ( operand ) operand->print( os, indent+1 );
[7f5566b]471}
472
[db4ecc5]473
474ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( ApplicationExpr * callExpr ) : callExpr( callExpr ) {
475        assert( callExpr );
[50377a4]476        assert( callExpr->result );
[906e24d]477        set_result( callExpr->get_result()->clone() );
[db4ecc5]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() {
[d5556a3]487        set_env( nullptr ); // ImplicitCopyCtorExpr does not take ownership of an environment
[db4ecc5]488        delete callExpr;
489        deleteAll( tempDecls );
490        deleteAll( returnDecls );
491        deleteAll( dtors );
492}
493
[50377a4]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 );
[db4ecc5]501        Expression::print( os, indent );
502}
503
[3be261a]504
[b6fe7e6]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 );
[50377a4]510        set_result( maybeClone( arg->result ) );
[b6fe7e6]511}
[3be261a]512
[b6fe7e6]513ConstructorExpr::ConstructorExpr( const ConstructorExpr & other ) : Expression( other ), callExpr( maybeClone( other.callExpr ) ) {
514}
515
516ConstructorExpr::~ConstructorExpr() {
517        delete callExpr;
518}
519
[50377a4]520void ConstructorExpr::print( std::ostream &os, Indenter indent ) const {
521        os <<  "Constructor Expression: " << std::endl << indent+1;
[b6fe7e6]522        callExpr->print( os, indent + 2 );
523        Expression::print( os, indent );
[0dd3a2f]524}
525
[3be261a]526
[fbcde64]527CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : initializer( initializer ) {
[3c13c03]528        assert( type && initializer );
[5ccb10d]529        type->set_lvalue( true );
[fbcde64]530        set_result( type );
[630a82a]531}
532
[fbcde64]533CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), initializer( other.initializer->clone() ) {}
[630a82a]534
535CompoundLiteralExpr::~CompoundLiteralExpr() {
536        delete initializer;
537}
538
[50377a4]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 );
[d5556a3]544        Expression::print( os, indent );
[630a82a]545}
546
[d9e2280]547RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {}
[3c13c03]548RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {}
[50377a4]549void RangeExpr::print( std::ostream &os, Indenter indent ) const {
[3c13c03]550        os << "Range Expression: ";
[8688ce1]551        low->print( os, indent );
552        os << " ... ";
553        high->print( os, indent );
[d5556a3]554        Expression::print( os, indent );
[8688ce1]555}
[3be261a]556
[6eb8948]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() ) ) {
[aa8f9df]562                        set_result( maybeClone( exprStmt->get_expr()->get_result() ) );
[6eb8948]563                }
564        }
[07516b56]565        // ensure that StmtExpr has a result type
566        if ( ! result ) {
567                set_result( new VoidType( Type::Qualifiers() ) );
568        }
[6eb8948]569}
[d5556a3]570StmtExpr::StmtExpr( const StmtExpr &other ) : Expression( other ), statements( other.statements->clone() ) {
571        cloneAll( other.returnDecls, returnDecls );
572        cloneAll( other.dtors, dtors );
573}
[6eb8948]574StmtExpr::~StmtExpr() {
575        delete statements;
[d5556a3]576        deleteAll( dtors );
577        deleteAll( returnDecls );
[6eb8948]578}
[50377a4]579void StmtExpr::print( std::ostream &os, Indenter indent ) const {
580        os << "Statement Expression: " << std::endl << indent+1;
581        statements->print( os, indent+1 );
[d5556a3]582        if ( ! returnDecls.empty() ) {
[50377a4]583                os << indent+1 << "... with returnDecls: ";
584                printAll( returnDecls, os, indent+1 );
[d5556a3]585        }
586        if ( ! dtors.empty() ) {
[50377a4]587                os << indent+1 << "... with dtors: ";
588                printAll( dtors, os, indent+1 );
[d5556a3]589        }
590        Expression::print( os, indent );
[6eb8948]591}
592
[3c13c03]593
[bf32bb8]594long long UniqueExpr::count = 0;
[141b786]595UniqueExpr::UniqueExpr( Expression *expr, long long idVal ) : expr( expr ), object( nullptr ), var( nullptr ), id( idVal ) {
596        assert( expr );
[bf32bb8]597        assert( count != -1 );
598        if ( id == -1 ) id = count++;
599        if ( expr->get_result() ) {
600                set_result( expr->get_result()->clone() );
601        }
[3c13c03]602}
[141b786]603UniqueExpr::UniqueExpr( const UniqueExpr &other ) : Expression( other ), expr( maybeClone( other.expr ) ), object( maybeClone( other.object ) ), var( maybeClone( other.var ) ), id( other.id ) {
[3c13c03]604}
605UniqueExpr::~UniqueExpr() {
[141b786]606        delete expr;
607        delete object;
608        delete var;
[3c13c03]609}
[50377a4]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 );
[77971f6]616        }
[d5556a3]617        Expression::print( os, indent );
[3c13c03]618}
619
[e4d829b]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
[50377a4]633void UntypedInitExpr::print( std::ostream & os, Indenter indent ) const {
634        os << "Untyped Init Expression" << std::endl << indent+1;
635        expr->print( os, indent+1 );
[e4d829b]636        if ( ! initAlts.empty() ) {
637                for ( const InitAlternative & alt : initAlts ) {
[50377a4]638                        os << indent+1 <<  "InitAlternative: ";
639                        alt.type->print( os, indent+1 );
640                        alt.designation->print( os, indent+1 );
[e4d829b]641                }
642        }
643}
644
[62423350]645InitExpr::InitExpr( Expression * expr, Designation * designation ) : expr( expr ), designation( designation ) {
646        set_result( expr->get_result()->clone() );
[e4d829b]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
[50377a4]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 );
[e4d829b]659}
660
[0dd3a2f]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.