summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/global/qglobal.h7
-rw-r--r--src/corelib/global/qsystemdetection.h9
-rw-r--r--src/corelib/kernel/qmetaobject.cpp2
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp12
-rw-r--r--src/corelib/kernel/qobjectdefs.h37
-rw-r--r--src/tools/moc/generator.cpp11
-rw-r--r--tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp6
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp7
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;