diff options
Diffstat (limited to 'lib/CodeGen/CGException.cpp')
-rw-r--r-- | lib/CodeGen/CGException.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index 78655bdc11..5845f1ec02 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -172,6 +172,22 @@ void EHScopeStack::popNullFixups() { BranchFixups.pop_back(); } +llvm::Value *CodeGenFunction::initFullExprCleanup() { + // Create a variable to decide whether the cleanup needs to be run. + llvm::AllocaInst *run = CreateTempAlloca(Builder.getInt1Ty(), "cleanup.cond"); + + // Initialize it to false at a site that's guaranteed to be run + // before each evaluation. + llvm::BasicBlock *block = OutermostConditional->getStartingBlock(); + new llvm::StoreInst(Builder.getFalse(), run, + block->getFirstNonPHIOrDbg()); + + // Initialize it to true at the current location. + Builder.CreateStore(Builder.getTrue(), run); + + return run; +} + static llvm::Constant *getAllocateExceptionFn(CodeGenFunction &CGF) { // void *__cxa_allocate_exception(size_t thrown_size); const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType()); @@ -1656,3 +1672,23 @@ CodeGenFunction::UnwindDest CodeGenFunction::getRethrowDest() { EHScopeStack::Cleanup::~Cleanup() { llvm_unreachable("Cleanup is indestructable"); } + +void EHScopeStack::ConditionalCleanup::Emit(CodeGenFunction &CGF, + bool IsForEHCleanup) { + // Determine whether we should run the cleanup. + llvm::Value *condVal = CGF.Builder.CreateLoad(cond, "cond.should-run"); + + llvm::BasicBlock *cleanup = CGF.createBasicBlock("cond-cleanup.run"); + llvm::BasicBlock *cont = CGF.createBasicBlock("cond-cleanup.cont"); + + // If we shouldn't run the cleanup, jump directly to the continuation block. + CGF.Builder.CreateCondBr(condVal, cleanup, cont); + CGF.EmitBlock(cleanup); + + // Emit the core of the cleanup. + EmitImpl(CGF, IsForEHCleanup); + assert(CGF.HaveInsertPoint() && "cleanup didn't end with valid IP!"); + + // Fall into the continuation block. + CGF.EmitBlock(cont); +} |