diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/io/qdebug.cpp | 4 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobject.cpp | 92 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobject.h | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobject_p.h | 3 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobjectbuilder.cpp | 49 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobjectbuilder_p.h | 3 | ||||
-rw-r--r-- | src/dbus/qdbusmetaobject.cpp | 2 | ||||
-rw-r--r-- | src/tools/moc/generator.cpp | 15 | ||||
-rw-r--r-- | src/tools/moc/moc.h | 2 |
9 files changed, 129 insertions, 42 deletions
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp index 12f590584c..2e825d2373 100644 --- a/src/corelib/io/qdebug.cpp +++ b/src/corelib/io/qdebug.cpp @@ -946,7 +946,7 @@ QDebug qt_QMetaEnum_debugOperator(QDebug &dbg, int value, const QMetaObject *met if (const char *scope = me.scope()) dbg << scope << "::"; if (me.isScoped()) - dbg << name << "::"; + dbg << me.enumName() << "::"; dbg << key; } else { dbg << meta->className() << "::" << name << "(" << value << ")"; @@ -964,7 +964,7 @@ QDebug qt_QMetaEnum_flagDebugOperator(QDebug &debug, quint64 value, const QMetaO const QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name)); if (const char *scope = me.scope()) debug << scope << "::"; - debug << me.name() << ">(" << me.valueToKeys(value) << ')'; + debug << me.enumName() << ">(" << me.valueToKeys(value) << ')'; return debug; } #endif // !QT_NO_QOBJECT diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 27138dd075..65d0bd2351 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -968,10 +968,24 @@ static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, co int QMetaObject::indexOfEnumerator(const char *name) const { const QMetaObject *m = this; + const int intsPerEnum = priv(m->d.data)->revision >= 8 ? 5 : 4; while (m) { const QMetaObjectPrivate *d = priv(m->d.data); for (int i = d->enumeratorCount - 1; i >= 0; --i) { - const char *prop = rawStringData(m, m->d.data[d->enumeratorData + 4*i]); + const char *prop = rawStringData(m, m->d.data[d->enumeratorData + intsPerEnum * i]); + if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) { + i += m->enumeratorOffset(); + return i; + } + } + m = m->d.superdata; + } + // Check alias names: + m = this; + while (m) { + const QMetaObjectPrivate *d = priv(m->d.data); + for (int i = d->enumeratorCount - 1; i >= 0; --i) { + const char *prop = rawStringData(m, m->d.data[d->enumeratorData + intsPerEnum * i + 1]); if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) { i += m->enumeratorOffset(); return i; @@ -1086,10 +1100,11 @@ QMetaEnum QMetaObject::enumerator(int index) const if (i < 0 && d.superdata) return d.superdata->enumerator(index); + const int intsPerEnum = priv(d.data)->revision >= 8 ? 5 : 4; QMetaEnum result; if (i >= 0 && i < priv(d.data)->enumeratorCount) { result.mobj = this; - result.handle = priv(d.data)->enumeratorData + 4*i; + result.handle = priv(d.data)->enumeratorData + intsPerEnum * i; } return result; } @@ -2552,12 +2567,15 @@ bool QMetaMethod::invokeOnGadget(void* gadget, QGenericReturnArgument returnValu */ /*! - Returns the name of the enumerator (without the scope). + Returns the name of the type (without the scope). + + For example, the Qt::Key enumeration has \c + Key as the type name and \l Qt as the scope. - For example, the Qt::AlignmentFlag enumeration has \c - AlignmentFlag as the name and \l Qt as the scope. + For flags this returns the name of the flag type, not the + name of the enum type. - \sa isValid(), scope() + \sa isValid(), scope(), enumName() */ const char *QMetaEnum::name() const { @@ -2567,6 +2585,28 @@ const char *QMetaEnum::name() const } /*! + Returns the enum name of the flag (without the scope). + + For example, the Qt::AlignmentFlag flag has \c + AlignmentFlag as the enum name, but \c Alignment as as the type name. + Non flag enums has the same type and enum names. + + Enum names have the same scope as the type name. + + \since 5.12 + \sa isValid(), name() +*/ +const char *QMetaEnum::enumName() const +{ + if (!mobj) + return 0; + const bool rev8p = priv(mobj->d.data)->revision >= 8; + if (rev8p) + return rawStringData(mobj, mobj->d.data[handle + 1]); + return name(); +} + +/*! Returns the number of keys. \sa key() @@ -2575,10 +2615,10 @@ int QMetaEnum::keyCount() const { if (!mobj) return 0; - return mobj->d.data[handle + 2]; + const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2; + return mobj->d.data[handle + offset]; } - /*! Returns the key with the given \a index, or 0 if no such key exists. @@ -2588,8 +2628,9 @@ const char *QMetaEnum::key(int index) const { if (!mobj) return 0; - int count = mobj->d.data[handle + 2]; - int data = mobj->d.data[handle + 3]; + const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2; + int count = mobj->d.data[handle + offset]; + int data = mobj->d.data[handle + offset + 1]; if (index >= 0 && index < count) return rawStringData(mobj, mobj->d.data[data + 2*index]); return 0; @@ -2605,8 +2646,9 @@ int QMetaEnum::value(int index) const { if (!mobj) return 0; - int count = mobj->d.data[handle + 2]; - int data = mobj->d.data[handle + 3]; + const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2; + int count = mobj->d.data[handle + offset]; + int data = mobj->d.data[handle + offset + 1]; if (index >= 0 && index < count) return mobj->d.data[data + 2*index + 1]; return -1; @@ -2624,7 +2666,8 @@ int QMetaEnum::value(int index) const */ bool QMetaEnum::isFlag() const { - return mobj && mobj->d.data[handle + 1] & EnumIsFlag; + const int offset = priv(mobj->d.data)->revision >= 8 ? 2 : 1; + return mobj && mobj->d.data[handle + offset] & EnumIsFlag; } /*! @@ -2635,7 +2678,8 @@ bool QMetaEnum::isFlag() const */ bool QMetaEnum::isScoped() const { - return mobj && mobj->d.data[handle + 1] & EnumIsScoped; + const int offset = priv(mobj->d.data)->revision >= 8 ? 2 : 1; + return mobj && mobj->d.data[handle + offset] & EnumIsScoped; } /*! @@ -2677,8 +2721,9 @@ int QMetaEnum::keyToValue(const char *key, bool *ok) const scope = s - key - 1; key += scope + 2; } - int count = mobj->d.data[handle + 2]; - int data = mobj->d.data[handle + 3]; + const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2; + int count = mobj->d.data[handle + offset]; + int data = mobj->d.data[handle + offset + 1]; for (int i = 0; i < count; ++i) { const QByteArray className = stringData(mobj, priv(mobj->d.data)->className); if ((!scope || (className.size() == int(scope) && strncmp(qualified_key, className.constData(), scope) == 0)) @@ -2703,8 +2748,9 @@ const char* QMetaEnum::valueToKey(int value) const { if (!mobj) return 0; - int count = mobj->d.data[handle + 2]; - int data = mobj->d.data[handle + 3]; + const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2; + int count = mobj->d.data[handle + offset]; + int data = mobj->d.data[handle + offset + 1]; for (int i = 0; i < count; ++i) if (value == (int)mobj->d.data[data + 2*i + 1]) return rawStringData(mobj, mobj->d.data[data + 2*i]); @@ -2735,8 +2781,9 @@ int QMetaEnum::keysToValue(const char *keys, bool *ok) const return 0; // ### TODO write proper code: do not allocate memory, so we can go nothrow int value = 0; - int count = mobj->d.data[handle + 2]; - int data = mobj->d.data[handle + 3]; + const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2; + int count = mobj->d.data[handle + offset]; + int data = mobj->d.data[handle + offset + 1]; for (const QStringRef &untrimmed : splitKeys) { const QStringRef trimmed = untrimmed.trimmed(); QByteArray qualified_key = trimmed.toLatin1(); @@ -2778,8 +2825,9 @@ QByteArray QMetaEnum::valueToKeys(int value) const QByteArray keys; if (!mobj) return keys; - int count = mobj->d.data[handle + 2]; - int data = mobj->d.data[handle + 3]; + const int offset = priv(mobj->d.data)->revision >= 8 ? 3 : 2; + int count = mobj->d.data[handle + offset]; + int data = mobj->d.data[handle + offset + 1]; int v = value; // reverse iterate to ensure values like Qt::Dialog=0x2|Qt::Window are processed first. for (int i = count - 1; i >= 0; --i) { diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h index 51df8faad3..51ace3d5f7 100644 --- a/src/corelib/kernel/qmetaobject.h +++ b/src/corelib/kernel/qmetaobject.h @@ -209,6 +209,7 @@ public: Q_DECL_CONSTEXPR inline QMetaEnum() : mobj(nullptr), handle(0) {} const char *name() const; + const char *enumName() const; bool isFlag() const; bool isScoped() const; diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h index 434ef84808..4df9a8de77 100644 --- a/src/corelib/kernel/qmetaobject_p.h +++ b/src/corelib/kernel/qmetaobject_p.h @@ -171,7 +171,8 @@ class QMutex; struct QMetaObjectPrivate { // revision 7 is Qt 5.0 everything lower is not supported - enum { OutputRevision = 7 }; // Used by moc, qmetaobjectbuilder and qdbus + // revision 8 is Qt 5.12: It adds the enum name to QMetaEnum + enum { OutputRevision = 8 }; // Used by moc, qmetaobjectbuilder and qdbus int revision; int className; diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index e3b70638c6..d2030f0275 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -190,11 +190,12 @@ class QMetaEnumBuilderPrivate { public: QMetaEnumBuilderPrivate(const QByteArray& _name) - : name(_name), isFlag(false), isScoped(false) + : name(_name), enumName(_name), isFlag(false), isScoped(false) { } QByteArray name; + QByteArray enumName; bool isFlag; bool isScoped; QList<QByteArray> keys; @@ -637,6 +638,7 @@ QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray& name) QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QMetaEnum& prototype) { QMetaEnumBuilder en = addEnumerator(prototype.name()); + en.setEnumName(prototype.enumName()); en.setIsFlag(prototype.isFlag()); en.setIsScoped(prototype.isScoped()); int count = prototype.keyCount(); @@ -1216,7 +1218,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, - int(d->methods.size()) // return "parameters" don't have names - int(d->constructors.size()); // "this" parameters don't have names if (buf) { - Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 7, "QMetaObjectBuilder should generate the same version as moc"); + Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 8, "QMetaObjectBuilder should generate the same version as moc"); pmeta->revision = QMetaObjectPrivate::OutputRevision; pmeta->flags = d->flags; pmeta->className = 0; // Class name is always the first string. @@ -1244,7 +1246,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, pmeta->enumeratorCount = int(d->enumerators.size()); pmeta->enumeratorData = dataIndex; - dataIndex += 4 * int(d->enumerators.size()); + dataIndex += 5 * int(d->enumerators.size()); pmeta->constructorCount = int(d->constructors.size()); pmeta->constructorData = dataIndex; @@ -1261,7 +1263,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, dataIndex += int(d->properties.size()); if (hasRevisionedProperties) dataIndex += int(d->properties.size()); - dataIndex += 4 * int(d->enumerators.size()); + dataIndex += 5 * int(d->enumerators.size()); dataIndex += 5 * int(d->constructors.size()); } @@ -1410,15 +1412,17 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, 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; int count = enumerator.keys.size(); int enumOffset = enumIndex; if (buf) { data[dataIndex] = name; - data[dataIndex + 1] = isFlag | isScoped; - data[dataIndex + 2] = count; - data[dataIndex + 3] = enumOffset; + data[dataIndex + 1] = enumName; + data[dataIndex + 2] = isFlag | isScoped; + data[dataIndex + 3] = count; + data[dataIndex + 4] = enumOffset; } for (int key = 0; key < count; ++key) { int keyIndex = strings.enter(enumerator.keys[key]); @@ -1427,7 +1431,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, data[enumOffset++] = enumerator.values[key]; } } - dataIndex += 4; + dataIndex += 5; enumIndex += 2 * count; } @@ -2599,7 +2603,7 @@ QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const */ /*! - Returns the name of the enumerator (without the scope). + Returns the type name of the enumerator (without the scope). */ QByteArray QMetaEnumBuilder::name() const { @@ -2611,6 +2615,33 @@ QByteArray QMetaEnumBuilder::name() const } /*! + Returns the enum name of the enumerator (without the scope). + + \since 5.12 +*/ +QByteArray QMetaEnumBuilder::enumName() const +{ + QMetaEnumBuilderPrivate *d = d_func(); + if (d) + return d->enumName; + else + return QByteArray(); +} + +/*! + Sets this enumerator to have the enum name \c alias. + + \since 5.12 + \sa isFlag(), enumName() +*/ +void QMetaEnumBuilder::setEnumName(const QByteArray &alias) +{ + QMetaEnumBuilderPrivate *d = d_func(); + if (d) + d->enumName = alias; +} + +/*! Returns \c true if this enumerator is used as a flag; otherwise returns false. diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h index 03b2afaebc..781d206e0b 100644 --- a/src/corelib/kernel/qmetaobjectbuilder_p.h +++ b/src/corelib/kernel/qmetaobjectbuilder_p.h @@ -297,6 +297,9 @@ public: QByteArray name() const; + QByteArray enumName() const; + void setEnumName(const QByteArray &alias); + bool isFlag() const; void setIsFlag(bool value); diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp index f64e30b49b..c4296f5c55 100644 --- a/src/dbus/qdbusmetaobject.cpp +++ b/src/dbus/qdbusmetaobject.cpp @@ -412,7 +412,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) - methods.count(); // ditto QDBusMetaObjectPrivate *header = reinterpret_cast<QDBusMetaObjectPrivate *>(idata.data()); - Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 7, "QtDBus meta-object generator should generate the same version as moc"); + Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 8, "QtDBus meta-object generator should generate the same version as moc"); header->revision = QMetaObjectPrivate::OutputRevision; header->className = 0; header->classInfoCount = 0; diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 3dddbe907d..a3ef1147d6 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -200,9 +200,9 @@ void Generator::generateCode() 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.className = def.name; def.name = alias; enumList += def; } @@ -370,7 +370,7 @@ void Generator::generateCode() int enumsIndex = index; for (int i = 0; i < cdef->enumList.count(); ++i) - index += 4 + (cdef->enumList.at(i).values.count() * 2); + index += 5 + (cdef->enumList.at(i).values.count() * 2); fprintf(out, " %4d, %4d, // constructors\n", isConstructible ? cdef->constructorList.count() : 0, isConstructible ? index : 0); @@ -888,6 +888,8 @@ void Generator::registerEnumStrings() for (int i = 0; i < cdef->enumList.count(); ++i) { const EnumDef &e = cdef->enumList.at(i); strreg(e.name); + if (!e.enumName.isNull()) + strreg(e.enumName); for (int j = 0; j < e.values.count(); ++j) strreg(e.values.at(j)); } @@ -898,8 +900,8 @@ void Generator::generateEnums(int index) if (cdef->enumDeclarations.isEmpty()) return; - fprintf(out, "\n // enums: name, flags, count, data\n"); - index += 4 * cdef->enumList.count(); + fprintf(out, "\n // enums: name, alias, flags, count, data\n"); + index += 5 * cdef->enumList.count(); int i; for (i = 0; i < cdef->enumList.count(); ++i) { const EnumDef &e = cdef->enumList.at(i); @@ -908,8 +910,9 @@ void Generator::generateEnums(int index) flags |= EnumIsFlag; if (e.isEnumClass) flags |= EnumIsScoped; - fprintf(out, " %4d, 0x%.1x, %4d, %4d,\n", + fprintf(out, " %4d, %4d, 0x%.1x, %4d, %4d,\n", stridx(e.name), + e.enumName.isNull() ? stridx(e.name) : stridx(e.enumName), flags, e.values.count(), index); @@ -923,7 +926,7 @@ void Generator::generateEnums(int index) const QByteArray &val = e.values.at(j); QByteArray code = cdef->qualified.constData(); if (e.isEnumClass) - code += "::" + (e.className.isNull() ? e.name : e.className); + code += "::" + (e.enumName.isNull() ? e.name : e.enumName); code += "::" + val; fprintf(out, " %4d, uint(%s),\n", stridx(val), code.constData()); diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index 190fdfb733..56763c5e59 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -64,7 +64,7 @@ Q_DECLARE_TYPEINFO(Type, Q_MOVABLE_TYPE); struct EnumDef { QByteArray name; - QByteArray className; + QByteArray enumName; QList<QByteArray> values; bool isEnumClass; // c++11 enum class EnumDef() : isEnumClass(false) {} |