From 486b7a8f8a4d984d2783a5717ef8ec5dc9b1666d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 20 May 2021 11:36:39 +0200 Subject: [PATCH] Type erase native interfaces via string instead of typeid The latter forces users to build with RTTI enabled, as the typeid use is in our public headers. Surprisingly this is also the case even without instantiating the relevant template. Change-Id: Icd18a2b85b250e0b77960797e5c43b7eaf9bd891 Reviewed-by: Friedemann Kleint Reviewed-by: Fabian Kosmale --- src/corelib/global/qnativeinterface.h | 24 +++++++++++++----------- src/corelib/kernel/qcoreapplication.cpp | 4 ++-- src/gui/kernel/qguiapplication.cpp | 4 ++-- src/gui/kernel/qkeymapper.cpp | 4 ++-- src/gui/kernel/qoffscreensurface.cpp | 4 ++-- src/gui/kernel/qopenglcontext.cpp | 4 ++-- src/widgets/kernel/qapplication.cpp | 4 ++-- 7 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/corelib/global/qnativeinterface.h b/src/corelib/global/qnativeinterface.h index d009ec5340b..d32e2cd9820 100644 --- a/src/corelib/global/qnativeinterface.h +++ b/src/corelib/global/qnativeinterface.h @@ -43,8 +43,6 @@ #include #include -#include - #ifndef QT_STATIC # define Q_NATIVE_INTERFACE_EXPORT Q_DECL_EXPORT # define Q_NATIVE_INTERFACE_IMPORT Q_DECL_IMPORT @@ -65,6 +63,7 @@ QT_BEGIN_NAMESPACE virtual ~NativeInterface(); \ struct TypeInfo { \ using baseType = BaseType; \ + static constexpr char const *name = QT_STRINGIFY(NativeInterface); \ static constexpr int revision = Revision; \ }; \ public: \ @@ -85,6 +84,7 @@ namespace QNativeInterface::Private { template struct TypeInfo : private NativeInterface { + static constexpr char const *name() { return NativeInterface::TypeInfo::name; } static constexpr int revision() { return NativeInterface::TypeInfo::revision; } template @@ -93,7 +93,7 @@ namespace QNativeInterface::Private { }; template - Q_NATIVE_INTERFACE_IMPORT void *resolveInterface(const T *that, const std::type_info &type, int revision); + Q_NATIVE_INTERFACE_IMPORT void *resolveInterface(const T *that, const char *name, int revision); Q_CORE_EXPORT Q_DECLARE_LOGGING_CATEGORY(lcNativeInterface) } @@ -104,10 +104,12 @@ namespace QNativeInterface::Private { I *nativeInterface() const \ { \ using T = std::decay_t; \ - static_assert(QNativeInterface::Private::TypeInfo::template isCompatibleWith, \ + using NativeInterface = QNativeInterface::Private::TypeInfo; \ + static_assert(NativeInterface::template isCompatibleWith, \ "T::nativeInterface() requires that native interface I is compatible with T"); \ \ - return static_cast(QNativeInterface::Private::resolveInterface(this, typeid(I), QNativeInterface::Private::TypeInfo::revision())); \ + return static_cast(QNativeInterface::Private::resolveInterface(this, \ + NativeInterface::name(), NativeInterface::revision())); \ } // Provides a definition for the interface destructor @@ -119,17 +121,17 @@ namespace QNativeInterface::Private { #define QT_NATIVE_INTERFACE_RETURN_IF(NativeInterface, baseType) \ using QNativeInterface::Private::lcNativeInterface; \ - qCDebug(lcNativeInterface, "Comparing requested type id %s with available %s", \ - type.name(), typeid(NativeInterface).name()); \ - if (type == typeid(NativeInterface)) { \ - qCDebug(lcNativeInterface, "Match for type id %s. Comparing revisions (requested %d / available %d)", \ - type.name(), revision, TypeInfo::revision()); \ + qCDebug(lcNativeInterface, "Comparing requested interface name %s with available %s", \ + name, TypeInfo::name()); \ + if (qstrcmp(name, TypeInfo::name()) == 0) { \ + qCDebug(lcNativeInterface, "Match for interface %s. Comparing revisions (requested %d / available %d)", \ + name, revision, TypeInfo::revision()); \ if (revision == TypeInfo::revision()) { \ qCDebug(lcNativeInterface) << "Full match. Returning dynamic cast of" << baseType; \ return dynamic_cast(baseType); \ } else { \ qCWarning(lcNativeInterface, "Native interface revision mismatch (requested %d / available %d) for interface %s", \ - revision, TypeInfo::revision(), type.name()); \ + revision, TypeInfo::revision(), name); \ return nullptr; \ } \ } diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 0cb7f30644e..2969b24801d 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -3241,9 +3241,9 @@ QCoreApplication::checkPermission(const QString &permission) #endif // future && QT_NO_QOBJECT template <> -Q_NATIVE_INTERFACE_EXPORT void *QNativeInterface::Private::resolveInterface(const QCoreApplication *that, const std::type_info &type, int revision) +Q_NATIVE_INTERFACE_EXPORT void *QNativeInterface::Private::resolveInterface(const QCoreApplication *that, const char *name, int revision) { - Q_UNUSED(that); Q_UNUSED(type); Q_UNUSED(revision); + Q_UNUSED(that); Q_UNUSED(name); Q_UNUSED(revision); return nullptr; } diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 1905361c5e8..e8308d3b8c3 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -4197,7 +4197,7 @@ QInputDeviceManager *QGuiApplicationPrivate::inputDeviceManager() } template <> -Q_NATIVE_INTERFACE_EXPORT void *QNativeInterface::Private::resolveInterface(const QGuiApplication *that, const std::type_info &type, int revision) +Q_NATIVE_INTERFACE_EXPORT void *QNativeInterface::Private::resolveInterface(const QGuiApplication *that, const char *name, int revision) { using namespace QNativeInterface::Private; @@ -4208,7 +4208,7 @@ Q_NATIVE_INTERFACE_EXPORT void *QNativeInterface::Private::resolveInterface(cons QT_NATIVE_INTERFACE_RETURN_IF(QWindowsApplication, platformIntegration); #endif - return resolveInterface(that, type, revision); + return resolveInterface(that, name, revision); } #include "moc_qguiapplication.cpp" diff --git a/src/gui/kernel/qkeymapper.cpp b/src/gui/kernel/qkeymapper.cpp index 3781330073c..e3d39f80dc5 100644 --- a/src/gui/kernel/qkeymapper.cpp +++ b/src/gui/kernel/qkeymapper.cpp @@ -136,9 +136,9 @@ QList QKeyMapperPrivate::possibleKeys(QKeyEvent *e) } template <> -Q_NATIVE_INTERFACE_EXPORT void *QNativeInterface::Private::resolveInterface(const QKeyMapper *that, const std::type_info &type, int revision) +Q_NATIVE_INTERFACE_EXPORT void *QNativeInterface::Private::resolveInterface(const QKeyMapper *that, const char *name, int revision) { - Q_UNUSED(that); Q_UNUSED(type); Q_UNUSED(revision); + Q_UNUSED(that); Q_UNUSED(name); Q_UNUSED(revision); using namespace QNativeInterface::Private; #if QT_CONFIG(evdev) diff --git a/src/gui/kernel/qoffscreensurface.cpp b/src/gui/kernel/qoffscreensurface.cpp index 53c60b278ea..7cb8050504e 100644 --- a/src/gui/kernel/qoffscreensurface.cpp +++ b/src/gui/kernel/qoffscreensurface.cpp @@ -372,9 +372,9 @@ QPlatformSurface *QOffscreenSurface::surfaceHandle() const using namespace QNativeInterface; template <> -Q_NATIVE_INTERFACE_EXPORT void *QNativeInterface::Private::resolveInterface(const QOffscreenSurface *that, const std::type_info &type, int revision) +Q_NATIVE_INTERFACE_EXPORT void *QNativeInterface::Private::resolveInterface(const QOffscreenSurface *that, const char *name, int revision) { - Q_UNUSED(that); Q_UNUSED(type); Q_UNUSED(revision); + Q_UNUSED(that); Q_UNUSED(name); Q_UNUSED(revision); auto *surfacePrivate = QOffscreenSurfacePrivate::get(const_cast(that)); Q_UNUSED(surfacePrivate); diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 4a423e7ed5b..8a9cd2b85f3 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -1312,9 +1312,9 @@ QDebug operator<<(QDebug debug, const QOpenGLContextGroup *cg) using namespace QNativeInterface; template <> -Q_NATIVE_INTERFACE_EXPORT void *QNativeInterface::Private::resolveInterface(const QOpenGLContext *that, const std::type_info &type, int revision) +Q_NATIVE_INTERFACE_EXPORT void *QNativeInterface::Private::resolveInterface(const QOpenGLContext *that, const char *name, int revision) { - Q_UNUSED(that); Q_UNUSED(type); Q_UNUSED(revision); + Q_UNUSED(that); Q_UNUSED(name); Q_UNUSED(revision); auto *platformContext = that->handle(); Q_UNUSED(platformContext); diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 8f0ce895a6b..0be8ac269ce 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -4101,9 +4101,9 @@ QPixmap QApplicationPrivate::applyQIconStyleHelper(QIcon::Mode mode, const QPixm } template <> -Q_NATIVE_INTERFACE_EXPORT void *QNativeInterface::Private::resolveInterface(const QApplication *that, const std::type_info &type, int revision) +Q_NATIVE_INTERFACE_EXPORT void *QNativeInterface::Private::resolveInterface(const QApplication *that, const char *name, int revision) { - return resolveInterface(that, type, revision); + return resolveInterface(that, name, revision); } QT_END_NAMESPACE