aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/generator/shiboken2
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-10-22 07:34:36 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-10-22 07:34:36 +0200
commit9614cb5e47e863f036f19ac3f818253dd69bb828 (patch)
tree937a348b7beebbf3f0427cac4f79e5ac63e8764f /sources/shiboken2/generator/shiboken2
parent55fd16d92a36558335e7d7cd7cdb57ead43d55db (diff)
parent24cd62c9d18850707574ba7eb637ff24bee353a1 (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Diffstat (limited to 'sources/shiboken2/generator/shiboken2')
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp97
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.h5
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp2
3 files changed, 100 insertions, 4 deletions
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 11a6c193e..ee57c9e2c 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -255,6 +255,15 @@ const AbstractMetaFunction *CppGenerator::boolCast(const AbstractMetaClass *meta
&& func->arguments().isEmpty() ? func : nullptr;
}
+const AbstractMetaType *CppGenerator::findSmartPointerInstantiation(const TypeEntry *entry) const
+{
+ for (auto i : instantiatedSmartPointers()) {
+ if (i->instantiations().at(0)->typeEntry() == entry)
+ return i;
+ }
+ return nullptr;
+}
+
using FunctionGroupMap = QMap<QString, AbstractMetaFunctionList>;
// Prevent ELF symbol qt_version_tag from being generated into the source
@@ -1640,6 +1649,7 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas
}
};
+
if (!classContext.forSmartPointer()) {
writeConversionsForType(metaClass->qualifiedCppName());
} else {
@@ -1650,7 +1660,7 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas
Qt::SkipEmptyParts);
while (!lst.isEmpty()) {
QString signature = lst.join(QLatin1String("::"));
- writeConversions(QStringLiteral("%1<%2>").arg(smartPointerName, signature));
+ writeConversions(QStringLiteral("%1<%2 >").arg(smartPointerName, signature));
lst.removeFirst();
}
@@ -1742,6 +1752,30 @@ void CppGenerator::writeContainerConverterFunctions(QTextStream &s, const Abstra
writePythonToCppConversionFunctions(s, containerType);
}
+void CppGenerator::writeSmartPointerConverterFunctions(QTextStream &s, const AbstractMetaType *smartPointerType)
+{
+ const AbstractMetaClass *targetClass = AbstractMetaClass::findClass(classes(), smartPointerType->instantiations().at(0)->typeEntry());
+
+ if (targetClass) {
+ const auto *smartPointerTypeEntry =
+ static_cast<const SmartPointerTypeEntry *>(
+ smartPointerType->typeEntry());
+
+ // TODO: Missing conversion to smart pointer pointer type:
+
+ s << "// Register smartpointer conversion for all derived classes\n";
+ const auto classes = getBaseClasses(targetClass);
+ for (auto k : classes) {
+ if (smartPointerTypeEntry->matchesInstantiation(k->typeEntry())) {
+ if (auto smartTargetType = findSmartPointerInstantiation(k->typeEntry())) {
+ s << INDENT << "// SmartPointer derived class: " << smartTargetType->cppSignature() << "\n";
+ writePythonToCppConversionFunctions(s, smartPointerType, smartTargetType, {}, {}, {});
+ }
+ }
+ }
+ }
+}
+
void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &overloadData,
const GeneratorContext &context)
{
@@ -3063,10 +3097,10 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s,
QTextStream c(&code);
Indentor nested;
if (conversion.isEmpty())
- conversion = QLatin1Char('*') + cpythonWrapperCPtr(sourceType->typeEntry(), QLatin1String("pyIn"));
+ conversion = QLatin1Char('*') + cpythonWrapperCPtr(sourceType, QLatin1String("pyIn"));
if (!preConversion.isEmpty())
c << nested << preConversion << Qt::endl;
- const QString fullTypeName = getFullTypeName(targetType->typeEntry());
+ const QString fullTypeName = targetType->isSmartPointer() ? targetType->cppSignature() : getFullTypeName(targetType->typeEntry());
c << nested << "*reinterpret_cast<" << fullTypeName << " *>(cppOut) = "
<< fullTypeName << '(' << conversion << ");";
QString sourceTypeName = fixedCppTypeName(sourceType);
@@ -3934,6 +3968,44 @@ void CppGenerator::writeContainerConverterInitialization(QTextStream &s, const A
writeAddPythonToCppConversion(s, converterObject(type), toCpp, isConv);
}
+void CppGenerator::writeSmartPointerConverterInitialization(QTextStream &s, const AbstractMetaType *type)
+{
+ const QByteArray cppSignature = type->cppSignature().toUtf8();
+ auto writeConversionRegister = [this, &s](const AbstractMetaType *sourceType, const QString &targetTypeName, const QString &targetConverter)
+ {
+ const QString sourceTypeName = fixedCppTypeName(sourceType);
+ const QString toCpp = pythonToCppFunctionName(sourceTypeName, targetTypeName);
+ const QString isConv = convertibleToCppFunctionName(sourceTypeName, targetTypeName);
+
+ writeAddPythonToCppConversion(s, targetConverter, toCpp, isConv);
+ };
+
+ auto klass = AbstractMetaClass::findClass(classes(), type->instantiations().at(0)->typeEntry());
+ if (!klass)
+ return;
+
+ const auto classes = getBaseClasses(klass);
+ if (classes.isEmpty())
+ return;
+
+ s << INDENT << "// Register SmartPointer converter for type '" << cppSignature << "'." << Qt::endl;
+ s << INDENT << "///////////////////////////////////////////////////////////////////////////////////////"<< Qt::endl;
+ s << Qt::endl;
+
+ for (auto k : classes) {
+ if (auto smartTargetType = findSmartPointerInstantiation(k->typeEntry()))
+ {
+ s << INDENT << "// Convert to SmartPointer derived class: [" << smartTargetType->cppSignature() << "]" << Qt::endl;
+ const QString converter = QLatin1String("Shiboken::Conversions::getConverter(\"%1\")").arg(smartTargetType->cppSignature());
+ writeConversionRegister(type, fixedCppTypeName(smartTargetType), converter);
+ } else {
+ s << INDENT << "// Class not found:" << type->instantiations().at(0)->cppSignature();
+ }
+ }
+
+ s << INDENT << "///////////////////////////////////////////////////////////////////////////////////////"<< Qt::endl << Qt::endl;
+}
+
void CppGenerator::writeExtendedConverterInitialization(QTextStream &s, const TypeEntry *externalType,
const QVector<const AbstractMetaClass *>& conversions)
{
@@ -5979,6 +6051,17 @@ bool CppGenerator::finishGeneration()
s << Qt::endl;
}
+ // Implicit smart pointers conversions
+ const auto smartPointersList = instantiatedSmartPointers();
+ if (!smartPointersList.isEmpty()) {
+ s << "// SmartPointers converters.\n\n";
+ for (const AbstractMetaType *smartPointer : smartPointersList) {
+ s << "// C++ to Python conversion for type '" << smartPointer->cppSignature() << "'.\n";
+ writeSmartPointerConverterFunctions(s, smartPointer);
+ }
+ s << Qt::endl;
+ }
+
s << "static struct PyModuleDef moduledef = {\n";
s << " /* m_base */ PyModuleDef_HEAD_INIT,\n";
s << " /* m_name */ \"" << moduleName() << "\",\n";
@@ -6052,6 +6135,14 @@ bool CppGenerator::finishGeneration()
}
}
+ if (!smartPointersList.isEmpty()) {
+ s << Qt::endl;
+ for (const AbstractMetaType *smartPointer : smartPointersList) {
+ writeSmartPointerConverterInitialization(s, smartPointer);
+ s << Qt::endl;
+ }
+ }
+
if (!extendedConverters.isEmpty()) {
s << Qt::endl;
for (ExtendedConverterData::const_iterator it = extendedConverters.cbegin(), end = extendedConverters.cend(); it != end; ++it) {
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h
index 1d7894734..41bd17f21 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.h
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h
@@ -81,6 +81,8 @@ private:
void writeContainerConverterFunctions(QTextStream &s, const AbstractMetaType *containerType);
+ void writeSmartPointerConverterFunctions(QTextStream &s, const AbstractMetaType *smartPointerType);
+
void writeMethodWrapperPreamble(QTextStream &s, OverloadData &overloadData,
const GeneratorContext &context);
void writeConstructorWrapper(QTextStream &s, const AbstractMetaFunctionList &overloads,
@@ -332,6 +334,7 @@ private:
void writeEnumConverterInitialization(QTextStream &s, const TypeEntry *enumType);
void writeEnumConverterInitialization(QTextStream &s, const AbstractMetaEnum *metaEnum);
void writeContainerConverterInitialization(QTextStream &s, const AbstractMetaType *type);
+ void writeSmartPointerConverterInitialization(QTextStream &s, const AbstractMetaType *type);
void writeExtendedConverterInitialization(QTextStream &s, const TypeEntry *externalType, const QVector<const AbstractMetaClass *>& conversions);
void writeParentChildManagement(QTextStream &s, const AbstractMetaFunction *func, bool userHeuristicForReturn);
@@ -375,6 +378,8 @@ private:
bool hasBoolCast(const AbstractMetaClass *metaClass) const
{ return boolCast(metaClass) != nullptr; }
+ const AbstractMetaType *findSmartPointerInstantiation(const TypeEntry *entry) const;
+
// Number protocol structure members names.
static QHash<QString, QString> m_nbFuncs;
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 97aecf529..9ca5145a1 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -860,7 +860,7 @@ QString ShibokenGenerator::converterObject(const AbstractMetaType *type)
+ QLatin1String(">(") + QString::number(nestedArrayTypes.size())
+ QLatin1Char(')');
}
- if (type->typeEntry()->isContainer()) {
+ if (type->typeEntry()->isContainer() || type->typeEntry()->isSmartPointer()) {
return convertersVariableName(type->typeEntry()->targetLangPackage())
+ QLatin1Char('[') + getTypeIndexVariableName(type) + QLatin1Char(']');
}