diff options
Diffstat (limited to 'src/corelib/kernel/qmetaobjectbuilder.cpp')
-rw-r--r-- | src/corelib/kernel/qmetaobjectbuilder.cpp | 629 |
1 files changed, 163 insertions, 466 deletions
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index 77a47d306c..c2b44a4f00 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qmetaobjectbuilder_p.h" @@ -89,7 +53,7 @@ Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type) } // namespace QtPrivate // copied from qmetaobject.cpp -[[maybe_unused]] static inline const QMetaObjectPrivate *priv(const uint* data) +[[maybe_unused]] static inline const QMetaObjectPrivate *qmobPriv(const uint* data) { return reinterpret_cast<const QMetaObjectPrivate*>(data); } class QMetaMethodBuilderPrivate @@ -146,16 +110,17 @@ public: return signature.left(qMax(signature.indexOf('('), 0)); } }; -Q_DECLARE_TYPEINFO(QMetaMethodBuilderPrivate, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(QMetaMethodBuilderPrivate, Q_RELOCATABLE_TYPE); class QMetaPropertyBuilderPrivate { public: QMetaPropertyBuilderPrivate - (const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1, + (const QByteArray& _name, const QByteArray& _type, QMetaType _metaType, int notifierIdx=-1, int _revision = 0) : name(_name), type(QMetaObject::normalizedType(_type.constData())), + metaType(_metaType), flags(Readable | Writable | Scriptable), notifySignal(notifierIdx), revision(_revision) { @@ -164,6 +129,7 @@ public: QByteArray name; QByteArray type; + QMetaType metaType; int flags; int notifySignal; int revision; @@ -181,7 +147,7 @@ public: flags &= ~f; } }; -Q_DECLARE_TYPEINFO(QMetaPropertyBuilderPrivate, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(QMetaPropertyBuilderPrivate, Q_RELOCATABLE_TYPE); class QMetaEnumBuilderPrivate { @@ -193,12 +159,13 @@ public: QByteArray name; QByteArray enumName; + QMetaType metaType; bool isFlag; bool isScoped; QList<QByteArray> keys; QList<int> values; }; -Q_DECLARE_TYPEINFO(QMetaEnumBuilderPrivate, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(QMetaEnumBuilderPrivate, Q_RELOCATABLE_TYPE); class QMetaObjectBuilderPrivate { @@ -222,7 +189,7 @@ public: QList<QByteArray> classInfoValues; std::vector<QMetaEnumBuilderPrivate> enumerators; QList<const QMetaObject *> relatedMetaObjects; - int flags; + MetaObjectFlags flags; }; bool QMetaObjectBuilderPrivate::hasRevisionedMethods() const @@ -323,7 +290,7 @@ void QMetaObjectBuilder::setSuperClass(const QMetaObject *meta) */ MetaObjectFlags QMetaObjectBuilder::flags() const { - return MetaObjectFlags(d->flags); + return d->flags; } /*! @@ -556,8 +523,16 @@ QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod &prototy QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QByteArray &name, const QByteArray &type, int notifierId) { + return addProperty(name, type, QMetaType::fromName(type), notifierId); +} + +/*! + \overload + */ +QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QByteArray &name, const QByteArray &type, QMetaType metaType, int notifierId) +{ int index = int(d->properties.size()); - d->properties.push_back(QMetaPropertyBuilderPrivate(name, type, notifierId)); + d->properties.push_back(QMetaPropertyBuilderPrivate(name, type, metaType, notifierId)); return QMetaPropertyBuilder(this, index); } @@ -571,7 +546,7 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QByteArray &name, con */ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty &prototype) { - QMetaPropertyBuilder property = addProperty(prototype.name(), prototype.typeName()); + QMetaPropertyBuilder property = addProperty(prototype.name(), prototype.typeName(), prototype.metaType()); property.setReadable(prototype.isReadable()); property.setWritable(prototype.isWritable()); property.setResettable(prototype.isResettable()); @@ -623,6 +598,7 @@ QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QMetaEnum &prototype) { QMetaEnumBuilder en = addEnumerator(prototype.name()); en.setEnumName(prototype.enumName()); + en.setMetaType(prototype.metaType()); en.setIsFlag(prototype.isFlag()); en.setIsScoped(prototype.isScoped()); int count = prototype.keyCount(); @@ -730,7 +706,7 @@ void QMetaObjectBuilder::addMetaObject(const QMetaObject *prototype, } if ((members & RelatedMetaObjects) != 0) { - Q_ASSERT(priv(prototype->d.data)->revision >= 2); + Q_ASSERT(qmobPriv(prototype->d.data)->revision >= 2); const auto *objects = prototype->d.relatedMetaObjects; if (objects) { while (*objects != nullptr) { @@ -741,7 +717,7 @@ void QMetaObjectBuilder::addMetaObject(const QMetaObject *prototype, } if ((members & StaticMetacall) != 0) { - Q_ASSERT(priv(prototype->d.data)->revision >= 6); + Q_ASSERT(qmobPriv(prototype->d.data)->revision >= 6); if (prototype->d.static_metacall) setStaticMetacallFunction(prototype->d.static_metacall); } @@ -1052,6 +1028,9 @@ int QMetaObjectBuilder::indexOfClassInfo(const QByteArray &name) } // Align on a specific type boundary. +#ifdef ALIGN +# undef ALIGN +#endif #define ALIGN(size,type) \ (size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1) @@ -1109,7 +1088,7 @@ static void writeString(char *out, int i, const QByteArray &str, memcpy(out + 2 * i * sizeof(uint), &offsetLen, 2 * sizeof(uint)); memcpy(out + offset, str.constData(), size); - out[offsetOfStringdataMember + stringdataOffset + size] = '\0'; + out[offset + size] = '\0'; stringdataOffset += size + 1; } @@ -1150,31 +1129,32 @@ static int aggregateParameterCount(const std::vector<QMetaMethodBuilderPrivate> return sum; } +enum Mode { + Prepare, // compute the size of the metaobject + Construct // construct metaobject in pre-allocated buffer +}; // Build a QMetaObject in "buf" based on the information in "d". -// If "buf" is null, then return the number of bytes needed to -// build the QMetaObject. Returns -1 if the metaobject if -// relocatable is set, but the metaobject contains relatedMetaObjects. +// If the mode is prepare, then return the number of bytes needed to +// build the QMetaObject. +template<Mode mode> static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, - int expectedSize, bool relocatable) + int expectedSize) { Q_UNUSED(expectedSize); // Avoid warning in release mode - int size = 0; + Q_UNUSED(buf); + qsizetype size = 0; int dataIndex; int paramsIndex; int enumIndex; int index; bool hasRevisionedMethods = d->hasRevisionedMethods(); - if (relocatable && - (d->relatedMetaObjects.size() > 0 || d->staticMetacallFunction)) - return -1; - // Create the main QMetaObject structure at the start of the buffer. QMetaObject *meta = reinterpret_cast<QMetaObject *>(buf); size += sizeof(QMetaObject); ALIGN(size, int); - if (buf) { - if (!relocatable) meta->d.superdata = d->superClass; + if constexpr (mode == Construct) { + meta->d.superdata = d->superClass; meta->d.relatedMetaObjects = nullptr; meta->d.extradata = nullptr; meta->d.metaTypes = nullptr; @@ -1182,19 +1162,19 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, } // Populate the QMetaObjectPrivate structure. - QMetaObjectPrivate *pmeta - = reinterpret_cast<QMetaObjectPrivate *>(buf + size); - int pmetaSize = size; + QMetaObjectPrivate *pmeta = buf ? reinterpret_cast<QMetaObjectPrivate *>(buf + size) + : nullptr; + //int pmetaSize = size; dataIndex = MetaObjectPrivateFieldCount; int methodParametersDataSize = ((aggregateParameterCount(d->methods) + aggregateParameterCount(d->constructors)) * 2) // types and parameter names - int(d->methods.size()) // return "parameters" don't have names - int(d->constructors.size()); // "this" parameters don't have names - if (buf) { - static_assert(QMetaObjectPrivate::OutputRevision == 9, "QMetaObjectBuilder should generate the same version as moc"); + if constexpr (mode == Construct) { + static_assert(QMetaObjectPrivate::OutputRevision == 12, "QMetaObjectBuilder should generate the same version as moc"); pmeta->revision = QMetaObjectPrivate::OutputRevision; - pmeta->flags = d->flags; + pmeta->flags = d->flags.toInt(); pmeta->className = 0; // Class name is always the first string. //pmeta->signalCount is handled in the "output method loop" as an optimization. @@ -1245,15 +1225,10 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, int *data = reinterpret_cast<int *>(pmeta); size += dataIndex * sizeof(int); ALIGN(size, void *); - char *str = reinterpret_cast<char *>(buf + size); - if (buf) { - if (relocatable) { - meta->d.stringdata = reinterpret_cast<const uint *>((quintptr)size); - meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize); - } else { - meta->d.stringdata = reinterpret_cast<const uint *>(str); - meta->d.data = reinterpret_cast<uint *>(data); - } + [[maybe_unused]] char *str = reinterpret_cast<char *>(buf + size); + if constexpr (mode == Construct) { + meta->d.stringdata = reinterpret_cast<const uint *>(str); + meta->d.data = reinterpret_cast<uint *>(data); } // Reset the current data position to just past the QMetaObjectPrivate. @@ -1264,9 +1239,9 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, // Output the class infos, Q_ASSERT(!buf || dataIndex == pmeta->classInfoData); for (index = 0; index < d->classInfoNames.size(); ++index) { - int name = strings.enter(d->classInfoNames[index]); - int value = strings.enter(d->classInfoValues[index]); - if (buf) { + [[maybe_unused]] int name = strings.enter(d->classInfoNames[index]); + [[maybe_unused]] int value = strings.enter(d->classInfoValues[index]); + if constexpr (mode == Construct) { data[dataIndex] = name; data[dataIndex + 1] = value; } @@ -1275,13 +1250,14 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, // Output the methods in the class. Q_ASSERT(!buf || dataIndex == pmeta->methodData); - int parameterMetaTypesIndex = int(d->properties.size()); + // + 1 for metatype of this metaobject + int parameterMetaTypesIndex = int(d->properties.size()) + 1; for (const auto &method : d->methods) { - int name = strings.enter(method.name()); + [[maybe_unused]] int name = strings.enter(method.name()); int argc = method.parameterCount(); - int tag = strings.enter(method.tag); - int attrs = method.attributes; - if (buf) { + [[maybe_unused]] int tag = strings.enter(method.tag); + [[maybe_unused]] int attrs = method.attributes; + if constexpr (mode == Construct) { data[dataIndex] = name; data[dataIndex + 1] = argc; data[dataIndex + 2] = paramsIndex; @@ -1297,7 +1273,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, } if (hasRevisionedMethods) { for (const auto &method : d->methods) { - if (buf) + if constexpr (mode == Construct) data[dataIndex] = method.revision; ++dataIndex; } @@ -1313,12 +1289,12 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, int paramCount = paramTypeNames.size(); for (int i = -1; i < paramCount; ++i) { const QByteArray &typeName = (i < 0) ? method.returnType : paramTypeNames.at(i); - int typeInfo; + [[maybe_unused]] int typeInfo; if (QtPrivate::isBuiltinType(typeName)) typeInfo = QMetaType::fromName(typeName).id(); else typeInfo = IsUnresolvedType | strings.enter(typeName); - if (buf) + if constexpr (mode == Construct) data[dataIndex] = typeInfo; ++dataIndex; } @@ -1327,8 +1303,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, while (paramNames.size() < paramCount) paramNames.append(QByteArray()); for (int i = 0; i < paramCount; ++i) { - int stringIndex = strings.enter(paramNames.at(i)); - if (buf) + [[maybe_unused]] int stringIndex = strings.enter(paramNames.at(i)); + if constexpr (mode == Construct) data[dataIndex] = stringIndex; ++dataIndex; } @@ -1337,21 +1313,22 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, // Output the properties in the class. Q_ASSERT(!buf || dataIndex == pmeta->propertyData); - for (const auto &prop : d->properties) { - int name = strings.enter(prop.name); + for (QMetaPropertyBuilderPrivate &prop : d->properties) { + [[maybe_unused]] int name = strings.enter(prop.name); - int typeInfo; - if (QtPrivate::isBuiltinType(prop.type)) - typeInfo = QMetaType::fromName(prop.type).id(); - else - typeInfo = IsUnresolvedType | strings.enter(prop.type); + // try to resolve the metatype again if it was unknown + if (!prop.metaType.isValid()) + prop.metaType = QMetaType::fromName(prop.type); + [[maybe_unused]] const int typeInfo = prop.metaType.isValid() + ? prop.metaType.id() + : IsUnresolvedType | strings.enter(prop.type); - int flags = prop.flags; + [[maybe_unused]] int flags = prop.flags; if (!QtPrivate::isBuiltinType(prop.type)) flags |= EnumOrFlag; - if (buf) { + if constexpr (mode == Construct) { data[dataIndex] = name; data[dataIndex + 1] = typeInfo; data[dataIndex + 2] = flags; @@ -1364,13 +1341,13 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, // Output the enumerators in the class. Q_ASSERT(!buf || dataIndex == pmeta->enumeratorData); for (const auto &enumerator : d->enumerators) { - int name = strings.enter(enumerator.name); - int enumName = strings.enter(enumerator.enumName); - int isFlag = enumerator.isFlag ? EnumIsFlag : 0; - int isScoped = enumerator.isScoped ? EnumIsScoped : 0; + [[maybe_unused]] int name = strings.enter(enumerator.name); + [[maybe_unused]] int enumName = strings.enter(enumerator.enumName); + [[maybe_unused]] int isFlag = enumerator.isFlag ? EnumIsFlag : 0; + [[maybe_unused]] int isScoped = enumerator.isScoped ? EnumIsScoped : 0; int count = enumerator.keys.size(); int enumOffset = enumIndex; - if (buf) { + if constexpr (mode == Construct) { data[dataIndex] = name; data[dataIndex + 1] = enumName; data[dataIndex + 2] = isFlag | isScoped; @@ -1378,8 +1355,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, data[dataIndex + 4] = enumOffset; } for (int key = 0; key < count; ++key) { - int keyIndex = strings.enter(enumerator.keys[key]); - if (buf) { + [[maybe_unused]] int keyIndex = strings.enter(enumerator.keys[key]); + if constexpr (mode == Construct) { data[enumOffset++] = keyIndex; data[enumOffset++] = enumerator.values[key]; } @@ -1391,11 +1368,11 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, // Output the constructors in the class. Q_ASSERT(!buf || dataIndex == pmeta->constructorData); for (const auto &ctor : d->constructors) { - int name = strings.enter(ctor.name()); + [[maybe_unused]] int name = strings.enter(ctor.name()); int argc = ctor.parameterCount(); - int tag = strings.enter(ctor.tag); - int attrs = ctor.attributes; - if (buf) { + [[maybe_unused]] int tag = strings.enter(ctor.tag); + [[maybe_unused]] int attrs = ctor.attributes; + if constexpr (mode == Construct) { data[dataIndex] = name; data[dataIndex + 1] = argc; data[dataIndex + 2] = paramsIndex; @@ -1410,11 +1387,11 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, size += strings.blobSize(); - if (buf) + if constexpr (mode == Construct) strings.writeBlob(str); // Output the zero terminator in the data array. - if (buf) + if constexpr (mode == Construct) data[enumIndex] = 0; // Create the relatedMetaObjects block if we need one. @@ -1422,7 +1399,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, using SuperData = QMetaObject::SuperData; ALIGN(size, SuperData); auto objects = reinterpret_cast<SuperData *>(buf + size); - if (buf) { + if constexpr (mode == Construct) { meta->d.relatedMetaObjects = objects; for (index = 0; index < d->relatedMetaObjects.size(); ++index) objects[index] = d->relatedMetaObjects[index]; @@ -1431,37 +1408,39 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, size += sizeof(SuperData) * (d->relatedMetaObjects.size() + 1); } - if (d->properties.size() > 0 || d->methods.size() > 0 || d->constructors.size() > 0) { - ALIGN(size, QtPrivate::QMetaTypeInterface *); - auto types = reinterpret_cast<QtPrivate::QMetaTypeInterface **>(buf + size); - if (buf) { - meta->d.metaTypes = types; - for (const auto &prop : d->properties) { - QMetaType mt = QMetaType::fromName(prop.type); + ALIGN(size, QtPrivate::QMetaTypeInterface *); + auto types = reinterpret_cast<QtPrivate::QMetaTypeInterface **>(buf + size); + if constexpr (mode == Construct) { + meta->d.metaTypes = types; + for (const auto &prop : d->properties) { + QMetaType mt = prop.metaType; + *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt); + types++; + } + // add metatype interface for this metaobject - must be null + // as we can't know our metatype + *types = nullptr; + types++; + for (const auto &method: d->methods) { + QMetaType mt(QMetaType::fromName(method.returnType).id()); + *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt); + types++; + for (const auto ¶meterType: method.parameterTypes()) { + QMetaType mt = QMetaType::fromName(parameterType); *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt); types++; } - for (const auto &method: d->methods) { - QMetaType mt(QMetaType::fromName(method.returnType).id()); + } + for (const auto &constructor : d->constructors) { + for (const auto ¶meterType : constructor.parameterTypes()) { + QMetaType mt = QMetaType::fromName(parameterType); *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt); types++; - for (const auto ¶meterType: method.parameterTypes()) { - QMetaType mt = QMetaType::fromName(parameterType); - *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt); - types++; - } - } - for (const auto &constructor : d->constructors) { - for (const auto ¶meterType : constructor.parameterTypes()) { - QMetaType mt = QMetaType::fromName(parameterType); - *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt); - types++; - } } } - // parameterMetaTypesIndex is equal to the total number of metatypes - size += static_cast<int>(sizeof(QMetaType) * parameterMetaTypesIndex); } + // parameterMetaTypesIndex is equal to the total number of metatypes + size += sizeof(QMetaType) * parameterMetaTypesIndex; // Align the final size and return it. ALIGN(size, void *); @@ -1481,74 +1460,13 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, */ QMetaObject *QMetaObjectBuilder::toMetaObject() const { - int size = buildMetaObject(d, nullptr, 0, false); + int size = buildMetaObject<Prepare>(d, nullptr, 0); char *buf = reinterpret_cast<char *>(malloc(size)); memset(buf, 0, size); - buildMetaObject(d, buf, size, false); + buildMetaObject<Construct>(d, buf, size); return reinterpret_cast<QMetaObject *>(buf); } -/* - \internal - - Converts this meta object builder into relocatable data. This data can - be stored, copied and later passed to fromRelocatableData() to create a - concrete QMetaObject. - - The data is specific to the architecture on which it was created, but is not - specific to the process that created it. Not all meta object builder's can - be converted to data in this way. If \a ok is provided, it will be set to - true if the conversion succeeds, and false otherwise. If a - staticMetacallFunction() or any relatedMetaObject()'s are specified the - conversion to relocatable data will fail. -*/ -QByteArray QMetaObjectBuilder::toRelocatableData(bool *ok) const -{ - int size = buildMetaObject(d, nullptr, 0, true); - if (size == -1) { - if (ok) - *ok = false; - return QByteArray(); - } - - QByteArray data; - data.resize(size); - char *buf = data.data(); - memset(buf, 0, size); - buildMetaObject(d, buf, size, true); - if (ok) - *ok = true; - return data; -} - -/* - \internal - - Sets the \a data returned from toRelocatableData() onto a concrete - QMetaObject instance, \a output. As the meta object's super class is not - saved in the relocatable data, it must be passed as \a superClass. -*/ -void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output, - const QMetaObject *superclass, - const QByteArray &data) -{ - if (!output) - return; - - const char *buf = data.constData(); - const QMetaObject *dataMo = reinterpret_cast<const QMetaObject *>(buf); - - quintptr stringdataOffset = (quintptr)dataMo->d.stringdata; - quintptr dataOffset = (quintptr)dataMo->d.data; - - output->d.superdata = superclass; - output->d.stringdata = reinterpret_cast<const uint *>(buf + stringdataOffset); - output->d.data = reinterpret_cast<const uint *>(buf + dataOffset); - output->d.extradata = nullptr; - output->d.relatedMetaObjects = nullptr; - output->d.static_metacall = nullptr; -} - /*! \typedef QMetaObjectBuilder::StaticMetacallFunction @@ -1580,274 +1498,6 @@ void QMetaObjectBuilder::setStaticMetacallFunction d->staticMetacallFunction = value; } -#ifndef QT_NO_DATASTREAM - -/*! - Serializes the contents of the meta object builder onto \a stream. - - \sa deserialize() -*/ -void QMetaObjectBuilder::serialize(QDataStream &stream) const -{ - int index; - - // Write the class and super class names. - stream << d->className; - if (d->superClass) - stream << QByteArray(d->superClass->className()); - else - stream << QByteArray(); - - // Write the counts for each type of class member. - stream << int(d->classInfoNames.size()); - stream << int(d->methods.size()); - stream << int(d->properties.size()); - stream << int(d->enumerators.size()); - stream << int(d->constructors.size()); - stream << int(d->relatedMetaObjects.size()); - - // Write the items of class information. - for (index = 0; index < d->classInfoNames.size(); ++index) { - stream << d->classInfoNames[index]; - stream << d->classInfoValues[index]; - } - - // Write the methods. - for (const auto &method : d->methods) { - stream << method.signature; - stream << method.returnType; - stream << method.parameterNames; - stream << method.tag; - stream << method.attributes; - if (method.revision) - stream << method.revision; - } - - // Write the properties. - for (const auto &property : d->properties) { - stream << property.name; - stream << property.type; - stream << property.flags; - stream << property.notifySignal; - stream << property.revision; - } - - // Write the enumerators. - for (const auto &enumerator : d->enumerators) { - stream << enumerator.name; - stream << enumerator.isFlag; - stream << enumerator.isScoped; - stream << enumerator.keys; - stream << enumerator.values; - } - - // Write the constructors. - for (const auto &ctor : d->constructors) { - stream << ctor.signature; - stream << ctor.returnType; - stream << ctor.parameterNames; - stream << ctor.tag; - stream << ctor.attributes; - } - - // Write the related meta objects. - for (index = 0; index < d->relatedMetaObjects.size(); ++index) { - const QMetaObject *meta = d->relatedMetaObjects[index]; - stream << QByteArray(meta->className()); - } - - // Add an extra empty QByteArray for additional data in future versions. - // This should help maintain backwards compatibility, allowing older - // versions to read newer data. - stream << QByteArray(); -} - -// Resolve a class name using the name reference map. -static const QMetaObject *resolveClassName(const QMap<QByteArray, const QMetaObject *> &references, - const QByteArray &name) -{ - if (name == QByteArray("QObject")) - return &QObject::staticMetaObject; - else - return references.value(name, nullptr); -} - -/*! - Deserializes a meta object builder from \a stream into - this meta object builder. - - The \a references parameter specifies a mapping from class names - to QMetaObject instances for resolving the super class name and - related meta objects in the object that is deserialized. - The meta object for QObject is implicitly added to \a references - and does not need to be supplied. - - The QDataStream::status() value on \a stream will be set to - QDataStream::ReadCorruptData if the input data is corrupt. - The status will be set to QDataStream::ReadPastEnd if the - input was exhausted before the full meta object was read. - - \sa serialize() -*/ -void QMetaObjectBuilder::deserialize - (QDataStream& stream, - const QMap<QByteArray, const QMetaObject *>& references) -{ - QByteArray name; - const QMetaObject *cl; - int index; - - // Clear all members in the builder to their default states. - d->className.clear(); - d->superClass = &QObject::staticMetaObject; - d->classInfoNames.clear(); - d->classInfoValues.clear(); - d->methods.clear(); - d->properties.clear(); - d->enumerators.clear(); - d->constructors.clear(); - d->relatedMetaObjects.clear(); - d->staticMetacallFunction = nullptr; - - // Read the class and super class names. - stream >> d->className; - stream >> name; - if (name.isEmpty()) { - d->superClass = nullptr; - } else if ((cl = resolveClassName(references, name)) != nullptr) { - d->superClass = cl; - } else { - stream.setStatus(QDataStream::ReadCorruptData); - return; - } - - // Read the counts for each type of class member. - int classInfoCount, methodCount, propertyCount; - int enumeratorCount, constructorCount, relatedMetaObjectCount; - stream >> classInfoCount; - stream >> methodCount; - stream >> propertyCount; - stream >> enumeratorCount; - stream >> constructorCount; - stream >> relatedMetaObjectCount; - if (classInfoCount < 0 || methodCount < 0 || - propertyCount < 0 || enumeratorCount < 0 || - constructorCount < 0 || relatedMetaObjectCount < 0) { - stream.setStatus(QDataStream::ReadCorruptData); - return; - } - - // Read the items of class information. - for (index = 0; index < classInfoCount; ++index) { - if (stream.status() != QDataStream::Ok) - return; - QByteArray value; - stream >> name; - stream >> value; - addClassInfo(name, value); - } - - // Read the member methods. - for (index = 0; index < methodCount; ++index) { - if (stream.status() != QDataStream::Ok) - return; - stream >> name; - addMethod(name); - QMetaMethodBuilderPrivate &method = d->methods[index]; - stream >> method.returnType; - stream >> method.parameterNames; - stream >> method.tag; - stream >> method.attributes; - if (method.attributes & MethodRevisioned) - stream >> method.revision; - if (method.methodType() == QMetaMethod::Constructor) { - // Cannot add a constructor in this set of methods. - stream.setStatus(QDataStream::ReadCorruptData); - return; - } - } - - // Read the properties. - for (index = 0; index < propertyCount; ++index) { - if (stream.status() != QDataStream::Ok) - return; - QByteArray type; - stream >> name; - stream >> type; - addProperty(name, type); - QMetaPropertyBuilderPrivate &property = d->properties[index]; - stream >> property.flags; - stream >> property.notifySignal; - if (property.notifySignal < -1 || - property.notifySignal >= int(d->methods.size())) { - // Notify signal method index is out of range. - stream.setStatus(QDataStream::ReadCorruptData); - return; - } - if (property.notifySignal >= 0 && - d->methods[property.notifySignal].methodType() != QMetaMethod::Signal) { - // Notify signal method index does not refer to a signal. - stream.setStatus(QDataStream::ReadCorruptData); - return; - } - stream >> property.revision; - } - - // Read the enumerators. - for (index = 0; index < enumeratorCount; ++index) { - if (stream.status() != QDataStream::Ok) - return; - stream >> name; - addEnumerator(name); - QMetaEnumBuilderPrivate &enumerator = d->enumerators[index]; - stream >> enumerator.isFlag; - stream >> enumerator.isScoped; - stream >> enumerator.keys; - stream >> enumerator.values; - if (enumerator.keys.size() != enumerator.values.size()) { - // Mismatch between number of keys and number of values. - stream.setStatus(QDataStream::ReadCorruptData); - return; - } - } - - // Read the constructor methods. - for (index = 0; index < constructorCount; ++index) { - if (stream.status() != QDataStream::Ok) - return; - stream >> name; - addConstructor(name); - QMetaMethodBuilderPrivate &method = d->constructors[index]; - stream >> method.returnType; - stream >> method.parameterNames; - stream >> method.tag; - stream >> method.attributes; - if (method.methodType() != QMetaMethod::Constructor) { - // The type must be Constructor. - stream.setStatus(QDataStream::ReadCorruptData); - return; - } - } - - // Read the related meta objects. - for (index = 0; index < relatedMetaObjectCount; ++index) { - if (stream.status() != QDataStream::Ok) - return; - stream >> name; - cl = resolveClassName(references, name); - if (!cl) { - stream.setStatus(QDataStream::ReadCorruptData); - return; - } - addRelatedMetaObject(cl); - } - - // Read the extra data block, which is reserved for future use. - stream >> name; -} - -#endif // !QT_NO_DATASTREAM - /*! \class QMetaMethodBuilder \inmodule QtCore @@ -2060,6 +1710,28 @@ void QMetaMethodBuilder::setAttributes(int value) } /*! + Returns true if the method is const qualified. + */ +int QMetaMethodBuilder::isConst() const +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (!d) + return false; + return (d->attributes & MethodIsConst); +} + +void QMetaMethodBuilder::setConst(bool methodIsConst) +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (!d) + return; + if (methodIsConst) + d->attributes |= MethodIsConst; + else + d->attributes &= ~MethodIsConst; +} + +/*! Returns the revision of this method. \sa setRevision() @@ -2636,6 +2308,31 @@ void QMetaEnumBuilder::setEnumName(const QByteArray &alias) } /*! + Returns the meta type of the enumerator. + + \since 6.6 +*/ +QMetaType QMetaEnumBuilder::metaType() const +{ + if (QMetaEnumBuilderPrivate *d = d_func()) + return d->metaType; + return QMetaType(); +} + +/*! + Sets this enumerator to have the given \c metaType. + + \since 6.6 + \sa metaType() +*/ +void QMetaEnumBuilder::setMetaType(QMetaType metaType) +{ + QMetaEnumBuilderPrivate *d = d_func(); + if (d) + d->metaType = metaType; +} + +/*! Returns \c true if this enumerator is used as a flag; otherwise returns false. |