diff options
Diffstat (limited to 'lib/CodeGen/CGException.cpp')
-rw-r--r-- | lib/CodeGen/CGException.cpp | 66 |
1 files changed, 43 insertions, 23 deletions
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index 0edbce7267..f90c71bb46 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -11,17 +11,13 @@ // //===----------------------------------------------------------------------===// -#include "clang/AST/StmtCXX.h" - -#include "llvm/Intrinsics.h" -#include "llvm/IntrinsicInst.h" -#include "llvm/Support/CallSite.h" - -#include "CGObjCRuntime.h" #include "CodeGenFunction.h" -#include "CGException.h" #include "CGCleanup.h" +#include "CGObjCRuntime.h" #include "TargetInfo.h" +#include "clang/AST/StmtCXX.h" +#include "llvm/Intrinsics.h" +#include "llvm/Support/CallSite.h" using namespace clang; using namespace CodeGen; @@ -145,14 +141,37 @@ static llvm::Constant *getCatchallRethrowFn(CodeGenFunction &CGF, return CGF.CGM.CreateRuntimeFunction(FTy, Name); } -const EHPersonality EHPersonality::GNU_C("__gcc_personality_v0"); -const EHPersonality EHPersonality::GNU_C_SJLJ("__gcc_personality_sj0"); -const EHPersonality EHPersonality::NeXT_ObjC("__objc_personality_v0"); -const EHPersonality EHPersonality::GNU_CPlusPlus("__gxx_personality_v0"); -const EHPersonality EHPersonality::GNU_CPlusPlus_SJLJ("__gxx_personality_sj0"); -const EHPersonality EHPersonality::GNU_ObjC("__gnu_objc_personality_v0", - "objc_exception_throw"); -const EHPersonality EHPersonality::GNU_ObjCXX("__gnustep_objcxx_personality_v0"); +namespace { + /// The exceptions personality for a function. + struct EHPersonality { + const char *PersonalityFn; + + // If this is non-null, this personality requires a non-standard + // function for rethrowing an exception after a catchall cleanup. + // This function must have prototype void(void*). + const char *CatchallRethrowFn; + + static const EHPersonality &get(const LangOptions &Lang); + static const EHPersonality GNU_C; + static const EHPersonality GNU_C_SJLJ; + static const EHPersonality GNU_ObjC; + static const EHPersonality GNU_ObjCXX; + static const EHPersonality NeXT_ObjC; + static const EHPersonality GNU_CPlusPlus; + static const EHPersonality GNU_CPlusPlus_SJLJ; + }; +} + +const EHPersonality EHPersonality::GNU_C = { "__gcc_personality_v0", 0 }; +const EHPersonality EHPersonality::GNU_C_SJLJ = { "__gcc_personality_sj0", 0 }; +const EHPersonality EHPersonality::NeXT_ObjC = { "__objc_personality_v0", 0 }; +const EHPersonality EHPersonality::GNU_CPlusPlus = { "__gxx_personality_v0", 0}; +const EHPersonality +EHPersonality::GNU_CPlusPlus_SJLJ = { "__gxx_personality_sj0", 0 }; +const EHPersonality +EHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0", "objc_exception_throw"}; +const EHPersonality +EHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", 0 }; static const EHPersonality &getCPersonality(const LangOptions &L) { if (L.SjLjExceptions) @@ -212,7 +231,7 @@ static llvm::Constant *getPersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality) { llvm::Constant *Fn = CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, true), - Personality.getPersonalityFnName()); + Personality.PersonalityFn); return Fn; } @@ -286,12 +305,13 @@ void CodeGenModule::SimplifyPersonality() { const EHPersonality &ObjCXX = EHPersonality::get(Features); const EHPersonality &CXX = getCXXPersonality(Features); - if (&ObjCXX == &CXX || - ObjCXX.getPersonalityFnName() == CXX.getPersonalityFnName()) + if (&ObjCXX == &CXX) return; - llvm::Function *Fn = - getModule().getFunction(ObjCXX.getPersonalityFnName()); + assert(std::strcmp(ObjCXX.PersonalityFn, CXX.PersonalityFn) != 0 && + "Different EHPersonalities using the same personality function."); + + llvm::Function *Fn = getModule().getFunction(ObjCXX.PersonalityFn); // Nothing to do if it's unused. if (!Fn || Fn->use_empty()) return; @@ -1529,8 +1549,8 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock() { // This can always be a call because we necessarily didn't find // anything on the EH stack which needs our help. - StringRef RethrowName = Personality.getCatchallRethrowFnName(); - if (!RethrowName.empty()) { + const char *RethrowName = Personality.CatchallRethrowFn; + if (RethrowName != 0) { Builder.CreateCall(getCatchallRethrowFn(*this, RethrowName), getExceptionFromSlot()) ->setDoesNotReturn(); |