summaryrefslogtreecommitdiffstats
path: root/clang/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
commit33270211a00a9e239900ef9bd7de8a0de2d8e82b (patch)
treed88c87d18eb6b09ae242eaf0a7fe79cbc0b46991 /clang/lib/CodeGen/CodeGenFunction.cpp
parentb9878ee6b6bf20e804b47769937efed4f15c51b6 (diff)
downloadbcm5719-llvm-33270211a00a9e239900ef9bd7de8a0de2d8e82b.tar.gz
bcm5719-llvm-33270211a00a9e239900ef9bd7de8a0de2d8e82b.zip
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. llvm-svn: 90305
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp31
1 files changed, 22 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 6e0a77ca1b0..1e952f9a7db 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/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) {
OpenPOWER on IntegriCloud