]> granicus.if.org Git - clang/commitdiff
Break out code for reuse. WIP.
authorMike Stump <mrs@apple.com>
Wed, 9 Dec 2009 22:59:31 +0000 (22:59 +0000)
committerMike Stump <mrs@apple.com>
Wed, 9 Dec 2009 22:59:31 +0000 (22:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90991 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGException.cpp
lib/CodeGen/CodeGenFunction.h

index bcb59f5f97c672c9936d52f3c3a4edf346dbaadd..d1edde527366e5c1af47d76e42bc6abc62b26288 100644 (file)
@@ -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<llvm::Value*, 8> 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<llvm::Value*, 8> 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<llvm::Value*, 8> 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;
+}
index 5e23e2646d6e7c0af200ce033edc74fac45bae60..70d598dc0e948e04c169482530a32db2da899620 100644 (file)
@@ -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);