diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2022-05-03 08:52:41 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2022-05-03 11:49:35 +0200 |
commit | 9c37876d6f649b3c9bd1411d3c7ffe620786f1a8 (patch) | |
tree | fefb461dfac1bbc624f1ae339b9f0b1ab3511c2d /sources/shiboken6 | |
parent | bdfb36b880cecc40fa4b15ed963ee3e1c033d469 (diff) |
Expose the qHash() functions as tp_hash
The hash function attribute in AbstractMetaClass was so far populated
by the code model but unused by the generator. Change the
AbstractMetaClass attribute to be a string (to accommodate for
std::hash as well in a later change) and use it in the generator.
[ChangeLog][PySide6] All qHash() functions are now exposed to Python.
Fixes: PYSIDE-1906
Change-Id: I8b4cc503d8b073a6d437bbc0f6c5c7e048ec7ab9
Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources/shiboken6')
4 files changed, 38 insertions, 16 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp index c13364752..9d4c874fb 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp @@ -225,10 +225,12 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(const ArgumentMod void AbstractMetaBuilderPrivate::registerHashFunction(const FunctionModelItem &function_item, AbstractMetaClass *currentClass) { + if (function_item->isDeleted()) + return; ArgumentList arguments = function_item->arguments(); - if (arguments.size() == 1) { + if (arguments.size() >= 1) { // (Class, Hash seed). if (AbstractMetaClass *cls = argumentToClass(arguments.at(0), currentClass)) - cls->setHasHashFunction(true); + cls->setHashFunction(function_item->name()); } } @@ -3190,7 +3192,7 @@ void AbstractMetaBuilderPrivate::inheritTemplateFunctions(AbstractMetaClass *sub auto templateClass = subclass->templateBaseClass(); if (subclass->isTypeDef()) { - subclass->setHasHashFunction(templateClass->hasHashFunction()); + subclass->setHashFunction(templateClass->hashFunction()); subclass->setHasNonPrivateConstructor(templateClass->hasNonPrivateConstructor()); subclass->setHasPrivateDestructor(templateClass->hasPrivateDestructor()); subclass->setHasProtectedDestructor(templateClass->hasProtectedDestructor()); diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp index 09e9c1381..b1f5b8a4b 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp @@ -66,7 +66,6 @@ public: m_hasPrivateDestructor(false), m_hasProtectedDestructor(false), m_hasVirtualDestructor(false), - m_hasHashFunction(false), m_isTypeDef(false), m_hasToStringCapability(false), m_valueTypeWithCopyConstructorOnly(false), @@ -105,7 +104,6 @@ public: uint m_hasPrivateDestructor : 1; uint m_hasProtectedDestructor : 1; uint m_hasVirtualDestructor : 1; - uint m_hasHashFunction : 1; uint m_isTypeDef : 1; uint m_hasToStringCapability : 1; uint m_valueTypeWithCopyConstructorOnly : 1; @@ -125,6 +123,7 @@ public: AbstractMetaEnumList m_enums; QList<QPropertySpec> m_propertySpecs; AbstractMetaClassCList m_innerClasses; + QString m_hashFunction; AbstractMetaFunctionCList m_externalConversionOperators; @@ -644,14 +643,19 @@ void AbstractMetaClass::setTypeEntry(ComplexTypeEntry *type) d->m_typeEntry = type; } -void AbstractMetaClass::setHasHashFunction(bool on) +QString AbstractMetaClass::hashFunction() const { - d->m_hasHashFunction = on; + return d->m_hashFunction; +} + +void AbstractMetaClass::setHashFunction(const QString &f) +{ + d->m_hashFunction = f; } bool AbstractMetaClass::hasHashFunction() const { - return d->m_hasHashFunction; + return !d->m_hashFunction.isEmpty(); } // Search whether a functions is a property setter/getter/reset diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.h b/sources/shiboken6/ApiExtractor/abstractmetalang.h index 23a34e7e1..64d5cd411 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken6/ApiExtractor/abstractmetalang.h @@ -270,7 +270,9 @@ public: ComplexTypeEntry *typeEntry(); void setTypeEntry(ComplexTypeEntry *type); - void setHasHashFunction(bool on); + /// Returns the global hash function as found by the code parser + QString hashFunction() const; + void setHashFunction(const QString &); /// Returns whether the class has a qHash() overload. Currently unused, /// specified in type system. diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index ab9449a29..aa17ae8f4 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -492,6 +492,12 @@ static void writePyMethodDefs(TextStream &s, const QString &className, << "};\n\n"; } +static bool hasHashFunction(const AbstractMetaClass *c) +{ + return !c->typeEntry()->hashFunction().isEmpty() + || c->hasHashFunction(); +} + /// Function used to write the class generated binding code on the buffer /// \param s the output buffer /// \param classContext the pointer to metaclass information @@ -764,7 +770,7 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon s << closeExternC; - if (!typeEntry->hashFunction().isEmpty()) + if (hasHashFunction(metaClass)) writeHashFunction(s, classContext); // Write tp_traverse and tp_clear functions. @@ -907,7 +913,7 @@ void CppGenerator::generateSmartPointerClass(TextStream &s, const GeneratorConte s << closeExternC; - if (!typeEntry->hashFunction().isEmpty()) + if (hasHashFunction(metaClass)) writeHashFunction(s, classContext); // Write tp_traverse and tp_clear functions. @@ -4530,7 +4536,7 @@ void CppGenerator::writeClassDefinition(TextStream &s, s << "// Class Definition -----------------------------------------------\n" "extern \"C\" {\n"; - if (!metaClass->typeEntry()->hashFunction().isEmpty()) + if (hasHashFunction(metaClass)) tp_hash = u'&' + cpythonBaseName(metaClass) + u"_HashFunc"_s; const auto callOp = metaClass->findFunction(u"operator()"); @@ -6855,11 +6861,19 @@ void CppGenerator::writeHashFunction(TextStream &s, const GeneratorContext &cont const AbstractMetaClass *metaClass = context.metaClass(); const char hashType[] = "Py_hash_t"; s << "static " << hashType << ' ' << cpythonBaseName(metaClass) - << "_HashFunc(PyObject *self) {\n" << indent; + << "_HashFunc(PyObject *self)\n{\n" << indent; writeCppSelfDefinition(s, context); - s << "return " << hashType << '(' - << metaClass->typeEntry()->hashFunction() << '('; - if (!metaClass->isObjectType()) + + bool deref = true; + QString name = metaClass->typeEntry()->hashFunction(); + if (name.isEmpty()) + name = metaClass->hashFunction(); + else + deref = !metaClass->isObjectType(); + Q_ASSERT(!name.isEmpty()); + + s << "return " << hashType << '(' << name << '('; + if (deref) s << '*'; s << CPP_SELF_VAR << "));\n" << outdent << "}\n\n"; |