diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-04-10 15:46:48 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-04-23 10:35:30 +0200 |
commit | 9f09e1dda0f167432110a22db6f9a5accf800734 (patch) | |
tree | 6ad5495799775fa1a8ac389f9c7073511c05e825 /sources/shiboken6/generator | |
parent | 0e107b7ec39efe4f03b0c2ed586e2e04cdfea0fe (diff) |
Lazy Load: Fix polymorphic classes by identifying lazy groups
Classes with a polymorphicIdValue have an expression which
may reference a related class. We use that to identify
a lazy group, which has to be initialized at once.
This is now completely solved.
Pick-to: 6.7
Fixes: PYSIDE-2675
Change-Id: I957a1b2b95d37b96cc2e98082fc7f92e601322cb
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'sources/shiboken6/generator')
-rw-r--r-- | sources/shiboken6/generator/shiboken/cppgenerator.cpp | 66 | ||||
-rw-r--r-- | sources/shiboken6/generator/shiboken/cppgenerator.h | 3 |
2 files changed, 53 insertions, 16 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index 059ab7be3..bfde1ff53 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -5759,6 +5759,18 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(TextStream &s, const Generato } } +// Note: This is an incomplete function that does not work without a +// surrounding functionality. It's purpose is to make sure that exactly +// this expression always is used, although the first clause is never true in PySide. +// Without it can create false positives. +static AbstractMetaClassCPtr getPolymorphicBaseClass(const AbstractMetaClassCPtr &metaClass) +{ + auto baseClass = metaClass; + while (!baseClass->typeEntry()->isPolymorphicBase() && baseClass->baseClass()) + baseClass = baseClass->baseClass(); + return baseClass; +} + void CppGenerator::replacePolymorphicIdPlaceHolders(const AbstractMetaClassCPtr &metaClass, QString *id) { @@ -5768,9 +5780,7 @@ void CppGenerator::replacePolymorphicIdPlaceHolders(const AbstractMetaClassCPtr id->replace("%1"_L1, replacement); } if (id->contains("%B"_L1)) { - auto baseClass = metaClass; - while (!baseClass->typeEntry()->isPolymorphicBase() && baseClass->baseClass()) - baseClass = baseClass->baseClass(); + auto baseClass = getPolymorphicBaseClass(metaClass); QString replacement = " reinterpret_cast< "_L1 + m_gsp + baseClass->qualifiedCppName() + " *>(cptr)"_L1; id->replace("%B"_L1, replacement); @@ -5999,19 +6009,15 @@ void CppGenerator::writeNbBoolFunction(const GeneratorContext &context, void CppGenerator::writeInitFunc(TextStream &declStr, TextStream &callStr, const QString &initFunctionName, const TypeEntryCPtr &enclosingEntry, - const QString &pythonName, bool lazy) + const QString &pythonName, + const QString &lazyGroup) { + const QString functionName = "init_"_L1 + initFunctionName; const bool hasParent = enclosingEntry && enclosingEntry->type() != TypeEntry::TypeSystemType; declStr << "PyTypeObject *" << functionName << "(PyObject *" << (hasParent ? "enclosingClass" : "module") << ");\n"; - - if (!lazy) { - const QString enclosing = hasParent - ? "reinterpret_cast<PyObject *>("_L1 + cpythonTypeNameExt(enclosingEntry) + u')' - : "module"_L1; - callStr << functionName << '(' << enclosing << ");\n"; - } else if (hasParent) { + if (hasParent) { const QString &enclosingName = enclosingEntry->name(); const auto parts = QStringView{enclosingName}.split(u"::", Qt::SkipEmptyParts); callStr << "Shiboken::Module::AddTypeCreationFunction(" @@ -6023,9 +6029,13 @@ void CppGenerator::writeInitFunc(TextStream &declStr, TextStream &callStr, } callStr << "\");\n"; } else { - callStr << "Shiboken::Module::AddTypeCreationFunction(" - << "module, \"" << pythonName << "\", " - << "init_" << initFunctionName << ");\n"; + const char *funcName = lazyGroup.isEmpty() + ? "AddTypeCreationFunction" : "AddGroupedTypeCreationFunction"; + callStr << "Shiboken::Module::" << funcName << "(module, \"" + << pythonName << "\", " << functionName; + if (!lazyGroup.isEmpty()) + callStr << ", \"" << lazyGroup << "\""; + callStr << ");\n"; } } @@ -6042,6 +6052,12 @@ static void writeSubModuleHandling(TextStream &s, const QString &moduleName, << indent << "return nullptr;\n" << outdent << outdent << "}\n"; } +static AbstractMetaClassCPtr getLazyGroupBaseClass(const AbstractMetaClassCPtr &metaClass) +{ + return needsTypeDiscoveryFunction(metaClass) && !isQObject(metaClass) + ? getPolymorphicBaseClass(metaClass) : nullptr; +} + bool CppGenerator::finishGeneration() { //Generate CPython wrapper file @@ -6073,6 +6089,18 @@ bool CppGenerator::finishGeneration() s_globalFunctionDef << methodDefinitionEntries(overloadData); } + // Collect the lazy group base classes first, because we need to add + // these base classes into the group, too. + std::set<AbstractMetaClassCPtr> lazyGroupBaseClasses{}; + for (const auto &cls : api().classes()){ + auto te = cls->typeEntry(); + if (shouldGenerate(te)) { + auto lazyGroupCls = getLazyGroupBaseClass(cls); + if (lazyGroupCls) + lazyGroupBaseClasses.insert(lazyGroupCls); + } + } + AbstractMetaClassCList classesWithStaticFields; for (const auto &cls : api().classes()){ auto te = cls->typeEntry(); @@ -6082,9 +6110,17 @@ bool CppGenerator::finishGeneration() s_classInitDecl << te->configCondition() << '\n'; s_classPythonDefines << te->configCondition() << '\n'; } + auto lazyGroupCls = getLazyGroupBaseClass(cls); + if (!lazyGroupCls) { + auto it = lazyGroupBaseClasses.find(cls); + if (it != lazyGroupBaseClasses.end()) + lazyGroupCls = cls; + } writeInitFunc(s_classInitDecl, s_classPythonDefines, getSimpleClassInitFunctionName(cls), - targetLangEnclosingEntry(te), cls->name()); + targetLangEnclosingEntry(te), cls->name(), + lazyGroupCls ? lazyGroupCls->typeEntry()->qualifiedTargetLangName() + : QString()); if (cls->hasStaticFields()) { s_classInitDecl << "PyTypeObject *" << getSimpleClassStaticFieldsInitFunctionName(cls) << "(PyObject *module);\n"; diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h index 00ae31f9a..1b4ebf803 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.h +++ b/sources/shiboken6/generator/shiboken/cppgenerator.h @@ -63,7 +63,8 @@ private: static void writeInitFunc(TextStream &declStr, TextStream &callStr, const QString &initFunctionName, const TypeEntryCPtr &enclosingEntry, - const QString &pythonName, bool lazy = true); + const QString &pythonName, + const QString &lazyGroup = {}); static void writeCacheResetNative(TextStream &s, const GeneratorContext &classContext); void writeConstructorNative(TextStream &s, const GeneratorContext &classContext, const AbstractMetaFunctionCPtr &func) const; |