summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qglobal.h
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2021-08-16 17:04:08 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-08-17 02:02:17 +0000
commit8f68b4a070b6246af78884a5c41f830245174a66 (patch)
tree5983a588cd7d3423a0d55a4e83996884b3e5c59f /src/corelib/global/qglobal.h
parenta6ca7bfb54c149755e3ccf1352534f2426ab253d (diff)
Forward declare Objective-C classes as class, not typedef objc_object
Forward declaring an Objective-C class in Objective-C/C++ mode is done by using the `@class` syntax, e.g.: @class NSString; In C/C++ mode however there's no documented approach, so we chose to flatten the type down to the opaque objc_object "base class": typedef struct objc_object NSString; As it turns out, when Objective-C classes are used as arguments or return types in C++, the signature they produce is equal to what it would have been if the type was a normal class. For example: void foo(NSString *) -> __Z3fooP8NSString The is due to @class in Objective-C++ just being just sugar, so an NSString pointer is not treated as `struct objc_object *` but rather a pointer to a distinct type, which then gets mangled as such by LLVM's Itanium mangler in CXXNameMangler::mangleType(const ObjCObjectType *T). With our current forward declaration however, we are expecting: void foo(NSString *) -> __Z3fooP11objc_object As a consequence exported helper functions such as QString::fromNSString() are not possible to use from plain C++ right now, as it will give a linker error for the missing QString::fromNSString(objc_object*) function. And even if we did define the extra signature, it would not be possible to declare overloaded functions taking Objective-C classes, as they would all produce ambiguous overloads in C++ mode. To fix this we change the forward declaration to a plain old class, which matches the signature in both Objective-C++ and plain C++ mode, and allows overloads. This is a binary compatible change, as no client were using any of these functions from C++ anyways as they would have produced linker errors. It does have a slight source compatible break, for clients that manually forward declared classes using the old style, but that use-case is deemed fringe enough to accept, and clients can work around this by defining Q_FORWARD_DECLARE_OBJC_CLASS to their preferred format, which Qt will respect. Change-Id: I04813c60a7da22379dd9de1be56cc12c53a38232 Reviewed-by: Lars Knoll <lars.knoll@qt.io> (cherry picked from commit 0f39fc55c93bd0e9d53f42feb845524d2d9dfcd1) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/corelib/global/qglobal.h')
-rw-r--r--src/corelib/global/qglobal.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 8bf0e8c6bc..de4b981723 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -823,7 +823,7 @@ constexpr inline QTypeTraits::Promoted<T, U> qBound(const U &min, const T &val,
# ifdef __OBJC__
# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname
# else
-# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname
+# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) class classname
# endif
#endif
#ifndef Q_FORWARD_DECLARE_CF_TYPE