mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
Call desctructors on temporary variables
This commit is contained in:
@@ -203,6 +203,7 @@ struct Expression : Object
|
||||
|
||||
#if IN_LLVM
|
||||
virtual DValue* toElem(IRState* irs);
|
||||
DValue *toElemDtor(IRState *irs);
|
||||
virtual llvm::Constant *toConstElem(IRState *irs);
|
||||
virtual void cacheLvalue(IRState* irs);
|
||||
|
||||
|
||||
@@ -52,6 +52,11 @@ struct IRScope
|
||||
IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e);
|
||||
|
||||
const IRScope& operator=(const IRScope& rhs);
|
||||
|
||||
#if DMDV2
|
||||
// list of variables needing destruction
|
||||
std::vector<VarDeclaration*> varsInScope;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct IRBuilderHelper
|
||||
@@ -134,6 +139,7 @@ struct IRState
|
||||
// basic block scopes
|
||||
std::vector<IRScope> scopes;
|
||||
IRScope& scope();
|
||||
std::vector<VarDeclaration*> &varsInScope() { return scope().varsInScope; }
|
||||
llvm::BasicBlock* scopebb();
|
||||
llvm::BasicBlock* scopeend();
|
||||
bool scopereturned();
|
||||
|
||||
@@ -1037,6 +1037,16 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
|
||||
Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n';
|
||||
if (!vd->isRef())
|
||||
DtoInitializer(vd->ir.irLocal->value, vd->init); // TODO: Remove altogether?
|
||||
|
||||
#if DMDV2
|
||||
/* Mark the point of construction of a variable that needs to be destructed.
|
||||
*/
|
||||
if (vd->edtor && !vd->noscope)
|
||||
{
|
||||
// Put vd on list of things needing destruction
|
||||
gIR->varsInScope().push_back(vd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return new DVarValue(vd->type, vd, vd->ir.getIrValue());
|
||||
|
||||
@@ -92,7 +92,7 @@ void ReturnStatement::toIR(IRState* p)
|
||||
|
||||
// get return pointer
|
||||
DValue* rvar = new DVarValue(f->type->next, f->decl->ir.irFunc->retArg);
|
||||
DValue* e = exp->toElem(p);
|
||||
DValue* e = exp->toElemDtor(p);
|
||||
// store return value
|
||||
DtoAssign(loc, rvar, e);
|
||||
|
||||
@@ -118,7 +118,7 @@ void ReturnStatement::toIR(IRState* p)
|
||||
else
|
||||
{
|
||||
LLValue* v;
|
||||
DValue* dval = exp->toElem(p);
|
||||
DValue* dval = exp->toElemDtor(p);
|
||||
|
||||
#if DMDV2
|
||||
// call postblit if necessary
|
||||
@@ -219,10 +219,10 @@ void ExpStatement::toIR(IRState* p)
|
||||
// a cast(void) around the expression is allowed, but doesn't require any code
|
||||
if(exp->op == TOKcast && exp->type == Type::tvoid) {
|
||||
CastExp* cexp = (CastExp*)exp;
|
||||
e = cexp->e1->toElem(p);
|
||||
e = cexp->e1->toElemDtor(p);
|
||||
}
|
||||
else
|
||||
e = exp->toElem(p);
|
||||
e = exp->toElemDtor(p);
|
||||
delete e;
|
||||
}
|
||||
/*elem* e = exp->toElem(p);
|
||||
@@ -246,7 +246,7 @@ void IfStatement::toIR(IRState* p)
|
||||
if (match)
|
||||
DtoRawVarDeclaration(match);
|
||||
|
||||
DValue* cond_e = condition->toElem(p);
|
||||
DValue* cond_e = condition->toElemDtor(p);
|
||||
LLValue* cond_val = cond_e->getRVal();
|
||||
|
||||
llvm::BasicBlock* oldend = gIR->scopeend();
|
||||
@@ -347,7 +347,7 @@ void WhileStatement::toIR(IRState* p)
|
||||
gIR->scope() = IRScope(whilebb,endbb);
|
||||
|
||||
// create the condition
|
||||
DValue* cond_e = condition->toElem(p);
|
||||
DValue* cond_e = condition->toElemDtor(p);
|
||||
LLValue* cond_val = DtoCast(loc, cond_e, Type::tbool)->getRVal();
|
||||
delete cond_e;
|
||||
|
||||
@@ -407,7 +407,7 @@ void DoStatement::toIR(IRState* p)
|
||||
gIR->scope() = IRScope(condbb,endbb);
|
||||
|
||||
// create the condition
|
||||
DValue* cond_e = condition->toElem(p);
|
||||
DValue* cond_e = condition->toElemDtor(p);
|
||||
LLValue* cond_val = DtoCast(loc, cond_e, Type::tbool)->getRVal();
|
||||
delete cond_e;
|
||||
|
||||
@@ -454,7 +454,7 @@ void ForStatement::toIR(IRState* p)
|
||||
LLValue* cond_val;
|
||||
if (condition)
|
||||
{
|
||||
DValue* cond_e = condition->toElem(p);
|
||||
DValue* cond_e = condition->toElemDtor(p);
|
||||
cond_val = DtoCast(loc, cond_e, Type::tbool)->getRVal();
|
||||
delete cond_e;
|
||||
}
|
||||
@@ -481,7 +481,7 @@ void ForStatement::toIR(IRState* p)
|
||||
|
||||
// increment
|
||||
if (increment) {
|
||||
DValue* inc = increment->toElem(p);
|
||||
DValue* inc = increment->toElemDtor(p);
|
||||
delete inc;
|
||||
}
|
||||
|
||||
@@ -776,7 +776,7 @@ void ThrowStatement::toIR(IRState* p)
|
||||
#endif
|
||||
|
||||
assert(exp);
|
||||
DValue* e = exp->toElem(p);
|
||||
DValue* e = exp->toElemDtor(p);
|
||||
|
||||
#ifndef DISABLE_DEBUG_INFO
|
||||
if (global.params.symdebug) DtoDwarfFuncEnd(gIR->func()->decl);
|
||||
@@ -842,7 +842,7 @@ static LLValue* call_string_switch_runtime(llvm::Value* table, Expression* e)
|
||||
}
|
||||
assert(table->getType() == fn->getFunctionType()->getParamType(0));
|
||||
|
||||
DValue* val = e->toElem(gIR);
|
||||
DValue* val = e->toElemDtor(gIR);
|
||||
LLValue* llval = val->getRVal();
|
||||
assert(llval->getType() == fn->getFunctionType()->getParamType(1));
|
||||
|
||||
@@ -883,7 +883,7 @@ void SwitchStatement::toIR(IRState* p)
|
||||
if (cs->exp->op == TOKvar)
|
||||
vd = ((VarExp*)cs->exp)->var->isVarDeclaration();
|
||||
if (vd && !vd->init) {
|
||||
cs->llvmIdx = cs->exp->toElem(p)->getRVal();
|
||||
cs->llvmIdx = cs->exp->toElemDtor(p)->getRVal();
|
||||
useSwitchInst = false;
|
||||
}
|
||||
}
|
||||
@@ -965,7 +965,7 @@ void SwitchStatement::toIR(IRState* p)
|
||||
LLValue* condVal;
|
||||
// integral switch
|
||||
if (condition->type->isintegral()) {
|
||||
DValue* cond = condition->toElem(p);
|
||||
DValue* cond = condition->toElemDtor(p);
|
||||
condVal = cond->getRVal();
|
||||
}
|
||||
// string switch
|
||||
@@ -983,7 +983,7 @@ void SwitchStatement::toIR(IRState* p)
|
||||
}
|
||||
else
|
||||
{ // we can't use switch, so we will use a bunch of br instructions instead
|
||||
DValue* cond = condition->toElem(p);
|
||||
DValue* cond = condition->toElemDtor(p);
|
||||
LLValue *condVal = cond->getRVal();
|
||||
|
||||
llvm::BasicBlock* nextbb = llvm::BasicBlock::Create(gIR->context(), "checkcase", p->topfunc(), oldend);
|
||||
@@ -1177,7 +1177,7 @@ void ForeachStatement::toIR(IRState* p)
|
||||
}
|
||||
|
||||
// what to iterate
|
||||
DValue* aggrval = aggr->toElem(p);
|
||||
DValue* aggrval = aggr->toElemDtor(p);
|
||||
|
||||
// get length and pointer
|
||||
LLValue* niters = DtoArrayLen(aggrval);
|
||||
@@ -1281,9 +1281,9 @@ void ForeachRangeStatement::toIR(IRState* p)
|
||||
|
||||
// evaluate lwr/upr
|
||||
assert(lwr->type->isintegral());
|
||||
LLValue* lower = lwr->toElem(p)->getRVal();
|
||||
LLValue* lower = lwr->toElemDtor(p)->getRVal();
|
||||
assert(upr->type->isintegral());
|
||||
LLValue* upper = upr->toElem(p)->getRVal();
|
||||
LLValue* upper = upr->toElemDtor(p)->getRVal();
|
||||
|
||||
// handle key
|
||||
assert(key->type->isintegral());
|
||||
@@ -1506,7 +1506,7 @@ void WithStatement::toIR(IRState* p)
|
||||
// with(..) can either be used with expressions or with symbols
|
||||
// wthis == null indicates the symbol form
|
||||
if (wthis) {
|
||||
DValue* e = exp->toElem(p);
|
||||
DValue* e = exp->toElemDtor(p);
|
||||
LLValue* mem = DtoRawVarDeclaration(wthis);
|
||||
DtoStore(e->getRVal(), mem);
|
||||
}
|
||||
|
||||
33
gen/toir.cpp
33
gen/toir.cpp
@@ -56,6 +56,31 @@ void Expression::cacheLvalue(IRState* irs)
|
||||
fatal();
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* Evaluate Expression, then call destructors on any temporaries in it.
|
||||
*/
|
||||
|
||||
DValue *Expression::toElemDtor(IRState *irs)
|
||||
{
|
||||
#if DMDV2
|
||||
Logger::println("Expression::toElemDtor(): %s", toChars());
|
||||
size_t starti = irs->varsInScope().size();
|
||||
DValue *val = toElem(irs);
|
||||
size_t endi = irs->varsInScope().size();
|
||||
|
||||
// Add destructors
|
||||
while (endi-- > starti)
|
||||
{
|
||||
VarDeclaration *vd = gIR->varsInScope().back();
|
||||
gIR->varsInScope().pop_back();
|
||||
vd->edtor->toElem(gIR);
|
||||
}
|
||||
return val;
|
||||
#else
|
||||
return toElem(irs);
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* DeclarationExp::toElem(IRState* p)
|
||||
@@ -2045,7 +2070,7 @@ DValue* AndAndExp::toElem(IRState* p)
|
||||
llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb());
|
||||
|
||||
p->scope() = IRScope(andand, andandend);
|
||||
DValue* v = e2->toElem(p);
|
||||
DValue* v = e2->toElemDtor(p);
|
||||
|
||||
LLValue* vbool = 0;
|
||||
if (!v->isFunc() && v->getType() != Type::tvoid)
|
||||
@@ -2092,7 +2117,7 @@ DValue* OrOrExp::toElem(IRState* p)
|
||||
llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb());
|
||||
|
||||
p->scope() = IRScope(oror, ororend);
|
||||
DValue* v = e2->toElem(p);
|
||||
DValue* v = e2->toElemDtor(p);
|
||||
|
||||
LLValue* vbool = 0;
|
||||
if (v && !v->isFunc() && v->getType() != Type::tvoid)
|
||||
@@ -2359,13 +2384,13 @@ DValue* CondExp::toElem(IRState* p)
|
||||
llvm::BranchInst::Create(condtrue,condfalse,cond_val,p->scopebb());
|
||||
|
||||
p->scope() = IRScope(condtrue, condfalse);
|
||||
DValue* u = e1->toElem(p);
|
||||
DValue* u = e1->toElemDtor(p);
|
||||
if (dtype->ty != Tvoid)
|
||||
DtoAssign(loc, dvv, u);
|
||||
llvm::BranchInst::Create(condend,p->scopebb());
|
||||
|
||||
p->scope() = IRScope(condfalse, condend);
|
||||
DValue* v = e2->toElem(p);
|
||||
DValue* v = e2->toElemDtor(p);
|
||||
if (dtype->ty != Tvoid)
|
||||
DtoAssign(loc, dvv, v);
|
||||
llvm::BranchInst::Create(condend,p->scopebb());
|
||||
|
||||
Reference in New Issue
Block a user