diff options
-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 | ||||
-rw-r--r-- | tests/auto/corelib/io/qdebug/tst_qdebug.cpp | 16 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp | 13 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp | 19 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp | 2 | ||||
-rw-r--r-- | tests/auto/tools/moc/cxx11-enums.h | 4 | ||||
-rw-r--r-- | tests/auto/tools/moc/tst_moc.cpp | 36 |
15 files changed, 200 insertions, 61 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) {} diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp index b43ea7cfa5..7b8b1df166 100644 --- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp +++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp @@ -38,6 +38,13 @@ class tst_QDebug: public QObject { Q_OBJECT +public: + enum EnumType { EnumValue1 = 1, EnumValue2 = 2 }; + enum FlagType { EnumFlag1 = 1, EnumFlag2 = 2 }; + Q_ENUM(EnumType) + Q_DECLARE_FLAGS(Flags, FlagType) + Q_FLAG(Flags) + private slots: void assignment() const; void warningWithoutDebug() const; @@ -637,6 +644,15 @@ void tst_QDebug::qDebugQFlags() const QCOMPARE(s_line, line); QCOMPARE(QString::fromLatin1(s_function), function); + // Test the output of QFlags with an enum not declared with Q_DECLARE_FLAGS and Q_FLAGS + QFlags<EnumType> flags2(EnumValue2); + qDebug() << flags2; + QCOMPARE(s_msg, QString::fromLatin1("QFlags<tst_QDebug::EnumType>(EnumValue2)")); + + // A now for one that was fully declared + tst_QDebug::Flags flags3(EnumFlag1); + qDebug() << flags3; + QCOMPARE(s_msg, QString::fromLatin1("QFlags<tst_QDebug::FlagType>(EnumFlag1)")); } void tst_QDebug::textStreamModifiers() const diff --git a/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp b/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp index e4aa8b80c0..bb111a9137 100644 --- a/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp +++ b/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp @@ -37,7 +37,10 @@ class tst_QMetaEnum : public QObject Q_OBJECT public: enum SuperEnum { SuperValue1 = 1 , SuperValue2 = 2 }; + enum Flag { Flag1 = 1 , Flag2 = 2 }; + Q_DECLARE_FLAGS(Flags, Flag) Q_ENUM(SuperEnum) + Q_FLAG(Flags) private slots: void fromType(); @@ -49,7 +52,17 @@ void tst_QMetaEnum::fromType() { QMetaEnum meta = QMetaEnum::fromType<SuperEnum>(); QVERIFY(meta.isValid()); + QVERIFY(!meta.isFlag()); QCOMPARE(meta.name(), "SuperEnum"); + QCOMPARE(meta.enumName(), "SuperEnum"); + QCOMPARE(meta.enclosingMetaObject(), &staticMetaObject); + QCOMPARE(meta.keyCount(), 2); + + meta = QMetaEnum::fromType<Flags>(); + QVERIFY(meta.isValid()); + QVERIFY(meta.isFlag()); + QCOMPARE(meta.name(), "Flags"); + QCOMPARE(meta.enumName(), "Flag"); QCOMPARE(meta.enclosingMetaObject(), &staticMetaObject); QCOMPARE(meta.keyCount(), 2); } diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index 2d67e978f7..9c33dc4c4d 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -69,7 +69,13 @@ namespace MyNamespace { MyFlag2 = 0x02, MyFlag3 = 0x04 }; + enum class MyScopedFlag { + MyFlag1 = 0x10, + MyFlag2 = 0x20, + MyFlag3 = 0x40 + }; Q_DECLARE_FLAGS(MyFlags, MyFlag) + Q_DECLARE_FLAGS(MyScopedFlags, MyScopedFlag) MyEnum myEnum() const { return m_enum; } void setMyEnum(MyEnum val) { m_enum = val; } @@ -87,6 +93,7 @@ namespace MyNamespace { Q_ENUM(MyScopedEnum) Q_ENUM(MyAnotherEnum) Q_FLAG(MyFlags) + Q_FLAG(MyScopedFlags) MyEnum m_enum; MyFlags m_flags; @@ -1745,13 +1752,21 @@ void tst_QMetaObject::enumDebugStream() QTest::ignoreMessage(QtDebugMsg, "Qt::WindowTitleHint Qt::Window Qt::Desktop Qt::WindowSystemMenuHint"); qDebug() << Qt::WindowTitleHint << Qt::Window << Qt::Desktop << Qt::WindowSystemMenuHint; - QTest::ignoreMessage(QtDebugMsg, "hello QFlags<MyNamespace::MyClass::MyFlags>(MyFlag1) world"); + QTest::ignoreMessage(QtDebugMsg, "hello QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) world"); MyNamespace::MyClass::MyFlags f1 = MyNamespace::MyClass::MyFlag1; qDebug() << "hello" << f1 << "world"; MyNamespace::MyClass::MyFlags f2 = MyNamespace::MyClass::MyFlag2 | MyNamespace::MyClass::MyFlag3; - QTest::ignoreMessage(QtDebugMsg, "QFlags<MyNamespace::MyClass::MyFlags>(MyFlag1) QFlags<MyNamespace::MyClass::MyFlags>(MyFlag2|MyFlag3)"); + QTest::ignoreMessage(QtDebugMsg, "QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) QFlags<MyNamespace::MyClass::MyFlag>(MyFlag2|MyFlag3)"); qDebug() << f1 << f2; + + QTest::ignoreMessage(QtDebugMsg, "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2)"); + MyNamespace::MyClass::MyScopedFlags f3 = MyNamespace::MyClass::MyScopedFlag::MyFlag2; + qDebug() << f3; + + QTest::ignoreMessage(QtDebugMsg, "QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2|MyFlag3)"); + f3 |= MyNamespace::MyClass::MyScopedFlag::MyFlag3; + qDebug() << f3; } void tst_QMetaObject::inherits_data() diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 6bb031e357..56623773a2 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -830,6 +830,7 @@ void tst_QMetaObjectBuilder::enumerator() // Modify the attributes on enum1. enum1.setIsFlag(true); enum1.setIsScoped(true); + enum1.setEnumName(QByteArrayLiteral("fooFlag")); QCOMPARE(enum1.addKey("ABC", 0), 0); QCOMPARE(enum1.addKey("DEF", 1), 1); QCOMPARE(enum1.addKey("GHI", -1), 2); @@ -838,6 +839,7 @@ void tst_QMetaObjectBuilder::enumerator() QCOMPARE(enum1.name(), QByteArray("foo")); QVERIFY(enum1.isFlag()); QVERIFY(enum1.isScoped()); + QCOMPARE(enum1.enumName(), QByteArray("fooFlag")); QCOMPARE(enum1.keyCount(), 3); QCOMPARE(enum1.index(), 0); QCOMPARE(enum1.key(0), QByteArray("ABC")); diff --git a/tests/auto/tools/moc/cxx11-enums.h b/tests/auto/tools/moc/cxx11-enums.h index 209ec4eb43..93ab16c157 100644 --- a/tests/auto/tools/moc/cxx11-enums.h +++ b/tests/auto/tools/moc/cxx11-enums.h @@ -39,7 +39,7 @@ public: enum TypedEnum : char { B0, B1 , B2, B3 }; enum class TypedEnumClass : char { C0, C1, C2, C3 }; enum NormalEnum { D2 = 2, D3, D0 =0 , D1 }; - enum class ClassFlag { F0, F1, F2, F3 }; + enum class ClassFlag { F0 = 1, F1 = 2, F2 = 4, F3 = 8}; Q_DECLARE_FLAGS(ClassFlags, ClassFlag) Q_ENUM(EnumClass) @@ -58,7 +58,7 @@ public: enum TypedEnum : char { B0, B1 , B2, B3 }; enum class TypedEnumClass : char { C0, C1, C2, C3 }; enum NormalEnum { D2 = 2, D3, D0 =0 , D1 }; - enum class ClassFlag { F0, F1, F2, F3 }; + enum class ClassFlag { F0 = 1, F1 = 2, F2 = 4, F3 = 8 }; Q_DECLARE_FLAGS(ClassFlags, ClassFlag) Q_ENUMS(EnumClass TypedEnum TypedEnumClass NormalEnum) Q_FLAGS(ClassFlags) diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 8a08de9bc6..92a94055a4 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -2248,6 +2248,7 @@ void tst_Moc::privateClass() void tst_Moc::cxx11Enums_data() { QTest::addColumn<const QMetaObject *>("meta"); + QTest::addColumn<QByteArray>("typeName"); QTest::addColumn<QByteArray>("enumName"); QTest::addColumn<char>("prefix"); QTest::addColumn<bool>("isScoped"); @@ -2255,16 +2256,16 @@ void tst_Moc::cxx11Enums_data() const QMetaObject *meta1 = &CXX11Enums::staticMetaObject; const QMetaObject *meta2 = &CXX11Enums2::staticMetaObject; - QTest::newRow("EnumClass") << meta1 << QByteArray("EnumClass") << 'A' << true; - QTest::newRow("EnumClass 2") << meta2 << QByteArray("EnumClass") << 'A' << true; - QTest::newRow("TypedEnum") << meta1 << QByteArray("TypedEnum") << 'B' << false; - QTest::newRow("TypedEnum 2") << meta2 << QByteArray("TypedEnum") << 'B' << false; - QTest::newRow("TypedEnumClass") << meta1 << QByteArray("TypedEnumClass") << 'C' << true; - QTest::newRow("TypedEnumClass 2") << meta2 << QByteArray("TypedEnumClass") << 'C' << true; - QTest::newRow("NormalEnum") << meta1 << QByteArray("NormalEnum") << 'D' << false; - QTest::newRow("NormalEnum 2") << meta2 << QByteArray("NormalEnum") << 'D' << false; - QTest::newRow("ClassFlags") << meta1 << QByteArray("ClassFlags") << 'F' << true; - QTest::newRow("ClassFlags 2") << meta2 << QByteArray("ClassFlags") << 'F' << true; + QTest::newRow("EnumClass") << meta1 << QByteArray("EnumClass") << QByteArray("EnumClass") << 'A' << true; + QTest::newRow("EnumClass 2") << meta2 << QByteArray("EnumClass") << QByteArray("EnumClass") << 'A' << true; + QTest::newRow("TypedEnum") << meta1 << QByteArray("TypedEnum") << QByteArray("TypedEnum") << 'B' << false; + QTest::newRow("TypedEnum 2") << meta2 << QByteArray("TypedEnum") << QByteArray("TypedEnum") << 'B' << false; + QTest::newRow("TypedEnumClass") << meta1 << QByteArray("TypedEnumClass") << QByteArray("TypedEnumClass") << 'C' << true; + QTest::newRow("TypedEnumClass 2") << meta2 << QByteArray("TypedEnumClass") << QByteArray("TypedEnumClass") << 'C' << true; + QTest::newRow("NormalEnum") << meta1 << QByteArray("NormalEnum") << QByteArray("NormalEnum") << 'D' << false; + QTest::newRow("NormalEnum 2") << meta2 << QByteArray("NormalEnum") << QByteArray("NormalEnum") << 'D' << false; + QTest::newRow("ClassFlags") << meta1 << QByteArray("ClassFlags") << QByteArray("ClassFlag") << 'F' << true; + QTest::newRow("ClassFlags 2") << meta2 << QByteArray("ClassFlags") << QByteArray("ClassFlag") << 'F' << true; } void tst_Moc::cxx11Enums() @@ -2272,21 +2273,26 @@ void tst_Moc::cxx11Enums() QFETCH(const QMetaObject *,meta); QCOMPARE(meta->enumeratorOffset(), 0); + QFETCH(QByteArray, typeName); QFETCH(QByteArray, enumName); QFETCH(char, prefix); QFETCH(bool, isScoped); - int idx; - idx = meta->indexOfEnumerator(enumName); + int idx = meta->indexOfEnumerator(typeName); QVERIFY(idx != -1); + QCOMPARE(meta->indexOfEnumerator(enumName), idx); + QCOMPARE(meta->enumerator(idx).enclosingMetaObject(), meta); QCOMPARE(meta->enumerator(idx).isValid(), true); QCOMPARE(meta->enumerator(idx).keyCount(), 4); - QCOMPARE(meta->enumerator(idx).name(), enumName.constData()); + QCOMPARE(meta->enumerator(idx).name(), typeName.constData()); + QCOMPARE(meta->enumerator(idx).enumName(), enumName.constData()); + bool isFlag = meta->enumerator(idx).isFlag(); for (int i = 0; i < 4; i++) { QByteArray v = prefix + QByteArray::number(i); - QCOMPARE(meta->enumerator(idx).keyToValue(v), i); - QCOMPARE(meta->enumerator(idx).valueToKey(i), v.constData()); + const int value = isFlag ? (1 << i) : i; + QCOMPARE(meta->enumerator(idx).keyToValue(v), value); + QCOMPARE(meta->enumerator(idx).valueToKey(value), v.constData()); } QCOMPARE(meta->enumerator(idx).isScoped(), isScoped); } |