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 <thiago.macieira@intel.com>
(cherry picked from commit e816f915411a0f517021769abd8919a423f635c3)
This commit is contained in:
Giuseppe D'Angelo 2023-01-06 02:57:00 +01:00
parent b4b80e0794
commit f8c481e7e5

View File

@ -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");