moc: Add basic support for nested inline namespaces

This improves moc's support for nested inline namespaces, so that code
containing them will not break compilation.
For simplicity, we allow nested inline namespaces even in C++17 mode
(the actual C++ compiler will reject the code anyway, and probably with
a better error message than moc could output).
moc still has no real awareness how inline namespaces work, but that is
a preexisting issue.

Pick-to: 6.4 6.2
Fixes: QTBUG-106920
Change-Id: I7b415a99133575f101bc81d01d4670a5f752917f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Fabian Kosmale 2022-09-26 10:27:17 +02:00
parent 9527581239
commit 5222df2be7
2 changed files with 15 additions and 0 deletions

View File

@ -606,6 +606,12 @@ void Moc::parse()
QByteArray nsName = lexem(); QByteArray nsName = lexem();
QByteArrayList nested; QByteArrayList nested;
while (test(SCOPE)) { while (test(SCOPE)) {
/* treat (C++20's) namespace A::inline B {} as A::B
this is mostly to not break compilation when encountering such
a construct in a header; the interaction of Qt's meta-macros with
inline namespaces is still rather poor.
*/
test(INLINE);
next(IDENTIFIER); next(IDENTIFIER);
nested.append(nsName); nested.append(nsName);
nsName = lexem(); nsName = lexem();

View File

@ -64,6 +64,15 @@
const char *string_hash_hash = STRING_HASH_HASH("baz"); const char *string_hash_hash = STRING_HASH_HASH("baz");
#endif #endif
#if defined(Q_MOC_RUN) || __cplusplus > 202002L
/* Check that nested inline namespaces are at least not causing moc to break.
Check it even outside of C++20 mode as moc gets passed the wrong __cplusplus version
and also to increase coverage, given how few C++20 configurations exist in the CI at the time
of writing this comment.
*/
namespace A::inline B {}
#endif
Q_DECLARE_METATYPE(const QMetaObject*); Q_DECLARE_METATYPE(const QMetaObject*);
#define TESTEXPORTMACRO Q_DECL_EXPORT #define TESTEXPORTMACRO Q_DECL_EXPORT