From 872a9729ce063dc16c8527f56901942ae74431c1 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 8 Mar 2017 13:50:00 +0100 Subject: Improve Qt initialization order hack In CppGenerator::finishGeneration(), the code tried to reorder the classlist such that the initialization of QMetaObject is written before the initialization of QObject by re-inserting the QMetaObject class entry in front of QObject. This does not consider the dependency of QMetaObject::Connection on QMetaObject and worked only by coincidence since the old parser did not recognize QMetaObject::Connection as an inner class due to it being forward-declared. With the Clang-based parser, which recognizes this, the initialization for QMetaObject::Connection would be called before the initialization of QMetaObject, causing a crash. Fix this by making it possible to pass additional dependencies as pairs of QString to the topological sorting functions, which then generate the correct sequence. Task-number: PYSIDE-323 Change-Id: Ia915b47131d57e71df366876a1a9f317cfd8d497 Reviewed-by: Christian Tismer Reviewed-by: Alexandru Croitor --- generator/generator.cpp | 4 ++-- generator/generator.h | 3 ++- generator/shiboken2/cppgenerator.cpp | 21 +++++++++++++-------- 3 files changed, 17 insertions(+), 11 deletions(-) (limited to 'generator') diff --git a/generator/generator.cpp b/generator/generator.cpp index 20a7e9c..bde69f1 100644 --- a/generator/generator.cpp +++ b/generator/generator.cpp @@ -177,9 +177,9 @@ AbstractMetaClassList Generator::classes() const return m_d->apiextractor->classes(); } -AbstractMetaClassList Generator::classesTopologicalSorted() const +AbstractMetaClassList Generator::classesTopologicalSorted(const Dependencies &additionalDependencies) const { - return m_d->apiextractor->classesTopologicalSorted(); + return m_d->apiextractor->classesTopologicalSorted(additionalDependencies); } AbstractMetaFunctionList Generator::globalFunctions() const diff --git a/generator/generator.h b/generator/generator.h index e570d8b..ac78d62 100644 --- a/generator/generator.h +++ b/generator/generator.h @@ -30,6 +30,7 @@ #define GENERATOR_H #include +#include #include #include #include @@ -120,7 +121,7 @@ public: /// /// The classes are ordered such that derived classes appear later in the list than /// their parent classes. - AbstractMetaClassList classesTopologicalSorted() const; + AbstractMetaClassList classesTopologicalSorted(const Dependencies &additionalDependencies = Dependencies()) const; /// Returns all global functions found by APIExtractor AbstractMetaFunctionList globalFunctions() const; diff --git a/generator/shiboken2/cppgenerator.cpp b/generator/shiboken2/cppgenerator.cpp index efdcbaf..74c061c 100644 --- a/generator/shiboken2/cppgenerator.cpp +++ b/generator/shiboken2/cppgenerator.cpp @@ -4691,6 +4691,9 @@ void CppGenerator::writeGetattroFunction(QTextStream& s, const AbstractMetaClass s << '}' << endl; } +static inline QString qObjectClassName() { return QStringLiteral("QObject"); } +static inline QString qMetaObjectClassName() { return QStringLiteral("QMetaObject"); } + bool CppGenerator::finishGeneration() { //Generate CPython wrapper file @@ -4727,14 +4730,16 @@ bool CppGenerator::finishGeneration() //this is a temporary solution before new type revison implementation //We need move QMetaObject register before QObject - AbstractMetaClassList lst = classesTopologicalSorted(); - AbstractMetaClass* klassQObject = lst.findClass(QLatin1String("QObject")); - AbstractMetaClass* klassQMetaObject = lst.findClass(QLatin1String("QMetaObject")); - if (klassQObject && klassQMetaObject) { - lst.removeAll(klassQMetaObject); - int indexOf = lst.indexOf(klassQObject); - lst.insert(indexOf, klassQMetaObject); - } + Dependencies additionalDependencies; + const AbstractMetaClassList &allClasses = classes(); + if (allClasses.findClass(qObjectClassName()) != Q_NULLPTR + && allClasses.findClass(qMetaObjectClassName()) != Q_NULLPTR) { + Dependency dependency; + dependency.parent = qMetaObjectClassName(); + dependency.child = qObjectClassName(); + additionalDependencies.append(dependency); + } + const AbstractMetaClassList lst = classesTopologicalSorted(additionalDependencies); foreach (const AbstractMetaClass* cls, lst) { if (!shouldGenerate(cls)) -- cgit v1.2.3