aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-12-02 07:41:41 +0000
committerMike Stump <mrs@apple.com>2009-12-02 07:41:41 +0000
commit99533834ba8f3658559f334e68a518ebb6388cea (patch)
treeb6c92246d2d7ed9dfbc8c500363106cb37e964cd /lib/CodeGen/CodeGenFunction.cpp
parent5fcf1f0df06e72581647efd579f970378f77eb55 (diff)
More exception handling improvements... WIP.
Highlights include: Add a helper to generate __cxa_free_exception and _ZSt9terminatev. Add a region to handle EH object deallocation for ctor failures for throw. Add a terminate handler for __cxa_end_catch. A framework for adding cleanup actions for the exceptional edges only. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90305 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp31
1 files changed, 22 insertions, 9 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 6e0a77ca1b..1e952f9a7d 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -606,8 +606,10 @@ llvm::Value* CodeGenFunction::EmitVAListRef(const Expr* E) {
}
void CodeGenFunction::PushCleanupBlock(llvm::BasicBlock *CleanupEntryBlock,
- llvm::BasicBlock *CleanupExitBlock) {
- CleanupEntries.push_back(CleanupEntry(CleanupEntryBlock, CleanupExitBlock));
+ llvm::BasicBlock *CleanupExitBlock,
+ bool EHOnly) {
+ CleanupEntries.push_back(CleanupEntry(CleanupEntryBlock, CleanupExitBlock,
+ EHOnly));
}
void CodeGenFunction::EmitCleanupBlocks(size_t OldCleanupStackSize) {
@@ -629,6 +631,8 @@ CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
std::vector<llvm::BranchInst *> BranchFixups;
std::swap(BranchFixups, CE.BranchFixups);
+ bool EHOnly = CE.EHOnly;
+
CleanupEntries.pop_back();
// Check if any branch fixups pointed to the scope we just popped. If so,
@@ -663,8 +667,9 @@ CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
Builder.SetInsertPoint(SwitchBlock);
- llvm::Value *DestCodePtr = CreateTempAlloca(llvm::Type::getInt32Ty(VMContext),
- "cleanup.dst");
+ llvm::Value *DestCodePtr
+ = CreateTempAlloca(llvm::Type::getInt32Ty(VMContext),
+ "cleanup.dst");
llvm::Value *DestCode = Builder.CreateLoad(DestCodePtr, "tmp");
// Create a switch instruction to determine where to jump next.
@@ -710,15 +715,16 @@ CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
new llvm::StoreInst(ID, DestCodePtr, BI);
} else {
// We need to jump through another cleanup block. Create a pad block
- // with a branch instruction that jumps to the final destination and
- // add it as a branch fixup to the current cleanup scope.
+ // with a branch instruction that jumps to the final destination and add
+ // it as a branch fixup to the current cleanup scope.
// Create the pad block.
llvm::BasicBlock *CleanupPad = createBasicBlock("cleanup.pad", CurFn);
// Create a unique case ID.
- llvm::ConstantInt *ID = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
- SI->getNumSuccessors());
+ llvm::ConstantInt *ID
+ = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+ SI->getNumSuccessors());
// Store the jump destination before the branch instruction.
new llvm::StoreInst(ID, DestCodePtr, BI);
@@ -744,12 +750,19 @@ CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
BlockScopes.erase(Blocks[i]);
}
- return CleanupBlockInfo(CleanupEntryBlock, SwitchBlock, EndBlock);
+ return CleanupBlockInfo(CleanupEntryBlock, SwitchBlock, EndBlock, EHOnly);
}
void CodeGenFunction::EmitCleanupBlock() {
CleanupBlockInfo Info = PopCleanupBlock();
+ if (Info.EHOnly) {
+ // FIXME: Add this to the exceptional edge
+ if (Info.CleanupBlock->getNumUses() == 0)
+ delete Info.CleanupBlock;
+ return;
+ }
+
llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
if (CurBB && !CurBB->getTerminator() &&
Info.CleanupBlock->getNumUses() == 0) {