aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-11-25 12:53:02 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2023-02-22 08:33:10 +0100
commit76b9c085dcc73dc631483609f59140dba1cf87e4 (patch)
treeb546a282eacec356c9c36cbce728919385e6d231
parent2c795c34e4a8a1689fe6ac6a1099011e017893ed (diff)
Add support for excluding classes by a preprocessor condition in the module headers
Task-number: PYSIDE-962 Change-Id: I5796d10bda9b760a3fd5d71dc750b3f5f7f29e94 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
-rw-r--r--sources/shiboken6/ApiExtractor/complextypeentry.h4
-rw-r--r--sources/shiboken6/ApiExtractor/configurabletypeentry.h28
-rw-r--r--sources/shiboken6/ApiExtractor/enumtypeentry.h5
-rw-r--r--sources/shiboken6/ApiExtractor/flagstypeentry.h1
-rw-r--r--sources/shiboken6/ApiExtractor/messages.cpp8
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.cpp65
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem_typedefs.h3
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.cpp29
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser_p.h3
-rw-r--r--sources/shiboken6/doc/typesystem_manipulating_objects.rst26
-rw-r--r--sources/shiboken6/doc/typesystem_specifying_types.rst11
-rw-r--r--sources/shiboken6/generator/shiboken/configurablescope.h33
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp19
-rw-r--r--sources/shiboken6/generator/shiboken/headergenerator.cpp29
14 files changed, 242 insertions, 22 deletions
diff --git a/sources/shiboken6/ApiExtractor/complextypeentry.h b/sources/shiboken6/ApiExtractor/complextypeentry.h
index bdbd7fa22..ea38da7f8 100644
--- a/sources/shiboken6/ApiExtractor/complextypeentry.h
+++ b/sources/shiboken6/ApiExtractor/complextypeentry.h
@@ -4,7 +4,7 @@
#ifndef COMPLEXTYPEENTRY_H
#define COMPLEXTYPEENTRY_H
-#include "typesystem.h"
+#include "configurabletypeentry.h"
#include "typesystem_enums.h"
#include "modifications_typedefs.h"
#include "pymethoddefentry.h"
@@ -33,7 +33,7 @@ struct TypeSystemProperty
bool generateGetSetDef = false;
};
-class ComplexTypeEntry : public TypeEntry
+class ComplexTypeEntry : public ConfigurableTypeEntry
{
public:
enum TypeFlag {
diff --git a/sources/shiboken6/ApiExtractor/configurabletypeentry.h b/sources/shiboken6/ApiExtractor/configurabletypeentry.h
new file mode 100644
index 000000000..59522e16c
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/configurabletypeentry.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef CONFIGURABLETYPEENTRY_H
+#define CONFIGURABLETYPEENTRY_H
+
+#include "typesystem.h"
+
+class ConfigurableTypeEntryPrivate;
+
+class ConfigurableTypeEntry : public TypeEntry
+{
+public:
+ explicit ConfigurableTypeEntry(const QString &entryName, Type t,
+ const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ TypeEntry *clone() const override;
+
+ QString configCondition() const;
+ void setConfigCondition(const QString &c);
+ bool hasConfigCondition() const;
+
+protected:
+ explicit ConfigurableTypeEntry(ConfigurableTypeEntryPrivate *d);
+};
+
+#endif // CONFIGURABLETYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/enumtypeentry.h b/sources/shiboken6/ApiExtractor/enumtypeentry.h
index 14bab50cf..c7fe54d01 100644
--- a/sources/shiboken6/ApiExtractor/enumtypeentry.h
+++ b/sources/shiboken6/ApiExtractor/enumtypeentry.h
@@ -4,12 +4,13 @@
#ifndef ENUMTYPEENTRY_H
#define ENUMTYPEENTRY_H
-#include "typesystem.h"
+#include "configurabletypeentry.h"
#include "typesystem_enums.h"
class EnumTypeEntryPrivate;
-class EnumTypeEntry : public TypeEntry
+// EnumTypeEntry is configurable for global enums only
+class EnumTypeEntry : public ConfigurableTypeEntry
{
public:
explicit EnumTypeEntry(const QString &entryName,
diff --git a/sources/shiboken6/ApiExtractor/flagstypeentry.h b/sources/shiboken6/ApiExtractor/flagstypeentry.h
index b784b64e6..6eddcd12b 100644
--- a/sources/shiboken6/ApiExtractor/flagstypeentry.h
+++ b/sources/shiboken6/ApiExtractor/flagstypeentry.h
@@ -9,6 +9,7 @@
class EnumTypeEntry;
class FlagsTypeEntryPrivate;
+// FlagsTypeEntry is configurable for global flags only
class FlagsTypeEntry : public TypeEntry
{
public:
diff --git a/sources/shiboken6/ApiExtractor/messages.cpp b/sources/shiboken6/ApiExtractor/messages.cpp
index e7af80fe3..bcebf4630 100644
--- a/sources/shiboken6/ApiExtractor/messages.cpp
+++ b/sources/shiboken6/ApiExtractor/messages.cpp
@@ -349,8 +349,14 @@ QString msgTypeNotDefined(const TypeEntryCPtr &entry)
{
QString result;
QTextStream str(&result);
+ const bool hasConfigCondition = entry->isComplex()
+ && std::static_pointer_cast<const ConfigurableTypeEntry>(entry)->hasConfigCondition();
str << entry->sourceLocation() << "type '" <<entry->qualifiedCppName()
- << "' is specified in typesystem, but not defined. " << msgCompilationError;
+ << "' is specified in typesystem, but not defined";
+ if (hasConfigCondition)
+ str << " (disabled by configuration?).";
+ else
+ str << ". " << msgCompilationError;
return result;
}
diff --git a/sources/shiboken6/ApiExtractor/typesystem.cpp b/sources/shiboken6/ApiExtractor/typesystem.cpp
index 1ec0ef5f3..541c84484 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystem.cpp
@@ -5,6 +5,7 @@
#include "arraytypeentry.h"
#include "codesnip.h"
#include "complextypeentry.h"
+#include "configurabletypeentry.h"
#include "constantvaluetypeentry.h"
#include "containertypeentry.h"
#include "customtypenentry.h"
@@ -953,12 +954,60 @@ PrimitiveTypeEntry::PrimitiveTypeEntry(PrimitiveTypeEntryPrivate *d)
{
}
-// ----------------- EnumTypeEntry
-class EnumTypeEntryPrivate : public TypeEntryPrivate
+// ----------------- ConfigurableTypeEntry
+
+class ConfigurableTypeEntryPrivate : public TypeEntryPrivate
{
public:
using TypeEntryPrivate::TypeEntryPrivate;
+ QString m_configCondition;
+};
+
+ConfigurableTypeEntry::ConfigurableTypeEntry(const QString &entryName, Type t,
+ const QVersionNumber &vr,
+ const TypeEntryCPtr &parent) :
+ TypeEntry(new ConfigurableTypeEntryPrivate(entryName, t, vr, parent))
+{
+}
+
+ConfigurableTypeEntry::ConfigurableTypeEntry(ConfigurableTypeEntryPrivate *d) :
+ TypeEntry(d)
+{
+}
+
+TypeEntry *ConfigurableTypeEntry::clone() const
+{
+ S_D(const ConfigurableTypeEntry);
+ return new ConfigurableTypeEntry(new ConfigurableTypeEntryPrivate(*d));
+}
+
+QString ConfigurableTypeEntry::configCondition() const
+{
+ S_D(const ConfigurableTypeEntry);
+ return d->m_configCondition;
+}
+
+void ConfigurableTypeEntry::setConfigCondition(const QString &c)
+{
+ S_D(ConfigurableTypeEntry);
+ d->m_configCondition = c;
+ if (!d->m_configCondition.startsWith(u'#'))
+ d->m_configCondition.prepend(u"#if ");
+}
+
+bool ConfigurableTypeEntry::hasConfigCondition() const
+{
+ S_D(const ConfigurableTypeEntry);
+ return !d->m_configCondition.isEmpty();
+}
+
+// ----------------- EnumTypeEntry
+class EnumTypeEntryPrivate : public ConfigurableTypeEntryPrivate
+{
+public:
+ using ConfigurableTypeEntryPrivate::ConfigurableTypeEntryPrivate;
+
EnumValueTypeEntryCPtr m_nullValue;
QStringList m_rejectedEnums;
FlagsTypeEntryPtr m_flags;
@@ -969,7 +1018,7 @@ public:
EnumTypeEntry::EnumTypeEntry(const QString &entryName,
const QVersionNumber &vr,
const TypeEntryCPtr &parent) :
- TypeEntry(new EnumTypeEntryPrivate(entryName, EnumType, vr, parent))
+ ConfigurableTypeEntry(new EnumTypeEntryPrivate(entryName, EnumType, vr, parent))
{
}
@@ -1063,7 +1112,7 @@ TypeEntry *EnumTypeEntry::clone() const
}
EnumTypeEntry::EnumTypeEntry(EnumTypeEntryPrivate *d) :
- TypeEntry(d)
+ ConfigurableTypeEntry(d)
{
}
@@ -1202,13 +1251,13 @@ ConstantValueTypeEntry::ConstantValueTypeEntry(TypeEntryPrivate *d) :
}
// ----------------- ComplexTypeEntry
-class ComplexTypeEntryPrivate : public TypeEntryPrivate
+class ComplexTypeEntryPrivate : public ConfigurableTypeEntryPrivate
{
public:
ComplexTypeEntryPrivate(const QString &entryName, TypeEntry::Type t,
const QVersionNumber &vr,
const TypeEntryCPtr &parent) :
- TypeEntryPrivate(entryName, t, vr, parent),
+ ConfigurableTypeEntryPrivate(entryName, t, vr, parent),
m_qualifiedCppName(buildName(entryName, parent)),
m_polymorphicBase(false),
m_genericClass(false),
@@ -1257,7 +1306,7 @@ public:
ComplexTypeEntry::ComplexTypeEntry(const QString &entryName, TypeEntry::Type t,
const QVersionNumber &vr,
const TypeEntryCPtr &parent) :
- TypeEntry(new ComplexTypeEntryPrivate(entryName, t, vr, parent))
+ ConfigurableTypeEntry(new ComplexTypeEntryPrivate(entryName, t, vr, parent))
{
}
@@ -1690,7 +1739,7 @@ void ComplexTypeEntry::useAsTypedef(const ComplexTypeEntryCPtr &source)
}
ComplexTypeEntry::ComplexTypeEntry(ComplexTypeEntryPrivate *d) :
- TypeEntry(d)
+ ConfigurableTypeEntry(d)
{
}
diff --git a/sources/shiboken6/ApiExtractor/typesystem_typedefs.h b/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
index bd835a8c1..59bb452a3 100644
--- a/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
+++ b/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
@@ -10,6 +10,7 @@
class ArrayTypeEntry;
class ComplexTypeEntry;
+class ConfigurableTypeEntry;
class ConstantValueTypeEntry;
class ContainerTypeEntry;
class CustomTypeEntry;
@@ -29,6 +30,7 @@ class ValueTypeEntry;
using ArrayTypeEntryPtr = std::shared_ptr<ArrayTypeEntry>;
using ComplexTypeEntryPtr = std::shared_ptr<ComplexTypeEntry>;
+using ConfigurableTypeEntryPtr = std::shared_ptr<ConfigurableTypeEntry>;
using ConstantValueTypeEntryPtr = std::shared_ptr<ConstantValueTypeEntry>;
using ContainerTypeEntryPtr = std::shared_ptr<ContainerTypeEntry>;
using CustomTypeEntryPtr = std::shared_ptr<CustomTypeEntry>;
@@ -49,6 +51,7 @@ using ValueTypeEntryPtr = std::shared_ptr<ValueTypeEntry>;
using ArrayTypeEntryCPtr = std::shared_ptr<const ArrayTypeEntry>;
using ComplexTypeEntryCPtr = std::shared_ptr<const ComplexTypeEntry>;
using ConstantValueTypeEntryCPtr = std::shared_ptr<const ConstantValueTypeEntry>;
+using ConfigurableTypeEntryCPtr = std::shared_ptr<const ConfigurableTypeEntry>;
using ContainerTypeEntryCPtr = std::shared_ptr<const ContainerTypeEntry>;
using CustomTypeEntryCPtr = std::shared_ptr<const CustomTypeEntry>;
using EnumTypeEntryCPtr = std::shared_ptr<const EnumTypeEntry>;
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
index 8898c8715..26b9fc94a 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
@@ -440,6 +440,7 @@ static const StackElementHash &stackElementHash()
{u"add-function", StackElement::AddFunction},
{u"add-pymethoddef", StackElement::AddPyMethodDef},
{u"array", StackElement::Array},
+ {u"configuration", StackElement::Configuration},
{u"container-type", StackElement::ContainerTypeEntry},
{u"conversion-rule", StackElement::ConversionRule},
{u"custom-constructor", StackElement::Unimplemented},
@@ -1920,6 +1921,32 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
ctype->setCodeGeneration(TypeEntry::GenerationDisabled);
}
+bool TypeSystemParser::parseConfiguration(StackElement topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (!isComplexTypeEntry(topElement)
+ && topElement != StackElement::EnumTypeEntry) {
+ m_error = u"<configuration> must be nested into a complex or enum type entry."_s;
+ return false;
+ }
+ QString condition;
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == u"condition") {
+ condition = attributes->takeAt(i).value().toString();
+ }
+ }
+ if (condition.isEmpty()) {
+ m_error = u"<configuration> requires a \"condition\" attribute."_s;
+ return false;
+ }
+ const auto topEntry = m_contextStack.top()->entry;
+ const auto configurableEntry = std::dynamic_pointer_cast<ConfigurableTypeEntry>(topEntry);
+ Q_ASSERT(configurableEntry);
+ configurableEntry->setConfigCondition(condition);
+ return true;
+}
+
bool TypeSystemParser::parseRenameFunction(const ConditionalStreamReader &,
QString *name, QXmlStreamAttributes *attributes)
{
@@ -3529,6 +3556,8 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
break;
case StackElement::OpaqueContainer:
if (!parseOpaqueContainerElement(&attributes))
+ case StackElement::Configuration:
+ if (!parseConfiguration(topElement, &attributes))
return false;
break;
default:
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser_p.h b/sources/shiboken6/ApiExtractor/typesystemparser_p.h
index 01463f056..96c4a5e37 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser_p.h
+++ b/sources/shiboken6/ApiExtractor/typesystemparser_p.h
@@ -104,6 +104,7 @@ enum class StackElement {
ImportFile,
OpaqueContainer,
+ Configuration,
Unimplemented
};
@@ -199,6 +200,8 @@ private:
const QVersionNumber &since, QXmlStreamAttributes *);
void applyComplexTypeAttributes(const ConditionalStreamReader &, const ComplexTypeEntryPtr &ctype,
QXmlStreamAttributes *) const;
+ bool parseConfiguration(StackElement topElement,
+ QXmlStreamAttributes *attributes);
bool parseRenameFunction(const ConditionalStreamReader &, QString *name,
QXmlStreamAttributes *);
bool parseInjectDocumentation(const ConditionalStreamReader &, StackElement topElement,
diff --git a/sources/shiboken6/doc/typesystem_manipulating_objects.rst b/sources/shiboken6/doc/typesystem_manipulating_objects.rst
index c8d35cf9c..9207d9510 100644
--- a/sources/shiboken6/doc/typesystem_manipulating_objects.rst
+++ b/sources/shiboken6/doc/typesystem_manipulating_objects.rst
@@ -460,3 +460,29 @@ property
.. note:: In the *Qt* coding style, the property name typically conflicts
with the getter name. It is recommended to exclude the getter from the
wrapper generation using the ``remove`` function modification.
+
+.. _configuration-element:
+
+configuration
+^^^^^^^^^^^^^
+
+ The ``configuration`` element allows you to generate a preprocessor
+ condition excluding a type depending on an expression into the module
+ header. This is specifically tailored to the
+ `Qt Feature system <https://doc.qt.io/qt-6/configure-options.html>`_ ,
+ but may also be used for similar systems.
+
+ It may appear as a child of a complex type such as :ref:`object-type` or
+ :ref:`value-type`.
+
+ .. code-block:: xml
+
+ <configuration condition="..."/>
+
+ The ``condition`` attribute specifies the preprocessor condition.
+
+ This is an alternative way of omitting classes depending on some
+ configuration (see also option :ref:`drop-type-entries`) intended
+ for building several configurations from one generated source tree,
+ but still requires listing the correct source files in the
+ ``CMakeLists.txt`` file.
diff --git a/sources/shiboken6/doc/typesystem_specifying_types.rst b/sources/shiboken6/doc/typesystem_specifying_types.rst
index dca076c1a..07a2a69e3 100644
--- a/sources/shiboken6/doc/typesystem_specifying_types.rst
+++ b/sources/shiboken6/doc/typesystem_specifying_types.rst
@@ -320,8 +320,8 @@ value-type
language as a value type. This means that it is an object passed by value on C++,
i.e. it is stored in the function call stack. It is a child of the :ref:`typesystem`
node or other type nodes and may contain :ref:`add-function`, :ref:`add-pymethoddef`,
- :ref:`declare-function`, :ref:`conversion-rule`, :ref:`enum-type`,
- :ref:`extra-includes`, :ref:`include-element`, :ref:`modify-function`,
+ :ref:`configuration-element`, :ref:`declare-function`, :ref:`conversion-rule`,
+ :ref:`enum-type`, :ref:`extra-includes`, :ref:`include-element`, :ref:`modify-function`,
:ref:`object-type`, :ref:`smart-pointer-type`, :ref:`typedef-type` or further
``value-type`` child nodes.
@@ -399,9 +399,10 @@ object-type
language as an object type. This means that it is an object passed by pointer on
C++ and it is stored on the heap. It is a child of the :ref:`typesystem` node
or other type nodes and may contain :ref:`add-function`, :ref:`add-pymethoddef`,
- :ref:`declare-function`, :ref:`enum-type`, :ref:`extra-includes`,
- :ref:`include-element`, :ref:`modify-function`, ``object-type``,
- :ref:`smart-pointer-type`, :ref:`typedef-type` or :ref:`value-type` child nodes.
+ :ref:`configuration-element`, :ref:`declare-function`, :ref:`enum-type`,
+ :ref:`extra-includes`, :ref:`include-element`, :ref:`modify-function`,
+ ``object-type``, :ref:`smart-pointer-type`, :ref:`typedef-type` or
+ :ref:`value-type` child nodes.
.. code-block:: xml
diff --git a/sources/shiboken6/generator/shiboken/configurablescope.h b/sources/shiboken6/generator/shiboken/configurablescope.h
new file mode 100644
index 000000000..9040c7ad9
--- /dev/null
+++ b/sources/shiboken6/generator/shiboken/configurablescope.h
@@ -0,0 +1,33 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef CONFIGURABLESCOPE_H
+#define CONFIGURABLESCOPE_H
+
+#include <textstream.h>
+#include <configurabletypeentry.h>
+
+/// Enclose a scope within preprocessor conditions for configurable entries
+class ConfigurableScope
+{
+public:
+ explicit ConfigurableScope(TextStream &s, const ConfigurableTypeEntryCPtr &t) :
+ m_stream(s),
+ m_hasConfigCondition(t->hasConfigCondition())
+ {
+ if (m_hasConfigCondition)
+ m_stream << t->configCondition() << '\n';
+ }
+
+ ~ConfigurableScope()
+ {
+ if (m_hasConfigCondition)
+ m_stream << "#endif\n";
+ }
+
+private:
+ TextStream &m_stream;
+ const bool m_hasConfigCondition;
+};
+
+#endif // CONFIGURABLESCOPE_H
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 327842613..34fa0cff7 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "cppgenerator.h"
+#include "configurablescope.h"
#include "generatorargument.h"
#include "defaultvalue.h"
#include "generatorcontext.h"
@@ -1799,6 +1800,8 @@ void CppGenerator::writeEnumConverterFunctions(TextStream &s, const AbstractMeta
generateDeprecatedValueWarnings(c, metaEnum, useSurrogateName);
c << "*reinterpret_cast<" << cppTypeName << " *>(cppOut) = value;\n";
+
+ ConfigurableScope configScope(s, enumType);
writePythonToCppFunction(s, c.toString(), typeName, typeName);
QString pyTypeCheck = u"PyObject_TypeCheck(pyIn, "_s + enumPythonType + u')';
@@ -5665,6 +5668,7 @@ void CppGenerator::writeEnumsInitialization(TextStream &s, AbstractMetaEnumList
<< "PyTypeObject *FType{};\n\n";
preambleWrittenF = true;
}
+ ConfigurableScope configScope(s, cppEnum.typeEntry());
writeEnumInitialization(s, cppEnum, errorReturn);
}
}
@@ -5881,6 +5885,7 @@ void CppGenerator::writeFlagsNumberMethodsDefinitions(TextStream &s,
{
for (const AbstractMetaEnum &e : enums) {
if (!e.isAnonymous() && !e.isPrivate() && e.typeEntry()->flags()) {
+ ConfigurableScope configScope(s, e.typeEntry());
writeFlagsMethods(s, e);
writeFlagsNumberMethodsDefinition(s, e);
s << '\n';
@@ -6651,6 +6656,11 @@ bool CppGenerator::finishGeneration()
for (const auto &cls : api().classes()){
auto te = cls->typeEntry();
if (shouldGenerate(te)) {
+ const bool hasConfigCondition = te->hasConfigCondition();
+ if (hasConfigCondition) {
+ s_classInitDecl << te->configCondition() << '\n';
+ s_classPythonDefines << te->configCondition() << '\n';
+ }
writeInitFunc(s_classInitDecl, s_classPythonDefines,
getSimpleClassInitFunctionName(cls),
targetLangEnclosingEntry(te));
@@ -6659,6 +6669,10 @@ bool CppGenerator::finishGeneration()
<< getSimpleClassStaticFieldsInitFunctionName(cls) << "();\n";
classesWithStaticFields.append(cls);
}
+ if (hasConfigCondition) {
+ s_classInitDecl << "#endif\n";
+ s_classPythonDefines << "#endif\n";
+ }
}
}
@@ -7005,8 +7019,10 @@ bool CppGenerator::finishGeneration()
// of the previously registered types (PYSIDE-1529).
if (!classesWithStaticFields.isEmpty()) {
s << "\n// Static field initialization\n";
- for (const auto &cls : std::as_const(classesWithStaticFields))
+ for (const auto &cls : std::as_const(classesWithStaticFields)) {
+ ConfigurableScope configScope(s, cls->typeEntry());
s << getSimpleClassStaticFieldsInitFunctionName(cls) << "();\n";
+ }
}
s << "\nif (PyErr_Occurred()) {\n" << indent
@@ -7025,6 +7041,7 @@ bool CppGenerator::finishGeneration()
if (usePySideExtensions()) {
for (const AbstractMetaEnum &metaEnum : std::as_const(globalEnums))
if (!metaEnum.isAnonymous()) {
+ ConfigurableScope configScope(s, metaEnum.typeEntry());
s << "qRegisterMetaType< ::" << metaEnum.typeEntry()->qualifiedCppName()
<< " >(\"" << metaEnum.name() << "\");\n";
}
diff --git a/sources/shiboken6/generator/shiboken/headergenerator.cpp b/sources/shiboken6/generator/shiboken/headergenerator.cpp
index d1a36c700..c7039d2b1 100644
--- a/sources/shiboken6/generator/shiboken/headergenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/headergenerator.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "headergenerator.h"
+#include "configurablescope.h"
#include "generatorcontext.h"
#include <apiextractorresult.h>
#include <abstractmetaargument.h>
@@ -551,10 +552,21 @@ static void writeForwardDeclarations(TextStream &s,
}
// Include parameters required for the module/private module header
+
+using ConditionalIncludeMap = QMap<QString, IncludeGroup>;
+
+static TextStream &operator<<(TextStream &s, const ConditionalIncludeMap &m)
+{
+ for (auto it = m.cbegin(), end = m.cend(); it != end; ++it)
+ s << it.key() << '\n' << it.value() << "#endif\n";
+ return s;
+}
+
struct ModuleHeaderParameters
{
AbstractMetaClassCList forwardDeclarations;
std::set<Include> includes;
+ ConditionalIncludeMap conditionalIncludes;
QString typeFunctions;
};
@@ -657,7 +669,11 @@ bool HeaderGenerator::finishGeneration()
for (const AbstractMetaEnum &cppEnum : api().globalEnums()) {
if (!cppEnum.isAnonymous()) {
- parameters.includes.insert(cppEnum.typeEntry()->include());
+ const auto te = cppEnum.typeEntry();
+ if (te->hasConfigCondition())
+ parameters.conditionalIncludes[te->configCondition()].append(te->include());
+ else
+ parameters.includes.insert(cppEnum.typeEntry()->include());
writeSbkTypeFunction(typeFunctions, cppEnum);
}
}
@@ -672,13 +688,17 @@ bool HeaderGenerator::finishGeneration()
const bool isPrivate = classType->isPrivate();
auto &par = isPrivate ? privateParameters : parameters;
const auto classInclude = classType->include();
+ const bool hasConfigCondition = classType->hasConfigCondition();
if (leanHeaders() && canForwardDeclare(metaClass))
par.forwardDeclarations.append(metaClass);
+ else if (hasConfigCondition)
+ par.conditionalIncludes[classType->configCondition()].append(classInclude);
else
par.includes.insert(classInclude);
auto &typeFunctionsStr = isPrivate ? privateTypeFunctions : typeFunctions;
+ ConfigurableScope configScope(typeFunctionsStr, classType);
for (const AbstractMetaEnum &cppEnum : metaClass->enums()) {
if (cppEnum.isAnonymous() || cppEnum.isPrivate())
continue;
@@ -731,6 +751,7 @@ bool HeaderGenerator::finishGeneration()
s << "// Bound library includes\n";
for (const Include &include : parameters.includes)
s << include;
+ s << parameters.conditionalIncludes;
if (leanHeaders()) {
writeForwardDeclarations(s, parameters.forwardDeclarations);
@@ -791,6 +812,7 @@ void HeaderGenerator::writePrivateHeader(const QString &moduleHeaderDir,
for (const Include &include : parameters.includes)
ps << include;
+ ps << parameters.conditionalIncludes;
ps << '\n';
if (leanHeaders())
@@ -830,9 +852,10 @@ void HeaderGenerator::writeSbkTypeFunction(TextStream &s, const AbstractMetaEnum
const QString enumName = avoidProtectedHack() && cppEnum.isProtected()
? protectedEnumSurrogateName(cppEnum)
: cppEnum.qualifiedCppName();
-
+ const auto te = cppEnum.typeEntry();
+ ConfigurableScope configScope(s, te);
s << "template<> inline PyTypeObject *SbkType< ::" << enumName << " >() ";
- s << "{ return " << cpythonTypeNameExt(cppEnum.typeEntry()) << "; }\n";
+ s << "{ return " << cpythonTypeNameExt(te) << "; }\n";
const auto flag = cppEnum.typeEntry()->flags();
if (flag) {