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
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2021-08-17 02:55:12 +0200
commit0f39fc55c93bd0e9d53f42feb845524d2d9dfcd1 (patch)
tree24bda8f8ea136c610e9ce55dcd4da09dcddc63cd /src/corelib/global/qglobal.h
parentde9c03dc6eff8fd54c95d1aa533eabecaad20417 (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. Pick-to: 6.2 Change-Id: I04813c60a7da22379dd9de1be56cc12c53a38232 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
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 e2dc919e26..6467ba1984 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -859,7 +859,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