diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-06-11 10:37:50 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-06-16 15:20:10 +0000 |
commit | 9b7411b644273c644331b99fc35d1f1460f9fcec (patch) | |
tree | 62036e1a89bef16c8d9ddbb2a8e7481209440038 | |
parent | b8ebeeb81ce599a9afeef996faaf2f1463ab5981 (diff) |
shiboken6: Fix duplicate indexes for template instantiations
For a typedef "using Foo=QList<int>", shiboken generates SBK_QLIST_INT
besides SBK_FOO which is then matched by function arguments. The code
was however missing a check to restrict this to typedefs, so it
triggered for
class Alternative : public QVariantList,
class Sequence : public QVariantList
producing duplicate indexes.
Restrict this to real typedefs (which are also represented as classes.
Split out the function creating the special alternate index for
clarity and add a check for potential equivalent typedefs which would
also produce clashes.
Task-number: PYSIDE-1571
Change-Id: I9275963c4ddb8fc589e414ee1fa19282f6004793
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
(cherry picked from commit 42c0854f077d004dba43b713ec2cabb76747a270)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
4 files changed, 53 insertions, 28 deletions
diff --git a/sources/shiboken6/generator/shiboken/headergenerator.cpp b/sources/shiboken6/generator/shiboken/headergenerator.cpp index 8bf22d52c..5df22cf4d 100644 --- a/sources/shiboken6/generator/shiboken/headergenerator.cpp +++ b/sources/shiboken6/generator/shiboken/headergenerator.cpp @@ -332,6 +332,23 @@ static inline void _writeTypeIndexValueLine(TextStream &s, s << ",\n"; } +// Find equivalent typedefs "using Foo=QList<int>", "using Bar=QList<int>" +static const AbstractMetaClass * + findEquivalentTemplateTypedef(const AbstractMetaClassCList &haystack, + const AbstractMetaClass *needle) +{ + auto *templateBaseClass = needle->templateBaseClass(); + const auto &instantiations = needle->templateBaseClassInstantiations(); + for (auto *candidate : haystack) { + if (candidate->isTypeDef() + && candidate->templateBaseClass() == templateBaseClass + && candidate->templateBaseClassInstantiations() == instantiations) { + return candidate; + } + } + return nullptr; +} + void HeaderGenerator::writeTypeIndexValueLine(TextStream &s, const ApiExtractorResult &api, const TypeEntry *typeEntry) { @@ -341,12 +358,22 @@ void HeaderGenerator::writeTypeIndexValueLine(TextStream &s, const ApiExtractorR const int typeIndex = typeEntry->sbkIndex(); _writeTypeIndexValueLine(s, getTypeIndexVariableName(typeEntry), typeIndex); if (typeEntry->isComplex()) { + // For a typedef "using Foo=QList<int>", write a type index + // SBK_QLIST_INT besides SBK_FOO which is then matched by function + // argument. Check against duplicate typedefs for the same types. const auto *cType = static_cast<const ComplexTypeEntry *>(typeEntry); if (cType->baseContainerType()) { auto metaClass = AbstractMetaClass::findClass(api.classes(), cType); Q_ASSERT(metaClass != nullptr); - if (metaClass->templateBaseClass()) - _writeTypeIndexValueLine(s, getTypeIndexVariableName(metaClass, true), typeIndex); + if (metaClass->isTypeDef() + && metaClass->templateBaseClass() != nullptr + && findEquivalentTemplateTypedef(m_alternateTemplateIndexes, + metaClass) == nullptr) { + const QString indexVariable = + getTypeAlternateTemplateIndexVariableName(metaClass); + _writeTypeIndexValueLine(s, indexVariable, typeIndex); + m_alternateTemplateIndexes.append(m_alternateTemplateIndexes); + } } } if (typeEntry->isEnum()) { diff --git a/sources/shiboken6/generator/shiboken/headergenerator.h b/sources/shiboken6/generator/shiboken/headergenerator.h index 1fe0dd444..f2cf23a69 100644 --- a/sources/shiboken6/generator/shiboken/headergenerator.h +++ b/sources/shiboken6/generator/shiboken/headergenerator.h @@ -57,16 +57,17 @@ private: void writeSbkTypeFunction(TextStream &s, const AbstractMetaEnum &cppEnum) const; static void writeSbkTypeFunction(TextStream &s, const AbstractMetaClass *cppClass) ; static void writeSbkTypeFunction(TextStream &s, const AbstractMetaType &metaType) ; - static void writeTypeIndexValueLine(TextStream &s, const ApiExtractorResult &api, - const TypeEntry *typeEntry); - static void writeTypeIndexValueLines(TextStream &s, const ApiExtractorResult &api, - const AbstractMetaClass *metaClass); + void writeTypeIndexValueLine(TextStream &s, const ApiExtractorResult &api, + const TypeEntry *typeEntry); + void writeTypeIndexValueLines(TextStream &s, const ApiExtractorResult &api, + const AbstractMetaClass *metaClass); void writeProtectedEnumSurrogate(TextStream &s, const AbstractMetaEnum &cppEnum) const; void writeMemberFunctionWrapper(TextStream &s, const AbstractMetaFunctionCPtr &func, const QString &postfix = {}) const; QSet<AbstractMetaFunctionCPtr> m_inheritedOverloads; + AbstractMetaClassCList m_alternateTemplateIndexes; }; #endif // HEADERGENERATOR_H diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp index 05a9e7571..2543c6187 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp @@ -2516,20 +2516,20 @@ static void appendIndexSuffix(QString *s) s->append(QStringLiteral("IDX")); } -QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaClass *metaClass, - bool alternativeTemplateName) -{ - if (alternativeTemplateName) { - const AbstractMetaClass *templateBaseClass = metaClass->templateBaseClass(); - if (!templateBaseClass) - return QString(); - QString result = QLatin1String("SBK_") - + _fixedCppTypeName(templateBaseClass->typeEntry()->qualifiedCppName()).toUpper(); - for (const auto &instantiation : metaClass->templateBaseClassInstantiations()) - result += processInstantiationsVariableName(instantiation); - appendIndexSuffix(&result); - return result; - } +QString ShibokenGenerator::getTypeAlternateTemplateIndexVariableName(const AbstractMetaClass *metaClass) +{ + const AbstractMetaClass *templateBaseClass = metaClass->templateBaseClass(); + Q_ASSERT(templateBaseClass); + QString result = QLatin1String("SBK_") + + _fixedCppTypeName(templateBaseClass->typeEntry()->qualifiedCppName()).toUpper(); + for (const auto &instantiation : metaClass->templateBaseClassInstantiations()) + result += processInstantiationsVariableName(instantiation); + appendIndexSuffix(&result); + return result; +} + +QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaClass *metaClass) +{ return getTypeIndexVariableName(metaClass->typeEntry()); } QString ShibokenGenerator::getTypeIndexVariableName(const TypeEntry *type) diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h index bcba349cf..a18dd8478 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.h +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h @@ -329,14 +329,11 @@ protected: static QString cppApiVariableName(const QString &moduleName = QString()); static QString pythonModuleObjectName(const QString &moduleName = QString()); static QString convertersVariableName(const QString &moduleName = QString()); - /** - * Returns the type index variable name for a given class. If \p alternativeTemplateName is true - * and the class is a typedef for a template class instantiation, it will return an alternative name - * made of the template class and the instantiation values, or an empty string if the class isn't - * derived from a template class at all. - */ - static QString getTypeIndexVariableName(const AbstractMetaClass *metaClass, - bool alternativeTemplateName = false); + /// Returns the type index variable name for a given class. + static QString getTypeIndexVariableName(const AbstractMetaClass *metaClass); + /// Returns the type index variable name for a given typedef for a template + /// class instantiation made of the template class and the instantiation values + static QString getTypeAlternateTemplateIndexVariableName(const AbstractMetaClass *metaClass); static QString getTypeIndexVariableName(const TypeEntry *type); static QString getTypeIndexVariableName(const AbstractMetaType &type) ; |