diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2019-11-26 11:31:01 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2019-12-05 09:36:59 +0100 |
commit | d0fbcc90bd02090f921313dafecba20065fb2eb5 (patch) | |
tree | b369b0d3424222988b33bdeef4ffaacc00b7275d /sources | |
parent | 44729f5c176e2585f00b6fefacffa7830b1e9f22 (diff) |
shiboken: Fix passing of the parent type to smart pointer init functions
The code was assuming that smart pointers instances live in the global
namespace and passed the module as parent, which does not work in case
of std::shared_ptr.
Factor out the code writing the init function call and use the same
code for classes and smart pointer instances.
Task-number: PYSIDE-454
Change-Id: Iffe5ace31d734dd19ca784841344c50248952342
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources')
-rw-r--r-- | sources/shiboken2/ApiExtractor/typesystem.cpp | 12 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/typesystem.h | 2 | ||||
-rw-r--r-- | sources/shiboken2/generator/shiboken2/cppgenerator.cpp | 45 | ||||
-rw-r--r-- | sources/shiboken2/generator/shiboken2/cppgenerator.h | 3 |
4 files changed, 43 insertions, 19 deletions
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp index 854728711..cbcd713f1 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.cpp +++ b/sources/shiboken2/ApiExtractor/typesystem.cpp @@ -693,6 +693,16 @@ const TypeSystemTypeEntry *TypeEntry::typeSystemTypeEntry() const return nullptr; } +const TypeEntry *TypeEntry::targetLangEnclosingEntry() const +{ + auto result = m_parent; + while (result && result->type() != TypeEntry::TypeSystemType + && !NamespaceTypeEntry::isVisibleScope(result)) { + result = result->parent(); + } + return result; +} + QString TypeEntry::targetLangName() const { if (m_cachedTargetLangName.isEmpty()) @@ -754,6 +764,8 @@ TypeEntry *TypeEntry::clone() const // Take over parameters relevant for typedefs void TypeEntry::useAsTypedef(const TypeEntry *source) { + // XML Typedefs are in the global namespace for now. + m_parent = source->typeSystemTypeEntry(); m_entryName = source->m_entryName; m_name = source->m_name; m_targetLangPackage = source->m_targetLangPackage; diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h index 7f5eaac4b..0cbcc9c25 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.h +++ b/sources/shiboken2/ApiExtractor/typesystem.h @@ -606,6 +606,8 @@ public: const TypeEntry *parent() const { return m_parent; } void setParent(const TypeEntry *p) { m_parent = p; } const TypeSystemTypeEntry *typeSystemTypeEntry() const; + // cf AbstractMetaClass::targetLangEnclosingClass() + const TypeEntry *targetLangEnclosingEntry() const; bool isPrimitive() const { diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index 589e1ef94..db05b21d6 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -5397,6 +5397,25 @@ void CppGenerator::writeGetattroFunction(QTextStream &s, GeneratorContext &conte s << '}' << endl; } +// Write declaration and invocation of the init function for the module init +// function. +void CppGenerator::writeInitFunc(QTextStream &declStr, QTextStream &callStr, + const Indentor &indent, const QString &initFunctionName, + const TypeEntry *enclosingEntry) +{ + const bool hasParent = + enclosingEntry && enclosingEntry->type() != TypeEntry::TypeSystemType; + declStr << "void init_" << initFunctionName << "(PyObject *" + << (hasParent ? "enclosingClass" : "module") << ");\n"; + callStr << indent << "init_" << initFunctionName; + if (hasParent) { + callStr << "(reinterpret_cast<PyTypeObject *>(" + << cpythonTypeNameExt(enclosingEntry) << ")->tp_dict);\n"; + } else { + callStr << "(module);\n"; + } +} + bool CppGenerator::finishGeneration() { //Generate CPython wrapper file @@ -5451,32 +5470,20 @@ bool CppGenerator::finishGeneration() const AbstractMetaClassList lst = classesTopologicalSorted(additionalDependencies); for (const AbstractMetaClass *cls : lst){ - if (!shouldGenerate(cls)) - continue; - - const QString initFunctionName = QLatin1String("init_") + getSimpleClassInitFunctionName(cls); - - s_classInitDecl << "void " << initFunctionName << "(PyObject *module);" << endl; - - s_classPythonDefines << INDENT << initFunctionName; - if (auto enclosing = cls->targetLangEnclosingClass()) { - s_classPythonDefines << "(reinterpret_cast<PyTypeObject *>(" - << cpythonTypeNameExt(enclosing->typeEntry()) << ")->tp_dict);"; - } else { - s_classPythonDefines << "(module);"; + if (shouldGenerate(cls)) { + writeInitFunc(s_classInitDecl, s_classPythonDefines, INDENT, + getSimpleClassInitFunctionName(cls), + cls->typeEntry()->targetLangEnclosingEntry()); } - s_classPythonDefines << endl; } // Initialize smart pointer types. const QVector<const AbstractMetaType *> &smartPtrs = instantiatedSmartPointers(); for (const AbstractMetaType *metaType : smartPtrs) { GeneratorContext context(nullptr, metaType, true); - QString initFunctionName = getInitFunctionName(context); - s_classInitDecl << "void init_" << initFunctionName << "(PyObject *module);" << endl; - QString defineStr = QLatin1String("init_") + initFunctionName; - defineStr += QLatin1String("(module);"); - s_classPythonDefines << INDENT << defineStr << endl; + writeInitFunc(s_classInitDecl, s_classPythonDefines, INDENT, + getInitFunctionName(context), + metaType->typeEntry()->targetLangEnclosingEntry()); } QString moduleFileName(outputDirectory() + QLatin1Char('/') + subDirectoryForPackage(packageName())); diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h index 005518f96..fd272eaad 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.h +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h @@ -50,6 +50,9 @@ protected: bool finishGeneration() override; private: + void writeInitFunc(QTextStream &declStr, QTextStream &callStr, + const Indentor &indent, const QString &initFunctionName, + const TypeEntry *enclosingEntry = nullptr); void writeConstructorNative(QTextStream &s, const AbstractMetaFunction *func); void writeDestructorNative(QTextStream &s, const AbstractMetaClass *metaClass); |