aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2024-04-12 10:09:04 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2024-04-12 10:42:13 +0000
commitbd786b82c96bf491e01a227d4e2be3afcf34db03 (patch)
treed5a3c014e46b3fd6d0cc2405bd7850aeff27be92
parent46ea5407a9b06dc89e81d35871d79e18df83ac53 (diff)
shiboken6: Add a placeholder for the base class to polymorphic-id-expression
Add %B for base class in addition to %1 for the class itself, which is not useful and may lead to undefined behavior. As a drive-by fix up the hitherto unused "polymorphic-base" which is a boolean indicating the base class. Task-number: PYSIDE-2675 Change-Id: I078191dc7b4c686b196fe58d6df9a249cdf2b151 Reviewed-by: Christian Tismer <tismer@stackless.com> (cherry picked from commit 4a04afc95d348c8f26919a2f084ee80fa404e7d9) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.cpp7
-rw-r--r--sources/shiboken6/doc/typesystem_specifying_types.rst20
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp22
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h2
4 files changed, 46 insertions, 5 deletions
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
index 1c1565ac2..71e80cfa8 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
@@ -88,6 +88,7 @@ constexpr auto pyiTypeAttribute = "pyi-type"_L1;
constexpr auto overloadNumberAttribute = "overload-number"_L1;
constexpr auto ownershipAttribute = "owner"_L1;
constexpr auto packageAttribute = "package"_L1;
+constexpr auto polymorphicBaseAttribute = "polymorphic-base"_L1;
constexpr auto positionAttribute = "position"_L1;
constexpr auto preferredConversionAttribute = "preferred-conversion"_L1;
constexpr auto preferredTargetLangTypeAttribute = "preferred-target-lang-type"_L1;
@@ -1810,8 +1811,10 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
ctype->setGenericClass(v);
} else if (name == targetLangNameAttribute) {
ctype->setTargetLangName(attributes->takeAt(i).value().toString());
- } else if (name == u"polymorphic-base") {
- ctype->setPolymorphicIdValue(attributes->takeAt(i).value().toString());
+ } else if (name == polymorphicBaseAttribute) {
+ const bool v = convertBoolean(attributes->takeAt(i).value(),
+ polymorphicBaseAttribute, false);
+ ctype->setIsPolymorphicBase(v);
} else if (name == u"polymorphic-name-function") {
ctype->setPolymorphicNameFunction(attributes->takeAt(i).value().toString());
} else if (name == u"polymorphic-id-expression") {
diff --git a/sources/shiboken6/doc/typesystem_specifying_types.rst b/sources/shiboken6/doc/typesystem_specifying_types.rst
index 7a1471b44..66e68ae2b 100644
--- a/sources/shiboken6/doc/typesystem_specifying_types.rst
+++ b/sources/shiboken6/doc/typesystem_specifying_types.rst
@@ -453,6 +453,7 @@ or other type nodes and may contain :ref:`add-function`, :ref:`add-pymethoddef`,
parent-management="yes | no"
polymorphic-id-expression="..."
polymorphic-name-function="..."
+ polymorphic-base="yes | no"
private="yes | no"
qt-metaobject="yes | no"
qt-register-metatype = "yes | no | base"
@@ -540,6 +541,21 @@ expression checking whether a base class pointer is of the matching
type. For example, in a ``virtual eventHandler(BaseEvent *e)``
function, this is used to construct a Python wrapper matching
the derived class (for example, a ``MouseEvent`` or similar).
+The attribute value may contain placeholders:
+
+%1
+ Fully qualified class name
+
+%B
+ Fully qualified name of the base class (found by base class
+ search or as indicated by **polymorphic-base**).
+
+To check for a class inheriting ``BaseEvent``, specify:
+
+.. code-block:: xml
+
+ <object-type name="MouseEvent"
+ polymorphic-id-expression="%B-&gt;type() == BaseEvent::MouseEvent"/>
The *optional* **polymorphic-name-function** specifies the name of a
function returning the type name of a derived class on the base class
@@ -548,6 +564,10 @@ However, this fails if the type hierarchy does not have virtual functions.
In this case, a function is required which typically decides depending
on some type enumeration.
+The *optional* **polymorphic-base** attribute indicates
+whether the class is the base class of a class hierarchy
+(used for the *%B* placeholder in **polymorphic-id-expression**).
+
interface-type
^^^^^^^^^^^^^^
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 05539eb55..329b48d1c 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -5718,6 +5718,24 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(TextStream &s, const Generato
}
}
+void CppGenerator::replacePolymorphicIdPlaceHolders(const AbstractMetaClassCPtr &metaClass,
+ QString *id)
+{
+ if (id->contains("%1"_L1)) {
+ QString replacement = " reinterpret_cast< "_L1 + m_gsp + metaClass->qualifiedCppName()
+ + " *>(cptr)"_L1;
+ id->replace("%1"_L1, replacement);
+ }
+ if (id->contains("%B"_L1)) {
+ auto baseClass = metaClass;
+ while (!baseClass->typeEntry()->isPolymorphicBase() && baseClass->baseClass())
+ baseClass = baseClass->baseClass();
+ QString replacement = " reinterpret_cast< "_L1 + m_gsp + baseClass->qualifiedCppName()
+ + " *>(cptr)"_L1;
+ id->replace("%B"_L1, replacement);
+ }
+}
+
void CppGenerator::writeTypeDiscoveryFunction(TextStream &s,
const AbstractMetaClassCPtr &metaClass)
{
@@ -5729,9 +5747,7 @@ void CppGenerator::writeTypeDiscoveryFunction(TextStream &s,
<< sbkUnusedVariableCast("instanceType");
if (!polymorphicExpr.isEmpty()) {
- polymorphicExpr.replace(u"%1"_s, " reinterpret_cast< "_L1
- + m_gsp + metaClass->qualifiedCppName()
- + " *>(cptr)"_L1);
+ replacePolymorphicIdPlaceHolders(metaClass, &polymorphicExpr);
s << " if (" << polymorphicExpr << ")\n" << indent
<< "return cptr;\n" << outdent;
} else if (metaClass->isPolymorphic()) {
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h
index 94ad87bbe..7e87fd9f3 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.h
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.h
@@ -192,6 +192,8 @@ private:
static void writeTypeCheck(TextStream& s, const std::shared_ptr<OverloadDataNode> &overloadData,
const QString &argumentName);
+ static void replacePolymorphicIdPlaceHolders(const AbstractMetaClassCPtr &metaClass,
+ QString *id);
static void writeTypeDiscoveryFunction(TextStream &s,
const AbstractMetaClassCPtr &metaClass);