diff options
Diffstat (limited to 'sources/shiboken6/generator/shiboken')
5 files changed, 142 insertions, 110 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index ad4071c35..97a38a08d 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -59,8 +59,10 @@ using namespace Qt::StringLiterals; static const char shibokenErrorsOccurred[] = "Shiboken::Errors::occurred() != nullptr"; static constexpr auto virtualMethodStaticReturnVar = "result"_L1; +static constexpr auto initFuncPrefix = "init_"_L1; static constexpr auto sbkObjectTypeF = "SbkObject_TypeF()"_L1; +static const char initInheritanceFunction[] = "initInheritance"; static QString mangleName(QString name) { @@ -1336,7 +1338,8 @@ void CppGenerator::writeVirtualMethodPythonOverride(TextStream &s, s << "if (" << PYTHON_RETURN_VAR << ".isNull()) {\n" << indent << "// An error happened in python code!\n" - << "Shiboken::Errors::storeErrorOrPrint();\n" + << "Shiboken::Errors::storePythonOverrideErrorOrPrint(\"" + << func->ownerClass()->name() << "\", funcName);\n" << returnStatement.statement << "\n" << outdent << "}\n"; @@ -1589,6 +1592,33 @@ void CppGenerator::writeEnumConverterFunctions(TextStream &s, const AbstractMeta s << '\n'; } +static void writePointerToPythonConverter(TextStream &c, + const AbstractMetaClassCPtr &metaClass, + const QString &typeName, + const QString &cpythonType) +{ + c << "auto *pyOut = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(cppIn));\n" + << "if (pyOut) {\n" << indent + << "Py_INCREF(pyOut);\nreturn pyOut;\n" << outdent + << "}\n"; + + const QString nameFunc = metaClass->typeEntry()->polymorphicNameFunction(); + if (nameFunc.isEmpty() && !metaClass->hasVirtualDestructor()) { + c << "return Shiboken::Object::newObjectWithHeuristics(" + << cpythonType << ", const_cast<void *>(cppIn), false);\n"; + return; + } + + c << "auto *tCppIn = reinterpret_cast<const " << typeName << R"( *>(cppIn); +const char *typeName = )"; + if (nameFunc.isEmpty()) + c << "typeid(*tCppIn).name();\n"; + else + c << nameFunc << "(tCppIn);\n"; + c << "return Shiboken::Object::newObjectForPointer(" + << cpythonType << ", const_cast<void *>(cppIn), false, typeName);\n"; +} + void CppGenerator::writeConverterFunctions(TextStream &s, const AbstractMetaClassCPtr &metaClass, const GeneratorContext &classContext) const { @@ -1634,30 +1664,7 @@ void CppGenerator::writeConverterFunctions(TextStream &s, const AbstractMetaClas c << "return PySide::getWrapperForQObject(reinterpret_cast<" << typeName << " *>(const_cast<void *>(cppIn)), " << cpythonType << ");\n"; } else { - c << "auto *pyOut = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(cppIn));\n" - << "if (pyOut) {\n" << indent - << "Py_INCREF(pyOut);\nreturn pyOut;\n" << outdent - << "}\n" - << "bool changedTypeName = false;\n" - << "auto *tCppIn = reinterpret_cast<const " << typeName << R"( *>(cppIn); -const char *typeName = )"; - - const QString nameFunc = metaClass->typeEntry()->polymorphicNameFunction(); - if (nameFunc.isEmpty()) - c << "typeid(*tCppIn).name();\n"; - else - c << nameFunc << "(tCppIn);\n"; - c << R"(auto *sbkType = Shiboken::ObjectType::typeForTypeName(typeName); -if (sbkType != nullptr && Shiboken::ObjectType::hasSpecialCastFunction(sbkType)) { - typeName = Shiboken::typeNameOf(typeid(*tCppIn).name()); - changedTypeName = true; -} -)" - << "PyObject *result = Shiboken::Object::newObject(" << cpythonType - << R"(, const_cast<void *>(cppIn), false, /* exactType */ changedTypeName, typeName); -if (changedTypeName) - delete [] typeName; -return result;)"; + writePointerToPythonConverter(c, metaClass, typeName, cpythonType); } std::swap(targetTypeName, sourceTypeName); writeCppToPythonFunction(s, c.toString(), sourceTypeName, targetTypeName); @@ -4260,6 +4267,12 @@ QString CppGenerator::writeContainerConverterInitialization(TextStream &s, return converter; } +QString CppGenerator::typeInitStruct(const TypeEntryCPtr &te) +{ + return cppApiVariableName(te->targetLangPackage()) + u'[' + + getTypeIndexVariableName(te) + u']'; +} + void CppGenerator::writeExtendedConverterInitialization(TextStream &s, const TypeEntryCPtr &externalType, const AbstractMetaClassCList &conversions) @@ -4267,15 +4280,13 @@ void CppGenerator::writeExtendedConverterInitialization(TextStream &s, s << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << ".\n"; for (const auto &sourceClass : conversions) { - const QString converterVar = cppApiVariableName(externalType->targetLangPackage()) + u'[' - + getTypeIndexVariableName(externalType) + u']'; QString sourceTypeName = fixedCppTypeName(sourceClass->typeEntry()); QString targetTypeName = fixedCppTypeName(externalType); QString toCpp = pythonToCppFunctionName(sourceTypeName, targetTypeName); QString isConv = convertibleToCppFunctionName(sourceTypeName, targetTypeName); if (!externalType->isPrimitive()) s << cpythonTypeNameExt(externalType) << ";\n"; - writeAddPythonToCppConversion(s, converterVar, toCpp, isConv); + writeAddPythonToCppConversion(s, typeInitStruct(externalType), toCpp, isConv); } } @@ -5095,6 +5106,17 @@ QList<PyMethodDefEntry> return result; } +QString CppGenerator::pythonSignature(const AbstractMetaType &type) const +{ + if (type.isSmartPointer() && !type.instantiations().isEmpty()) { + const auto ste = std::static_pointer_cast<const SmartPointerTypeEntry>(type.typeEntry()); + const auto instantiationTe = type.instantiations().constFirst().typeEntry(); + if (auto opt = api().findSmartPointerInstantiation(ste, instantiationTe)) + return opt->specialized->typeEntry()->qualifiedTargetLangName(); + } + return type.pythonSignature(); +} + // Format the type signature of a function parameter QString CppGenerator::signatureParameter(const AbstractMetaArgument &arg) const { @@ -5106,17 +5128,22 @@ QString CppGenerator::signatureParameter(const AbstractMetaArgument &arg) const metaType = *viewOn; s << arg.name() << ':'; - QStringList signatures(metaType.pythonSignature()); + QStringList signatures(pythonSignature(metaType)); // Implicit conversions (C++): Check for converting constructors // "QColor(Qt::GlobalColor)" or conversion operators const AbstractMetaFunctionCList conversions = api().implicitConversions(metaType); for (const auto &f : conversions) { - if (f->isConstructor() && !f->arguments().isEmpty()) - signatures << f->arguments().constFirst().type().pythonSignature(); - else if (f->isConversionOperator()) + if (f->isConstructor() && !f->arguments().isEmpty()) { + // PYSIDE-2712: modified types from converting constructors are not always correct + // candidates if they are modified by the type system reference + if (!f->arguments().constFirst().isTypeModified()) { + signatures << pythonSignature(f->arguments().constFirst().type()); + } + } else if (f->isConversionOperator()) { signatures << f->ownerClass()->fullName(); + } } const qsizetype size = signatures.size(); @@ -5173,7 +5200,7 @@ void CppGenerator::writeSignatureInfo(TextStream &s, const OverloadData &overloa QString returnType = f->pyiTypeReplaced(0); // pyi or modified type if (returnType.isEmpty() && !f->isVoid()) - returnType = f->type().pythonSignature(); + returnType = pythonSignature(f->type()); if (!returnType.isEmpty()) s << "->" << returnType; @@ -5473,6 +5500,27 @@ QStringList CppGenerator::pyBaseTypes(const AbstractMetaClassCPtr &metaClass) return result; } +void CppGenerator::writeInitInheritance(TextStream &s) const +{ + s << "static void " << initInheritanceFunction << "()\n{\n" << indent + << "auto &bm = Shiboken::BindingManager::instance();\n" + << sbkUnusedVariableCast("bm"); + for (const auto &cls : api().classes()){ + auto te = cls->typeEntry(); + if (shouldGenerate(te)) { + const auto &baseEntries = pyBaseTypeEntries(cls); + if (!baseEntries.isEmpty()) { + const QString childTypeInitStruct = typeInitStruct(cls->typeEntry()); + for (const auto &baseEntry : baseEntries) { + s << "bm.addClassInheritance(&" << typeInitStruct(baseEntry) << ",\n" + << Pad(' ', 23) << '&' << childTypeInitStruct << ");\n"; + } + } + } + } + s << outdent << "}\n\n"; +} + void CppGenerator::writeClassRegister(TextStream &s, const AbstractMetaClassCPtr &metaClass, const GeneratorContext &classContext, @@ -5571,6 +5619,9 @@ void CppGenerator::writeClassRegister(TextStream &s, writeConverterRegister(s, metaClass, classContext); s << '\n'; + if (classContext.forSmartPointer()) + writeSmartPointerConverterInitialization(s, classContext.preciseType()); + // class inject-code target/beginning if (!classTypeEntry->codeSnips().isEmpty()) { writeClassCodeSnips(s, classTypeEntry->codeSnips(), @@ -5804,7 +5855,7 @@ void CppGenerator::writeTypeDiscoveryFunction(TextStream &s, } else if (metaClass->isPolymorphic()) { const auto &ancestors = metaClass->allTypeSystemAncestors(); for (const auto &ancestor : ancestors) { - if (ancestor->baseClass()) + if (ancestor->baseClass() && !ancestor->typeEntry()->isPolymorphicBase()) continue; if (ancestor->isPolymorphic()) { s << "if (instanceType == Shiboken::SbkType< " << m_gsp @@ -6006,16 +6057,20 @@ void CppGenerator::writeNbBoolFunction(const GeneratorContext &context, // Write declaration and invocation of the init function for the module init // function. -void CppGenerator::writeInitFunc(TextStream &declStr, TextStream &callStr, - const QString &initFunctionName, - const TypeEntryCPtr &enclosingEntry, - const QString &pythonName, bool lazy) +static void writeInitFuncDecl(TextStream &declStr, + const QString &functionName) { - const QString functionName = "init_"_L1 + initFunctionName; - const bool hasParent = enclosingEntry && enclosingEntry->type() != TypeEntry::TypeSystemType; - declStr << "PyTypeObject *" << functionName << "(PyObject *" - << (hasParent ? "enclosingClass" : "module") << ");\n"; + declStr << "PyTypeObject *" << functionName << "(PyObject *enclosing);\n"; +} +// Write declaration and invocation of the init function for the module init +// function. +void CppGenerator::writeInitFuncCall(TextStream &callStr, + const QString &functionName, + const TypeEntryCPtr &enclosingEntry, + const QString &pythonName, bool lazy) +{ + const bool hasParent = enclosingEntry && enclosingEntry->type() != TypeEntry::TypeSystemType; if (!lazy) { const QString enclosing = hasParent ? "reinterpret_cast<PyObject *>("_L1 + cpythonTypeNameExt(enclosingEntry) + u')' @@ -6024,18 +6079,14 @@ void CppGenerator::writeInitFunc(TextStream &declStr, TextStream &callStr, } else if (hasParent) { const QString &enclosingName = enclosingEntry->name(); const auto parts = QStringView{enclosingName}.split(u"::", Qt::SkipEmptyParts); + const QString namePathPrefix = enclosingEntry->name().replace("::"_L1, "."_L1); callStr << "Shiboken::Module::AddTypeCreationFunction(" - << "module, \"" << pythonName << "\", " << functionName << ", \""; - for (qsizetype i = 0; i < parts.size(); ++i) { - if (i > 0) - callStr << "\", \""; - callStr << parts.at(i); - } - callStr << "\");\n"; + << "module, \"" << parts[0] << "\", " + << functionName << ", \"" << namePathPrefix << '.' << pythonName << "\");\n"; } else { callStr << "Shiboken::Module::AddTypeCreationFunction(" << "module, \"" << pythonName << "\", " - << "init_" << initFunctionName << ");\n"; + << functionName << ");\n"; } } @@ -6092,9 +6143,10 @@ bool CppGenerator::finishGeneration() s_classInitDecl << te->configCondition() << '\n'; s_classPythonDefines << te->configCondition() << '\n'; } - writeInitFunc(s_classInitDecl, s_classPythonDefines, - getSimpleClassInitFunctionName(cls), - targetLangEnclosingEntry(te), cls->name()); + const QString initFunc = initFuncPrefix + getSimpleClassInitFunctionName(cls); + writeInitFuncDecl(s_classInitDecl, initFunc); + writeInitFuncCall(s_classPythonDefines, initFunc, + targetLangEnclosingEntry(te), cls->name()); if (cls->hasStaticFields()) { s_classInitDecl << "PyTypeObject *" << getSimpleClassStaticFieldsInitFunctionName(cls) << "(PyObject *module);\n"; @@ -6111,13 +6163,12 @@ bool CppGenerator::finishGeneration() for (const auto &smp : api().instantiatedSmartPointers()) { GeneratorContext context = contextForSmartPointer(smp.specialized, smp.type); const auto enclosingClass = context.metaClass()->enclosingClass(); - auto enclosingTypeEntry = enclosingClass - ? enclosingClass->typeEntry() - : targetLangEnclosingEntry(smp.type.typeEntry()); + auto enclosingTypeEntry = targetLangEnclosingEntry(smp.specialized->typeEntry()); - writeInitFunc(s_classInitDecl, s_classPythonDefines, - getInitFunctionName(context), - enclosingTypeEntry, smp.type.name()); + const QString initFunc = initFuncPrefix + getInitFunctionName(context); + writeInitFuncDecl(s_classInitDecl, initFunc); + writeInitFuncCall(s_classPythonDefines, + initFunc, enclosingTypeEntry, smp.specialized->name()); includes.insert(smp.type.instantiations().constFirst().typeEntry()->include()); } @@ -6311,18 +6362,6 @@ bool CppGenerator::finishGeneration() s << '\n'; } - // Implicit smart pointers conversions - const auto &smartPointersList = api().instantiatedSmartPointers(); - if (!smartPointersList.isEmpty()) { - s << "// SmartPointers converters.\n\n"; - for (const auto &smp : smartPointersList) { - s << "// C++ to Python conversion for smart pointer type '" - << smp.type.cppSignature() << "'.\n"; - writeSmartPointerConverterFunctions(s, smp.type); - } - s << '\n'; - } - s << "static struct PyModuleDef moduledef = {\n" << " /* m_base */ PyModuleDef_HEAD_INIT,\n" << " /* m_name */ \"" << moduleName() << "\",\n" @@ -6337,6 +6376,8 @@ bool CppGenerator::finishGeneration() // PYSIDE-510: Create a signatures string for the introspection feature. writeSignatureStrings(s, signatureStream.toString(), moduleName(), "global functions"); + writeInitInheritance(s); + // Write module init function const QString globalModuleVar = pythonModuleObjectName(); s << "extern \"C\" LIBSHIBOKEN_EXPORT PyObject *PyInit_" @@ -6379,9 +6420,14 @@ bool CppGenerator::finishGeneration() s << "{nullptr, nullptr}\n" << outdent << "};\n" << "// The new global structure consisting of (type, name) pairs.\n" - << cppApiVariableName() << " = cppApi;\n" - << "// The backward compatible alias with upper case indexes.\n" - << cppApiVariableNameOld() << " = reinterpret_cast<PyTypeObject **>(cppApi);\n\n"; + << cppApiVariableName() << " = cppApi;\n"; + if (usePySideExtensions()) + s << "QT_WARNING_PUSH\nQT_WARNING_DISABLE_DEPRECATED\n"; + s << "// The backward compatible alias with upper case indexes.\n" + << cppApiVariableNameOld() << " = reinterpret_cast<PyTypeObject **>(cppApi);\n"; + if (usePySideExtensions()) + s << "QT_WARNING_POP\n"; + s << '\n'; } s << "// Create an array of primitive type converters for the current module.\n" @@ -6430,14 +6476,6 @@ bool CppGenerator::finishGeneration() s << '\n'; } - if (!smartPointersList.isEmpty()) { - s << '\n'; - for (const auto &smp : smartPointersList) { - writeSmartPointerConverterInitialization(s, smp.type); - s << '\n'; - } - } - if (!extendedConverters.isEmpty()) { s << '\n'; for (ExtendedConverterData::const_iterator it = extendedConverters.cbegin(), end = extendedConverters.cend(); it != end; ++it) { @@ -6474,7 +6512,8 @@ bool CppGenerator::finishGeneration() } } - s << "\nif (" << shibokenErrorsOccurred << ") {\n" << indent + s << '\n' << initInheritanceFunction << "();\n" + << "\nif (" << shibokenErrorsOccurred << ") {\n" << indent << "PyErr_Print();\n" << "Py_FatalError(\"can't initialize module " << moduleName() << "\");\n" << outdent << "}\n"; diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h index 1ad576895..5920c9a3a 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.h +++ b/sources/shiboken6/generator/shiboken/cppgenerator.h @@ -60,10 +60,10 @@ private: void generateIncludes(TextStream &s, const GeneratorContext &classContext, const IncludeGroupList &includes = {}, const AbstractMetaClassCList &innerClasses = {}) const; - static void writeInitFunc(TextStream &declStr, TextStream &callStr, - const QString &initFunctionName, - const TypeEntryCPtr &enclosingEntry, - const QString &pythonName, bool lazy = true); + static void writeInitFuncCall(TextStream &callStr, + const QString &functionName, + const TypeEntryCPtr &enclosingEntry, + const QString &pythonName, bool lazy = true); static void writeCacheResetNative(TextStream &s, const GeneratorContext &classContext); void writeConstructorNative(TextStream &s, const GeneratorContext &classContext, const AbstractMetaFunctionCPtr &func) const; @@ -395,6 +395,7 @@ private: static void writeSignatureStrings(TextStream &s, const QString &signatures, const QString &arrayName, const char *comment); + void writeInitInheritance(TextStream &s) const; void writeClassRegister(TextStream &s, const AbstractMetaClassCPtr &metaClass, const GeneratorContext &classContext, @@ -412,6 +413,7 @@ private: void writeSignatureInfo(TextStream &s, const OverloadData &overloads) const; QString signatureParameter(const AbstractMetaArgument &arg) const; + QString pythonSignature(const AbstractMetaType &type) const; /// Writes the implementation of all methods part of python sequence protocol void writeSequenceMethods(TextStream &s, const AbstractMetaClassCPtr &metaClass, @@ -480,6 +482,8 @@ private: const AbstractMetaType &type, const ApiExtractorResult &api); void writeSmartPointerConverterInitialization(TextStream &s, const AbstractMetaType &ype) const; + + static QString typeInitStruct(const TypeEntryCPtr &te); static void writeExtendedConverterInitialization(TextStream &s, const TypeEntryCPtr &externalType, const AbstractMetaClassCList &conversions); @@ -547,9 +551,6 @@ private: static bool hasBoolCast(const AbstractMetaClassCPtr &metaClass) { return boolCast(metaClass).has_value(); } - std::optional<AbstractMetaType> - findSmartPointerInstantiation(const SmartPointerTypeEntryCPtr &pointer, - const TypeEntryCPtr &pointee) const; void clearTpFuncs(); static QString chopType(QString s); diff --git a/sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp b/sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp index 1b893640a..44b76f181 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp @@ -86,18 +86,6 @@ static ComparisonOperatorList smartPointeeComparisons(const GeneratorContext &co return result; } -std::optional<AbstractMetaType> - CppGenerator::findSmartPointerInstantiation(const SmartPointerTypeEntryCPtr &pointer, - const TypeEntryCPtr &pointee) const -{ - for (const auto &smp : api().instantiatedSmartPointers()) { - const auto &i = smp.type; - if (i.typeEntry() == pointer && i.instantiations().at(0).typeEntry() == pointee) - return i; - } - return {}; -} - static bool hasParameterPredicate(const AbstractMetaFunctionCPtr &f) { return !f->arguments().isEmpty(); @@ -225,6 +213,8 @@ void CppGenerator::generateSmartPointerClass(TextStream &s, const GeneratorConte s << '\n'; writeConverterFunctions(s, metaClass, classContext); + // Implicit smart pointers conversions + writeSmartPointerConverterFunctions(s, classContext.preciseType()); writeClassRegister(s, metaClass, classContext, signatureStream); // class inject-code native/end @@ -252,8 +242,8 @@ void CppGenerator::writeSmartPointerConverterFunctions(TextStream &s, for (const auto &base : baseClasses) { auto baseTe = base->typeEntry(); if (smartPointerTypeEntry->matchesInstantiation(baseTe)) { - if (auto opt = findSmartPointerInstantiation(smartPointerTypeEntry, baseTe)) { - const auto smartTargetType = opt.value(); + if (auto opt = api().findSmartPointerInstantiation(smartPointerTypeEntry, baseTe)) { + const auto &smartTargetType = opt.value().type; s << "// SmartPointer derived class: " << smartTargetType.cppSignature() << "\n"; writePythonToCppConversionFunctions(s, smartPointerType, @@ -308,8 +298,8 @@ void CppGenerator::writeSmartPointerConverterInitialization(TextStream &s, for (const auto &base : classes) { auto baseTe = base->typeEntry(); - if (auto opt = findSmartPointerInstantiation(smartPointerTypeEntry, baseTe)) { - const auto smartTargetType = opt.value(); + if (auto opt = api().findSmartPointerInstantiation(smartPointerTypeEntry, baseTe)) { + const auto &smartTargetType = opt.value().type; s << "// Convert to SmartPointer derived class: [" << smartTargetType.cppSignature() << "]\n"; const QString converter = u"Shiboken::Conversions::getConverter(\""_s diff --git a/sources/shiboken6/generator/shiboken/headergenerator.cpp b/sources/shiboken6/generator/shiboken/headergenerator.cpp index 1f574b47c..7cec9c38e 100644 --- a/sources/shiboken6/generator/shiboken/headergenerator.cpp +++ b/sources/shiboken6/generator/shiboken/headergenerator.cpp @@ -198,9 +198,6 @@ void HeaderGenerator::writeWrapperClassDeclaration(TextStream &s, const auto typeEntry = metaClass->typeEntry(); InheritedOverloadSet inheritedOverloads; - // write license comment - s << licenseComment(); - // Class s << "class " << wrapperName << " : public " << metaClass->qualifiedCppName() @@ -706,8 +703,12 @@ bool HeaderGenerator::finishGeneration() macrosStream << ti; macrosStream << "};\n\n"; + // FIXME: Remove backwards compatible variable in PySide 7. macrosStream << "// This variable stores all Python types exported by this module.\n"; macrosStream << "extern Shiboken::Module::TypeInitStruct *" << cppApiVariableName() << ";\n\n"; + macrosStream << "// This variable stores all Python types exported by this module "; + macrosStream << "in a backwards compatible way with identical indexing.\n"; + macrosStream << "[[deprecated]] extern PyTypeObject **" << cppApiVariableNameOld() << ";\n\n"; macrosStream << "// This variable stores the Python module object exported by this module.\n"; macrosStream << "extern PyObject *" << pythonModuleObjectName() << ";\n\n"; macrosStream << "// This variable stores all type converters exported by this module.\n"; diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp index a1417e5d9..67fd9c994 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp @@ -2555,7 +2555,8 @@ void ShibokenGenerator::collectFullTypeNamesArray(QStringList &typeNames) int smartPointerCountIndex = getMaxTypeIndex(); for (const auto &smp : api().instantiatedSmartPointers()) { auto entry = smp.type.typeEntry(); - typeNames[smartPointerCountIndex] = entry->qualifiedTargetLangName(); + typeNames[smartPointerCountIndex] = + smp.specialized->typeEntry()->qualifiedTargetLangName(); ++smartPointerCountIndex; } } |