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
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
[bf4b4cf]37Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), extension( other.extension ) {
[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.