diff options
author | John McCall <rjmccall@apple.com> | 2010-07-21 00:52:03 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-07-21 00:52:03 +0000 |
commit | 55b20fc514678ff8ae1627cd9aef047d1f780119 (patch) | |
tree | 3194b078be072f82aa9143c1ffddd4fce5d4581f /lib/CodeGen/CGException.cpp | |
parent | 11f5ccf2d88c2ea600ed950831f100ed96d89fed (diff) |
Convert the end-catch call for finally blocks to a lazy cleanup. This kills off
the last of the shared-code cleanups.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108975 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGException.cpp')
-rw-r--r-- | lib/CodeGen/CGException.cpp | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index 4649b90156..f0c1d5193d 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -1337,6 +1337,28 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) { EmitBlock(ContBB); } +namespace { + struct CallEndCatchForFinally : EHScopeStack::LazyCleanup { + llvm::Value *ForEHVar; + llvm::Value *EndCatchFn; + CallEndCatchForFinally(llvm::Value *ForEHVar, llvm::Value *EndCatchFn) + : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {} + + void Emit(CodeGenFunction &CGF, bool IsForEH) { + llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch"); + llvm::BasicBlock *CleanupContBB = + CGF.createBasicBlock("finally.cleanup.cont"); + + llvm::Value *ShouldEndCatch = + CGF.Builder.CreateLoad(ForEHVar, "finally.endcatch"); + CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB); + CGF.EmitBlock(EndCatchBB); + CGF.EmitCallOrInvoke(EndCatchFn, 0, 0); // catch-all, so might throw + CGF.EmitBlock(CleanupContBB); + } + }; +} + /// Enters a finally block for an implementation using zero-cost /// exceptions. This is mostly general, but hard-codes some /// language/ABI-specific behavior in the catch-all sections. @@ -1392,19 +1414,9 @@ CodeGenFunction::EnterFinallyBlock(const Stmt *Body, CodeGenFunction::CleanupBlock Cleanup(*this, NormalCleanup); // Enter a cleanup to call the end-catch function if one was provided. - if (EndCatchFn) { - CodeGenFunction::CleanupBlock FinallyExitCleanup(CGF, NormalAndEHCleanup); - - llvm::BasicBlock *EndCatchBB = createBasicBlock("finally.endcatch"); - llvm::BasicBlock *CleanupContBB = createBasicBlock("finally.cleanup.cont"); - - llvm::Value *ShouldEndCatch = - Builder.CreateLoad(ForEHVar, "finally.endcatch"); - Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB); - EmitBlock(EndCatchBB); - EmitCallOrInvoke(EndCatchFn, 0, 0); // catch-all, so might throw - EmitBlock(CleanupContBB); - } + if (EndCatchFn) + EHStack.pushLazyCleanup<CallEndCatchForFinally>(NormalAndEHCleanup, + ForEHVar, EndCatchFn); // Emit the finally block. EmitStmt(Body); |