Reapply r170344, this time without forgetting to commit the header changes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@170354 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index deac5f6..ced5a4c 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -772,7 +772,7 @@
args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy);
llvm::Value *copyCppAtomicObjectFn =
- CGF.CGM.getObjCRuntime().GetCppAtomicObjectFunction();
+ CGF.CGM.getObjCRuntime().GetCppAtomicObjectGetFunction();
CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(CGF.getContext().VoidTy,
args,
FunctionType::ExtInfo(),
@@ -1007,7 +1007,7 @@
args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy);
llvm::Value *copyCppAtomicObjectFn =
- CGF.CGM.getObjCRuntime().GetCppAtomicObjectFunction();
+ CGF.CGM.getObjCRuntime().GetCppAtomicObjectSetFunction();
CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(CGF.getContext().VoidTy,
args,
FunctionType::ExtInfo(),
@@ -2800,8 +2800,7 @@
}
static bool hasAtomicCopyHelperAPI(const ObjCRuntime &runtime) {
- // For now, only NeXT has these APIs.
- return runtime.isNeXTFamily();
+ return runtime.hasAtomicCopyHelper();
}
/// GenerateObjCAtomicSetterCopyHelperFunction - Given a c++ object type with
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 245c891..2328583 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -492,8 +492,9 @@
virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
bool copy);
virtual llvm::Constant *GetSetStructFunction();
- virtual llvm::Constant *GetCppAtomicObjectFunction();
virtual llvm::Constant *GetGetStructFunction();
+ virtual llvm::Constant *GetCppAtomicObjectGetFunction();
+ virtual llvm::Constant *GetCppAtomicObjectSetFunction();
virtual llvm::Constant *EnumerationMutationFunction();
virtual void EmitTryStmt(CodeGenFunction &CGF,
@@ -601,6 +602,20 @@
/// arguments. Returns the slot for the corresponding method. Superclass
/// message lookup rarely changes, so this is a good caching opportunity.
LazyRuntimeFunction SlotLookupSuperFn;
+ /// Specialised function for setting atomic retain properties
+ LazyRuntimeFunction SetPropertyAtomic;
+ /// Specialised function for setting atomic copy properties
+ LazyRuntimeFunction SetPropertyAtomicCopy;
+ /// Specialised function for setting nonatomic retain properties
+ LazyRuntimeFunction SetPropertyNonAtomic;
+ /// Specialised function for setting nonatomic copy properties
+ LazyRuntimeFunction SetPropertyNonAtomicCopy;
+ /// Function to perform atomic copies of C++ objects with nontrivial copy
+ /// constructors from Objective-C ivars.
+ LazyRuntimeFunction CxxAtomicObjectGetFn;
+ /// Function to perform atomic copies of C++ objects with nontrivial copy
+ /// constructors to Objective-C ivars.
+ LazyRuntimeFunction CxxAtomicObjectSetFn;
/// Type of an slot structure pointer. This is returned by the various
/// lookup functions.
llvm::Type *SlotTy;
@@ -676,8 +691,60 @@
// void __cxa_end_catch(void)
ExitCatchFn.init(&CGM, "__cxa_end_catch", VoidTy, NULL);
// void _Unwind_Resume_or_Rethrow(void*)
- ExceptionReThrowFn.init(&CGM, "_Unwind_Resume_or_Rethrow", VoidTy, PtrTy, NULL);
+ ExceptionReThrowFn.init(&CGM, "_Unwind_Resume_or_Rethrow", VoidTy,
+ PtrTy, NULL);
}
+ llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
+ SetPropertyAtomic.init(&CGM, "objc_setProperty_atomic", VoidTy, IdTy,
+ SelectorTy, IdTy, PtrDiffTy, NULL);
+ SetPropertyAtomicCopy.init(&CGM, "objc_setProperty_atomic_copy", VoidTy,
+ IdTy, SelectorTy, IdTy, PtrDiffTy, NULL);
+ SetPropertyNonAtomic.init(&CGM, "objc_setProperty_nonatomic", VoidTy,
+ IdTy, SelectorTy, IdTy, PtrDiffTy, NULL);
+ SetPropertyNonAtomicCopy.init(&CGM, "objc_setProperty_nonatomic_copy",
+ VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy, NULL);
+ // void objc_setCppObjectAtomic(void *dest, const void *src, void
+ // *helper);
+ CxxAtomicObjectSetFn.init(&CGM, "objc_setCppObjectAtomic", VoidTy, PtrTy,
+ PtrTy, PtrTy, NULL);
+ // void objc_getCppObjectAtomic(void *dest, const void *src, void
+ // *helper);
+ CxxAtomicObjectGetFn.init(&CGM, "objc_getCppObjectAtomic", VoidTy, PtrTy,
+ PtrTy, PtrTy, NULL);
+ }
+ virtual llvm::Constant *GetCppAtomicObjectGetFunction() {
+ // The optimised functions were added in version 1.7 of the GNUstep
+ // runtime.
+ assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
+ VersionTuple(1, 7));
+ return CxxAtomicObjectGetFn;
+ }
+ virtual llvm::Constant *GetCppAtomicObjectSetFunction() {
+ // The optimised functions were added in version 1.7 of the GNUstep
+ // runtime.
+ assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
+ VersionTuple(1, 7));
+ return CxxAtomicObjectSetFn;
+ }
+ virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
+ bool copy) {
+ // The optimised property functions omit the GC check, and so are not
+ // safe to use in GC mode. The standard functions are fast in GC mode,
+ // so there is less advantage in using them.
+ assert ((CGM.getLangOpts().getGC() == LangOptions::NonGC));
+ // The optimised functions were added in version 1.7 of the GNUstep
+ // runtime.
+ assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
+ VersionTuple(1, 7));
+
+ if (atomic) {
+ if (copy) return SetPropertyAtomicCopy;
+ return SetPropertyAtomic;
+ }
+ if (copy) return SetPropertyNonAtomicCopy;
+ return SetPropertyNonAtomic;
+
+ return 0;
}
};
@@ -2535,7 +2602,10 @@
llvm::Constant *CGObjCGNU::GetSetStructFunction() {
return SetStructPropertyFn;
}
-llvm::Constant *CGObjCGNU::GetCppAtomicObjectFunction() {
+llvm::Constant *CGObjCGNU::GetCppAtomicObjectGetFunction() {
+ return 0;
+}
+llvm::Constant *CGObjCGNU::GetCppAtomicObjectSetFunction() {
return 0;
}
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index d84875b..aff804c 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -1223,7 +1223,8 @@
bool copy);
virtual llvm::Constant *GetGetStructFunction();
virtual llvm::Constant *GetSetStructFunction();
- virtual llvm::Constant *GetCppAtomicObjectFunction();
+ virtual llvm::Constant *GetCppAtomicObjectGetFunction();
+ virtual llvm::Constant *GetCppAtomicObjectSetFunction();
virtual llvm::Constant *EnumerationMutationFunction();
virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
@@ -1494,7 +1495,10 @@
virtual llvm::Constant *GetGetStructFunction() {
return ObjCTypes.getCopyStructFn();
}
- virtual llvm::Constant *GetCppAtomicObjectFunction() {
+ virtual llvm::Constant *GetCppAtomicObjectSetFunction() {
+ return ObjCTypes.getCppAtomicObjectFunction();
+ }
+ virtual llvm::Constant *GetCppAtomicObjectGetFunction() {
return ObjCTypes.getCppAtomicObjectFunction();
}
@@ -3409,7 +3413,10 @@
return ObjCTypes.getCopyStructFn();
}
-llvm::Constant *CGObjCMac::GetCppAtomicObjectFunction() {
+llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
+ return ObjCTypes.getCppAtomicObjectFunction();
+}
+llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
return ObjCTypes.getCppAtomicObjectFunction();
}
diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h
index 934464b..584bf67 100644
--- a/lib/CodeGen/CGObjCRuntime.h
+++ b/lib/CodeGen/CGObjCRuntime.h
@@ -209,9 +209,12 @@
virtual llvm::Constant *GetGetStructFunction() = 0;
// API for atomic copying of qualified aggregates in setter.
virtual llvm::Constant *GetSetStructFunction() = 0;
- // API for atomic copying of qualified aggregates with non-trivial copy
- // assignment (c++) in setter/getter.
- virtual llvm::Constant *GetCppAtomicObjectFunction() = 0;
+ /// API for atomic copying of qualified aggregates with non-trivial copy
+ /// assignment (c++) in setter.
+ virtual llvm::Constant *GetCppAtomicObjectSetFunction() = 0;
+ /// API for atomic copying of qualified aggregates with non-trivial copy
+ /// assignment (c++) in getter.
+ virtual llvm::Constant *GetCppAtomicObjectGetFunction() = 0;
/// GetClass - Return a reference to the class for the given
/// interface decl.