Pick the correct personality function based on the language. This prevents link failures when C/ObjC code uses __attribute__((cleanup())) (previously this was inserting references to two libstc++ symbols; the personality function and the __terminate() function).

This is still probably wrong for Objective-C++ and adds a couple of lines in CGException that should probably be in the CGObjCRuntime subclass.  The personality function is now only looked up in one place in CGException though, so this should be easier to fix in the future.

llvm-svn: 103938
This commit is contained in:
David Chisnall 2010-05-17 13:49:20 +00:00
parent 05fa30d595
commit f9c4225af6
1 changed files with 26 additions and 25 deletions

View File

@ -119,7 +119,28 @@ static llvm::Constant *getTerminateFn(CodeGenFunction &CGF) {
const llvm::FunctionType *FTy = const llvm::FunctionType *FTy =
llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false); llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false);
return CGF.CGM.CreateRuntimeFunction(FTy, "_ZSt9terminatev"); return CGF.CGM.CreateRuntimeFunction(FTy,
CGF.CGM.getLangOptions().CPlusPlus ? "_ZSt9terminatev" : "abort");
}
static llvm::Constant *getPersonalityFn(CodeGenModule &CGM) {
const char *PersonalityFnName = "__gcc_personality_v0";
LangOptions Opts = CGM.getLangOptions();
if (Opts.CPlusPlus)
PersonalityFnName = "__gxx_personality_v0";
else if (Opts.ObjC1)
if (Opts.NeXTRuntime) {
if (Opts.ObjCNonFragileABI)
PersonalityFnName = "__gcc_personality_v0";
} else
PersonalityFnName = "__gnu_objc_personality_v0";
llvm::Constant *Personality =
CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(
CGM.getLLVMContext()),
true),
PersonalityFnName);
return llvm::ConstantExpr::getBitCast(Personality, CGM.PtrToInt8Ty);
} }
// Emits an exception expression into the given location. This // Emits an exception expression into the given location. This
@ -324,12 +345,7 @@ void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
if (!Proto->hasExceptionSpec()) if (!Proto->hasExceptionSpec())
return; return;
llvm::Constant *Personality = llvm::Constant *Personality = getPersonalityFn(CGM);
CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
(VMContext),
true),
"__gxx_personality_v0");
Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
llvm::Value *llvm_eh_exception = llvm::Value *llvm_eh_exception =
CGM.getIntrinsic(llvm::Intrinsic::eh_exception); CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
llvm::Value *llvm_eh_selector = llvm::Value *llvm_eh_selector =
@ -444,12 +460,7 @@ CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S) {
void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S,
CXXTryStmtInfo TryInfo) { CXXTryStmtInfo TryInfo) {
// Pointer to the personality function // Pointer to the personality function
llvm::Constant *Personality = llvm::Constant *Personality = getPersonalityFn(CGM);
CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
(VMContext),
true),
"__gxx_personality_v0");
Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
llvm::Value *llvm_eh_exception = llvm::Value *llvm_eh_exception =
CGM.getIntrinsic(llvm::Intrinsic::eh_exception); CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
llvm::Value *llvm_eh_selector = llvm::Value *llvm_eh_selector =
@ -654,12 +665,7 @@ CodeGenFunction::EHCleanupBlock::~EHCleanupBlock() {
// The libstdc++ personality function. // The libstdc++ personality function.
// TODO: generalize to work with other libraries. // TODO: generalize to work with other libraries.
llvm::Constant *Personality = llvm::Constant *Personality = getPersonalityFn(CGF.CGM);
CGF.CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
(CGF.VMContext),
true),
"__gxx_personality_v0");
Personality = llvm::ConstantExpr::getBitCast(Personality, CGF.PtrToInt8Ty);
// %exception = call i8* @llvm.eh.exception() // %exception = call i8* @llvm.eh.exception()
// Magic intrinsic which tells gives us a handle to the caught // Magic intrinsic which tells gives us a handle to the caught
@ -715,12 +721,7 @@ llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
llvm::BasicBlock::iterator SavedInsertPoint = Builder.GetInsertPoint(); llvm::BasicBlock::iterator SavedInsertPoint = Builder.GetInsertPoint();
Builder.ClearInsertionPoint(); Builder.ClearInsertionPoint();
llvm::Constant *Personality = llvm::Constant *Personality = getPersonalityFn(CGM);
CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
(VMContext),
true),
"__gxx_personality_v0");
Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty);
llvm::Value *llvm_eh_exception = llvm::Value *llvm_eh_exception =
CGM.getIntrinsic(llvm::Intrinsic::eh_exception); CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
llvm::Value *llvm_eh_selector = llvm::Value *llvm_eh_selector =