diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index f582be91f46..c09de5f91b6 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -186,129 +186,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSPanelContentsWrapper); // ------------------------------------------------------------------------- -// Depending on the ABI of the platform, we may need to use objc_msgSendSuper_stret: -// - http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html -// - https://lists.apple.com/archives/cocoa-dev/2008/Feb/msg02338.html -template -struct objc_msgsend_requires_stret -{ static const bool value = -#if defined(Q_PROCESSOR_X86) - #define PLATFORM_USES_SEND_SUPER_STRET 1 - // Any return value larger than two registers on i386/x86_64 - sizeof(T) > sizeof(void*) * 2; -#elif defined(Q_PROCESSOR_ARM_32) - #define PLATFORM_USES_SEND_SUPER_STRET 1 - // Any return value larger than a single register on arm - sizeof(T) > sizeof(void*); -#elif defined(Q_PROCESSOR_ARM_64) - #define PLATFORM_USES_SEND_SUPER_STRET 0 - false; // Stret not used on arm64 -#endif -}; - -template <> -struct objc_msgsend_requires_stret -{ static const bool value = false; }; - -template -ReturnType qt_msgSendSuper(id receiver, SEL selector, Args... args) -{ - static_assert(!objc_msgsend_requires_stret::value, - "The given return type requires stret on this platform"); - - typedef ReturnType (*SuperFn)(objc_super *, SEL, Args...); - SuperFn superFn = reinterpret_cast(objc_msgSendSuper); - objc_super sup = { receiver, [receiver superclass] }; - return superFn(&sup, selector, args...); -} - -#if PLATFORM_USES_SEND_SUPER_STRET -template -ReturnType qt_msgSendSuper_stret(id receiver, SEL selector, Args... args) -{ - static_assert(objc_msgsend_requires_stret::value, - "The given return type does not use stret on this platform"); - - typedef void (*SuperStretFn)(ReturnType *, objc_super *, SEL, Args...); - SuperStretFn superStretFn = reinterpret_cast(objc_msgSendSuper_stret); - - objc_super sup = { receiver, [receiver superclass] }; - ReturnType ret; - superStretFn(&ret, &sup, selector, args...); - return ret; -} -#endif - -template -class QSendSuperHelper { -public: - QSendSuperHelper(id receiver, SEL sel, Args... args) - : m_receiver(receiver), m_selector(sel), m_args(std::make_tuple(args...)), m_sent(false) - { - } - - ~QSendSuperHelper() - { - if (!m_sent) - msgSendSuper(m_args); - } - - template - operator ReturnType() - { -#if defined(QT_DEBUG) - Method method = class_getInstanceMethod(object_getClass(m_receiver), m_selector); - char returnTypeEncoding[256]; - method_getReturnType(method, returnTypeEncoding, sizeof(returnTypeEncoding)); - NSUInteger alignedReturnTypeSize = 0; - NSGetSizeAndAlignment(returnTypeEncoding, nullptr, &alignedReturnTypeSize); - Q_ASSERT(alignedReturnTypeSize == sizeof(ReturnType)); -#endif - m_sent = true; - return msgSendSuper(m_args); - } - -private: - template - using if_requires_stret = typename std::enable_if::value == V, ReturnType>::type; - - template - if_requires_stret msgSendSuper(std::tuple& args, std::index_sequence) - { - return qt_msgSendSuper(m_receiver, m_selector, std::get(args)...); - } - -#if PLATFORM_USES_SEND_SUPER_STRET - template - if_requires_stret msgSendSuper(std::tuple& args, std::index_sequence) - { - return qt_msgSendSuper_stret(m_receiver, m_selector, std::get(args)...); - } -#endif - - template - ReturnType msgSendSuper(std::tuple& args) - { - return msgSendSuper(args, std::make_index_sequence{}); - } - - id m_receiver; - SEL m_selector; - std::tuple m_args; - bool m_sent; -}; - -template -QSendSuperHelper qt_objcDynamicSuperHelper(id receiver, SEL selector, Args... args) -{ - return QSendSuperHelper(receiver, selector, args...); -} - -// Same as calling super, but the super_class field resolved at runtime instead of compile time -#define qt_objcDynamicSuper(...) qt_objcDynamicSuperHelper(self, _cmd, ##__VA_ARGS__) - -// ------------------------------------------------------------------------- - struct InputMethodQueryResult : public QHash { operator bool() { return !isEmpty(); }