From aa0a53fc19be10b8b1d191415bda82af259a8b23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 26 Apr 2022 10:56:54 +0200 Subject: [PATCH] Don't declare type 'id' in the global namespace in a public header It's not necessary, and it breaks the qttools build (where we have a global variable named 'id'), and thus will most certainly build a lot of existing user code. Amends e47c22480fe84c100019cd92d0296f0dd2a7f3f1. Change-Id: I97a91c2cb23fdae65143cf14c81570cf88d529d5 Reviewed-by: Volker Hilsheimer --- src/corelib/io/qdebug.h | 7 +- tests/auto/corelib/io/qdebug/CMakeLists.txt | 4 ++ tests/auto/corelib/io/qdebug/tst_qdebug.cpp | 73 +++++++++++++++++++++ 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index 847fc676ad2..306be901022 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -530,7 +530,7 @@ inline QDebug operator<<(QDebug debug, QKeyCombination combination) QT_END_NAMESPACE Q_FORWARD_DECLARE_CF_TYPE(CFString); -typedef struct objc_object *id; +struct objc_object; Q_FORWARD_DECLARE_OBJC_CLASS(NSObject); QT_FOR_EACH_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_CF_TYPE) QT_FOR_EACH_MUTABLE_CORE_FOUNDATION_TYPE(QT_FORWARD_DECLARE_MUTABLE_CF_TYPE) @@ -555,7 +555,10 @@ QT_BEGIN_NAMESPACE } // Defined in qcore_mac_objc.mm -Q_CORE_EXPORT QDebug operator<<(QDebug, id obj); +#if defined(__OBJC__) +Q_CORE_EXPORT QDebug operator<<(QDebug, id); +#endif +Q_CORE_EXPORT QDebug operator<<(QDebug, objc_object *); Q_CORE_EXPORT QDebug operator<<(QDebug, const NSObject *); Q_CORE_EXPORT QDebug operator<<(QDebug, CFStringRef); diff --git a/tests/auto/corelib/io/qdebug/CMakeLists.txt b/tests/auto/corelib/io/qdebug/CMakeLists.txt index 39b92b9d2fd..067e3be04be 100644 --- a/tests/auto/corelib/io/qdebug/CMakeLists.txt +++ b/tests/auto/corelib/io/qdebug/CMakeLists.txt @@ -10,3 +10,7 @@ qt_internal_add_test(tst_qdebug PUBLIC_LIBRARIES Qt::Concurrent ) + +if (APPLE) + target_compile_options(tst_qdebug PRIVATE -x objective-c++) +endif() diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp index 9b9696d7c12..a85d8328e05 100644 --- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp +++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp @@ -52,6 +52,10 @@ struct ConvertsToQVariant { }; static_assert(!QTypeTraits::has_ostream_operator_v); +#if defined(Q_OS_DARWIN) +#include +#include +#endif class tst_QDebug: public QObject { @@ -88,6 +92,12 @@ private slots: void threadSafety() const; void toString() const; void noQVariantEndlessRecursion() const; +#if defined(Q_OS_DARWIN) + void objcInCppMode_data() const; + void objcInCppMode() const; + void objcInObjcMode_data() const; + void objcInObjcMode() const; +#endif }; void tst_QDebug::assignment() const @@ -873,6 +883,69 @@ void tst_QDebug::noQVariantEndlessRecursion() const qDebug() << var; } +#if defined(Q_OS_DARWIN) + +@interface MyObjcClass : NSObject +@end + +@implementation MyObjcClass : NSObject +- (NSString *)description +{ + return @"MyObjcClass is the best"; +} +@end + +void tst_QDebug::objcInCppMode_data() const +{ + QTest::addColumn("object"); + QTest::addColumn("message"); + + QTest::newRow("nil") << static_cast(nullptr) << QString::fromLatin1("(null)"); + + // Not an NSObject subclass + auto *nsproxy = reinterpret_cast(class_createInstance(objc_getClass("NSProxy"), 0)); + QTest::newRow("NSProxy") << nsproxy << QString::fromLatin1("").arg(uintptr_t(nsproxy), 1, 16); + + // Plain NSObject + auto *nsobject = reinterpret_cast(class_createInstance(objc_getClass("NSObject"), 0)); + QTest::newRow("NSObject") << nsobject << QString::fromLatin1("").arg(uintptr_t(nsobject), 1, 16); + + auto str = QString::fromLatin1("foo"); + QTest::newRow("NSString") << reinterpret_cast(str.toNSString()) << str; + + // Custom debug description + QTest::newRow("MyObjcClass") << reinterpret_cast([[MyObjcClass alloc] init]) + << QString::fromLatin1("MyObjcClass is the best"); +} + +void tst_QDebug::objcInCppMode() const +{ + QFETCH(objc_object *, object); + QFETCH(QString, message); + + MessageHandlerSetter mhs(myMessageHandler); + { qDebug() << object; } + + QCOMPARE(s_msg, message); +} + +void tst_QDebug::objcInObjcMode_data() const +{ + objcInCppMode_data(); +} + +void tst_QDebug::objcInObjcMode() const +{ + QFETCH(objc_object *, object); + QFETCH(QString, message); + + MessageHandlerSetter mhs(myMessageHandler); + { qDebug() << static_cast(object); } + + QCOMPARE(s_msg, message); +} +#endif + // Should compile: instentiation of unrelated operator<< should not cause cause compilation // error in QDebug operators (QTBUG-47375) class TestClassA {};