summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qmetaobject.cpp27
-rw-r--r--src/corelib/kernel/qmetaobject_p.h1
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp55
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder_p.h4
-rw-r--r--src/corelib/kernel/qobjectdefs.h2
-rw-r--r--src/corelib/kernel/qtmocconstants.h3
-rw-r--r--src/corelib/kernel/qtmochelpers.h7
-rw-r--r--src/dbus/qdbusmetaobject.cpp3
-rw-r--r--src/gui/kernel/qguiapplication_p.h4
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp32
-rw-r--r--src/gui/math3d/qquaternion.h8
-rw-r--r--src/gui/math3d/qvectornd.cpp17
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp1
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow_p.h1
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style.cpp2
-rw-r--r--src/tools/moc/generator.cpp31
-rw-r--r--src/tools/moc/generator.h10
-rw-r--r--src/tools/moc/moc.cpp65
18 files changed, 204 insertions, 69 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 24cc58829c8..c7e50788b45 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -469,6 +469,33 @@ QMetaType QMetaObject::metaType() const
}
}
+static inline QByteArrayView objectMetaObjectHash(const QMetaObject *m)
+{
+ // metaObjectHash didn't exist before revision 14
+ if (QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && priv(m->d.data)->revision < 14)
+ return {};
+ const auto index = priv(m->d.data)->metaObjectHashIndex;
+ if (index == -1)
+ return {};
+ return stringDataView(m, index);
+}
+
+/*!
+ \since 6.11
+
+ Returns the revisioned hash of the contents of this QMetaObject or nullptr.
+
+ The hash has the following format <hash_revision>$<hash_b64>, where
+ hash_revision is an integer and hash_b64 is the base64 encoding of the
+ hash.
+
+ Note that only hashes of the same revision should be compared.
+*/
+const char *QMetaObject::metaObjectHash() const
+{
+ return objectMetaObjectHash(this).constData();
+}
+
/*!
Returns the method offset for this class; i.e. the index position
of this class's first member function.
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index bfda30fda28..7264d2a956f 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -124,6 +124,7 @@ struct QMetaObjectPrivate
int constructorCount, constructorData;
int flags;
int signalCount;
+ int metaObjectHashIndex;
static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
{ return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); }
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp
index 6065bf2baea..9af6de73680 100644
--- a/src/corelib/kernel/qmetaobjectbuilder.cpp
+++ b/src/corelib/kernel/qmetaobjectbuilder.cpp
@@ -558,6 +558,8 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty &protot
property.setEnumOrFlag(prototype.isEnumType());
property.setConstant(prototype.isConstant());
property.setFinal(prototype.isFinal());
+ property.setVirtual(prototype.isVirtual());
+ property.setOverride(prototype.isOverride());
property.setRevision(prototype.revision());
if (prototype.hasNotifySignal()) {
// Find an existing method for the notify signal, or add a new one.
@@ -1177,10 +1179,11 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
int methodParametersDataSize = aggregateParameterCount(d->methods)
+ aggregateParameterCount(d->constructors);
if constexpr (mode == Construct) {
- static_assert(QMetaObjectPrivate::OutputRevision == 13, "QMetaObjectBuilder should generate the same version as moc");
+ static_assert(QMetaObjectPrivate::OutputRevision == 14, "QMetaObjectBuilder should generate the same version as moc");
pmeta->revision = QMetaObjectPrivate::OutputRevision;
pmeta->flags = d->flags.toInt() | AllocatedMetaObject;
pmeta->className = 0; // Class name is always the first string.
+ pmeta->metaObjectHashIndex = -1; // TODO support hash in the builder too
//pmeta->signalCount is handled in the "output method loop" as an optimization.
pmeta->classInfoCount = d->classInfoNames.size();
@@ -2068,6 +2071,32 @@ bool QMetaPropertyBuilder::isFinal() const
}
/*!
+ Returns \c true if the property is virtual; otherwise returns \c false.
+ The default value is false.
+*/
+bool QMetaPropertyBuilder::isVirtual() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Virtual);
+ else
+ return false;
+}
+
+/*!
+ Returns \c true if the property does override; otherwise returns \c false.
+ The default value is false.
+*/
+bool QMetaPropertyBuilder::isOverride() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Override);
+ else
+ return false;
+}
+
+/*!
* Returns \c true if the property is an alias.
* The default value is false
*/
@@ -2239,6 +2268,30 @@ void QMetaPropertyBuilder::setFinal(bool value)
}
/*!
+ Sets the \c VIRTUAL flag on this property to \a value.
+
+ \sa isFinal()
+*/
+void QMetaPropertyBuilder::setVirtual(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(Virtual, value);
+}
+
+/*!
+ Sets the \c OVERRIDE flag on this property to \a value.
+
+ \sa isOverride()
+*/
+void QMetaPropertyBuilder::setOverride(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(Override, value);
+}
+
+/*!
Sets the \c ALIAS flag on this property to \a value
*/
void QMetaPropertyBuilder::setAlias(bool value)
diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h
index 563704d60e6..9591944602a 100644
--- a/src/corelib/kernel/qmetaobjectbuilder_p.h
+++ b/src/corelib/kernel/qmetaobjectbuilder_p.h
@@ -214,6 +214,8 @@ public:
bool isEnumOrFlag() const;
bool isConstant() const;
bool isFinal() const;
+ bool isVirtual() const;
+ bool isOverride() const;
bool isAlias() const;
bool isBindable() const;
bool isRequired() const;
@@ -229,6 +231,8 @@ public:
void setEnumOrFlag(bool value);
void setConstant(bool value);
void setFinal(bool value);
+ void setVirtual(bool value);
+ void setOverride(bool value);
void setAlias(bool value);
void setBindable(bool value);
void setRequired(bool value);
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 848102cc57a..d3e761982f5 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -247,6 +247,8 @@ struct Q_CORE_EXPORT QMetaObject
QMetaType metaType() const;
+ const char *metaObjectHash() const;
+
int methodOffset() const;
int enumeratorOffset() const;
int propertyOffset() const;
diff --git a/src/corelib/kernel/qtmocconstants.h b/src/corelib/kernel/qtmocconstants.h
index 260ac2fa5f8..822e02e6c8e 100644
--- a/src/corelib/kernel/qtmocconstants.h
+++ b/src/corelib/kernel/qtmocconstants.h
@@ -30,7 +30,8 @@ namespace QtMocConstants {
// revision 11 is Qt 6.5: The metatype for void is stored in the metatypes array
// revision 12 is Qt 6.6: It adds the metatype for enums
// revision 13 is Qt 6.9: Adds support for 64-bit QFlags and moves the method revision
-enum { OutputRevision = 13 }; // Used by moc, qmetaobjectbuilder and qdbus
+// revision 14 is Qt 6.11: Adds a hash of meta object contents
+enum { OutputRevision = 14 }; // Used by moc, qmetaobjectbuilder and qdbus
enum PropertyFlags : uint {
Invalid = 0x00000000,
diff --git a/src/corelib/kernel/qtmochelpers.h b/src/corelib/kernel/qtmochelpers.h
index 4c549e78ad5..3d2b59d2a73 100644
--- a/src/corelib/kernel/qtmochelpers.h
+++ b/src/corelib/kernel/qtmochelpers.h
@@ -511,7 +511,8 @@ template <typename ObjectType, typename Unique, typename Strings,
typename Constructors = UintData<>, typename ClassInfo = detail::UintDataBlock<0, 0>>
constexpr auto metaObjectData(uint flags, const Strings &strings,
const Methods &methods, const Properties &properties,
- const Enums &enums, const Constructors &constructors = {},
+ const Enums &enums, int qt_metaObjectHashIndex = -1,
+ const Constructors &constructors = {},
const ClassInfo &classInfo = {})
{
constexpr uint MetaTypeCount = Properties::metaTypeCount()
@@ -520,7 +521,7 @@ constexpr auto metaObjectData(uint flags, const Strings &strings,
+ Methods::metaTypeCount()
+ Constructors::metaTypeCount();
- constexpr uint HeaderSize = 14;
+ constexpr uint HeaderSize = 15;
constexpr uint TotalSize = HeaderSize
+ Properties::dataSize()
+ Enums::dataSize()
@@ -582,6 +583,8 @@ constexpr auto metaObjectData(uint flags, const Strings &strings,
}
}
+ data[14] = qt_metaObjectHashIndex;
+
return result;
}
diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp
index 149392f9c3c..a4ffd7a64dd 100644
--- a/src/dbus/qdbusmetaobject.cpp
+++ b/src/dbus/qdbusmetaobject.cpp
@@ -383,9 +383,10 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
- methods.size(); // ditto
QDBusMetaObjectPrivate *header = reinterpret_cast<QDBusMetaObjectPrivate *>(idata.data());
- static_assert(QMetaObjectPrivate::OutputRevision == 13, "QtDBus meta-object generator should generate the same version as moc");
+ static_assert(QMetaObjectPrivate::OutputRevision == 14, "QtDBus meta-object generator should generate the same version as moc");
header->revision = QMetaObjectPrivate::OutputRevision;
header->className = 0;
+ header->metaObjectHashIndex = -1; // TODO support hash in dbus metaobject too
header->classInfoCount = 0;
header->classInfoData = 0;
header->methodCount = int(signals_.size() + methods.size());
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index cb4702b5f7e..633ae7895ba 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -228,8 +228,8 @@ public:
// to use single-point precision.
friend constexpr bool operator==(const QLastCursorPosition &p1, const QPointF &p2) noexcept
{
- return qFuzzyCompare(float(p1.x()), float(p2.x()))
- && qFuzzyCompare(float(p1.y()), float(p2.y()));
+ return QtPrivate::fuzzyCompare(float(p1.x()), float(p2.x()))
+ && QtPrivate::fuzzyCompare(float(p1.y()), float(p2.y()));
}
friend constexpr bool operator!=(const QLastCursorPosition &p1, const QPointF &p2) noexcept
{
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp
index f6a06fd47ca..95b9524172f 100644
--- a/src/gui/math3d/qmatrix4x4.cpp
+++ b/src/gui/math3d/qmatrix4x4.cpp
@@ -738,22 +738,22 @@ QMatrix4x4 operator/(const QMatrix4x4& matrix, float divisor)
*/
bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2) noexcept
{
- return qFuzzyCompare(m1.m[0][0], m2.m[0][0]) &&
- qFuzzyCompare(m1.m[0][1], m2.m[0][1]) &&
- qFuzzyCompare(m1.m[0][2], m2.m[0][2]) &&
- qFuzzyCompare(m1.m[0][3], m2.m[0][3]) &&
- qFuzzyCompare(m1.m[1][0], m2.m[1][0]) &&
- qFuzzyCompare(m1.m[1][1], m2.m[1][1]) &&
- qFuzzyCompare(m1.m[1][2], m2.m[1][2]) &&
- qFuzzyCompare(m1.m[1][3], m2.m[1][3]) &&
- qFuzzyCompare(m1.m[2][0], m2.m[2][0]) &&
- qFuzzyCompare(m1.m[2][1], m2.m[2][1]) &&
- qFuzzyCompare(m1.m[2][2], m2.m[2][2]) &&
- qFuzzyCompare(m1.m[2][3], m2.m[2][3]) &&
- qFuzzyCompare(m1.m[3][0], m2.m[3][0]) &&
- qFuzzyCompare(m1.m[3][1], m2.m[3][1]) &&
- qFuzzyCompare(m1.m[3][2], m2.m[3][2]) &&
- qFuzzyCompare(m1.m[3][3], m2.m[3][3]);
+ return QtPrivate::fuzzyCompare(m1.m[0][0], m2.m[0][0])
+ && QtPrivate::fuzzyCompare(m1.m[0][1], m2.m[0][1])
+ && QtPrivate::fuzzyCompare(m1.m[0][2], m2.m[0][2])
+ && QtPrivate::fuzzyCompare(m1.m[0][3], m2.m[0][3])
+ && QtPrivate::fuzzyCompare(m1.m[1][0], m2.m[1][0])
+ && QtPrivate::fuzzyCompare(m1.m[1][1], m2.m[1][1])
+ && QtPrivate::fuzzyCompare(m1.m[1][2], m2.m[1][2])
+ && QtPrivate::fuzzyCompare(m1.m[1][3], m2.m[1][3])
+ && QtPrivate::fuzzyCompare(m1.m[2][0], m2.m[2][0])
+ && QtPrivate::fuzzyCompare(m1.m[2][1], m2.m[2][1])
+ && QtPrivate::fuzzyCompare(m1.m[2][2], m2.m[2][2])
+ && QtPrivate::fuzzyCompare(m1.m[2][3], m2.m[2][3])
+ && QtPrivate::fuzzyCompare(m1.m[3][0], m2.m[3][0])
+ && QtPrivate::fuzzyCompare(m1.m[3][1], m2.m[3][1])
+ && QtPrivate::fuzzyCompare(m1.m[3][2], m2.m[3][2])
+ && QtPrivate::fuzzyCompare(m1.m[3][3], m2.m[3][3]);
}
diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h
index a7b1d432df7..c92e7177199 100644
--- a/src/gui/math3d/qquaternion.h
+++ b/src/gui/math3d/qquaternion.h
@@ -305,10 +305,10 @@ constexpr QQuaternion operator/(const QQuaternion &quaternion, float divisor)
constexpr bool qFuzzyCompare(const QQuaternion &q1, const QQuaternion &q2) noexcept
{
- return qFuzzyCompare(q1.wp, q2.wp) &&
- qFuzzyCompare(q1.xp, q2.xp) &&
- qFuzzyCompare(q1.yp, q2.yp) &&
- qFuzzyCompare(q1.zp, q2.zp);
+ return QtPrivate::fuzzyCompare(q1.wp, q2.wp)
+ && QtPrivate::fuzzyCompare(q1.xp, q2.xp)
+ && QtPrivate::fuzzyCompare(q1.yp, q2.yp)
+ && QtPrivate::fuzzyCompare(q1.zp, q2.zp);
}
#if QT_GUI_INLINE_IMPL_SINCE(6, 11)
diff --git a/src/gui/math3d/qvectornd.cpp b/src/gui/math3d/qvectornd.cpp
index ec836cfa56e..ee070b2b5be 100644
--- a/src/gui/math3d/qvectornd.cpp
+++ b/src/gui/math3d/qvectornd.cpp
@@ -375,7 +375,8 @@ QT_BEGIN_NAMESPACE
*/
bool qFuzzyCompare(QVector2D v1, QVector2D v2) noexcept
{
- return qFuzzyCompare(v1.v[0], v2.v[0]) && qFuzzyCompare(v1.v[1], v2.v[1]);
+ return QtPrivate::fuzzyCompare(v1.v[0], v2.v[0])
+ && QtPrivate::fuzzyCompare(v1.v[1], v2.v[1]);
}
#ifndef QT_NO_VECTOR3D
@@ -979,9 +980,9 @@ QVector3D QVector3D::unproject(const QMatrix4x4 &modelView, const QMatrix4x4 &pr
*/
bool qFuzzyCompare(QVector3D v1, QVector3D v2) noexcept
{
- return qFuzzyCompare(v1.v[0], v2.v[0]) &&
- qFuzzyCompare(v1.v[1], v2.v[1]) &&
- qFuzzyCompare(v1.v[2], v2.v[2]);
+ return QtPrivate::fuzzyCompare(v1.v[0], v2.v[0])
+ && QtPrivate::fuzzyCompare(v1.v[1], v2.v[1])
+ && QtPrivate::fuzzyCompare(v1.v[2], v2.v[2]);
}
#ifndef QT_NO_VECTOR2D
@@ -1501,10 +1502,10 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector)
*/
bool qFuzzyCompare(QVector4D v1, QVector4D v2) noexcept
{
- return qFuzzyCompare(v1.v[0], v2.v[0]) &&
- qFuzzyCompare(v1.v[1], v2.v[1]) &&
- qFuzzyCompare(v1.v[2], v2.v[2]) &&
- qFuzzyCompare(v1.v[3], v2.v[3]);
+ return QtPrivate::fuzzyCompare(v1.v[0], v2.v[0])
+ && QtPrivate::fuzzyCompare(v1.v[1], v2.v[1])
+ && QtPrivate::fuzzyCompare(v1.v[2], v2.v[2])
+ && QtPrivate::fuzzyCompare(v1.v[3], v2.v[3]);
}
#ifndef QT_NO_VECTOR2D
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp
index f27943070d0..2be05625971 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -513,7 +513,6 @@ void QWaylandWindow::setGeometry(const QRect &r)
mWindowDecoration->update();
QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(window(), geometry());
- mSentInitialResize = true;
}
// Wayland has no concept of areas being exposed or not, only the entire window, when our geometry changes, we need to flag the new area as exposed
diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h
index 9e1bd92af30..7dda16cc776 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow_p.h
+++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h
@@ -334,7 +334,6 @@ protected:
int mFrameCallbackTimeout = 100;
QVariantMap m_properties;
- bool mSentInitialResize = false;
QPoint mOffset;
std::optional<qreal> mScale = std::nullopt;
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp
index 6fd857828d3..7caa352afe4 100644
--- a/src/plugins/styles/modernwindows/qwindows11style.cpp
+++ b/src/plugins/styles/modernwindows/qwindows11style.cpp
@@ -917,7 +917,7 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
const bool isReverse = option->direction == Qt::RightToLeft;
const bool isOpen = option->state & QStyle::State_Open;
QFont f(d->assetFont);
- f.setPointSize(6);
+ f.setPointSize(8);
painter->setFont(f);
painter->setPen(option->palette.color(isOpen ? QPalette::Active : QPalette::Disabled,
QPalette::WindowText));
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 6e7077b383e..94c75ae6eb3 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -78,16 +78,18 @@ QT_FOR_EACH_STATIC_TYPE(RETURN_METATYPENAME_STRING)
return nullptr;
}
- Generator::Generator(Moc *moc, ClassDef *classDef, const QList<QByteArray> &metaTypes,
+ Generator::Generator(Moc *moc, const ClassDef *classDef, const QList<QByteArray> &metaTypes,
const QHash<QByteArray, QByteArray> &knownQObjectClasses,
- const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile,
- bool requireCompleteTypes)
+ const QHash<QByteArray, QByteArray> &knownGadgets,
+ const QHash<QByteArray, QByteArray> &hashes,
+ FILE *outfile, bool requireCompleteTypes)
: parser(moc),
out(outfile),
cdef(classDef),
metaTypes(metaTypes),
knownQObjectClasses(knownQObjectClasses),
knownGadgets(knownGadgets),
+ hashes(hashes),
requireCompleteTypes(requireCompleteTypes)
{
if (cdef->superclassList.size())
@@ -228,28 +230,11 @@ void Generator::generateCode()
bool isQObject = (cdef->classname == "QObject");
bool isConstructible = !cdef->constructorList.isEmpty();
- // filter out undeclared enumerators and sets
- {
- QList<EnumDef> enumList;
- for (EnumDef def : std::as_const(cdef->enumList)) {
- if (cdef->enumDeclarations.contains(def.name)) {
- enumList += def;
- }
- def.enumName = def.name;
- QByteArray alias = cdef->flagAliases.value(def.name);
- if (cdef->enumDeclarations.contains(alias)) {
- def.name = alias;
- def.flags |= cdef->enumDeclarations[alias];
- enumList += def;
- }
- }
- cdef->enumList = enumList;
- }
-
//
// Register all strings used in data section
//
strreg(cdef->qualified);
+ strreg(hashes[cdef->qualified]);
registerClassInfoStrings();
registerFunctionStrings(cdef->signalList);
registerFunctionStrings(cdef->slotList);
@@ -308,6 +293,8 @@ void Generator::generateCode()
addEnums();
fprintf(out, " };\n");
+ fprintf(out, " uint qt_metaObjectHashIndex = %d;\n", stridx(hashes[cdef->qualified]));
+
const char *uintDataParams = "";
if (isConstructible || !cdef->classInfoList.isEmpty()) {
if (isConstructible) {
@@ -340,7 +327,7 @@ void Generator::generateCode()
if (!requireCompleteness)
tagType = "qt_meta_tag_" + qualifiedClassNameIdentifier + "_t";
fprintf(out, " return QtMocHelpers::metaObjectData<%s, %s>(%s, qt_stringData,\n"
- " qt_methods, qt_properties, qt_enums%s);\n"
+ " qt_methods, qt_properties, qt_enums, qt_metaObjectHashIndex%s);\n"
"}\n",
ownType, tagType.constData(), metaObjectFlags, uintDataParams);
}
diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h
index 45df0783c2b..77be2fc6714 100644
--- a/src/tools/moc/generator.h
+++ b/src/tools/moc/generator.h
@@ -12,14 +12,15 @@ class Generator
{
Moc *parser = nullptr;
FILE *out;
- ClassDef *cdef;
+ const ClassDef *cdef;
QList<uint> meta_data;
public:
- Generator(Moc *moc, ClassDef *classDef, const QList<QByteArray> &metaTypes,
+ Generator(Moc *moc, const ClassDef *classDef, const QList<QByteArray> &metaTypes,
const QHash<QByteArray, QByteArray> &knownQObjectClasses,
- const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile = nullptr,
- bool requireCompleteTypes = false);
+ const QHash<QByteArray, QByteArray> &knownGadgets,
+ const QHash<QByteArray, QByteArray> &hashes,
+ FILE *outfile = nullptr, bool requireCompleteTypes = false);
void generateCode();
qsizetype registeredStringsCount() { return strings.size(); }
@@ -54,6 +55,7 @@ private:
QList<QByteArray> metaTypes;
QHash<QByteArray, QByteArray> knownQObjectClasses;
QHash<QByteArray, QByteArray> knownGadgets;
+ QHash<QByteArray, QByteArray> hashes;
bool requireCompleteTypes;
};
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index baa6690350d..7f05f34edb6 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -17,6 +17,10 @@
#include <private/qmetaobject_moc_p.h>
#include <private/qduplicatetracker_p.h>
+// This is a bootstrapped tool, so we can't rely on QCryptographicHash for the
+// faster SHA1 implementations from OpenSSL.
+#include "../../3rdparty/sha1/sha1.cpp"
+
QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
@@ -1191,6 +1195,24 @@ static QByteArrayList requiredQtContainers(const QList<ClassDef> &classes)
return required;
}
+QByteArray classDefJsonObjectHash(const QJsonObject &object)
+{
+ const QByteArray json = QJsonDocument(object).toJson(QJsonValue::JsonFormat::Compact);
+ QByteArray hash(20, 0); // SHA1 produces 160 bits of data
+
+ {
+ Sha1State state;
+ sha1InitState(&state);
+ sha1Update(&state, reinterpret_cast<const uchar *>(json.constData()), json.size());
+ sha1FinalizeState(&state);
+ sha1ToHash(&state, reinterpret_cast<uchar *>(hash.data()));
+ }
+
+ static const char revisionPrefix[] = "0$";
+ const QByteArray hashB64 = hash.toBase64(QByteArray::OmitTrailingEquals);
+ return revisionPrefix + hashB64;
+}
+
void Moc::generate(FILE *out, FILE *jsonOutput)
{
QByteArrayView fn = strippedFileName();
@@ -1247,14 +1269,40 @@ void Moc::generate(FILE *out, FILE *jsonOutput)
"#endif\n\n");
#endif
+ // filter out undeclared enumerators and sets
+ for (ClassDef &cdef : classList) {
+ QList<EnumDef> enumList;
+ for (EnumDef def : std::as_const(cdef.enumList)) {
+ if (cdef.enumDeclarations.contains(def.name)) {
+ enumList += def;
+ }
+ def.enumName = def.name;
+ QByteArray alias = cdef.flagAliases.value(def.name);
+ if (cdef.enumDeclarations.contains(alias)) {
+ def.name = alias;
+ def.flags |= cdef.enumDeclarations[alias];
+ enumList += def;
+ }
+ }
+ cdef.enumList = enumList;
+ }
+
fprintf(out, "QT_WARNING_PUSH\n");
fprintf(out, "QT_WARNING_DISABLE_DEPRECATED\n");
fprintf(out, "QT_WARNING_DISABLE_GCC(\"-Wuseless-cast\")\n");
+ QHash<QByteArray, QJsonObject> classDefJsonObjects;
+ QHash<QByteArray, QByteArray> metaObjectHashes;
+ for (const ClassDef &def : std::as_const(classList)) {
+ const QJsonObject jsonObject = def.toJson();
+ classDefJsonObjects.insert(def.qualified, jsonObject);
+ metaObjectHashes.insert(def.qualified, classDefJsonObjectHash(jsonObject));
+ }
+
fputs("", out);
- for (ClassDef &def : classList) {
- Generator generator(this, &def, metaTypes, knownQObjectClasses, knownGadgets, out,
- requireCompleteTypes);
+ for (const ClassDef &def : std::as_const(classList)) {
+ Generator generator(this, &def, metaTypes, knownQObjectClasses, knownGadgets,
+ metaObjectHashes, out, requireCompleteTypes);
generator.generateCode();
// generator.generateCode() should have already registered all strings
@@ -1273,13 +1321,20 @@ void Moc::generate(FILE *out, FILE *jsonOutput)
mocData["inputFile"_L1] = QLatin1StringView(fn.constData());
QJsonArray classesJsonFormatted;
+ QJsonObject hashesJsonObject;
- for (const ClassDef &cdef: std::as_const(classList))
- classesJsonFormatted.append(cdef.toJson());
+ for (const ClassDef &cdef : std::as_const(classList)) {
+ classesJsonFormatted.append(classDefJsonObjects[cdef.qualified]);
+ hashesJsonObject.insert(QString::fromLatin1(cdef.qualified),
+ QString::fromLatin1(metaObjectHashes[cdef.qualified]));
+ }
if (!classesJsonFormatted.isEmpty())
mocData["classes"_L1] = classesJsonFormatted;
+ if (!hashesJsonObject.isEmpty())
+ mocData["hashes"_L1] = hashesJsonObject;
+
QJsonDocument jsonDoc(mocData);
fputs(jsonDoc.toJson().constData(), jsonOutput);
}