diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-03-14 15:48:49 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-03-31 17:42:58 +0200 |
commit | b83de5f9a43b094bbb77b3aeea77983ea508a2b0 (patch) | |
tree | dcd800c2067d70691ad41cb05f8c3f032cc270ce /tests/auto/tools/moc | |
parent | ecd7ddcc3e7ccf7750190b4aedd3ad683dd4f97d (diff) |
moc: Record types of enumerations
This will be helpful in a number of places, in particular in order to
support enums of different sizes in QML. We record the type as string in
the JSON output and as QMetaTypeInterface in the generated C++.
Task-number: QTBUG-112180
Change-Id: I943fac67f8b25b013d3860301416cdd293c0c69e
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tests/auto/tools/moc')
-rw-r--r-- | tests/auto/tools/moc/allmocs_baseline_in.json | 64 | ||||
-rw-r--r-- | tests/auto/tools/moc/cxx11-enums.h | 16 | ||||
-rw-r--r-- | tests/auto/tools/moc/tst_moc.cpp | 110 |
3 files changed, 161 insertions, 29 deletions
diff --git a/tests/auto/tools/moc/allmocs_baseline_in.json b/tests/auto/tools/moc/allmocs_baseline_in.json index 46f643d09b..50dbb200d2 100644 --- a/tests/auto/tools/moc/allmocs_baseline_in.json +++ b/tests/auto/tools/moc/allmocs_baseline_in.json @@ -91,6 +91,7 @@ "isClass": false, "isFlag": false, "name": "TypedEnum", + "type": "char", "values": [ "B0", "B1", @@ -102,6 +103,7 @@ "isClass": true, "isFlag": false, "name": "TypedEnumClass", + "type": "char", "values": [ "C0", "C1", @@ -147,6 +149,7 @@ "isClass": true, "isFlag": false, "name": "TypedEnumStruct", + "type": "char", "values": [ "H0", "H1", @@ -188,6 +191,7 @@ "isClass": false, "isFlag": false, "name": "TypedEnum", + "type": "char", "values": [ "B0", "B1", @@ -199,6 +203,7 @@ "isClass": true, "isFlag": false, "name": "TypedEnumClass", + "type": "char", "values": [ "C0", "C1", @@ -232,6 +237,65 @@ ], "gadget": true, "qualifiedClassName": "CXX11Enums2" + }, + { + "className": "CXX11Enums3", + "enums": [ + { + "isClass": true, + "isFlag": false, + "name": "EnumClass", + "values": [ + "A0", + "A1", + "A2", + "A3" + ] + }, + { + "isClass": false, + "isFlag": false, + "name": "TypedEnum", + "type": "char", + "values": [ + "B0", + "B1", + "B2", + "B3" + ] + }, + { + "isClass": true, + "isFlag": false, + "name": "TypedEnumClass", + "type": "char", + "values": [ + "C0", + "C1", + "C2", + "C3" + ] + }, + { + "isClass": false, + "isFlag": false, + "name": "NormalEnum", + "values": [ + "D2", + "D3", + "D0", + "D1" + ] + } + ], + "object": true, + "qualifiedClassName": "CXX11Enums3", + "superClasses": [ + { + "access": "public", + "name": "QObject" + } + ] } ], "inputFile": "cxx11-enums.h", diff --git a/tests/auto/tools/moc/cxx11-enums.h b/tests/auto/tools/moc/cxx11-enums.h index cd82a5df6d..821cd03863 100644 --- a/tests/auto/tools/moc/cxx11-enums.h +++ b/tests/auto/tools/moc/cxx11-enums.h @@ -47,4 +47,20 @@ public: Q_FLAGS(ClassFlags) }; +class CXX11Enums3 : public QObject +{ + Q_OBJECT +public: + enum class EnumClass { A0, A1, A2, A3 }; + 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 = 1, F1 = 2, F2 = 4, F3 = 8 }; + + Q_ENUM(EnumClass) + Q_ENUM(TypedEnum) + Q_ENUM(TypedEnumClass) + Q_ENUM(NormalEnum) +}; + #endif // CXX11_ENUMS_H diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index e2844e29d1..6a2962d609 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -98,6 +98,12 @@ public: Key2 }; Q_ENUM(TestGEnum2) + + enum TestGEnum3: quint8 { + Key1 = 23, + Key2 + }; + Q_ENUM(TestGEnum3) }; } @@ -116,6 +122,12 @@ namespace TestQNamespace { }; Q_ENUM_NS(TestEnum2) + enum TestEnum3: qint8 { + Key1 = 23, + Key2 + }; + Q_ENUM_NS(TestEnum3) + // try to dizzy moc by adding a struct in between struct TestGadget { Q_GADGET @@ -128,8 +140,13 @@ namespace TestQNamespace { Key1 = 23, Key2 }; + enum TestGEnum3: qint16 { + Key1 = 33, + Key2 + }; Q_ENUM(TestGEnum1) Q_ENUM(TestGEnum2) + Q_ENUM(TestGEnum3) }; struct TestGadgetExport { @@ -146,6 +163,12 @@ namespace TestQNamespace { Key2 }; Q_ENUM(TestGeEnum2) + enum TestGeEnum3: quint16 { + Key1 = 26, + Key2 + }; + Q_ENUM(TestGeEnum3) + }; enum class TestFlag1 { @@ -2428,23 +2451,29 @@ void tst_Moc::cxx11Enums_data() QTest::addColumn<QByteArray>("enumName"); QTest::addColumn<char>("prefix"); QTest::addColumn<bool>("isScoped"); + QTest::addColumn<bool>("isTyped"); const QMetaObject *meta1 = &CXX11Enums::staticMetaObject; const QMetaObject *meta2 = &CXX11Enums2::staticMetaObject; - - 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; - QTest::newRow("EnumStruct") << meta1 << QByteArray("EnumStruct") << QByteArray("EnumStruct") << 'G' << true; - QTest::newRow("TypedEnumStruct") << meta1 << QByteArray("TypedEnumStruct") << QByteArray("TypedEnumStruct") << 'H' << true; - QTest::newRow("StructFlags") << meta1 << QByteArray("StructFlags") << QByteArray("StructFlag") << 'I' << true; + const QMetaObject *meta3 = &CXX11Enums3::staticMetaObject; + + QTest::newRow("EnumClass") << meta1 << QByteArray("EnumClass") << QByteArray("EnumClass") << 'A' << true << false; + QTest::newRow("EnumClass 2") << meta2 << QByteArray("EnumClass") << QByteArray("EnumClass") << 'A' << true << false; + QTest::newRow("EnumClass 3") << meta3 << QByteArray("EnumClass") << QByteArray("EnumClass") << 'A' << true << false; + QTest::newRow("TypedEnum") << meta1 << QByteArray("TypedEnum") << QByteArray("TypedEnum") << 'B' << false << true; + QTest::newRow("TypedEnum 2") << meta2 << QByteArray("TypedEnum") << QByteArray("TypedEnum") << 'B' << false << true; + QTest::newRow("TypedEnum 3") << meta3 << QByteArray("TypedEnum") << QByteArray("TypedEnum") << 'B' << false << true; + QTest::newRow("TypedEnumClass") << meta1 << QByteArray("TypedEnumClass") << QByteArray("TypedEnumClass") << 'C' << true << true; + QTest::newRow("TypedEnumClass 2") << meta2 << QByteArray("TypedEnumClass") << QByteArray("TypedEnumClass") << 'C' << true << true; + QTest::newRow("TypedEnumClass 3") << meta3 << QByteArray("TypedEnumClass") << QByteArray("TypedEnumClass") << 'C' << true << true; + QTest::newRow("NormalEnum") << meta1 << QByteArray("NormalEnum") << QByteArray("NormalEnum") << 'D' << false << false; + QTest::newRow("NormalEnum 2") << meta2 << QByteArray("NormalEnum") << QByteArray("NormalEnum") << 'D' << false << false; + QTest::newRow("NormalEnum 3") << meta3 << QByteArray("NormalEnum") << QByteArray("NormalEnum") << 'D' << false << false; + QTest::newRow("ClassFlags") << meta1 << QByteArray("ClassFlags") << QByteArray("ClassFlag") << 'F' << true << false; + QTest::newRow("ClassFlags 2") << meta2 << QByteArray("ClassFlags") << QByteArray("ClassFlag") << 'F' << true << false; + QTest::newRow("EnumStruct") << meta1 << QByteArray("EnumStruct") << QByteArray("EnumStruct") << 'G' << true << false; + QTest::newRow("TypedEnumStruct") << meta1 << QByteArray("TypedEnumStruct") << QByteArray("TypedEnumStruct") << 'H' << true << true; + QTest::newRow("StructFlags") << meta1 << QByteArray("StructFlags") << QByteArray("StructFlag") << 'I' << true << false; } void tst_Moc::cxx11Enums() @@ -2456,24 +2485,39 @@ void tst_Moc::cxx11Enums() QFETCH(QByteArray, enumName); QFETCH(char, prefix); QFETCH(bool, isScoped); + QFETCH(bool, isTyped); 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(), typeName.constData()); - QCOMPARE(meta->enumerator(idx).enumName(), enumName.constData()); - bool isFlag = meta->enumerator(idx).isFlag(); + const QMetaEnum metaEnum = meta->enumerator(idx); + QCOMPARE(metaEnum.enclosingMetaObject(), meta); + QCOMPARE(metaEnum.isValid(), true); + QCOMPARE(metaEnum.keyCount(), 4); + QCOMPARE(metaEnum.name(), typeName.constData()); + QCOMPARE(metaEnum.enumName(), enumName.constData()); + + const QMetaType metaType = metaEnum.metaType(); + const bool isUnsigned = metaType.flags() & QMetaType::IsUnsignedEnumeration; + if (isTyped) { + QCOMPARE(metaType.sizeOf(), sizeof(char)); + QCOMPARE(isUnsigned, !std::is_signed_v<char>); + } else if (isScoped) { + QCOMPARE(metaType.sizeOf(), sizeof(int)); + QCOMPARE(isUnsigned, !std::is_signed_v<int>); + } else { + // underlying type is implementation defined + } + + bool isFlag = metaEnum.isFlag(); for (int i = 0; i < 4; i++) { QByteArray v = prefix + QByteArray::number(i); const int value = isFlag ? (1 << i) : i; - QCOMPARE(meta->enumerator(idx).keyToValue(v), value); - QCOMPARE(meta->enumerator(idx).valueToKey(value), v.constData()); + QCOMPARE(metaEnum.keyToValue(v), value); + QCOMPARE(metaEnum.valueToKey(value), v.constData()); } - QCOMPARE(meta->enumerator(idx).isScoped(), isScoped); + QCOMPARE(metaEnum.isScoped(), isScoped); } void tst_Moc::cxx11TrailingReturn() @@ -3994,10 +4038,12 @@ void tst_Moc::optionsFileError() } static void checkEnum(const QMetaEnum &enumerator, const QByteArray &name, - const QList<QPair<QByteArray, int>> &keys) + const QList<QPair<QByteArray, int>> &keys, + const QMetaType underlyingType = QMetaType::fromType<int>()) { QCOMPARE(name, QByteArray{enumerator.name()}); QCOMPARE(keys.size(), enumerator.keyCount()); + QCOMPARE(underlyingType, enumerator.metaType().underlyingType()); for (int i = 0; i < enumerator.keyCount(); ++i) { QCOMPARE(keys[i].first, QByteArray{enumerator.key(i)}); QCOMPARE(keys[i].second, enumerator.value(i)); @@ -4014,27 +4060,33 @@ public: void tst_Moc::testQNamespace() { - QCOMPARE(TestQNamespace::staticMetaObject.enumeratorCount(), 4); + QCOMPARE(TestQNamespace::staticMetaObject.enumeratorCount(), 5); checkEnum(TestQNamespace::staticMetaObject.enumerator(0), "TestEnum1", {{"Key1", 11}, {"Key2", 12}}); checkEnum(TestQNamespace::staticMetaObject.enumerator(1), "TestEnum2", {{"Key1", 17}, {"Key2", 18}}); - checkEnum(TestQNamespace::staticMetaObject.enumerator(2), "TestFlag1", + checkEnum(TestQNamespace::staticMetaObject.enumerator(2), "TestEnum3", + {{"Key1", 23}, {"Key2", 24}}, QMetaType::fromType<qint8>()); + checkEnum(TestQNamespace::staticMetaObject.enumerator(3), "TestFlag1", {{"None", 0}, {"Flag1", 1}, {"Flag2", 2}, {"Any", 1 | 2}}); - checkEnum(TestQNamespace::staticMetaObject.enumerator(3), "TestFlag2", + checkEnum(TestQNamespace::staticMetaObject.enumerator(4), "TestFlag2", {{"None", 0}, {"Flag1", 4}, {"Flag2", 8}, {"Any", 4 | 8}}); - QCOMPARE(TestQNamespace::TestGadget::staticMetaObject.enumeratorCount(), 2); + QCOMPARE(TestQNamespace::TestGadget::staticMetaObject.enumeratorCount(), 3); checkEnum(TestQNamespace::TestGadget::staticMetaObject.enumerator(0), "TestGEnum1", {{"Key1", 13}, {"Key2", 14}}); checkEnum(TestQNamespace::TestGadget::staticMetaObject.enumerator(1), "TestGEnum2", {{"Key1", 23}, {"Key2", 24}}); + checkEnum(TestQNamespace::TestGadget::staticMetaObject.enumerator(2), "TestGEnum3", + {{"Key1", 33}, {"Key2", 34}}, QMetaType::fromType<qint16>()); - QCOMPARE(TestQNamespace::TestGadgetExport::staticMetaObject.enumeratorCount(), 2); + QCOMPARE(TestQNamespace::TestGadgetExport::staticMetaObject.enumeratorCount(), 3); checkEnum(TestQNamespace::TestGadgetExport::staticMetaObject.enumerator(0), "TestGeEnum1", {{"Key1", 20}, {"Key2", 21}}); checkEnum(TestQNamespace::TestGadgetExport::staticMetaObject.enumerator(1), "TestGeEnum2", {{"Key1", 23}, {"Key2", 24}}); + checkEnum(TestQNamespace::TestGadgetExport::staticMetaObject.enumerator(2), "TestGeEnum3", + {{"Key1", 26}, {"Key2", 27}}, QMetaType::fromType<quint16>()); QMetaEnum meta = QMetaEnum::fromType<TestQNamespace::TestEnum1>(); QVERIFY(meta.isValid()); |