summaryrefslogtreecommitdiffstats
path: root/src/tools/moc
diff options
context:
space:
mode:
authorAhmad Samir <a.samirh78@gmail.com>2023-06-07 16:34:45 +0300
committerAhmad Samir <a.samirh78@gmail.com>2023-06-18 21:28:58 +0300
commit7779400ba6fee98b1f90702f92c17a5a4089c5ce (patch)
treee66be9f45a8981bfcda6eb83fd5042b374acc76f /src/tools/moc
parente603661c48903fa674332a218b21cb35b288de4c (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.cpp3
-rw-r--r--src/tools/moc/moc.cpp19
-rw-r--r--src/tools/moc/moc.h1
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);