diff options
-rw-r--r-- | src/corelib/global/qglobal.h | 7 | ||||
-rw-r--r-- | src/corelib/global/qsystemdetection.h | 9 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobject.cpp | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobjectbuilder.cpp | 12 | ||||
-rw-r--r-- | src/corelib/kernel/qobjectdefs.h | 37 | ||||
-rw-r--r-- | src/tools/moc/generator.cpp | 11 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp | 6 | ||||
-rw-r--r-- | tests/auto/tools/moc/tst_moc.cpp | 7 |
8 files changed, 66 insertions, 25 deletions
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 80f59d92d0..77ca63803f 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2019 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -612,7 +612,8 @@ using qsizetype = QIntegerForSizeof<std::size_t>::Signed; # define Q_ALWAYS_INLINE inline #endif -#if defined(Q_CC_GNU) && defined(Q_OS_WIN) +#if defined(Q_CC_GNU) && defined(Q_OS_WIN) && !defined(QT_NO_DATA_RELOCATION) +// ### Qt6: you can remove me # define QT_INIT_METAOBJECT __attribute__((init_priority(101))) #else # define QT_INIT_METAOBJECT diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index 02e2f77c6b..4ebbe16ead 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2019 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -180,6 +181,12 @@ #if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINRT) # define Q_OS_WINDOWS # define Q_OS_WIN +# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +// On Windows, pointers to dllimport'ed variables are not constant expressions, +// so to keep to certain initializations (like QMetaObject) constexpr, we need +// to use functions instead. +# define QT_NO_DATA_RELOCATION +# endif #endif #if defined(Q_OS_WIN) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 56217262f2..acb1f54bdf 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -953,7 +953,7 @@ static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, co return self; if (self->d.relatedMetaObjects) { Q_ASSERT(priv(self->d.data)->revision >= 2); - const QMetaObject * const *e = self->d.relatedMetaObjects; + const auto *e = self->d.relatedMetaObjects; if (e) { while (*e) { if (const QMetaObject *m =QMetaObject_findMetaObject((*e), name)) diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index d2030f0275..f77c4ce32f 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -747,7 +747,7 @@ void QMetaObjectBuilder::addMetaObject if ((members & RelatedMetaObjects) != 0) { Q_ASSERT(priv(prototype->d.data)->revision >= 2); - const QMetaObject * const *objects = prototype->d.relatedMetaObjects; + const auto *objects = prototype->d.relatedMetaObjects; if (objects) { while (*objects != 0) { addRelatedMetaObject(*objects); @@ -1464,16 +1464,16 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, // Create the relatedMetaObjects block if we need one. if (d->relatedMetaObjects.size() > 0) { - ALIGN(size, QMetaObject *); - const QMetaObject **objects = - reinterpret_cast<const QMetaObject **>(buf + size); + using SuperData = QMetaObject::SuperData; + ALIGN(size, SuperData); + auto objects = reinterpret_cast<SuperData *>(buf + size); if (buf) { meta->d.relatedMetaObjects = objects; for (index = 0; index < d->relatedMetaObjects.size(); ++index) objects[index] = d->relatedMetaObjects[index]; - objects[index] = 0; + objects[index] = nullptr; } - size += sizeof(QMetaObject *) * (d->relatedMetaObjects.size() + 1); + size += sizeof(SuperData) * (d->relatedMetaObjects.size() + 1); } // Align the final size and return it. diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index ef22b6e67f..dc2d832fe5 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2019 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -572,13 +572,42 @@ struct Q_CORE_EXPORT QMetaObject int static_metacall(Call, int, void **) const; static int metacall(QObject *, Call, int, void **); + template <const QMetaObject &MO> static constexpr const QMetaObject *staticMetaObject() + { + return &MO; + } + + struct SuperData { + const QMetaObject *direct; + SuperData() = default; + constexpr SuperData(std::nullptr_t) : direct(nullptr) {} + constexpr SuperData(const QMetaObject *mo) : direct(mo) {} + + 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 + { return indirect ? indirect() : direct; } + template <const QMetaObject &MO> static constexpr SuperData link() + { return SuperData(QMetaObject::staticMetaObject<MO>); } +#else + constexpr operator const QMetaObject *() const + { return direct; } + template <const QMetaObject &MO> static constexpr SuperData link() + { return SuperData(QMetaObject::staticMetaObject<MO>()); } +#endif + }; + struct { // private data - const QMetaObject *superdata; + SuperData superdata; const QByteArrayData *stringdata; const uint *data; typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **); StaticMetacallFunction static_metacall; - const QMetaObject * const *relatedMetaObjects; + const SuperData *relatedMetaObjects; void *extradata; //reserved for future use } d; diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 41d0bbf2a1..6a74e739e6 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -518,10 +518,15 @@ void Generator::generateCode() } } +// +// Generate meta object link to parent meta objects +// + if (!extraList.isEmpty()) { - fprintf(out, "static const QMetaObject * const qt_meta_extradata_%s[] = {\n ", qualifiedClassNameIdentifier.constData()); + fprintf(out, "static const QMetaObject::SuperData qt_meta_extradata_%s[] = {\n", + qualifiedClassNameIdentifier.constData()); for (int i = 0; i < extraList.count(); ++i) { - fprintf(out, " &%s::staticMetaObject,\n", extraList.at(i).constData()); + fprintf(out, " QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", extraList.at(i).constData()); } fprintf(out, " nullptr\n};\n\n"); } @@ -537,7 +542,7 @@ void Generator::generateCode() if (isQObject) fprintf(out, " nullptr,\n"); else if (cdef->superclassList.size() && (!cdef->hasQGadget || knownGadgets.contains(purestSuperClass))) - fprintf(out, " &%s::staticMetaObject,\n", purestSuperClass.constData()); + fprintf(out, " QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", purestSuperClass.constData()); else fprintf(out, " nullptr,\n"); fprintf(out, " qt_meta_stringdata_%s.data,\n" diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 56623773a2..9fe7d63727 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -1322,8 +1322,8 @@ bool tst_QMetaObjectBuilder::sameMetaObject return false; } - const QMetaObject * const *objects1 = meta1->d.relatedMetaObjects; - const QMetaObject * const *objects2 = meta2->d.relatedMetaObjects; + const auto *objects1 = meta1->d.relatedMetaObjects; + const auto *objects2 = meta2->d.relatedMetaObjects; if (objects1 && !objects2) return false; if (objects2 && !objects1) @@ -1391,7 +1391,7 @@ private: }; QMetaObject TestObject::staticMetaObject = { - { 0, 0, 0, 0, 0, 0 } + { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr } }; TestObject::TestObject(QObject *parent) diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index b88d929ca9..89f563f11d 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -1053,7 +1053,7 @@ void tst_Moc::testExtraDataForEnum() const QMetaObject *mobjUser = &EnumUserClass::staticMetaObject; QCOMPARE(mobjUser->enumeratorCount(), 0); - const QMetaObject * const *objects = mobjUser->d.relatedMetaObjects; + const auto *objects = mobjUser->d.relatedMetaObjects; QVERIFY(objects); QCOMPARE(objects[0], mobjSource); QVERIFY(!objects[1]); @@ -3579,10 +3579,9 @@ namespace QTBUG32933_relatedObjectsDontIncludeItself { void tst_Moc::QTBUG32933_relatedObjectsDontIncludeItself() { const QMetaObject *mo = &QTBUG32933_relatedObjectsDontIncludeItself::NS::Obj::staticMetaObject; - const QMetaObject * const *objects = mo->d.relatedMetaObjects; + const auto *objects = mo->d.relatedMetaObjects; // the related objects should be empty because the enums is in the same object. QVERIFY(!objects); - } class UnrelatedClass : public QObject @@ -3688,7 +3687,7 @@ void tst_Moc::relatedMetaObjectsNameConflict() // load all specified metaobjects int a set QSet<const QMetaObject*> dependency; - const QMetaObject *const *i = dependingObject->d.relatedMetaObjects; + const auto *i = dependingObject->d.relatedMetaObjects; while (*i) { dependency.insert(*i); ++i; |