@@ -168,6 +168,8 @@ class CGObjCGNU : public CGObjCRuntime {
168
168
// / Does the current target use SEH-based exceptions? False implies
169
169
// / Itanium-style DWARF unwinding.
170
170
bool usesSEHExceptions;
171
+ // / Does the current target uses C++-based exceptions?
172
+ bool usesCxxExceptions;
171
173
172
174
// / Helper to check if we are targeting a specific runtime version or later.
173
175
bool isRuntime (ObjCRuntime::Kind kind, unsigned major, unsigned minor=0 ) {
@@ -819,12 +821,18 @@ class CGObjCGNUstep : public CGObjCGNU {
819
821
SlotLookupSuperFn.init (&CGM, " objc_slot_lookup_super" , SlotTy,
820
822
PtrToObjCSuperTy, SelectorTy);
821
823
// If we're in ObjC++ mode, then we want to make
822
- if (usesSEHExceptions) {
823
- llvm::Type *VoidTy = llvm::Type::getVoidTy (VMContext);
824
- // void objc_exception_rethrow(void)
825
- ExceptionReThrowFn.init (&CGM, " objc_exception_rethrow" , VoidTy);
824
+ llvm::Type *VoidTy = llvm::Type::getVoidTy (VMContext);
825
+ if (usesCxxExceptions) {
826
+ // void *__cxa_begin_catch(void *e)
827
+ EnterCatchFn.init (&CGM, " __cxa_begin_catch" , PtrTy, PtrTy);
828
+ // void __cxa_end_catch(void)
829
+ ExitCatchFn.init (&CGM, " __cxa_end_catch" , VoidTy);
830
+ // void objc_exception_rethrow(void*)
831
+ ExceptionReThrowFn.init (&CGM, " __cxa_rethrow" , PtrTy);
832
+ } else if (usesSEHExceptions) {
833
+ // void objc_exception_rethrow(void)
834
+ ExceptionReThrowFn.init (&CGM, " objc_exception_rethrow" , VoidTy);
826
835
} else if (CGM.getLangOpts ().CPlusPlus ) {
827
- llvm::Type *VoidTy = llvm::Type::getVoidTy (VMContext);
828
836
// void *__cxa_begin_catch(void *e)
829
837
EnterCatchFn.init (&CGM, " __cxa_begin_catch" , PtrTy, PtrTy);
830
838
// void __cxa_end_catch(void)
@@ -833,15 +841,13 @@ class CGObjCGNUstep : public CGObjCGNU {
833
841
ExceptionReThrowFn.init (&CGM, " _Unwind_Resume_or_Rethrow" , VoidTy,
834
842
PtrTy);
835
843
} else if (R.getVersion () >= VersionTuple (1 , 7 )) {
836
- llvm::Type *VoidTy = llvm::Type::getVoidTy (VMContext);
837
844
// id objc_begin_catch(void *e)
838
845
EnterCatchFn.init (&CGM, " objc_begin_catch" , IdTy, PtrTy);
839
846
// void objc_end_catch(void)
840
847
ExitCatchFn.init (&CGM, " objc_end_catch" , VoidTy);
841
848
// void _Unwind_Resume_or_Rethrow(void*)
842
849
ExceptionReThrowFn.init (&CGM, " objc_exception_rethrow" , VoidTy, PtrTy);
843
850
}
844
- llvm::Type *VoidTy = llvm::Type::getVoidTy (VMContext);
845
851
SetPropertyAtomic.init (&CGM, " objc_setProperty_atomic" , VoidTy, IdTy,
846
852
SelectorTy, IdTy, PtrDiffTy);
847
853
SetPropertyAtomicCopy.init (&CGM, " objc_setProperty_atomic_copy" , VoidTy,
@@ -2126,6 +2132,9 @@ CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
2126
2132
msgSendMDKind = VMContext.getMDKindID (" GNUObjCMessageSend" );
2127
2133
usesSEHExceptions =
2128
2134
cgm.getContext ().getTargetInfo ().getTriple ().isWindowsMSVCEnvironment ();
2135
+ usesCxxExceptions =
2136
+ cgm.getContext ().getTargetInfo ().getTriple ().isOSCygMing () &&
2137
+ isRuntime (ObjCRuntime::GNUstep, 2 );
2129
2138
2130
2139
CodeGenTypes &Types = CGM.getTypes ();
2131
2140
IntTy = cast<llvm::IntegerType>(
@@ -2212,7 +2221,10 @@ CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
2212
2221
2213
2222
// void objc_exception_throw(id);
2214
2223
ExceptionThrowFn.init (&CGM, " objc_exception_throw" , VoidTy, IdTy);
2215
- ExceptionReThrowFn.init (&CGM, " objc_exception_throw" , VoidTy, IdTy);
2224
+ ExceptionReThrowFn.init (&CGM,
2225
+ usesCxxExceptions ? " objc_exception_rethrow"
2226
+ : " objc_exception_throw" ,
2227
+ VoidTy, IdTy);
2216
2228
// int objc_sync_enter(id);
2217
2229
SyncEnterFn.init (&CGM, " objc_sync_enter" , IntTy, IdTy);
2218
2230
// int objc_sync_exit(id);
@@ -2389,7 +2401,7 @@ llvm::Constant *CGObjCGNUstep::GetEHType(QualType T) {
2389
2401
if (usesSEHExceptions)
2390
2402
return CGM.getCXXABI ().getAddrOfRTTIDescriptor (T);
2391
2403
2392
- if (!CGM.getLangOpts ().CPlusPlus )
2404
+ if (!CGM.getLangOpts ().CPlusPlus && !usesCxxExceptions )
2393
2405
return CGObjCGNU::GetEHType (T);
2394
2406
2395
2407
// For Objective-C++, we want to provide the ability to catch both C++ and
@@ -3995,7 +4007,7 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF,
3995
4007
ExceptionAsObject = CGF.ObjCEHValueStack .back ();
3996
4008
isRethrow = true ;
3997
4009
}
3998
- if (isRethrow && usesSEHExceptions) {
4010
+ if (isRethrow && ( usesSEHExceptions || usesCxxExceptions) ) {
3999
4011
// For SEH, ExceptionAsObject may be undef, because the catch handler is
4000
4012
// not passed it for catchalls and so it is not visible to the catch
4001
4013
// funclet. The real thrown object will still be live on the stack at this
@@ -4005,8 +4017,7 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF,
4005
4017
// argument.
4006
4018
llvm::CallBase *Throw = CGF.EmitRuntimeCallOrInvoke (ExceptionReThrowFn);
4007
4019
Throw->setDoesNotReturn ();
4008
- }
4009
- else {
4020
+ } else {
4010
4021
ExceptionAsObject = CGF.Builder .CreateBitCast (ExceptionAsObject, IdTy);
4011
4022
llvm::CallBase *Throw =
4012
4023
CGF.EmitRuntimeCallOrInvoke (ExceptionThrowFn, ExceptionAsObject);
0 commit comments