aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenFunction.h
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-06-22 02:32:12 +0000
committerJohn McCall <rjmccall@apple.com>2011-06-22 02:32:12 +0000
commitd768e9d29abe1ac1ccc3ed63f2dce835d9bab342 (patch)
tree70f54ed568bf18e819cc844e1a0e2d4a42313a8f /lib/CodeGen/CodeGenFunction.h
parent4dba7b56d4551b7e03e20eeb7f45e5c962baa20c (diff)
Emit @finally blocks completely lazily instead of forcing their
existence by always threading an edge from the catchall. Not doing this was previously causing a crash in the very extreme case where neither the normal cleanup nor the EH catchall was actually reachable: we would delete the catchall entry block, which would cause us to delete the entry block of the finally cleanup as well because the cleanup logic would merge the blocks, which in turn triggered an assert because later blocks in the finally would still be using values from the entry. Laziness turns out to be the most elegant solution to the problem. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133601 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.h')
-rw-r--r--lib/CodeGen/CodeGenFunction.h30
1 files changed, 21 insertions, 9 deletions
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index e72d6ced92..1aaa700f7e 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -635,16 +635,28 @@ public:
/// rethrows.
llvm::SmallVector<llvm::Value*, 8> ObjCEHValueStack;
- // A struct holding information about a finally block's IR
- // generation. For now, doesn't actually hold anything.
- struct FinallyInfo {
- };
+ /// A class controlling the emission of a finally block.
+ class FinallyInfo {
+ /// Where the catchall's edge through the cleanup should go.
+ JumpDest RethrowDest;
+
+ /// A function to call to enter the catch.
+ llvm::Constant *BeginCatchFn;
+
+ /// An i1 variable indicating whether or not the @finally is
+ /// running for an exception.
+ llvm::AllocaInst *ForEHVar;
- FinallyInfo EnterFinallyBlock(const Stmt *Stmt,
- llvm::Constant *BeginCatchFn,
- llvm::Constant *EndCatchFn,
- llvm::Constant *RethrowFn);
- void ExitFinallyBlock(FinallyInfo &FinallyInfo);
+ /// An i8* variable into which the exception pointer to rethrow
+ /// has been saved.
+ llvm::AllocaInst *SavedExnVar;
+
+ public:
+ void enter(CodeGenFunction &CGF, const Stmt *Finally,
+ llvm::Constant *beginCatchFn, llvm::Constant *endCatchFn,
+ llvm::Constant *rethrowFn);
+ void exit(CodeGenFunction &CGF);
+ };
/// pushFullExprCleanup - Push a cleanup to be run at the end of the
/// current full-expression. Safe against the possibility that