summaryrefslogtreecommitdiffstats
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:40 +0000
commitfa9eaab0459afcfca46fc757bc6347f02de6d210 (patch)
tree441393e0986ce6e89a56ddc36147ece8e35000ba
parentf5bf8f131654c06aa6dfcc3901f8e72979cdcdd3 (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 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 556073e..400ecce 100644
--- a/tools/dumpcpp/main.cpp
+++ b/tools/dumpcpp/main.cpp
@@ -569,13 +569,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);