forked from OSchip/llvm-project
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:
parent
05fa30d595
commit
f9c4225af6
|
@ -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 =
|
||||||
|
|
Loading…
Reference in New Issue