diff options
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) { |
