diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-10-19 16:54:01 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-10-21 13:03:07 +0200 |
commit | c0beb9f29f36ea3bc8be26675a05253cc5584fe4 (patch) | |
tree | 38e2c5b7e3d1167a701061c82940fc5f80a3ab38 /sources/shiboken6/generator/shiboken/cppgenerator.cpp | |
parent | be8980798ad04a5c8a6cd32962349734ac6d223c (diff) |
shiboken6: Implement opaque containers for getters (non-const)
Extract helpers from the opaque containers generation for fields
and use them for function returns if the type is modified accordingly.
[ChangeLog][shiboken6] Getters returning containers by reference can
now be modified to return an opaque container by modifying the return
type accordingly.
Pick-to: 6.2
Task-number: PYSIDE-1605
Change-Id: Ieaf5eb92d248d3a23e511222e5f61823e85540c0
Reviewed-by: Christian Tismer <tismer@stackless.com>
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/shiboken6/generator/shiboken/cppgenerator.cpp')
-rw-r--r-- | sources/shiboken6/generator/shiboken/cppgenerator.cpp | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index b7d826d3d..a6abeb077 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -190,6 +190,26 @@ const ProtocolEntries &sequenceProtocols() return result; } +// Return name of function to create PyObject wrapping a container +static QString opaqueContainerCreationFunc(const AbstractMetaType &type) +{ + const auto *containerTypeEntry = + static_cast<const ContainerTypeEntry *>(type.typeEntry()); + const auto *instantiationTypeEntry = + type.instantiations().constFirst().typeEntry(); + return u"create"_qs + + containerTypeEntry->opaqueContainerName(instantiationTypeEntry->name()); +} + +// Write declaration of the function to create PyObject wrapping a container +static void writeOpaqueContainerCreationFuncDecl(TextStream &s, const QString &name, + AbstractMetaType type) +{ + type.setReferenceType(NoReference); + type.setConstant(false); + s << "PyObject *" << name << '(' << type.cppSignature() << "*);\n"; +} + CppGenerator::CppGenerator() = default; QString CppGenerator::fileNameSuffix() const @@ -3796,17 +3816,23 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr } // Convert result + const auto funcType = func->type(); if (!func->conversionRule(TypeSystem::TargetLangCode, 0).isEmpty()) { writeConversionRule(s, func, TypeSystem::TargetLangCode, QLatin1String(PYTHON_RETURN_VAR)); } else if (!isCtor && !func->isInplaceOperator() && !func->isVoid() && !func->injectedCodeHasReturnValueAttribution(TypeSystem::TargetLangCode)) { - s << PYTHON_RETURN_VAR << " = "; if (func->type().isObjectTypeUsedAsValueType()) { - s << "Shiboken::Object::newObject(" + s << PYTHON_RETURN_VAR << " = Shiboken::Object::newObject(" << cpythonTypeNameExt(func->type().typeEntry()) << ", " << CPP_RETURN_VAR << ", true, true)"; + } else if (func->generateOpaqueContainerReturn()) { + const QString creationFunc = opaqueContainerCreationFunc(funcType); + writeOpaqueContainerCreationFuncDecl(s, creationFunc, funcType); + s << PYTHON_RETURN_VAR << " = " << creationFunc + << "(&" << CPP_RETURN_VAR << ");\n"; } else { - writeToPythonConversion(s, func->type(), func->ownerClass(), QLatin1String(CPP_RETURN_VAR)); + s << PYTHON_RETURN_VAR << " = "; + writeToPythonConversion(s, funcType, func->ownerClass(), QLatin1String(CPP_RETURN_VAR)); } s << ";\n"; } @@ -4716,14 +4742,9 @@ void CppGenerator::writeGetterFunction(TextStream &s, if (metaField.generateOpaqueContainer() && fieldType.generateOpaqueContainer()) { - const auto *containerTypeEntry = - static_cast<const ContainerTypeEntry *>(fieldType.typeEntry()); - const auto *instantiationTypeEntry = - fieldType.instantiations().constFirst().typeEntry(); - const QString creationFunc = - u"create"_qs + containerTypeEntry->opaqueContainerName(instantiationTypeEntry->name()); - s << "PyObject *" << creationFunc << '(' << fieldType.cppSignature() << "*);\n" - << "PyObject *pyOut = " << creationFunc + const QString creationFunc = opaqueContainerCreationFunc(fieldType); + writeOpaqueContainerCreationFuncDecl(s, creationFunc, fieldType); + s << "PyObject *pyOut = " << creationFunc << "(&" << cppField << ");\nPy_IncRef(pyOut);\n" << "return pyOut;\n" << outdent << "}\n"; return; |