return TerminateHandler;
}
-CodeGenFunction::CleanupBlock::CleanupBlock(CodeGenFunction &CGF,
- CleanupKind Kind)
- : CGF(CGF), SavedIP(CGF.Builder.saveIP()), NormalCleanupExitBB(0) {
- llvm::BasicBlock *EntryBB = CGF.createBasicBlock("cleanup");
- CGF.Builder.SetInsertPoint(EntryBB);
-
- switch (Kind) {
- case NormalAndEHCleanup:
- NormalCleanupEntryBB = EHCleanupEntryBB = EntryBB;
- break;
-
- case NormalCleanup:
- NormalCleanupEntryBB = EntryBB;
- EHCleanupEntryBB = 0;
- break;
-
- case EHCleanup:
- NormalCleanupEntryBB = 0;
- EHCleanupEntryBB = EntryBB;
- CGF.EHStack.pushTerminate();
- break;
- }
-}
-
-void CodeGenFunction::CleanupBlock::beginEHCleanup() {
- assert(EHCleanupEntryBB == 0 && "already started an EH cleanup");
- NormalCleanupExitBB = CGF.Builder.GetInsertBlock();
- assert(NormalCleanupExitBB && "end of normal cleanup is unreachable");
-
- EHCleanupEntryBB = CGF.createBasicBlock("eh.cleanup");
- CGF.Builder.SetInsertPoint(EHCleanupEntryBB);
- CGF.EHStack.pushTerminate();
-}
-
-CodeGenFunction::CleanupBlock::~CleanupBlock() {
- llvm::BasicBlock *EHCleanupExitBB = 0;
-
- // If we're currently writing the EH cleanup...
- if (EHCleanupEntryBB) {
- // Set the EH cleanup exit block.
- EHCleanupExitBB = CGF.Builder.GetInsertBlock();
- assert(EHCleanupExitBB && "end of EH cleanup is unreachable");
-
- // If we're actually writing both at once, set the normal exit, too.
- if (EHCleanupEntryBB == NormalCleanupEntryBB)
- NormalCleanupExitBB = EHCleanupExitBB;
-
- // Otherwise, we must have pushed a terminate handler.
- else
- CGF.EHStack.popTerminate();
-
- // Otherwise, just set the normal cleanup exit block.
- } else {
- NormalCleanupExitBB = CGF.Builder.GetInsertBlock();
- assert(NormalCleanupExitBB && "end of normal cleanup is unreachable");
- }
-
- CGF.EHStack.pushCleanup(NormalCleanupEntryBB, NormalCleanupExitBB,
- EHCleanupEntryBB, EHCleanupExitBB);
-
- CGF.Builder.restoreIP(SavedIP);
-}
-
EHScopeStack::LazyCleanup::~LazyCleanup() {
llvm_unreachable("LazyCleanup is indestructable");
}
/// process all branch fixups.
void PopCleanupBlock();
- /// CleanupBlock - RAII object that will create a cleanup block and
- /// set the insert point to that block. When destructed, it sets the
- /// insert point to the previous block and pushes a new cleanup
- /// entry on the stack.
- class CleanupBlock {
- CodeGenFunction &CGF;
- CGBuilderTy::InsertPoint SavedIP;
- llvm::BasicBlock *NormalCleanupEntryBB;
- llvm::BasicBlock *NormalCleanupExitBB;
- llvm::BasicBlock *EHCleanupEntryBB;
-
- public:
- CleanupBlock(CodeGenFunction &CGF, CleanupKind Kind);
-
- /// If we're currently writing a normal cleanup, tie that off and
- /// start writing an EH cleanup.
- void beginEHCleanup();
-
- ~CleanupBlock();
- };
-
/// \brief Enters a new scope for capturing cleanups, all of which
/// will be executed once the scope is exited.
class RunCleanupsScope {