mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-07 03:16:05 +03:00
Issue #426 part 2. Generate a try-finally block only if it is required
(i.e. there are actually some destructor calls that are needed to be put into finally)
This commit is contained in:
parent
71023952d4
commit
1999749415
3 changed files with 57 additions and 43 deletions
|
@ -72,9 +72,6 @@ struct IRScope
|
|||
IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e);
|
||||
|
||||
const IRScope& operator=(const IRScope& rhs);
|
||||
|
||||
// list of variables needing destruction
|
||||
std::vector<VarDeclaration*> varsInScope;
|
||||
};
|
||||
|
||||
struct IRBuilderHelper
|
||||
|
@ -157,7 +154,6 @@ 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();
|
||||
|
|
|
@ -1055,7 +1055,7 @@ void DtoVarDeclaration(VarDeclaration* vd)
|
|||
{
|
||||
vd->ir.irLocal->value = val;
|
||||
}
|
||||
goto Lexit;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1087,15 +1087,6 @@ void DtoVarDeclaration(VarDeclaration* vd)
|
|||
ex->exp->toElem(gIR);
|
||||
}
|
||||
}
|
||||
|
||||
Lexit:
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
DValue* DtoDeclarationExp(Dsymbol* declaration)
|
||||
|
|
51
gen/toir.cpp
51
gen/toir.cpp
|
@ -72,7 +72,11 @@ DValue *Expression::toElemDtor(IRState *p)
|
|||
|
||||
class CallDestructors : public IRLandingPadCatchFinallyInfo {
|
||||
public:
|
||||
std::vector<Expression*> edtors;
|
||||
CallDestructors(const std::vector<Expression*> &edtors_)
|
||||
: edtors(edtors_)
|
||||
{}
|
||||
|
||||
const std::vector<Expression*> &edtors;
|
||||
|
||||
void toIR(LLValue */*eh_ptr*/ = 0)
|
||||
{
|
||||
|
@ -80,10 +84,39 @@ DValue *Expression::toElemDtor(IRState *p)
|
|||
for (itr = edtors.rbegin(); itr != end; ++itr)
|
||||
(*itr)->toElem(gIR);
|
||||
}
|
||||
|
||||
static int searchVarsWithDesctructors(Expression *exp, void *edtors)
|
||||
{
|
||||
if (exp->op == TOKdeclaration) {
|
||||
DeclarationExp *de = (DeclarationExp*)exp;
|
||||
if (VarDeclaration *vd = de->declaration->isVarDeclaration()) {
|
||||
while (vd->aliassym) {
|
||||
vd = vd->aliassym->isVarDeclaration();
|
||||
if (!vd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vd->init) {
|
||||
if (ExpInitializer *ex = vd->init->isExpInitializer())
|
||||
ex->exp->apply(&searchVarsWithDesctructors, edtors);
|
||||
}
|
||||
|
||||
if (!vd->isDataseg() && vd->edtor && !vd->noscope)
|
||||
static_cast<std::vector<Expression*>*>(edtors)->push_back(vd->edtor);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// find destructors that must be called
|
||||
std::vector<Expression*> edtors;
|
||||
apply(&CallDestructors::searchVarsWithDesctructors, &edtors);
|
||||
|
||||
if (!edtors.empty()) {
|
||||
// create finally block that calls destructors on temporaries
|
||||
CallDestructors *callDestructors = new CallDestructors;
|
||||
CallDestructors *callDestructors = new CallDestructors(edtors);
|
||||
|
||||
// create landing pad
|
||||
llvm::BasicBlock *oldend = p->scopeend();
|
||||
|
@ -94,17 +127,8 @@ DValue *Expression::toElemDtor(IRState *p)
|
|||
pad.addFinally(callDestructors);
|
||||
pad.push(landingpadbb);
|
||||
|
||||
// evaluate expression
|
||||
size_t starti = p->varsInScope().size();
|
||||
// evaluate the expression
|
||||
DValue *val = toElem(p);
|
||||
size_t endi = p->varsInScope().size();
|
||||
|
||||
// prepare list of the destructors
|
||||
while (endi-- > starti) {
|
||||
VarDeclaration *vd = gIR->varsInScope().back();
|
||||
gIR->varsInScope().pop_back();
|
||||
callDestructors->edtors.push_back(vd->edtor);
|
||||
}
|
||||
|
||||
// build the landing pad
|
||||
llvm::BasicBlock *oldbb = p->scopebb();
|
||||
|
@ -115,6 +139,9 @@ DValue *Expression::toElemDtor(IRState *p)
|
|||
callDestructors->toIR();
|
||||
delete callDestructors;
|
||||
return val;
|
||||
} else {
|
||||
return toElem(p);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue