summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2022-06-20 15:58:11 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2022-06-21 07:49:09 +0200
commita4e0ae01fdd7e9686445d9db3d62103dbbfafa91 (patch)
tree98c8ad2d622119f6c083ba3f7452a9ed6807cb34
parent99c59f82575695163e45e3848a5338f2d4fadaae (diff)
Postprocess moc output to fully qualify types
If a property is declared with a type that is also the name of a member function, then the generated code will result in conflicts and compile errors. For instance, a property "AddressEntry" might be of type "AddressEntry*" and have a getter "AddressEntry", where the type lives in the same namespace as the current class. This is reproducible with the qutlook example, which doesn't build. This issue can also be provoked by valid C++ code, but since moc has no information about which types are classes or enums, or in which namespace they live in, we cannot do anything about that problem (yet). However, dumpcpp has information about which namespace a type live in, so we can postprocess the moc output and fix the problematic code by fully qualifying the types used with the namespace they were generated in. This slows down dumpcpp runs quite a bit, but those are infrequent as the type library typically doesn't change. Fixes: QTBUG-100145 Pick-to: 6.4 6.3 Change-Id: Id9b4656cb1ff2c319e0b87bd22b7e9399e7c410d Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r--tools/dumpcpp/main.cpp28
1 files changed, 26 insertions, 2 deletions
diff --git a/tools/dumpcpp/main.cpp b/tools/dumpcpp/main.cpp
index 9471fcf..c2120b7 100644
--- a/tools/dumpcpp/main.cpp
+++ b/tools/dumpcpp/main.cpp
@@ -544,13 +544,37 @@ bool generateClassImpl(QTextStream &out, const QMetaObject *mo, const QByteArray
qualifiedClassName = nameSpace + "::";
qualifiedClassName += className;
- const QString moCode = mocCode(mo, QLatin1String(qualifiedClassName),
- errorString);
+ QString moCode = mocCode(mo, QLatin1String(qualifiedClassName), errorString);
if (moCode.isEmpty()) {
out << "#error moc error\n";
return false;
}
+ // Postprocess the moc output to fully qualify types. This works around moc
+ // not having any semantic type information, and a fix for QTBUG-100145.
+ constexpr QStringView typeAndForceComplete(u"QtPrivate::TypeAndForceComplete<");
+ qsizetype nextTypeAndForceComplete = 0;
+ do {
+ nextTypeAndForceComplete = moCode.indexOf(typeAndForceComplete, nextTypeAndForceComplete);
+ if (nextTypeAndForceComplete == -1)
+ break;
+ const auto startType = nextTypeAndForceComplete + typeAndForceComplete.length();
+ const auto lengthType = moCode.indexOf(u',', startType) - startType;
+ if (lengthType == -1)
+ break;
+
+ QString type = moCode.sliced(startType, lengthType);
+ if (type.endsWith(u'*'))
+ type.chop(1);
+ type = type.trimmed();
+ const auto namespaceForTypeEntry = namespaceForType.constFind(type.toUtf8());
+ if (namespaceForTypeEntry != namespaceForType.constEnd()) {
+ const auto ns = QString::fromUtf8(namespaceForTypeEntry.value());
+ moCode.insert(startType, ns + QStringView(u"::"));
+ }
+ nextTypeAndForceComplete = startType + lengthType;
+ } while (true);
+
out << moCode << "\n\n";
formatConstructorBody(out, nameSpace, className, controlID, category, useControlName);