diff options
author | Mike Stump <mrs@apple.com> | 2009-12-02 07:41:41 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-12-02 07:41:41 +0000 |
commit | 33270211a00a9e239900ef9bd7de8a0de2d8e82b (patch) | |
tree | d88c87d18eb6b09ae242eaf0a7fe79cbc0b46991 /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | b9878ee6b6bf20e804b47769937efed4f15c51b6 (diff) | |
download | bcm5719-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.cpp | 31 |
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) { |