moc: Fix parsing of [[deprecated]] enum values

moc now successfully parses enum values, that have been deprecated with
[[deprecated]]. This is valid c++17 and should be handled correctly.
By adding that functionality it is possible to parse Windows headers
which use this deprecation mechanism.

To make sure, that moc works correctly even on compilers that do not
support deprecated enum values yet, the auto test explicitly uses
[[deprecated]] enum values during moc run.

Fixes: QTBUG-74126
Change-Id: I7b9d9a49af6093a97f8fdb800ffbc5af3d54d262
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@qt.io>
This commit is contained in:
Oliver Wolff 2019-03-01 09:38:45 +01:00
parent 75c6bd54d7
commit 2412cfac51
3 changed files with 61 additions and 0 deletions

View File

@ -285,6 +285,7 @@ bool Moc::parseEnum(EnumDef *def)
break;
next(IDENTIFIER);
def->values += lexem();
skipCxxAttributes();
} while (test(EQ) ? until(COMMA) : test(COMMA));
next(RBRACE);
if (isTypdefEnum) {

View File

@ -57,4 +57,47 @@ public slots:
#endif
};
#ifdef Q_MOC_RUN
# define TEST_COMPILER_DEPRECATION [[deprecated]]
# define TEST_COMPILER_DEPRECATION_X(x) [[deprecated(x)]]
#else
# define TEST_COMPILER_DEPRECATION Q_DECL_ENUMERATOR_DEPRECATED
# define TEST_COMPILER_DEPRECATION_X(x) Q_DECL_ENUMERATOR_DEPRECATED_X(x)
#endif
namespace TestQNamespaceDeprecated {
Q_NAMESPACE
enum class TestEnum1 {
Key1 = 11,
Key2 TEST_COMPILER_DEPRECATION,
Key3 TEST_COMPILER_DEPRECATION_X("reason"),
Key4 TEST_COMPILER_DEPRECATION_X("reason["),
Key5 TEST_COMPILER_DEPRECATION_X("reason[["),
Key6 TEST_COMPILER_DEPRECATION_X("reason]"),
Key7 TEST_COMPILER_DEPRECATION_X("reason]]"),
};
Q_ENUM_NS(TestEnum1)
// try to dizzy moc by adding a struct in between
struct TestGadget {
Q_GADGET
public:
enum class TestGEnum1 {
Key1 = 13,
Key2 TEST_COMPILER_DEPRECATION,
Key3 TEST_COMPILER_DEPRECATION_X("reason")
};
Q_ENUM(TestGEnum1)
};
enum class TestFlag1 {
None = 0,
Flag1 = 1,
Flag2 TEST_COMPILER_DEPRECATION = 2,
Flag3 TEST_COMPILER_DEPRECATION_X("reason") = 3,
Any = Flag1 | Flag2 | Flag3
};
Q_FLAG_NS(TestFlag1)
}
#endif // CXXATTRIBUTE_H

View File

@ -3926,6 +3926,23 @@ void tst_Moc::cxxAttributes()
}) {
QVERIFY(so.indexOfSlot(a) != 1);
}
QCOMPARE(TestQNamespaceDeprecated::staticMetaObject.enumeratorCount(), 2);
checkEnum(TestQNamespaceDeprecated::staticMetaObject.enumerator(0), "TestEnum1",
{{"Key1", 11}, {"Key2", 12}, {"Key3", 13}, {"Key4", 14}, {"Key5", 15}, {"Key6", 16},
{"Key7", 17}});
checkEnum(TestQNamespaceDeprecated::staticMetaObject.enumerator(1), "TestFlag1",
{{"None", 0}, {"Flag1", 1}, {"Flag2", 2}, {"Flag3", 3}, {"Any", 1 | 2 | 3}});
QCOMPARE(TestQNamespaceDeprecated::TestGadget::staticMetaObject.enumeratorCount(), 1);
checkEnum(TestQNamespaceDeprecated::TestGadget::staticMetaObject.enumerator(0), "TestGEnum1",
{{"Key1", 13}, {"Key2", 14}, {"Key3", 15}});
QMetaEnum meta = QMetaEnum::fromType<TestQNamespaceDeprecated::TestEnum1>();
QVERIFY(meta.isValid());
QCOMPARE(meta.name(), "TestEnum1");
QCOMPARE(meta.enclosingMetaObject(), &TestQNamespaceDeprecated::staticMetaObject);
QCOMPARE(meta.keyCount(), 7);
}
QTEST_MAIN(tst_Moc)