moc: fix const-init for Windows

References to __declspec(dllimport) is not a constant expression on
Windows, so we can't have a direct reference to a staticMetaObject.
Commit 9b8493314d fixed the Q_OBJECT parent
link (added in 5.14, kicked in for 6.0 with the ABI break), but commit
656d6f2a9b added links for Q_GADGETs too
without taking the need for Windows DLLs into account.

This change is a no-op everywhere but Windows. On Windows, since we
store the pointer to the indirect getter function, now you may get non-
null pointers from QMetaObject::superClass().

Pick-to: 6.4
Change-Id: I6d3880c7d99d4fc494c8fffd16fab51aa255106e
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Thiago Macieira 2022-06-21 11:08:58 -07:00
parent 9af59838d7
commit 688e8f63a2
2 changed files with 5 additions and 5 deletions

View File

@ -369,6 +369,7 @@ struct Q_CORE_EXPORT QMetaObject
}
struct SuperData {
using Getter = const QMetaObject *(*)();
const QMetaObject *direct;
SuperData() = default;
constexpr SuperData(std::nullptr_t) : direct(nullptr) {}
@ -377,7 +378,6 @@ struct Q_CORE_EXPORT QMetaObject
constexpr const QMetaObject *operator->() const { return operator const QMetaObject *(); }
#ifdef QT_NO_DATA_RELOCATION
using Getter = const QMetaObject *(*)();
Getter indirect = nullptr;
constexpr SuperData(Getter g) : direct(nullptr), indirect(g) {}
constexpr operator const QMetaObject *() const
@ -385,6 +385,7 @@ struct Q_CORE_EXPORT QMetaObject
template <const QMetaObject &MO> static constexpr SuperData link()
{ return SuperData(QMetaObject::staticMetaObject<MO>); }
#else
constexpr SuperData(Getter g) : direct(g()) {}
constexpr operator const QMetaObject *() const
{ return direct; }
template <const QMetaObject &MO> static constexpr SuperData link()

View File

@ -489,16 +489,15 @@ void Generator::generateCode()
//
// Finally create and initialize the static meta object
//
fprintf(out, "%sconst QMetaObject %s::staticMetaObject = { {\n",
// ### FIXME: gadgets are not constinit on Windows!
cdef->hasQGadget ? "" : "Q_CONSTINIT ", cdef->qualified.constData());
fprintf(out, "Q_CONSTINIT const QMetaObject %s::staticMetaObject = { {\n",
cdef->qualified.constData());
if (isQObject)
fprintf(out, " nullptr,\n");
else if (cdef->superclassList.size() && !cdef->hasQGadget && !cdef->hasQNamespace) // for qobject, we know the super class must have a static metaobject
fprintf(out, " QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", purestSuperClass.constData());
else if (cdef->superclassList.size()) // for gadgets we need to query at compile time for it
fprintf(out, " QtPrivate::MetaObjectForType<%s>::value(),\n", purestSuperClass.constData());
fprintf(out, " QtPrivate::MetaObjectForType<%s>::value,\n", purestSuperClass.constData());
else
fprintf(out, " nullptr,\n");
fprintf(out, " qt_meta_stringdata_%s.offsetsAndSizes,\n"