From 28aa3c4f6605a6331b12f47e03a9aba4aaefe201 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 27 Nov 2020 09:12:37 +0100 Subject: shiboken6: Clean up member variables of the generators There used to be a lot hash/list member variables in the generators, some of them static. Refactor this to: - Use initializer lists. - Introduce static functions returning a const ref to const hashes and lists and put them closer to where they are needed. - Move m_tpfuncs to cppgenerator. - Introduce a special struct for protocol function entries for clarity. As a drive by. streamline and fix CppGenerator::writeTypeAsMappingDefinition(), CppGenerator::writeTypeAsNumberDefinition() to generate nullptr and reinterpret_cast and not populate hashes with empty strings. Change-Id: Id1d067dec7769568f56b77ccafca843e01f99b0b Reviewed-by: Christian Tismer --- .../shiboken6/generator/shiboken/cppgenerator.cpp | 372 +++++++++++---------- .../shiboken6/generator/shiboken/cppgenerator.h | 17 +- sources/shiboken6/generator/shiboken/pytypenames.h | 41 +++ .../generator/shiboken/shibokengenerator.cpp | 264 +++++++-------- .../generator/shiboken/shibokengenerator.h | 16 +- 5 files changed, 366 insertions(+), 344 deletions(-) create mode 100644 sources/shiboken6/generator/shiboken/pytypenames.h diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index d4aa6d242..e679efbbd 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -30,6 +30,7 @@ #include "cppgenerator.h" #include "ctypenames.h" +#include "pytypenames.h" #include "fileout.h" #include "overloaddata.h" #include @@ -57,9 +58,8 @@ static const char CPP_ARG0[] = "cppArg0"; -QHash CppGenerator::m_nbFuncs = QHash(); -QHash CppGenerator::m_sqFuncs = QHash(); -QHash CppGenerator::m_mpFuncs = QHash(); +static inline QString reprFunction() { return QStringLiteral("__repr__"); } + QString CppGenerator::m_currentErrorCode(QLatin1String("{}")); static const char typeNameFunc[] = R"CPP( @@ -121,83 +121,74 @@ TextStream &operator<<(TextStream &s, const returnStatement &r) return s; } -CppGenerator::CppGenerator() -{ - // Number protocol structure members names - m_nbFuncs.insert(QLatin1String("__add__"), QLatin1String("nb_add")); - m_nbFuncs.insert(QLatin1String("__sub__"), QLatin1String("nb_subtract")); - m_nbFuncs.insert(QLatin1String("__mul__"), QLatin1String("nb_multiply")); - m_nbFuncs.insert(QLatin1String("__div__"), QLatin1String("nb_divide")); - m_nbFuncs.insert(QLatin1String("__mod__"), QLatin1String("nb_remainder")); - m_nbFuncs.insert(QLatin1String("__neg__"), QLatin1String("nb_negative")); - m_nbFuncs.insert(QLatin1String("__pos__"), QLatin1String("nb_positive")); - m_nbFuncs.insert(QLatin1String("__invert__"), QLatin1String("nb_invert")); - m_nbFuncs.insert(QLatin1String("__lshift__"), QLatin1String("nb_lshift")); - m_nbFuncs.insert(QLatin1String("__rshift__"), QLatin1String("nb_rshift")); - m_nbFuncs.insert(QLatin1String("__and__"), QLatin1String("nb_and")); - m_nbFuncs.insert(QLatin1String("__xor__"), QLatin1String("nb_xor")); - m_nbFuncs.insert(QLatin1String("__or__"), QLatin1String("nb_or")); - m_nbFuncs.insert(QLatin1String("__iadd__"), QLatin1String("nb_inplace_add")); - m_nbFuncs.insert(QLatin1String("__isub__"), QLatin1String("nb_inplace_subtract")); - m_nbFuncs.insert(QLatin1String("__imul__"), QLatin1String("nb_inplace_multiply")); - m_nbFuncs.insert(QLatin1String("__idiv__"), QLatin1String("nb_inplace_divide")); - m_nbFuncs.insert(QLatin1String("__imod__"), QLatin1String("nb_inplace_remainder")); - m_nbFuncs.insert(QLatin1String("__ilshift__"), QLatin1String("nb_inplace_lshift")); - m_nbFuncs.insert(QLatin1String("__irshift__"), QLatin1String("nb_inplace_rshift")); - m_nbFuncs.insert(QLatin1String("__iand__"), QLatin1String("nb_inplace_and")); - m_nbFuncs.insert(QLatin1String("__ixor__"), QLatin1String("nb_inplace_xor")); - m_nbFuncs.insert(QLatin1String("__ior__"), QLatin1String("nb_inplace_or")); - m_nbFuncs.insert(QLatin1String("bool"), QLatin1String("nb_nonzero")); - - // sequence protocol functions - m_sequenceProtocol.insert(QLatin1String("__len__"), - {QLatin1String("PyObject *self"), - QLatin1String("Py_ssize_t")}); - m_sequenceProtocol.insert(QLatin1String("__getitem__"), - {QLatin1String("PyObject *self, Py_ssize_t _i"), - QLatin1String("PyObject*")}); - m_sequenceProtocol.insert(QLatin1String("__setitem__"), - {QLatin1String("PyObject *self, Py_ssize_t _i, PyObject *_value"), - intT()}); - m_sequenceProtocol.insert(QLatin1String("__getslice__"), - {QLatin1String("PyObject *self, Py_ssize_t _i1, Py_ssize_t _i2"), - QLatin1String("PyObject*")}); - m_sequenceProtocol.insert(QLatin1String("__setslice__"), - {QLatin1String("PyObject *self, Py_ssize_t _i1, Py_ssize_t _i2, PyObject *_value"), - intT()}); - m_sequenceProtocol.insert(QLatin1String("__contains__"), - {QLatin1String("PyObject *self, PyObject *_value"), - intT()}); - m_sequenceProtocol.insert(QLatin1String("__concat__"), - {QLatin1String("PyObject *self, PyObject *_other"), - QLatin1String("PyObject*")}); +// Protocol function name / function parameters / return type +struct ProtocolEntry +{ + QString name; + QString arguments; + QString returnType; +}; - // Sequence protocol structure members names - m_sqFuncs.insert(QLatin1String("__concat__"), QLatin1String("sq_concat")); - m_sqFuncs.insert(QLatin1String("__contains__"), QLatin1String("sq_contains")); - m_sqFuncs.insert(QLatin1String("__getitem__"), QLatin1String("sq_item")); - m_sqFuncs.insert(QLatin1String("__getslice__"), QLatin1String("sq_slice")); - m_sqFuncs.insert(QLatin1String("__len__"), QLatin1String("sq_length")); - m_sqFuncs.insert(QLatin1String("__setitem__"), QLatin1String("sq_ass_item")); - m_sqFuncs.insert(QLatin1String("__setslice__"), QLatin1String("sq_ass_slice")); - - // mapping protocol function - m_mappingProtocol.insert(QLatin1String("__mlen__"), - {QLatin1String("PyObject *self"), - QLatin1String("Py_ssize_t")}); - m_mappingProtocol.insert(QLatin1String("__mgetitem__"), - {QLatin1String("PyObject *self, PyObject *_key"), - QLatin1String("PyObject*")}); - m_mappingProtocol.insert(QLatin1String("__msetitem__"), - {QLatin1String("PyObject *self, PyObject *_key, PyObject *_value"), - intT()}); +using ProtocolEntries = QList; - // Sequence protocol structure members names - m_mpFuncs.insert(QLatin1String("__mlen__"), QLatin1String("mp_length")); - m_mpFuncs.insert(QLatin1String("__mgetitem__"), QLatin1String("mp_subscript")); - m_mpFuncs.insert(QLatin1String("__msetitem__"), QLatin1String("mp_ass_subscript")); +static bool contains(const ProtocolEntries &l, const QString &needle) +{ + for (const auto &m : l) { + if (m.name == needle) + return true; + } + return false; +} + +// Maps special function names to function parameters and return types +// used by CPython API in the mapping protocol. +const ProtocolEntries &mappingProtocols() +{ + static const ProtocolEntries result = { + {QLatin1String("__mlen__"), + QLatin1String("PyObject *self"), + QLatin1String("Py_ssize_t")}, + {QLatin1String("__mgetitem__"), + QLatin1String("PyObject *self, PyObject *_key"), + QLatin1String("PyObject*")}, + {QLatin1String("__msetitem__"), + QLatin1String("PyObject *self, PyObject *_key, PyObject *_value"), + intT()}}; + return result; +} + +// Maps special function names to function parameters and return types +// used by CPython API in the sequence protocol. +const ProtocolEntries &sequenceProtocols() +{ + static const ProtocolEntries result = { + {QLatin1String("__len__"), + QLatin1String("PyObject *self"), + QLatin1String("Py_ssize_t")}, + {QLatin1String("__getitem__"), + QLatin1String("PyObject *self, Py_ssize_t _i"), + QLatin1String("PyObject*")}, + {QLatin1String("__setitem__"), + QLatin1String("PyObject *self, Py_ssize_t _i, PyObject *_value"), + intT()}, + {QLatin1String("__getslice__"), + QLatin1String("PyObject *self, Py_ssize_t _i1, Py_ssize_t _i2"), + QLatin1String("PyObject*")}, + {QLatin1String("__setslice__"), + QLatin1String("PyObject *self, Py_ssize_t _i1, Py_ssize_t _i2, PyObject *_value"), + intT()}, + {QLatin1String("__contains__"), + QLatin1String("PyObject *self, PyObject *_value"), + intT()}, + {QLatin1String("__concat__"), + QLatin1String("PyObject *self, PyObject *_other"), + QLatin1String("PyObject*")} + }; + return result; } +CppGenerator::CppGenerator() = default; + QString CppGenerator::fileNameSuffix() const { return QLatin1String("_wrapper.cpp"); @@ -273,6 +264,15 @@ std::optional return {}; } +void CppGenerator::clearTpFuncs() +{ + m_tpFuncs = { + {QLatin1String("__str__"), {}}, {QLatin1String("__str__"), {}}, + {reprFunction(), {}}, {QLatin1String("__iter__"), {}}, + {QLatin1String("__next__"), {}} + }; +} + using FunctionGroupMap = QMap; // Prevent ELF symbol qt_version_tag from being generated into the source @@ -541,8 +541,10 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon continue; const AbstractMetaFunction *rfunc = overloads.constFirst(); - if (m_sequenceProtocol.contains(rfunc->name()) || m_mappingProtocol.contains(rfunc->name())) + if (contains(sequenceProtocols(), rfunc->name()) + || contains(mappingProtocols(), rfunc->name())) { continue; + } if (rfunc->isConstructor()) { // @TODO: Implement constructor support for smart pointers, so that they can be @@ -1072,7 +1074,7 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s, if (!convert && argTypeEntry->isPrimitive()) { if (argTypeEntry->basicReferencedTypeEntry()) argTypeEntry = argTypeEntry->basicReferencedTypeEntry(); - convert = !m_formatUnits.contains(argTypeEntry->name()); + convert = !formatUnits().contains(argTypeEntry->name()); } StringStream ac(TextStream::Language::Cpp); @@ -2448,6 +2450,18 @@ void CppGenerator::writeArgumentConversion(TextStream &s, writeUnusedVariableCast(s, argName); } +static const QStringList &knownPythonTypes() +{ + static const QStringList result = { + pyBoolT(), pyIntT(), pyFloatT(), pyLongT(), + QLatin1String("PyObject"), QLatin1String("PyString"), + QLatin1String("PyBuffer"), QLatin1String("PySequence"), + QLatin1String("PyTuple"), QLatin1String("PyList"), + QLatin1String("PyDict"), QLatin1String("PyObject*"), + QLatin1String("PyObject *"), QLatin1String("PyTupleObject*")}; + return result; +} + std::optional CppGenerator::getArgumentType(const AbstractMetaFunction *func, int argPos) const { @@ -2466,7 +2480,7 @@ std::optional } auto argType = buildAbstractMetaTypeFromString(typeReplaced); - if (!argType.has_value() && !m_knownPythonTypes.contains(typeReplaced)) { + if (!argType.has_value() && !knownPythonTypes().contains(typeReplaced)) { qCWarning(lcShiboken, "%s", qPrintable(msgUnknownTypeInArgumentTypeReplacement(typeReplaced, func))); } @@ -4078,8 +4092,8 @@ QString CppGenerator::multipleInheritanceInitializerFunctionName(const AbstractM bool CppGenerator::supportsMappingProtocol(const AbstractMetaClass *metaClass) const { - for (auto it = m_mappingProtocol.cbegin(), end = m_mappingProtocol.cend(); it != end; ++it) { - if (metaClass->hasFunction(it.key())) + for (const auto &m : mappingProtocols()) { + if (metaClass->hasFunction(m.name)) return true; } @@ -4096,8 +4110,8 @@ bool CppGenerator::supportsNumberProtocol(const AbstractMetaClass *metaClass) co bool CppGenerator::supportsSequenceProtocol(const AbstractMetaClass *metaClass) const { - for (auto it = m_sequenceProtocol.cbegin(), end = m_sequenceProtocol.cend(); it != end; ++it) { - if (metaClass->hasFunction(it.key())) + for (const auto &seq : sequenceProtocols()) { + if (metaClass->hasFunction(seq.name)) return true; } @@ -4230,15 +4244,15 @@ void CppGenerator::writeClassDefinition(TextStream &s, tp_getset = cpythonGettersSettersDefinitionName(metaClass); // search for special functions - ShibokenGenerator::clearTpFuncs(); + clearTpFuncs(); const AbstractMetaFunctionList &funcs = metaClass->functions(); for (AbstractMetaFunction *func : funcs) { if (m_tpFuncs.contains(func->name())) m_tpFuncs[func->name()] = cpythonFunctionName(func); } - if (m_tpFuncs.value(QLatin1String("__repr__")).isEmpty() + if (m_tpFuncs.value(reprFunction()).isEmpty() && metaClass->hasToStringCapability()) { - m_tpFuncs[QLatin1String("__repr__")] = writeReprFunction(s, + m_tpFuncs[reprFunction()] = writeReprFunction(s, classContext, metaClass->toStringCapabilityIndirections()); } @@ -4276,7 +4290,7 @@ void CppGenerator::writeClassDefinition(TextStream &s, << "}\n\nstatic PyType_Slot " << className << "_slots[] = {\n" << indent << "{Py_tp_base, nullptr}, // inserted by introduceWrapperType\n" << pyTypeSlotEntry("Py_tp_dealloc", tp_dealloc) - << pyTypeSlotEntry("Py_tp_repr", m_tpFuncs.value(QLatin1String("__repr__"))) + << pyTypeSlotEntry("Py_tp_repr", m_tpFuncs.value(reprFunction())) << pyTypeSlotEntry("Py_tp_hash", tp_hash) << pyTypeSlotEntry("Py_tp_call", tp_call) << pyTypeSlotEntry("Py_tp_str", m_tpFuncs.value(QLatin1String("__str__"))) @@ -4318,16 +4332,13 @@ void CppGenerator::writeMappingMethods(TextStream &s, const AbstractMetaClass *metaClass, const GeneratorContext &context) const { - for (auto it = m_mappingProtocol.cbegin(), end = m_mappingProtocol.cend(); it != end; ++it) { - const AbstractMetaFunction *func = metaClass->findFunction(it.key()); + for (const auto & m : mappingProtocols()) { + const AbstractMetaFunction *func = metaClass->findFunction(m.name); if (!func) continue; QString funcName = cpythonFunctionName(func); - QString funcArgs = it.value().first; - QString funcRetVal = it.value().second; - CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode); - s << funcRetVal << ' ' << funcName << '(' << funcArgs << ")\n{\n"; + s << m.returnType << ' ' << funcName << '(' << m.arguments << ")\n{\n"; writeInvalidPyObjectCheck(s, QLatin1String("self")); writeCppSelfDefinition(s, func, context); @@ -4345,17 +4356,15 @@ void CppGenerator::writeSequenceMethods(TextStream &s, { bool injectedCode = false; - for (auto it = m_sequenceProtocol.cbegin(), end = m_sequenceProtocol.cend(); it != end; ++it) { - const AbstractMetaFunction *func = metaClass->findFunction(it.key()); + for (const auto &seq : sequenceProtocols()) { + const AbstractMetaFunction *func = metaClass->findFunction(seq.name); if (!func) continue; injectedCode = true; QString funcName = cpythonFunctionName(func); - QString funcArgs = it.value().first; - QString funcRetVal = it.value().second; CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode); - s << funcRetVal << ' ' << funcName << '(' << funcArgs << ")\n{\n" << indent; + s << seq.returnType << ' ' << funcName << '(' << seq.arguments << ")\n{\n" << indent; writeInvalidPyObjectCheck(s, QLatin1String("self")); writeCppSelfDefinition(s, func, context); @@ -4369,16 +4378,30 @@ void CppGenerator::writeSequenceMethods(TextStream &s, writeDefaultSequenceMethods(s, context); } +// Sequence protocol structure member names +static const QHash &sqFuncs() +{ + static const QHash result = { + {QLatin1String("__concat__"), QLatin1String("sq_concat")}, + {QLatin1String("__contains__"), QLatin1String("sq_contains")}, + {QLatin1String("__getitem__"), QLatin1String("sq_item")}, + {QLatin1String("__getslice__"), QLatin1String("sq_slice")}, + {QLatin1String("__len__"), QLatin1String("sq_length")}, + {QLatin1String("__setitem__"), QLatin1String("sq_ass_item")}, + {QLatin1String("__setslice__"), QLatin1String("sq_ass_slice")} + }; + return result; +} + void CppGenerator::writeTypeAsSequenceDefinition(TextStream &s, const AbstractMetaClass *metaClass) const { bool hasFunctions = false; QMap funcs; - for (auto it = m_sequenceProtocol.cbegin(), end = m_sequenceProtocol.cend(); it != end; ++it) { - const QString &funcName = it.key(); - const AbstractMetaFunction *func = metaClass->findFunction(funcName); - funcs[funcName] = func ? cpythonFunctionName(func).prepend(QLatin1Char('&')) : QString(); - if (!hasFunctions && func) + for (const auto &seq : sequenceProtocols()) { + if (const AbstractMetaFunction *func = metaClass->findFunction(seq.name)) { + funcs.insert(seq.name, QLatin1Char('&') + cpythonFunctionName(func)); hasFunctions = true; + } } QString baseName = cpythonBaseName(metaClass); @@ -4390,69 +4413,78 @@ void CppGenerator::writeTypeAsSequenceDefinition(TextStream &s, const AbstractMe funcs[QLatin1String("__setitem__")] = baseName + QLatin1String("__setitem__"); } - for (QHash::const_iterator it = m_sqFuncs.cbegin(), end = m_sqFuncs.cend(); it != end; ++it) { + for (auto it = sqFuncs().cbegin(), end = sqFuncs().cend(); it != end; ++it) { const QString &sqName = it.key(); - if (funcs[sqName].isEmpty()) - continue; - s << "{Py_" << it.value() << ", (void *)" << funcs[sqName] << "},\n"; + auto fit = funcs.constFind(sqName); + if (fit != funcs.constEnd()) { + s << "{Py_" << it.value() << ", reinterpret_cast(" + << fit.value() << ")},\n"; + } } } void CppGenerator::writeTypeAsMappingDefinition(TextStream &s, const AbstractMetaClass *metaClass) const { - bool hasFunctions = false; + // Sequence protocol structure members names + static const QHash mpFuncs{ + {QLatin1String("__mlen__"), QLatin1String("mp_length")}, + {QLatin1String("__mgetitem__"), QLatin1String("mp_subscript")}, + {QLatin1String("__msetitem__"), QLatin1String("mp_ass_subscript")}, + }; QMap funcs; - for (auto it = m_mappingProtocol.cbegin(), end = m_mappingProtocol.cend(); it != end; ++it) { - const QString &funcName = it.key(); - const AbstractMetaFunction *func = metaClass->findFunction(funcName); - funcs[funcName] = func ? cpythonFunctionName(func).prepend(QLatin1Char('&')) : QLatin1String("0"); - if (!hasFunctions && func) - hasFunctions = true; - } - - //use default implementation - if (!hasFunctions) { - funcs.insert(QLatin1String("__mlen__"), QString()); - funcs.insert(QLatin1String("__mgetitem__"), QString()); - funcs.insert(QLatin1String("__msetitem__"), QString()); - } - - for (auto it = m_mpFuncs.cbegin(), end = m_mpFuncs.cend(); it != end; ++it) { - const QString &mpName = it.key(); - if (funcs[mpName].isEmpty()) - continue; - s << "{Py_" << it.value() << ", (void *)" << funcs[mpName] << "},\n"; - } + for (const auto &m : mappingProtocols()) { + if (const AbstractMetaFunction *func = metaClass->findFunction(m.name)) { + const QString entry = QLatin1String("reinterpret_cast(&") + + cpythonFunctionName(func) + QLatin1Char(')'); + funcs.insert(m.name, entry); + } else { + funcs.insert(m.name, QLatin1String(NULL_PTR)); + } + } + + for (auto it = mpFuncs.cbegin(), end = mpFuncs.cend(); it != end; ++it) { + const auto fit = funcs.constFind(it.key()); + if (fit != funcs.constEnd()) + s << "{Py_" << it.value() << ", " << fit.value() << "},\n"; + } +} + +// Number protocol structure members names +static const QHash &nbFuncs() +{ + static const QHash result = { + {QLatin1String("__add__"), QLatin1String("nb_add")}, + {QLatin1String("__sub__"), QLatin1String("nb_subtract")}, + {QLatin1String("__mul__"), QLatin1String("nb_multiply")}, + {QLatin1String("__div__"), QLatin1String("nb_divide")}, + {QLatin1String("__mod__"), QLatin1String("nb_remainder")}, + {QLatin1String("__neg__"), QLatin1String("nb_negative")}, + {QLatin1String("__pos__"), QLatin1String("nb_positive")}, + {QLatin1String("__invert__"), QLatin1String("nb_invert")}, + {QLatin1String("__lshift__"), QLatin1String("nb_lshift")}, + {QLatin1String("__rshift__"), QLatin1String("nb_rshift")}, + {QLatin1String("__and__"), QLatin1String("nb_and")}, + {QLatin1String("__xor__"), QLatin1String("nb_xor")}, + {QLatin1String("__or__"), QLatin1String("nb_or")}, + {QLatin1String("__iadd__"), QLatin1String("nb_inplace_add")}, + {QLatin1String("__isub__"), QLatin1String("nb_inplace_subtract")}, + {QLatin1String("__imul__"), QLatin1String("nb_inplace_multiply")}, + {QLatin1String("__idiv__"), QLatin1String("nb_inplace_divide")}, + {QLatin1String("__imod__"), QLatin1String("nb_inplace_remainder")}, + {QLatin1String("__ilshift__"), QLatin1String("nb_inplace_lshift")}, + {QLatin1String("__irshift__"), QLatin1String("nb_inplace_rshift")}, + {QLatin1String("__iand__"), QLatin1String("nb_inplace_and")}, + {QLatin1String("__ixor__"), QLatin1String("nb_inplace_xor")}, + {QLatin1String("__ior__"), QLatin1String("nb_inplace_or")}, + {boolT(), QLatin1String("nb_nonzero")} + }; + return result; } void CppGenerator::writeTypeAsNumberDefinition(TextStream &s, const AbstractMetaClass *metaClass) const { QMap nb; - nb.insert(QLatin1String("__add__"), QString()); - nb.insert(QLatin1String("__sub__"), QString()); - nb.insert(QLatin1String("__mul__"), QString()); - nb.insert(QLatin1String("__div__"), QString()); - nb.insert(QLatin1String("__mod__"), QString()); - nb.insert(QLatin1String("__neg__"), QString()); - nb.insert(QLatin1String("__pos__"), QString()); - nb.insert(QLatin1String("__invert__"), QString()); - nb.insert(QLatin1String("__lshift__"), QString()); - nb.insert(QLatin1String("__rshift__"), QString()); - nb.insert(QLatin1String("__and__"), QString()); - nb.insert(QLatin1String("__xor__"), QString()); - nb.insert(QLatin1String("__or__"), QString()); - nb.insert(QLatin1String("__iadd__"), QString()); - nb.insert(QLatin1String("__isub__"), QString()); - nb.insert(QLatin1String("__imul__"), QString()); - nb.insert(QLatin1String("__idiv__"), QString()); - nb.insert(QLatin1String("__imod__"), QString()); - nb.insert(QLatin1String("__ilshift__"), QString()); - nb.insert(QLatin1String("__irshift__"), QString()); - nb.insert(QLatin1String("__iand__"), QString()); - nb.insert(QLatin1String("__ixor__"), QString()); - nb.insert(QLatin1String("__ior__"), QString()); - const QList opOverloads = filterGroupedOperatorFunctions(metaClass, AbstractMetaClass::ArithmeticOp @@ -4468,27 +4500,29 @@ void CppGenerator::writeTypeAsNumberDefinition(TextStream &s, const AbstractMeta QString baseName = cpythonBaseName(metaClass); if (hasBoolCast(metaClass)) - nb.insert(QLatin1String("bool"), baseName + QLatin1String("___nb_bool")); + nb.insert(boolT(), baseName + QLatin1String("___nb_bool")); - for (QHash::const_iterator it = m_nbFuncs.cbegin(), end = m_nbFuncs.cend(); it != end; ++it) { + for (auto it = nbFuncs().cbegin(), end = nbFuncs().cend(); it != end; ++it) { const QString &nbName = it.key(); - if (nb[nbName].isEmpty()) - continue; - - if (nbName == QLatin1String("bool")) { - s << "{Py_nb_bool, (void *)" << nb[nbName] << "},\n"; - } else { - bool excludeFromPy3K = nbName == QLatin1String("__div__") || nbName == QLatin1String("__idiv__"); - if (!excludeFromPy3K) - s << "{Py_" << it.value() << ", (void *)" << nb[nbName] << "},\n"; + if (nbName == QLatin1String("__div__") || nbName == QLatin1String("__idiv__")) + continue; // excludeFromPy3K + const auto nbIt = nb.constFind(nbName); + if (nbIt != nb.constEnd()) { + const QString fixednbName = nbName == boolT() + ? QLatin1String("nb_bool") : it.value(); + s << "{Py_" << fixednbName << ", reinterpret_cast(" + << nbIt.value() << ")},\n"; } } - if (!nb[QLatin1String("__div__")].isEmpty()) - s << "{Py_nb_true_divide, (void *)" << nb[QLatin1String("__div__")] << "},\n"; - if (!nb[QLatin1String("__idiv__")].isEmpty()) { + auto nbIt = nb.constFind(QLatin1String("__div__")); + if (nbIt != nb.constEnd()) + s << "{Py_nb_true_divide, reinterpret_cast(" << nbIt.value() << ")},\n"; + + nbIt = nb.constFind(QLatin1String("__idiv__")); + if (nbIt != nb.constEnd()) { s << "// This function is unused in Python 3. We reference it here.\n" - << "{0, (void *)" << nb[QLatin1String("__idiv__")] << "},\n" + << "{0, reinterpret_cast(" << nbIt.value() << ")},\n" << "// This list is ending at the first 0 entry.\n" << "// Therefore, we need to put the unused functions at the very end.\n"; } @@ -6413,7 +6447,7 @@ QString CppGenerator::writeReprFunction(TextStream &s, uint indirections) const { const AbstractMetaClass *metaClass = context.metaClass(); - QString funcName = cpythonBaseName(metaClass) + QLatin1String("__repr__"); + QString funcName = cpythonBaseName(metaClass) + reprFunction(); s << "extern \"C\"\n{\n" << "static PyObject *" << funcName << "(PyObject *self)\n{\n" << indent; writeCppSelfDefinition(s, context); diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h index 32e44ce59..0c5be6ebc 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.h +++ b/sources/shiboken6/generator/shiboken/cppgenerator.h @@ -401,20 +401,9 @@ private: std::optional findSmartPointerInstantiation(const TypeEntry *entry) const; - // Number protocol structure members names. - static QHash m_nbFuncs; - - // Maps special function names to function parameters and return types - // used by CPython API in the sequence protocol. - QHash > m_sequenceProtocol; - // Sequence protocol structure members names. - static QHash m_sqFuncs; - - // Maps special function names to function parameters and return types - // used by CPython API in the mapping protocol. - QHash > m_mappingProtocol; - // Mapping protocol structure members names. - static QHash m_mpFuncs; + void clearTpFuncs(); + + QHash m_tpFuncs; static QString m_currentErrorCode; diff --git a/sources/shiboken6/generator/shiboken/pytypenames.h b/sources/shiboken6/generator/shiboken/pytypenames.h new file mode 100644 index 000000000..bd5994cf4 --- /dev/null +++ b/sources/shiboken6/generator/shiboken/pytypenames.h @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PYTYPENAMES_H +#define PYTYPENAMES_H + +#include + +static inline QString pyBoolT() { return QStringLiteral("PyBool"); } +static inline QString pyFloatT() { return QStringLiteral("PyFloat"); } +static inline QString pyIntT() { return QStringLiteral("PyInt"); } +static inline QString pyLongT() { return QStringLiteral("PyLong"); } + +static inline QString sbkCharT() { return QStringLiteral("SbkChar"); } + +#endif // PYTYPENAMES_H diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp index 3e8153175..4d3ac58b2 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp @@ -36,6 +36,7 @@ #include #include "overloaddata.h" #include "propertyspec.h" +#include "pytypenames.h" #include #include #include @@ -73,14 +74,6 @@ const char *BEGIN_ALLOW_THREADS = "PyThreadState *_save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS"; const char *END_ALLOW_THREADS = "PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS"; -//static void dumpFunction(AbstractMetaFunctionList lst); - -QHash ShibokenGenerator::m_pythonPrimitiveTypeName = QHash(); -QHash ShibokenGenerator::m_pythonOperators = QHash(); -QHash ShibokenGenerator::m_formatUnits = QHash(); -QHash ShibokenGenerator::m_tpFuncs = QHash(); -QStringList ShibokenGenerator::m_knownPythonTypes = QStringList(); - // Return a prefix to fully qualify value, eg: // resolveScopePrefix("Class::NestedClass::Enum::Value1", "Enum::Value1") // -> "Class::NestedClass::") @@ -133,22 +126,6 @@ Q_GLOBAL_STATIC(GeneratorClassInfoCache, generatorClassInfoCache) ShibokenGenerator::ShibokenGenerator() { - if (m_pythonPrimitiveTypeName.isEmpty()) - ShibokenGenerator::initPrimitiveTypesCorrespondences(); - - if (m_tpFuncs.isEmpty()) - ShibokenGenerator::clearTpFuncs(); - - if (m_knownPythonTypes.isEmpty()) - ShibokenGenerator::initKnownPythonTypes(); - - m_metaTypeFromStringCache = AbstractMetaTypeCache(); - - m_typeSystemConvName[TypeSystemCheckFunction] = QLatin1String("checkType"); - m_typeSystemConvName[TypeSystemIsConvertibleFunction] = QLatin1String("isConvertible"); - m_typeSystemConvName[TypeSystemToCppFunction] = QLatin1String("toCpp"); - m_typeSystemConvName[TypeSystemToPythonFunction] = QLatin1String("toPython"); - const char CHECKTYPE_REGEX[] = R"(%CHECKTYPE\[([^\[]*)\]\()"; const char ISCONVERTIBLE_REGEX[] = R"(%ISCONVERTIBLE\[([^\[]*)\]\()"; const char CONVERTTOPYTHON_REGEX[] = R"(%CONVERTTOPYTHON\[([^\[]*)\]\()"; @@ -164,122 +141,60 @@ ShibokenGenerator::ShibokenGenerator() ShibokenGenerator::~ShibokenGenerator() = default; -void ShibokenGenerator::clearTpFuncs() -{ - m_tpFuncs.insert(QLatin1String("__str__"), QString()); - m_tpFuncs.insert(QLatin1String("__repr__"), QString()); - m_tpFuncs.insert(QLatin1String("__iter__"), QString()); - m_tpFuncs.insert(QLatin1String("__next__"), QString()); +// Correspondences between primitive and Python types. +static const QHash &primitiveTypesCorrespondences() +{ + static const QHash result = { + {QLatin1String("bool"), pyBoolT()}, + {QLatin1String("char"), sbkCharT()}, + {QLatin1String("signed char"), sbkCharT()}, + {QLatin1String("unsigned char"), sbkCharT()}, + {intT(), pyIntT()}, + {QLatin1String("signed int"), pyIntT()}, + {QLatin1String("uint"), pyIntT()}, + {QLatin1String("unsigned int"), pyIntT()}, + {shortT(), pyIntT()}, + {QLatin1String("ushort"), pyIntT()}, + {QLatin1String("signed short"), pyIntT()}, + {QLatin1String("signed short int"), pyIntT()}, + {unsignedShortT(), pyIntT()}, + {QLatin1String("unsigned short int"), pyIntT()}, + {longT(), pyIntT()}, + {doubleT(), pyFloatT()}, + {floatT(), pyFloatT()}, + {QLatin1String("unsigned long"), pyLongT()}, + {QLatin1String("signed long"), pyLongT()}, + {QLatin1String("ulong"), pyLongT()}, + {QLatin1String("unsigned long int"), pyLongT()}, + {QLatin1String("long long"), pyLongT()}, + {QLatin1String("__int64"), pyLongT()}, + {QLatin1String("unsigned long long"), pyLongT()}, + {QLatin1String("unsigned __int64"), pyLongT()}, + {QLatin1String("size_t"), pyLongT()} + }; + return result; } -void ShibokenGenerator::initPrimitiveTypesCorrespondences() -{ - // Python primitive types names - m_pythonPrimitiveTypeName.clear(); - - // PyBool - m_pythonPrimitiveTypeName.insert(QLatin1String("bool"), QLatin1String("PyBool")); - - const char *charTypes[] = { - "char", "signed char", "unsigned char" +// Format units for C++->Python->C++ conversion +const QHash &ShibokenGenerator::formatUnits() +{ + static const QHash result = { + {QLatin1String("char"), QLatin1String("b")}, + {QLatin1String("unsigned char"), QLatin1String("B")}, + {intT(), QLatin1String("i")}, + {QLatin1String("unsigned int"), QLatin1String("I")}, + {shortT(), QLatin1String("h")}, + {unsignedShortT(), QLatin1String("H")}, + {longT(), QLatin1String("l")}, + {unsignedLongLongT(), QLatin1String("k")}, + {longLongT(), QLatin1String("L")}, + {QLatin1String("__int64"), QLatin1String("L")}, + {unsignedLongLongT(), QLatin1String("K")}, + {QLatin1String("unsigned __int64"), QLatin1String("K")}, + {doubleT(), QLatin1String("d")}, + {floatT(), QLatin1String("f")}, }; - for (const char *charType : charTypes) - m_pythonPrimitiveTypeName.insert(QLatin1String(charType), QStringLiteral("SbkChar")); - - // PyInt - const char *intTypes[] = { - "int", "signed int", "uint", "unsigned int", - "short", "ushort", "signed short", "signed short int", - "unsigned short", "unsigned short", "unsigned short int", - "long" - }; - for (const char *intType : intTypes) - m_pythonPrimitiveTypeName.insert(QLatin1String(intType), QStringLiteral("PyInt")); - - // PyFloat - m_pythonPrimitiveTypeName.insert(doubleT(), QLatin1String("PyFloat")); - m_pythonPrimitiveTypeName.insert(floatT(), QLatin1String("PyFloat")); - - // PyLong - const char *longTypes[] = { - "unsigned long", "signed long", "ulong", "unsigned long int", - "long long", "__int64", - "unsigned long long", "unsigned __int64", "size_t" - }; - for (const char *longType : longTypes) - m_pythonPrimitiveTypeName.insert(QLatin1String(longType), QStringLiteral("PyLong")); - - // Python operators - m_pythonOperators.clear(); - - // call operator - m_pythonOperators.insert(QLatin1String("operator()"), QLatin1String("call")); - - // Arithmetic operators - m_pythonOperators.insert(QLatin1String("operator+"), QLatin1String("add")); - m_pythonOperators.insert(QLatin1String("operator-"), QLatin1String("sub")); - m_pythonOperators.insert(QLatin1String("operator*"), QLatin1String("mul")); - m_pythonOperators.insert(QLatin1String("operator/"), QLatin1String("div")); - m_pythonOperators.insert(QLatin1String("operator%"), QLatin1String("mod")); - - // Inplace arithmetic operators - m_pythonOperators.insert(QLatin1String("operator+="), QLatin1String("iadd")); - m_pythonOperators.insert(QLatin1String("operator-="), QLatin1String("isub")); - m_pythonOperators.insert(QLatin1String("operator++"), QLatin1String("iadd")); - m_pythonOperators.insert(QLatin1String("operator--"), QLatin1String("isub")); - m_pythonOperators.insert(QLatin1String("operator*="), QLatin1String("imul")); - m_pythonOperators.insert(QLatin1String("operator/="), QLatin1String("idiv")); - m_pythonOperators.insert(QLatin1String("operator%="), QLatin1String("imod")); - - // Bitwise operators - m_pythonOperators.insert(QLatin1String("operator&"), QLatin1String("and")); - m_pythonOperators.insert(QLatin1String("operator^"), QLatin1String("xor")); - m_pythonOperators.insert(QLatin1String("operator|"), QLatin1String("or")); - m_pythonOperators.insert(QLatin1String("operator<<"), QLatin1String("lshift")); - m_pythonOperators.insert(QLatin1String("operator>>"), QLatin1String("rshift")); - m_pythonOperators.insert(QLatin1String("operator~"), QLatin1String("invert")); - - // Inplace bitwise operators - m_pythonOperators.insert(QLatin1String("operator&="), QLatin1String("iand")); - m_pythonOperators.insert(QLatin1String("operator^="), QLatin1String("ixor")); - m_pythonOperators.insert(QLatin1String("operator|="), QLatin1String("ior")); - m_pythonOperators.insert(QLatin1String("operator<<="), QLatin1String("ilshift")); - m_pythonOperators.insert(QLatin1String("operator>>="), QLatin1String("irshift")); - - // Comparison operators - m_pythonOperators.insert(QLatin1String("operator=="), QLatin1String("eq")); - m_pythonOperators.insert(QLatin1String("operator!="), QLatin1String("ne")); - m_pythonOperators.insert(QLatin1String("operator<"), QLatin1String("lt")); - m_pythonOperators.insert(QLatin1String("operator>"), QLatin1String("gt")); - m_pythonOperators.insert(QLatin1String("operator<="), QLatin1String("le")); - m_pythonOperators.insert(QLatin1String("operator>="), QLatin1String("ge")); - - // Initialize format units for C++->Python->C++ conversion - m_formatUnits.clear(); - m_formatUnits.insert(QLatin1String("char"), QLatin1String("b")); - m_formatUnits.insert(QLatin1String("unsigned char"), QLatin1String("B")); - m_formatUnits.insert(intT(), QLatin1String("i")); - m_formatUnits.insert(QLatin1String("unsigned int"), QLatin1String("I")); - m_formatUnits.insert(shortT(), QLatin1String("h")); - m_formatUnits.insert(unsignedShortT(), QLatin1String("H")); - m_formatUnits.insert(longT(), QLatin1String("l")); - m_formatUnits.insert(unsignedLongLongT(), QLatin1String("k")); - m_formatUnits.insert(longLongT(), QLatin1String("L")); - m_formatUnits.insert(QLatin1String("__int64"), QLatin1String("L")); - m_formatUnits.insert(unsignedLongLongT(), QLatin1String("K")); - m_formatUnits.insert(QLatin1String("unsigned __int64"), QLatin1String("K")); - m_formatUnits.insert(doubleT(), QLatin1String("d")); - m_formatUnits.insert(floatT(), QLatin1String("f")); -} - -void ShibokenGenerator::initKnownPythonTypes() -{ - m_knownPythonTypes.clear(); - m_knownPythonTypes << QLatin1String("PyBool") << QLatin1String("PyInt") - << QLatin1String("PyFloat") << QLatin1String("PyLong") << QLatin1String("PyObject") - << QLatin1String("PyString") << QLatin1String("PyBuffer") << QLatin1String("PySequence") - << QLatin1String("PyTuple") << QLatin1String("PyList") << QLatin1String("PyDict") - << QLatin1String("PyObject*") << QLatin1String("PyObject *") << QLatin1String("PyTupleObject*"); + return result; } QString ShibokenGenerator::translateTypeForWrapperMethod(const AbstractMetaType &cType, @@ -764,8 +679,9 @@ QString ShibokenGenerator::getFormatUnitString(const AbstractMetaFunction *func, static_cast(type.typeEntry()); if (ptype->basicReferencedTypeEntry()) ptype = ptype->basicReferencedTypeEntry(); - if (m_formatUnits.contains(ptype->name())) - result += m_formatUnits[ptype->name()]; + const auto it = formatUnits().constFind(ptype->name()); + if (it != formatUnits().cend()) + result += it.value(); else result += QLatin1Char(objType); } else if (type.isCString()) { @@ -953,7 +869,7 @@ QString ShibokenGenerator::fixedCppTypeName(const TypeEntry *type, QString typeN QString ShibokenGenerator::pythonPrimitiveTypeName(const QString &cppTypeName) { - QString rv = ShibokenGenerator::m_pythonPrimitiveTypeName.value(cppTypeName, QString()); + QString rv = primitiveTypesCorrespondences().value(cppTypeName, QString()); if (rv.isEmpty()) { // activate this when some primitive types are missing, // i.e. when shiboken itself fails to build. @@ -974,9 +890,52 @@ QString ShibokenGenerator::pythonPrimitiveTypeName(const PrimitiveTypeEntry *typ return pythonPrimitiveTypeName(type->name()); } +static const QHash &pythonOperators() +{ + static const QHash result = { + // call operator + {QLatin1String("operator()"), QLatin1String("call")}, + // Arithmetic operators + {QLatin1String("operator+"), QLatin1String("add")}, + {QLatin1String("operator-"), QLatin1String("sub")}, + {QLatin1String("operator*"), QLatin1String("mul")}, + {QLatin1String("operator/"), QLatin1String("div")}, + {QLatin1String("operator%"), QLatin1String("mod")}, + // Inplace arithmetic operators + {QLatin1String("operator+="), QLatin1String("iadd")}, + {QLatin1String("operator-="), QLatin1String("isub")}, + {QLatin1String("operator++"), QLatin1String("iadd")}, + {QLatin1String("operator--"), QLatin1String("isub")}, + {QLatin1String("operator*="), QLatin1String("imul")}, + {QLatin1String("operator/="), QLatin1String("idiv")}, + {QLatin1String("operator%="), QLatin1String("imod")}, + // Bitwise operators + {QLatin1String("operator&"), QLatin1String("and")}, + {QLatin1String("operator^"), QLatin1String("xor")}, + {QLatin1String("operator|"), QLatin1String("or")}, + {QLatin1String("operator<<"), QLatin1String("lshift")}, + {QLatin1String("operator>>"), QLatin1String("rshift")}, + {QLatin1String("operator~"), QLatin1String("invert")}, + // Inplace bitwise operators + {QLatin1String("operator&="), QLatin1String("iand")}, + {QLatin1String("operator^="), QLatin1String("ixor")}, + {QLatin1String("operator|="), QLatin1String("ior")}, + {QLatin1String("operator<<="), QLatin1String("ilshift")}, + {QLatin1String("operator>>="), QLatin1String("irshift")}, + // Comparison operators + {QLatin1String("operator=="), QLatin1String("eq")}, + {QLatin1String("operator!="), QLatin1String("ne")}, + {QLatin1String("operator<"), QLatin1String("lt")}, + {QLatin1String("operator>"), QLatin1String("gt")}, + {QLatin1String("operator<="), QLatin1String("le")}, + {QLatin1String("operator>="), QLatin1String("ge")}, + }; + return result; +} + QString ShibokenGenerator::pythonOperatorFunctionName(const QString &cppOpFuncName) { - QString value = m_pythonOperators.value(cppOpFuncName); + QString value = pythonOperators().value(cppOpFuncName); if (value.isEmpty()) return unknownOperator(); value.prepend(QLatin1String("__")); @@ -1004,7 +963,7 @@ QString ShibokenGenerator::pythonOperatorFunctionName(const AbstractMetaFunction QString ShibokenGenerator::pythonRichCompareOperatorId(const QString &cppOpFuncName) { - return QLatin1String("Py_") + m_pythonOperators.value(cppOpFuncName).toUpper(); + return QLatin1String("Py_") + pythonOperators().value(cppOpFuncName).toUpper(); } QString ShibokenGenerator::pythonRichCompareOperatorId(const AbstractMetaFunction *func) @@ -1014,10 +973,9 @@ QString ShibokenGenerator::pythonRichCompareOperatorId(const AbstractMetaFunctio bool ShibokenGenerator::isNumber(const QString &cpythonApiName) { - return cpythonApiName == QLatin1String("PyInt") - || cpythonApiName == QLatin1String("PyFloat") - || cpythonApiName == QLatin1String("PyLong") - || cpythonApiName == QLatin1String("PyBool"); + return cpythonApiName == pyIntT() + || cpythonApiName == pyFloatT() || cpythonApiName == pyLongT() + || cpythonApiName == pyBoolT(); } bool ShibokenGenerator::isNumber(const TypeEntry *type) @@ -1959,6 +1917,18 @@ static QString getConverterTypeSystemVariableArgument(const QString &code, int p qFatal("Unbalanced parenthesis on type system converter variable call."); return arg; } + +const QHash &ShibokenGenerator::typeSystemConvName() +{ + static const QHash result = { + {TypeSystemCheckFunction, QLatin1String("checkType")}, + {TypeSystemIsConvertibleFunction, QLatin1String("isConvertible")}, + {TypeSystemToCppFunction, QLatin1String("toCpp")}, + {TypeSystemToPythonFunction, QLatin1String("toPython")} + }; + return result; +} + using StringPair = QPair; void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVariable converterVariable, @@ -1975,7 +1945,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa const auto conversionTypeO = buildAbstractMetaTypeFromString(conversionTypeName, &message); if (!conversionTypeO.has_value()) { qFatal("%s", qPrintable(msgCannotFindType(conversionTypeName, - m_typeSystemConvName[converterVariable], + typeSystemConvName().value(converterVariable), message))); } const auto conversionType = conversionTypeO.value(); diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h index 8d25bcc95..9bca5f85e 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.h +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h @@ -346,14 +346,6 @@ protected: void collectContainerTypesFromConverterMacros(const QString &code, bool toPythonMacro); - void clearTpFuncs(); - - - /// Initializes correspondences between primitive and Python types. - static void initPrimitiveTypesCorrespondences(); - /// Initializes a list of Python known type names. - static void initKnownPythonTypes(); - void writeFunctionCall(TextStream &s, const AbstractMetaFunction *metaFunc, Options options = NoOption) const; @@ -379,11 +371,7 @@ protected: static QString pythonArgsAt(int i); - static QHash m_pythonPrimitiveTypeName; - static QHash m_pythonOperators; - static QHash m_formatUnits; - static QHash m_tpFuncs; - static QStringList m_knownPythonTypes; + static const QHash &formatUnits(); private: static QString cpythonGetterFunctionName(const QString &name, @@ -513,7 +501,7 @@ private: mutable AbstractMetaTypeCache m_metaTypeFromStringCache; /// Type system converter variable replacement names and regular expressions. - QString m_typeSystemConvName[TypeSystemConverterVariables]; + static const QHash &typeSystemConvName(); QRegularExpression m_typeSystemConvRegEx[TypeSystemConverterVariables]; }; -- cgit v1.2.3