aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.cpp8
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.h1
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp53
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h3
4 files changed, 52 insertions, 13 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
index abc939dcf..47249b648 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
@@ -42,6 +42,8 @@
#include <QtCore/QDebug>
+#include <algorithm>
+
bool function_sorter(const AbstractMetaFunctionCPtr &a, const AbstractMetaFunctionCPtr &b)
{
return a->signature() < b->signature();
@@ -286,6 +288,12 @@ void AbstractMetaClass::addField(const AbstractMetaField &field)
d->m_fields << field;
}
+bool AbstractMetaClass::hasStaticFields() const
+{
+ return std::any_of(d->m_fields.cbegin(), d->m_fields.cend(),
+ [](const AbstractMetaField &f) { return f.isStatic(); });
+}
+
void AbstractMetaClass::sortFunctions()
{
std::sort(d->m_functions.begin(), d->m_functions.end(), function_sorter);
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.h b/sources/shiboken6/ApiExtractor/abstractmetalang.h
index 3626ba469..5a155c6fc 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang.h
@@ -123,6 +123,7 @@ public:
AbstractMetaFieldList &fields();
void setFields(const AbstractMetaFieldList &fields);
void addField(const AbstractMetaField &field);
+ bool hasStaticFields() const;
std::optional<AbstractMetaField> findField(const QString &name) const;
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 9eec438a6..2dd13c1c6 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -765,6 +765,9 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
writeConverterFunctions(s, metaClass, classContext);
writeClassRegister(s, metaClass, classContext, signatureStream);
+ if (metaClass->hasStaticFields())
+ writeStaticFieldInitialization(s, metaClass);
+
// class inject-code native/end
if (!metaClass->typeEntry()->codeSnips().isEmpty()) {
writeClassCodeSnips(s, metaClass->typeEntry()->codeSnips(),
@@ -5313,6 +5316,12 @@ QString CppGenerator::getInitFunctionName(const GeneratorContext &context) const
: getFilteredCppSignatureString(context.preciseType().cppSignature());
}
+QString CppGenerator::getSimpleClassStaticFieldsInitFunctionName(const AbstractMetaClass *metaClass) const
+{
+ return QLatin1String("init_") + getSimpleClassInitFunctionName(metaClass)
+ + QLatin1String("StaticFields");
+}
+
void CppGenerator::writeSignatureStrings(TextStream &s,
const QString &signatures,
const QString &arrayName,
@@ -5503,19 +5512,6 @@ void CppGenerator::writeClassRegister(TextStream &s,
if (metaClass->hasSignals())
writeSignalInitialization(s, metaClass);
- // Write static fields
- const AbstractMetaFieldList &fields = metaClass->fields();
- for (const AbstractMetaField &field : fields) {
- if (!field.isStatic())
- continue;
- s << "PyDict_SetItemString(reinterpret_cast<PyTypeObject *>("
- << cpythonTypeName(metaClass) << ")->tp_dict, \""
- << field.name() << "\", ";
- writeToPythonConversion(s, field.type(), metaClass, field.qualifiedCppName());
- s << ");\n";
- }
- s << '\n';
-
// class inject-code target/end
if (!classTypeEntry->codeSnips().isEmpty()) {
s << '\n';
@@ -5546,6 +5542,23 @@ void CppGenerator::writeClassRegister(TextStream &s,
s << outdent << "}\n";
}
+void CppGenerator::writeStaticFieldInitialization(TextStream &s,
+ const AbstractMetaClass *metaClass) const
+{
+ s << "\nvoid " << getSimpleClassStaticFieldsInitFunctionName(metaClass)
+ << "()\n{\n" << indent << "auto dict = reinterpret_cast<PyTypeObject *>("
+ << cpythonTypeName(metaClass) << ")->tp_dict;\n";
+ for (const AbstractMetaField &field : metaClass->fields()) {
+ if (field.isStatic()) {
+ s << "PyDict_SetItemString(dict, \"" << field.name()
+ << "\",\n ";
+ writeToPythonConversion(s, field.type(), metaClass, field.qualifiedCppName());
+ s << ");\n";
+ }
+ }
+ s << '\n' << outdent << "}\n";
+}
+
void CppGenerator::writeInitQtMetaTypeFunctionBody(TextStream &s, const GeneratorContext &context) const
{
const AbstractMetaClass *metaClass = context.metaClass();
@@ -5937,11 +5950,17 @@ bool CppGenerator::finishGeneration()
writeMethodDefinition(s_globalFunctionDef, overloads);
}
+ AbstractMetaClassCList classesWithStaticFields;
for (auto cls : api().classes()){
if (shouldGenerate(cls)) {
writeInitFunc(s_classInitDecl, s_classPythonDefines,
getSimpleClassInitFunctionName(cls),
cls->typeEntry()->targetLangEnclosingEntry());
+ if (cls->hasStaticFields()) {
+ s_classInitDecl << "void "
+ << getSimpleClassStaticFieldsInitFunctionName(cls) << "();\n";
+ classesWithStaticFields.append(cls);
+ }
}
}
@@ -6232,6 +6251,14 @@ bool CppGenerator::finishGeneration()
s << "Shiboken::Module::registerTypes(module, " << cppApiVariableName() << ");\n";
s << "Shiboken::Module::registerTypeConverters(module, " << convertersVariableName() << ");\n";
+ // Static fields are registered last since they may use converter functions
+ // of the previously registered types (PYSIDE-1529).
+ if (!classesWithStaticFields.isEmpty()) {
+ s << "\n// Static field initialization\n";
+ for (auto cls : qAsConst(classesWithStaticFields))
+ s << getSimpleClassStaticFieldsInitFunctionName(cls) << "();\n";
+ }
+
s << "\nif (PyErr_Occurred()) {\n" << indent
<< "PyErr_Print();\n"
<< "Py_FatalError(\"can't initialize module " << moduleName() << "\");\n"
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h
index 97811c946..26958e6a4 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.h
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.h
@@ -278,6 +278,7 @@ private:
QString getInitFunctionName(const GeneratorContext &context) const;
QString getSimpleClassInitFunctionName(const AbstractMetaClass *metaClass) const;
+ QString getSimpleClassStaticFieldsInitFunctionName(const AbstractMetaClass *metaClass) const;
void writeSignatureStrings(TextStream &s, const QString &signatures,
const QString &arrayName,
@@ -286,6 +287,8 @@ private:
const AbstractMetaClass *metaClass,
const GeneratorContext &classContext,
const QString &signatures) const;
+ void writeStaticFieldInitialization(TextStream &s,
+ const AbstractMetaClass *metaClass) const;
void writeClassDefinition(TextStream &s,
const AbstractMetaClass *metaClass,
const GeneratorContext &classContext);