From b76f66272692f39aaaaec7c398702f1585badf45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Thu, 13 Jun 2019 12:37:26 +0200 Subject: Fix all tst_qmetatype breakages after QList to QVector aliasing In Qt6 QList is just a typedef to QVector. To keep Qt5 behavior compatibility we need to register aliases, otherwise some type name based operations would not work. The patch adds automatic registration of QList metatype alias for every QVector. The patch doesn't cover usage of already typedef'ed and aliased QList and QVector, but that should be quite esoteric, especially after introduction of automatic QList and QVector type registration. Change-Id: I84672dda2b159d94e76cdc6034861e7d7ef52533 Reviewed-by: Thiago Macieira Reviewed-by: Simon Hausmann --- src/corelib/kernel/qmetatype.cpp | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'src/corelib/kernel/qmetatype.cpp') diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 356a675517..5c1e4b4ddd 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -37,6 +37,8 @@ ** ****************************************************************************/ +#include + #include "qmetatype.h" #include "qmetatype_p.h" #include "qobjectdefs.h" @@ -2416,6 +2418,50 @@ const QMetaObject *metaObjectForQWidget() return nullptr; return qMetaObjectWidgetsHelper; } + +void qt5CompatibilityHookPostRegister(int id, const QByteArray &normalizedTypeName) +{ + // In Qt6 QList got typedef'ed to QVector. To keep runtime behavior compatibility + // with Qt5 we install corresponding aliases. For example if one register + // QVector> + // we need to register the type plus all possible aliases: + // QVector> + // QList> + // QList> + // ### Qt6 TODO This is slow, as it allocates couple of strings we would need to + // if def this call with something like QT_NO_QLIST + const char *vectorName = "QVector<"; + const char *listName = "QList<"; + + auto isSubstringOfAType = [](char c) { return c != ' ' && c != ',' && c != '<'; }; + QVarLengthArray indexes; + + for (auto containerName: {vectorName, listName}) { + for (int i = normalizedTypeName.indexOf(containerName, 0); i != -1; i = normalizedTypeName.indexOf(containerName, i + 1)) { + if (!i || (i > 0 && !isSubstringOfAType(normalizedTypeName[i - 1]))) + indexes.append(i); + } + } + // To avoid problems with the constantly changing size we start replacements + // from the end of normalizedTypeName + std::sort(indexes.rbegin(), indexes.rend()); + + for (quint64 combination = 1; ; ++combination) { + std::bitset<64> bits(combination); + QByteArray name = normalizedTypeName; + for (auto j = 0; j < indexes.size(); ++j) { + if (bits.test(j)) { + auto i = indexes[j]; + auto replaceFrom = normalizedTypeName[i + 1] == 'V' ? vectorName : listName; + auto replaceTo = normalizedTypeName[i + 1] == 'V' ? listName : vectorName; + name.replace(i, sizeof(replaceFrom), replaceTo); + } + } + QMetaType::registerNormalizedTypedef(name, id); + if (bits.count() >= size_t(indexes.size())) + break; + } +} } namespace QtMetaTypePrivate { -- cgit v1.2.3