summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2022-06-20 15:58:11 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-06-21 06:02:42 +0000
commit1580c122b4a49ba7f9511e37453da42fb4b7adaf (patch)
tree655532460b544ed15f2ce851114ee365b8116e1e
parentf3081b5fda26420f102f4e9ebda13a24fc0b1822 (diff)
downloadqtactiveqt-1580c122b4a49ba7f9511e37453da42fb4b7adaf.tar.gz
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 Change-Id: Id9b4656cb1ff2c319e0b87bd22b7e9399e7c410d Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> (cherry picked from commit a4e0ae01fdd7e9686445d9db3d62103dbbfafa91) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-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);