From 30c490da13db4e0e08bfd78e8448c7d5ab97c815 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 2 Sep 2024 08:03:57 -0700 Subject: [PATCH] moc: change the mangling of class names to closer to the IA-64 ABI Commit e816f915411a0f517021769abd8919a423f635c3 ("Moc: avoid double underscores in a generated identifier") added the CLASS..SCOPE..ENDCLASS mangling to avoid creating double underscores, which are reserved to the compiler and thus undefined behavior for us to use. This commit changes that mangling to something similar to the IA-64 C++ ABI because a) that creates shorter identifier names that are often easier to read if you have to open the moc result and b) will not collide with a class name by the user that used SCOPE in the name, such as: namespace Outer { class Inner { Q_GADGET }; } class OuterSCOPEInner : public QObject { Q_OBJECT } }; Before: Q_CONSTINIT static const uint qt_meta_data_CLASSOuterSCOPEInnerENDCLASS[] = { Q_CONSTINIT static const uint qt_meta_data_CLASSOuterSCOPEInnerENDCLASS[] = { Now: Q_CONSTINIT static const uint qt_meta_data_ZN5Outer5InnerE[] = Q_CONSTINIT static const uint qt_meta_data_ZN15OuterSCOPEInnerE[] = While I make no promises that this matches the mangling scheme, it can actually be decoded by the c++filt(1) tool. The main difference (AFAICT) is that we use the N..E production even for types in the global namespace (e.g., "QObject" mangling should be "7QObject" but is "N7QObjectE"). $ c++filt _ZN42QTBUG32933_relatedObjectsDontIncludeItself2NS3ObjE QTBUG32933_relatedObjectsDontIncludeItself::NS::Obj Pick-to: 6.7 6.5 Change-Id: I40b756c1ac0f6a986d79fffd14b2e245ac195afb Reviewed-by: Fabian Kosmale (cherry picked from commit b020bff6e9a2e45760bab61bdb84efc078c45f7f) Reviewed-by: Qt Cherry-pick Bot --- src/tools/moc/generator.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 16eb5be4c90..0456f5854c0 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -202,17 +202,14 @@ static bool qualifiedNameEquals(const QByteArray &qualifiedName, const QByteArra static QByteArray generateQualifiedClassNameIdentifier(const QByteArray &identifier) { - QByteArray qualifiedClassNameIdentifier = identifier; - - // Remove ':'s in the name, but be sure not to create any illegal - // identifiers in the process. (Don't replace with '_', because - // that will create problems with things like NS_::_class.) - qualifiedClassNameIdentifier.replace("::", "SCOPE"); - - // Also, avoid any leading/trailing underscores (we'll concatenate - // the generated name with other prefixes/suffixes, and these latter - // may already include an underscore, leading to two underscores) - qualifiedClassNameIdentifier = "CLASS" + qualifiedClassNameIdentifier + "ENDCLASS"; + // This is similar to the IA-64 C++ ABI mangling scheme. + QByteArray qualifiedClassNameIdentifier = "ZN"; + for (const auto scope : qTokenize(QLatin1StringView(identifier), QLatin1Char(':'), + Qt::SkipEmptyParts)) { + qualifiedClassNameIdentifier += QByteArray::number(scope.size()); + qualifiedClassNameIdentifier += scope; + } + qualifiedClassNameIdentifier += 'E'; return qualifiedClassNameIdentifier; }