From f8c481e7e57944a33cce986634f7c8600aa65628 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Fri, 6 Jan 2023 02:57:00 +0100 Subject: [PATCH] Moc: avoid double underscores in a generated identifier In order to generate metadata for a class `NS::Class`, moc will "mangle" its name by turning the colons into underscores. This however makes the generated name have a double underscore, and all names with double underscores are reserved. Instead, replace double colons with another string ("SCOPE"). We are then going to use this mangled name to create other identifiers. To do so, underscores may get appended and prepended to the mangled name (e.g. "qt_metadata_" + mangled_name + "_t"). This means that a leading or trailing underscore in the mangled name would also be problematic; avoid that as well. Fixes: QTBUG-109851 Change-Id: I01391a57920545fc75f78ef4bfefaf6d3dd7b447 Reviewed-by: Thiago Macieira (cherry picked from commit e816f915411a0f517021769abd8919a423f635c3) --- src/tools/moc/generator.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 4c8a73043c8..ec5ba1dcdd0 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -210,6 +210,22 @@ static bool qualifiedNameEquals(const QByteArray &qualifiedName, const QByteArra return qualifiedNameEquals(qualifiedName.mid(index+2), name); } +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"; + return qualifiedClassNameIdentifier; +} + void Generator::generateCode() { bool isQObject = (cdef->classname == "QObject"); @@ -250,8 +266,7 @@ void Generator::generateCode() (cdef->hasQObject || !cdef->methodList.isEmpty() || !cdef->propertyList.isEmpty() || !cdef->constructorList.isEmpty()); - QByteArray qualifiedClassNameIdentifier = cdef->qualified; - qualifiedClassNameIdentifier.replace(':', '_'); + const QByteArray qualifiedClassNameIdentifier = generateQualifiedClassNameIdentifier(cdef->qualified); // ensure the qt_meta_stringdata_XXXX_t type is local fprintf(out, "namespace {\n");