diff options
| -rw-r--r-- | sources/shiboken6/ApiExtractor/typesystem_typedefs.h | 1 | ||||
| -rw-r--r-- | sources/shiboken6/generator/shiboken/cppgenerator.cpp | 84 | ||||
| -rw-r--r-- | sources/shiboken6/generator/shiboken/cppgenerator.h | 1 | ||||
| -rw-r--r-- | sources/shiboken6/libshiboken/basewrapper.cpp | 11 | ||||
| -rw-r--r-- | sources/shiboken6/libshiboken/basewrapper.h | 13 |
5 files changed, 60 insertions, 50 deletions
diff --git a/sources/shiboken6/ApiExtractor/typesystem_typedefs.h b/sources/shiboken6/ApiExtractor/typesystem_typedefs.h index 59bb452a3..5a4e12ff2 100644 --- a/sources/shiboken6/ApiExtractor/typesystem_typedefs.h +++ b/sources/shiboken6/ApiExtractor/typesystem_typedefs.h @@ -68,6 +68,7 @@ using TypedefEntryCPtr = std::shared_ptr<const TypedefEntry>; using TypeSystemTypeEntryCPtr = std::shared_ptr<const TypeSystemTypeEntry>; using ValueTypeEntryCPtr = std::shared_ptr<const ValueTypeEntry>; +using ComplexTypeEntryCList = QList<ComplexTypeEntryCPtr>; using ContainerTypeEntryCList = QList<ContainerTypeEntryCPtr>; using NamespaceTypeEntryList = QList<NamespaceTypeEntryPtr>; using PrimitiveTypeEntryCList = QList<PrimitiveTypeEntryCPtr>; diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index bfde1ff53..037209dfb 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -60,6 +60,8 @@ static const char shibokenErrorsOccurred[] = "Shiboken::Errors::occurred() != nu static constexpr auto virtualMethodStaticReturnVar = "result"_L1; +static constexpr auto sbkObjectTypeF = "SbkObject_TypeF()"_L1; + static QString mangleName(QString name) { if (name == u"None" || name == u"False" || name == u"True" || name == u"from") @@ -4356,7 +4358,6 @@ void CppGenerator::writeClassDefinition(TextStream &s, QString tp_hash; QString tp_call; const QString className = chopType(cpythonTypeName(metaClass)); - QString baseClassName; AbstractMetaFunctionCList ctors; const auto &allCtors = metaClass->queryFunctions(FunctionQueryOption::AnyConstructor); for (const auto &f : allCtors) { @@ -4366,9 +4367,6 @@ void CppGenerator::writeClassDefinition(TextStream &s, } } - if (!metaClass->baseClass()) - baseClassName = u"SbkObject_TypeF()"_s; - bool onlyPrivCtor = !metaClass->hasNonPrivateConstructor(); const bool isQApp = usePySideExtensions() @@ -4702,7 +4700,7 @@ void CppGenerator::writeTpTraverseFunction(TextStream &s, const AbstractMetaClas s << "static int " << baseName << "_traverse(PyObject *self, visitproc visit, void *arg)\n{\n" << indent << "auto traverseProc = " - << pyTypeGetSlot("traverseproc", "SbkObject_TypeF()", "Py_tp_traverse") << ";\n" + << pyTypeGetSlot("traverseproc", sbkObjectTypeF, "Py_tp_traverse") << ";\n" << "return traverseProc(self, visit, arg);\n" << outdent << "}\n"; } @@ -4712,7 +4710,7 @@ void CppGenerator::writeTpClearFunction(TextStream &s, const AbstractMetaClassCP QString baseName = cpythonBaseName(metaClass); s << "static int " << baseName << "_clear(PyObject *self)\n{\n" << indent << "auto clearProc = " - << pyTypeGetSlot("inquiry", "SbkObject_TypeF()", "Py_tp_clear") << ";\n" + << pyTypeGetSlot("inquiry", sbkObjectTypeF, "Py_tp_clear") << ";\n" << "return clearProc(self);\n" << outdent << "}\n"; } @@ -5441,6 +5439,40 @@ QString CppGenerator::destructorClassName(const AbstractMetaClassCPtr &metaClass return metaClass->qualifiedCppName(); } +// Return the base type entries for introduceWrapperType() +static ComplexTypeEntryCList pyBaseTypeEntries(const AbstractMetaClassCPtr &metaClass) +{ + ComplexTypeEntryCList result; + if (metaClass->isNamespace()) { + if (auto extended = metaClass->extendedNamespace()) + result.append(extended->typeEntry()); + return result; + } + + const auto &baseClasses = metaClass->typeSystemBaseClasses(); + for (auto base : baseClasses) { + for (; base != nullptr; base = base->baseClass()) { // Find a type that is not disabled. + const auto ct = base->typeEntry()->codeGeneration(); + if (ct == TypeEntry::GenerateCode || ct == TypeEntry::GenerateForSubclass) + break; + } + result.append(base->typeEntry()); + } + return result; +} + +// Return the base type strings for introduceWrapperType() +QStringList CppGenerator::pyBaseTypes(const AbstractMetaClassCPtr &metaClass) +{ + const auto &baseEntries = pyBaseTypeEntries(metaClass); + QStringList result; + for (const auto &baseEntry : baseEntries) + result.append("reinterpret_cast<PyObject *>("_L1 + cpythonTypeNameExt(baseEntry) + u')'); + if (result.isEmpty()) // no base classes -> SbkObjectType. + result.append(sbkObjectTypeF); + return result; +} + void CppGenerator::writeClassRegister(TextStream &s, const AbstractMetaClassCPtr &metaClass, const GeneratorContext &classContext, @@ -5467,18 +5499,15 @@ void CppGenerator::writeClassRegister(TextStream &s, // Multiple inheritance QString pyTypeBasesVariable = chopType(pyTypeName) + u"_Type_bases"_s; - const auto &baseClasses = metaClass->typeSystemBaseClasses(); - if (metaClass->baseClassNames().size() > 1) { - s << "PyObject *" << pyTypeBasesVariable - << " = PyTuple_Pack(" << baseClasses.size() << ',' << '\n' << indent; - for (qsizetype i = 0, size = baseClasses.size(); i < size; ++i) { - if (i) - s << ",\n"; - s << "reinterpret_cast<PyObject *>(" - << cpythonTypeNameExt(baseClasses.at(i)->typeEntry()) << ')'; - } - s << ");\n\n" << outdent; + const QStringList pyBases = pyBaseTypes(metaClass); + s << "Shiboken::AutoDecRef " << pyTypeBasesVariable << "(PyTuple_Pack(" + << pyBases.size() << ",\n" << indent; + for (qsizetype i = 0, size = pyBases.size(); i < size; ++i) { + if (i) + s << ",\n"; + s << pyBases.at(i); } + s << "));\n\n" << outdent; // Create type and insert it in the module or enclosing class. const QString typePtr = u"_"_s + chopType(pyTypeName) @@ -5513,27 +5542,8 @@ void CppGenerator::writeClassRegister(TextStream &s, s << "&Shiboken::callCppDestructor< " << globalScopePrefix(classContext) << dtorClassName << " >,\n"; - // 6:baseType: Find a type that is not disabled. - auto base = metaClass->isNamespace() - ? metaClass->extendedNamespace() : metaClass->baseClass(); - if (!metaClass->isNamespace()) { - for (; base != nullptr; base = base->baseClass()) { - const auto ct = base->typeEntry()->codeGeneration(); - if (ct == TypeEntry::GenerateCode || ct == TypeEntry::GenerateForSubclass) - break; - } - } - if (base) { - s << cpythonTypeNameExt(base->typeEntry()) << ",\n"; - } else { - s << "nullptr,\n"; - } - // 7:baseTypes - if (metaClass->baseClassNames().size() > 1) - s << pyTypeBasesVariable << ',' << '\n'; - else - s << "nullptr,\n"; + s << pyTypeBasesVariable << ".object()," << '\n'; // 8:wrapperflags QByteArrayList wrapperFlags; diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h index 1b4ebf803..6c20d9d78 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.h +++ b/sources/shiboken6/generator/shiboken/cppgenerator.h @@ -400,6 +400,7 @@ private: const AbstractMetaClassCPtr &metaClass, const GeneratorContext &classContext, const QString &signatures) const; + static QStringList pyBaseTypes(const AbstractMetaClassCPtr &metaClass); static QString destructorClassName(const AbstractMetaClassCPtr &metaClass, const GeneratorContext &classContext); static void writeStaticFieldInitialization(TextStream &s, diff --git a/sources/shiboken6/libshiboken/basewrapper.cpp b/sources/shiboken6/libshiboken/basewrapper.cpp index 35d46b1aa..5c058c482 100644 --- a/sources/shiboken6/libshiboken/basewrapper.cpp +++ b/sources/shiboken6/libshiboken/basewrapper.cpp @@ -970,17 +970,16 @@ introduceWrapperType(PyObject *enclosingObject, const char *originalName, PyType_Spec *typeSpec, ObjectDestructor cppObjDtor, - PyTypeObject *baseType, - PyObject *baseTypes, + PyObject *bases, unsigned wrapperFlags) { - auto *base = baseType ? baseType : SbkObject_TypeF(); - typeSpec->slots[0].pfunc = reinterpret_cast<void *>(base); - auto *bases = baseTypes ? baseTypes : PyTuple_Pack(1, base); + const auto basesSize = PySequence_Fast_GET_SIZE(bases); + assert(basesSize > 0); + typeSpec->slots[0].pfunc = PySequence_Fast_GET_ITEM(bases, 0); auto *type = SbkType_FromSpecBasesMeta(typeSpec, bases, SbkObjectType_TypeF()); - for (int i = 0; i < PySequence_Fast_GET_SIZE(bases); ++i) { + for (Py_ssize_t i = 0; i < basesSize; ++i) { auto *st = reinterpret_cast<PyTypeObject *>(PySequence_Fast_GET_ITEM(bases, i)); BindingManager::instance().addClassInheritance(st, type); } diff --git a/sources/shiboken6/libshiboken/basewrapper.h b/sources/shiboken6/libshiboken/basewrapper.h index f2189d824..4835c4810 100644 --- a/sources/shiboken6/libshiboken/basewrapper.h +++ b/sources/shiboken6/libshiboken/basewrapper.h @@ -229,13 +229,12 @@ enum WrapperFlags * \returns true if the initialization went fine, false otherwise. */ LIBSHIBOKEN_API PyTypeObject *introduceWrapperType(PyObject *enclosingObject, - const char *typeName, - const char *originalName, - PyType_Spec *typeSpec, - ObjectDestructor cppObjDtor, - PyTypeObject *baseType, - PyObject *baseTypes, - unsigned wrapperFlags = 0); + const char *typeName, + const char *originalName, + PyType_Spec *typeSpec, + ObjectDestructor cppObjDtor, + PyObject *bases, + unsigned wrapperFlags = 0); /** * Set the subtype init hook for a type. |
