diff options
author | Ahmad Samir <a.samirh78@gmail.com> | 2023-06-07 16:34:45 +0300 |
---|---|---|
committer | Ahmad Samir <a.samirh78@gmail.com> | 2023-06-18 21:28:58 +0300 |
commit | 7779400ba6fee98b1f90702f92c17a5a4089c5ce (patch) | |
tree | e66be9f45a8981bfcda6eb83fd5042b374acc76f /src/tools/moc | |
parent | e603661c48903fa674332a218b21cb35b288de4c (diff) |
Moc: fix generated code for nested enum class corner case
Fixes an issue with generated code where the name of an enclosing
namespace is identical to an enum class type, when Q_ENUM_NS is used.
Consider:
namespace a {
Q_NAMESPACE
namespace b {
enum class b { Key, Key2 };
Q_ENUM_NS(b);
}
}
moc generated code such as:
Q_CONSTINIT const QMetaObject a::b::staticMetaObject = { {
...
qt_incomplete_metaTypeArray<qt_meta_stringdata_CLASSaSCOPEbENDCLASS_t,
// enum 'TestEnum'
QtPrivate::TypeAndForceComplete<b::b, std::true_type>,
// Q_OBJECT / Q_GADGET
QtPrivate::TypeAndForceComplete<void, std::true_type>
>,
nullptr
} };
which confused the compiler:
error: ‘b’ is not a member of ‘a::b::b
83 | QtPrivate::TypeAndForceComplete<b::b, std::true_type>,
Fixes: QTBUG-112996
Pick-to: 6.6
Change-Id: I37aee83c32efe96cc9d6c2bd0bdb9ba80bb7b8a7
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/tools/moc')
-rw-r--r-- | src/tools/moc/generator.cpp | 3 | ||||
-rw-r--r-- | src/tools/moc/moc.cpp | 19 | ||||
-rw-r--r-- | src/tools/moc/moc.h | 1 |
3 files changed, 21 insertions, 2 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index f3a53dfccd..b083ed63b7 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -525,8 +525,7 @@ void Generator::generateCode() // metatypes for enums for (const EnumDef &e : std::as_const(cdef->enumList)) { fprintf(out, "%s\n // enum '%s'\n %s", - comma, e.name.constData(), - stringForType(cdef->classname % "::" % e.name, true).constData()); + comma, e.name.constData(), stringForType(e.qualifiedType(cdef), true).constData()); comma = ","; } diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 058df18f42..1d1948525c 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -2187,4 +2187,23 @@ QJsonObject EnumDef::toJson(const ClassDef &cdef) const return def; } +QByteArray EnumDef::qualifiedType(const ClassDef *cdef) const +{ + if (name == cdef->classname) { + // The name of the enclosing namespace is the same as the enum class name + if (cdef->qualified.contains("::")) { + // QTBUG-112996, fully qualify by using cdef->qualified to disambiguate enum + // class name and enclosing namespace, e.g.: + // namespace A { namespace B { Q_NAMESPACE; enum class B { }; Q_ENUM_NS(B) } } + return cdef->qualified % "::" % name; + } else { + // Just "B"; otherwise the compiler complains about the type "B::B" inside + // "B::staticMetaObject" in the generated code; e.g.: + // namespace B { Q_NAMESPACE; enum class B { }; Q_ENUM_NS(B) } + return name; + } + } + return cdef->classname % "::" % name; +} + QT_END_NAMESPACE diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index 04f1c835ce..a3ddb835b5 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -48,6 +48,7 @@ struct EnumDef bool isEnumClass; // c++11 enum class EnumDef() : isEnumClass(false) {} QJsonObject toJson(const ClassDef &cdef) const; + QByteArray qualifiedType(const ClassDef *cdef) const; }; Q_DECLARE_TYPEINFO(EnumDef, Q_RELOCATABLE_TYPE); |