aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/generator
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/generator')
-rw-r--r--sources/shiboken6/generator/generator.cpp5
-rw-r--r--sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp29
-rw-r--r--sources/shiboken6/generator/qtdoc/qtdocgenerator.h1
-rw-r--r--sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp54
-rw-r--r--sources/shiboken6/generator/qtdoc/qtxmltosphinxinterface.h9
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp205
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h15
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp22
-rw-r--r--sources/shiboken6/generator/shiboken/headergenerator.cpp7
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp3
10 files changed, 199 insertions, 151 deletions
diff --git a/sources/shiboken6/generator/generator.cpp b/sources/shiboken6/generator/generator.cpp
index b224858c5..a01326530 100644
--- a/sources/shiboken6/generator/generator.cpp
+++ b/sources/shiboken6/generator/generator.cpp
@@ -231,10 +231,9 @@ QString Generator::getFileNameBaseForSmartPointer(const AbstractMetaType &smartP
const AbstractMetaType innerType = smartPointerType.getSmartPointerInnerType();
smartPointerType.typeEntry()->qualifiedCppName();
QString fileName = smartPointerType.typeEntry()->qualifiedCppName().toLower();
- fileName.replace(u"::"_s, u"_"_s);
- fileName.append(u"_"_s);
+ fileName.append(u'_');
fileName.append(innerType.name().toLower());
-
+ fileName.replace(u"::"_s, u"_"_s); // std::shared_ptr<std::string>
return fileName;
}
diff --git a/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
index 2797ff254..1634a7e83 100644
--- a/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
@@ -970,8 +970,10 @@ static QStringList enumListToToc(const AbstractMetaEnumList &enums)
static QChar sortKey(const QString &key)
{
const auto size = key.size();
- if (size >= 2 && (key.at(0) == u'Q' || key.at(0) == u'q') && key.at(1).isUpper())
- return key.at(1); // "QClass" -> 'C', "qSin()" -> 'S'
+ if (size >= 2 && (key.at(0) == u'Q' || key.at(0) == u'q')
+ && (key.at(1).isUpper() || key.at(1).isDigit())) {
+ return key.at(1); // "QClass" -> 'C', "qSin()" -> 'S', 'Q3DSurfaceWidget' -> '3'
+ }
if (size >= 3 && key.startsWith("Q_"_L1))
return key.at(2).toUpper(); // "Q_ARG" -> 'A'
if (size >= 4 && key.startsWith("QT_"_L1))
@@ -1564,3 +1566,26 @@ QtXmlToSphinxLink QtDocGenerator::resolveLink(const QtXmlToSphinxLink &link) con
}
return resolved;
}
+
+QtXmlToSphinxDocGeneratorInterface::Image
+ QtDocGenerator::resolveImage(const QString &href, const QString &context) const
+{
+ QString relativeSourceDir = href;
+ const QString source = m_options.parameters.docDataDir + u'/' + relativeSourceDir;
+ if (!QFileInfo::exists(source))
+ throw Exception(msgCannotFindImage(href, context,source));
+
+ // Determine target directory from context, "Pyside2.QtGui.QPainter" ->"Pyside2/QtGui".
+ // FIXME: Not perfect yet, should have knowledge about namespaces (DataVis3D) or
+ // nested classes "Pyside2.QtGui.QTouchEvent.QTouchPoint".
+ QString relativeTargetDir = context;
+ const auto lastDot = relativeTargetDir.lastIndexOf(u'.');
+ if (lastDot != -1)
+ relativeTargetDir.truncate(lastDot);
+ relativeTargetDir.replace(u'.', u'/');
+ if (!relativeTargetDir.isEmpty())
+ relativeTargetDir += u'/';
+ relativeTargetDir += href;
+
+ return {relativeSourceDir, relativeTargetDir};
+}
diff --git a/sources/shiboken6/generator/qtdoc/qtdocgenerator.h b/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
index 3b1c82e74..56e15e2a1 100644
--- a/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
+++ b/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
@@ -48,6 +48,7 @@ public:
const QString &methodName) const override;
const QLoggingCategory &loggingCategory() const override;
QtXmlToSphinxLink resolveLink(const QtXmlToSphinxLink &) const override;
+ Image resolveImage(const QString &href, const QString &context) const override;
static QString getFuncName(const AbstractMetaFunctionCPtr &cppFunc);
static QString formatArgs(const AbstractMetaFunctionCPtr &func);
diff --git a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
index 55c1d2090..b8fec836c 100644
--- a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
+++ b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
@@ -1240,36 +1240,17 @@ WebXmlTag QtXmlToSphinx::parentTag() const
// Copy images that are placed in a subdirectory "images" under the webxml files
// by qdoc to a matching subdirectory under the "rst/PySide6/<module>" directory
-static bool copyImage(const QString &href, const QString &docDataDir,
- const QString &context, const QString &outputDir,
+static bool copyImage(const QString &docDataDir, const QString &relativeSourceFile,
+ const QString &outputDir, const QString &relativeTargetFile,
const QLoggingCategory &lc, QString *errorMessage)
{
- const QChar slash = u'/';
- const auto lastSlash = href.lastIndexOf(slash);
- const QString imagePath = lastSlash != -1 ? href.left(lastSlash) : QString();
- const QString imageFileName = lastSlash != -1 ? href.right(href.size() - lastSlash - 1) : href;
- QFileInfo imageSource(docDataDir + slash + href);
- if (!imageSource.exists()) {
- QTextStream(errorMessage) << "Image " << href << " does not exist in "
- << QDir::toNativeSeparators(docDataDir);
- return false;
- }
- // Determine directory from context, "Pyside2.QtGui.QPainter" ->"Pyside2/QtGui".
- // FIXME: Not perfect yet, should have knowledge about namespaces (DataVis3D) or
- // nested classes "Pyside2.QtGui.QTouchEvent.QTouchPoint".
- QString relativeTargetDir = context;
- const auto lastDot = relativeTargetDir.lastIndexOf(u'.');
- if (lastDot != -1)
- relativeTargetDir.truncate(lastDot);
- relativeTargetDir.replace(u'.', slash);
- if (!imagePath.isEmpty())
- relativeTargetDir += slash + imagePath;
-
- const QString targetDir = outputDir + slash + relativeTargetDir;
- const QString targetFileName = targetDir + slash + imageFileName;
+ QString targetFileName = outputDir + u'/' + relativeTargetFile;
if (QFileInfo::exists(targetFileName))
return true;
- if (!QFileInfo::exists(targetDir)) {
+
+ QString relativeTargetDir = relativeTargetFile;
+ relativeTargetDir.truncate(qMax(relativeTargetDir.lastIndexOf(u'/'), qsizetype(0)));
+ if (!relativeTargetDir.isEmpty() && !QFileInfo::exists(outputDir + u'/' + relativeTargetDir)) {
const QDir outDir(outputDir);
if (!outDir.mkpath(relativeTargetDir)) {
QTextStream(errorMessage) << "Cannot create " << QDir::toNativeSeparators(relativeTargetDir)
@@ -1278,28 +1259,29 @@ static bool copyImage(const QString &href, const QString &docDataDir,
}
}
- QFile source(imageSource.absoluteFilePath());
+ QFile source(docDataDir + u'/' + relativeSourceFile);
if (!source.copy(targetFileName)) {
QTextStream(errorMessage) << "Cannot copy " << QDir::toNativeSeparators(source.fileName())
<< " to " << QDir::toNativeSeparators(targetFileName) << ": "
<< source.errorString();
return false;
}
- qCDebug(lc).noquote().nospace() << __FUNCTION__ << " href=\""
- << href << "\", context=\"" << context << "\", docDataDir=\""
- << docDataDir << "\", outputDir=\"" << outputDir << "\", copied \""
- << source.fileName() << "\"->\"" << targetFileName << '"';
+
+ qCDebug(lc).noquote().nospace() << __FUNCTION__ << " \"" << relativeSourceFile
+ << "\"->\"" << relativeTargetFile << '"';
return true;
}
bool QtXmlToSphinx::copyImage(const QString &href) const
{
QString errorMessage;
- const bool result =
- ::copyImage(href, m_parameters.docDataDir, m_context,
- m_parameters.outputDirectory,
- m_generator->loggingCategory(),
- &errorMessage);
+ const auto imagePaths = m_generator->resolveImage(href, m_context);
+ const bool result = ::copyImage(m_parameters.docDataDir,
+ imagePaths.source,
+ m_parameters.outputDirectory,
+ imagePaths.target,
+ m_generator->loggingCategory(),
+ &errorMessage);
if (!result)
throw Exception(errorMessage);
return result;
diff --git a/sources/shiboken6/generator/qtdoc/qtxmltosphinxinterface.h b/sources/shiboken6/generator/qtdoc/qtxmltosphinxinterface.h
index 16eefad83..d4a098a12 100644
--- a/sources/shiboken6/generator/qtdoc/qtxmltosphinxinterface.h
+++ b/sources/shiboken6/generator/qtdoc/qtxmltosphinxinterface.h
@@ -53,6 +53,15 @@ public:
virtual QtXmlToSphinxLink resolveLink(const QtXmlToSphinxLink &) const = 0;
+ // Resolve images paths relative to doc data directory/output directory.
+ struct Image
+ {
+ QString source;
+ QString target;
+ };
+
+ virtual Image resolveImage(const QString &href, const QString &context) const = 0;
+
virtual ~QtXmlToSphinxDocGeneratorInterface() = default;
};
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;
}
}