From 2b488873bf9a552dd5928910240e73e0ad129f6d Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Wed, 9 Dec 2009 22:59:31 +0000 Subject: [PATCH] Break out code for reuse. WIP. llvm-svn: 90991 --- clang/lib/CodeGen/CGException.cpp | 61 ++++++++++++++++++----------- clang/lib/CodeGen/CodeGenFunction.h | 2 + 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index bcb59f5f97c6..d1edde527366 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -458,27 +458,7 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) { // Jump to end if there is no exception EmitBranchThroughCleanup(FinallyEnd); - // Set up terminate handler - llvm::BasicBlock *TerminateHandler = createBasicBlock("terminate.handler"); - EmitBlock(TerminateHandler); - llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc"); - // We are required to emit this call to satisfy LLVM, even - // though we don't use the result. - llvm::SmallVector Args; - Args.clear(); - Args.push_back(Exc); - Args.push_back(Personality); - Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), - 0)); - Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end()); - llvm::CallInst *TerminateCall = - Builder.CreateCall(getTerminateFn(*this)); - TerminateCall->setDoesNotReturn(); - TerminateCall->setDoesNotThrow(); - Builder.CreateUnreachable(); - - // Clear the insertion point to indicate we are in unreachable code. - Builder.ClearInsertionPoint(); + llvm::BasicBlock *TerminateHandler = getTerminateHandler(); // Emit the handlers EmitBlock(TryHandler); @@ -493,9 +473,10 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) { llvm::Value *llvm_eh_typeid_for = CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for); // Exception object - Exc = Builder.CreateCall(llvm_eh_exception, "exc"); + llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc"); llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow"); + llvm::SmallVector Args; Args.clear(); SelectorArgs.push_back(Exc); SelectorArgs.push_back(Personality); @@ -702,3 +683,39 @@ CodeGenFunction::EHCleanupBlock::~EHCleanupBlock() { if (CGF.Exceptions) CGF.setInvokeDest(CleanupHandler); } + +llvm::BasicBlock *CodeGenFunction::getTerminateHandler() { + llvm::Constant *Personality = + CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty + (VMContext), + true), + "__gxx_personality_v0"); + Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty); + llvm::Value *llvm_eh_exception = + CGM.getIntrinsic(llvm::Intrinsic::eh_exception); + llvm::Value *llvm_eh_selector = + CGM.getIntrinsic(llvm::Intrinsic::eh_selector); + + // Set up terminate handler + llvm::BasicBlock *TerminateHandler = createBasicBlock("terminate.handler"); + EmitBlock(TerminateHandler); + llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc"); + // We are required to emit this call to satisfy LLVM, even + // though we don't use the result. + llvm::SmallVector Args; + Args.push_back(Exc); + Args.push_back(Personality); + Args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), + 0)); + Builder.CreateCall(llvm_eh_selector, Args.begin(), Args.end()); + llvm::CallInst *TerminateCall = + Builder.CreateCall(getTerminateFn(*this)); + TerminateCall->setDoesNotReturn(); + TerminateCall->setDoesNotThrow(); + Builder.CreateUnreachable(); + + // Clear the insertion point to indicate we are in unreachable code. + Builder.ClearInsertionPoint(); + + return TerminateHandler; +} diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 5e23e2646d6e..70d598dc0e94 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -553,6 +553,8 @@ public: /// EmitEndEHSpec - Emit the end of the exception spec. void EmitEndEHSpec(const Decl *D); + llvm::BasicBlock *getTerminateHandler(); + const llvm::Type *ConvertTypeForMem(QualType T); const llvm::Type *ConvertType(QualType T);