diff --git a/gen/statements.cpp b/gen/statements.cpp index 5a2ff209..428a0379 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -678,7 +678,6 @@ void TryFinallyStatement::toIR(IRState* p) pad.addFinally(finalbody); pad.push(landingpadbb); gIR->func()->gen->targetScopes.push_back(IRTargetScope(this,new EnclosingTryFinally(this,gIR->func()->gen->landingPad),NULL,NULL)); - gIR->func()->gen->landingPad = pad.get(); // // do the try block @@ -695,7 +694,6 @@ void TryFinallyStatement::toIR(IRState* p) llvm::BranchInst::Create(finallybb, p->scopebb()); pad.pop(); - gIR->func()->gen->landingPad = pad.get(); gIR->func()->gen->targetScopes.pop_back(); // @@ -739,7 +737,7 @@ void TryCatchStatement::toIR(IRState* p) llvm::BranchInst::Create(trybb, p->scopebb()); // - // do catches and the landing pad + // set up the landing pad // assert(catches); gIR->scope() = IRScope(landingpadbb, endbb); @@ -752,7 +750,6 @@ void TryCatchStatement::toIR(IRState* p) } pad.push(landingpadbb); - gIR->func()->gen->landingPad = pad.get(); // // do the try block @@ -768,7 +765,6 @@ void TryCatchStatement::toIR(IRState* p) llvm::BranchInst::Create(endbb, p->scopebb()); pad.pop(); - gIR->func()->gen->landingPad = pad.get(); // rewrite the scope p->scope() = IRScope(endbb,oldend); diff --git a/ir/irlandingpad.cpp b/ir/irlandingpad.cpp index ddc7d495..491d5089 100644 --- a/ir/irlandingpad.cpp +++ b/ir/irlandingpad.cpp @@ -8,11 +8,39 @@ #include "gen/todebug.h" #include "ir/irlandingpad.h" -IRLandingPadInfo::IRLandingPadInfo(Catch* catchstmt, llvm::BasicBlock* end) -: finallyBody(NULL) +IRLandingPadInfo::IRLandingPadInfo(Catch* catchstmt_, llvm::BasicBlock* end_) : + finallyBody(NULL), catchstmt(catchstmt_), end(end_) { target = llvm::BasicBlock::Create(gIR->context(), "catch", gIR->topfunc(), end); - gIR->scope() = IRScope(target,end); + + assert(catchstmt->type); + catchType = catchstmt->type->toBasetype()->isClassHandle(); + assert(catchType); + catchType->codegen(Type::sir); + + if(catchstmt->var) { + #if DMDV2 + if(!catchstmt->var->nestedrefs.dim) { + #else + if(!catchstmt->var->nestedref) { + #endif + gIR->func()->gen->landingPadInfo.getExceptionStorage(); + } + } +} + +IRLandingPadInfo::IRLandingPadInfo(Statement* finallystmt) : + target(NULL), finallyBody(finallystmt), catchstmt(NULL) +{ + +} + +void IRLandingPadInfo::toIR() +{ + if (!catchstmt) + return; + + gIR->scope() = IRScope(target, target); DtoDwarfBlockStart(catchstmt->loc); // assign storage to catch var @@ -48,19 +76,9 @@ IRLandingPadInfo::IRLandingPadInfo(Catch* catchstmt, llvm::BasicBlock* end) if (!gIR->scopereturned()) gIR->ir->CreateBr(end); - assert(catchstmt->type); - catchType = catchstmt->type->toBasetype()->isClassHandle(); - assert(catchType); - catchType->codegen(Type::sir); DtoDwarfBlockEnd(); } -IRLandingPadInfo::IRLandingPadInfo(Statement* finallystmt) -: target(NULL), finallyBody(finallystmt), catchType(NULL) -{ - -} - void IRLandingPad::addCatch(Catch* catchstmt, llvm::BasicBlock* end) { @@ -79,17 +97,22 @@ void IRLandingPad::push(llvm::BasicBlock* inBB) infos.insert(infos.end(), unpushed_infos.begin(), unpushed_infos.end()); unpushed_infos.clear(); - constructLandingPad(inBB); - // store as invoke target padBBs.push(inBB); + gIR->func()->gen->landingPad = get(); } void IRLandingPad::pop() { + llvm::BasicBlock *inBB = padBBs.top(); padBBs.pop(); + gIR->func()->gen->landingPad = get(); size_t n = nInfos.top(); + for (int i = n, c = infos.size(); i < c; ++i) + infos.at(i).toIR(); + constructLandingPad(inBB); + infos.resize(n); nInfos.pop(); } diff --git a/ir/irlandingpad.h b/ir/irlandingpad.h index 45d6cba7..78e3f37f 100644 --- a/ir/irlandingpad.h +++ b/ir/irlandingpad.h @@ -19,8 +19,8 @@ namespace llvm { struct IRLandingPadInfo { // default constructor for being able to store in a vector - IRLandingPadInfo() - : target(NULL), finallyBody(NULL), catchType(NULL) + IRLandingPadInfo() : + target(NULL), finallyBody(NULL), catchstmt(NULL) {} // constructor for catch @@ -29,6 +29,9 @@ struct IRLandingPadInfo // constructor for finally IRLandingPadInfo(Statement* finallystmt); + // codegen the catch block + void toIR(); + // the target catch bb if this is a catch // or the target finally bb if this is a finally llvm::BasicBlock* target; @@ -37,6 +40,8 @@ struct IRLandingPadInfo Statement* finallyBody; // nonzero if this is a catch + Catch* catchstmt; + llvm::BasicBlock* end; ClassDeclaration* catchType; }; @@ -47,7 +52,7 @@ struct IRLandingPad { IRLandingPad() : catch_var(NULL) {} - // builds a new landing pad according to given infos + // creates a new landing pad according to given infos // and the ones on the stack. also stores it as invoke target void push(llvm::BasicBlock* inBB); @@ -56,7 +61,8 @@ struct IRLandingPad // add finally information, will be used in next call to push void addFinally(Statement* finallystmt); - // pops the most recently constructed landing pad bb + // builds the most recently constructed landing pad + // and the catch blocks, then pops the landing pad bb // and its infos void pop();