diff options
-rw-r--r-- | generator/cppgenerator.cpp | 363 | ||||
-rw-r--r-- | generator/cppgenerator.h | 4 | ||||
-rw-r--r-- | generator/shibokengenerator.cpp | 215 | ||||
-rw-r--r-- | generator/shibokengenerator.h | 4 | ||||
-rw-r--r-- | libshiboken/sbkenum.cpp | 12 | ||||
-rw-r--r-- | libshiboken/sbkenum.h | 6 |
6 files changed, 266 insertions, 338 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp index 0e32f76..216509e 100644 --- a/generator/cppgenerator.cpp +++ b/generator/cppgenerator.cpp @@ -192,21 +192,6 @@ void CppGenerator::writeRegisterType(QTextStream& s, const AbstractMetaEnum* met } } -void CppGenerator::writeToPythonFunction(QTextStream& s, const AbstractMetaClass* metaClass) -{ - ErrorCode errorCode(0); - s << "static PyObject* " << cpythonBaseName(metaClass) << "_ToPythonFunc(PyObject* " PYTHON_SELF_VAR ")" << endl; - s << '{' << endl; - writeCppSelfDefinition(s, metaClass); - - s << INDENT << "PyObject* " PYTHON_RETURN_VAR " = Shiboken::PythonConverter< ::" << metaClass->qualifiedCppName(); - s << " >::transformToPython(" CPP_SELF_VAR ");" << endl; - - writeFunctionReturnErrorCheckSection(s); - s << INDENT << "return " PYTHON_RETURN_VAR ";" << endl; - s << '}' << endl; -} - bool CppGenerator::hasBoolCast(const AbstractMetaClass* metaClass) const { if (!useIsNullAsNbNonZero()) @@ -389,12 +374,6 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl } } - //ToPython used by Python Conversion - if (metaClass->typeEntry()->hasTargetConversionRule()) { - writeToPythonFunction(s, metaClass); - md << INDENT << "{\"toPython\", (PyCFunction)" << cpythonBaseName(metaClass) << "_ToPythonFunc, METH_NOARGS}," << endl; - } - QString className = cpythonTypeName(metaClass).replace(QRegExp("_Type$"), ""); if (metaClass->typeEntry()->isValue()) @@ -800,7 +779,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun s << INDENT << "// Check return type" << endl; s << INDENT; - if (func->typeReplaced(0).isEmpty() && !retType->isEnum() && !retType->isFlags()) { + if (func->typeReplaced(0).isEmpty()) { s << "PythonToCppFunc " PYTHON_TO_CPP_VAR " = " << cpythonIsConvertibleFunction(func->type()); s << PYTHON_RETURN_VAR ");" << endl; s << INDENT << "if (!" PYTHON_TO_CPP_VAR ") {" << endl; @@ -814,7 +793,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun } s << INDENT << '}' << endl; - } else { // TODO-CONVERTER -------------------------------------------------------------- + } else { s << INDENT << "// Check return type" << endl; s << INDENT << "bool typeIsValid = "; @@ -834,7 +813,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun } s << INDENT << '}' << endl; - } // TODO-CONVERTER --------------------------------------------------------------------- + } } if (!func->conversionRule(TypeSystem::NativeCode, 0).isEmpty()) { @@ -948,11 +927,90 @@ void CppGenerator::writeMetaCast(QTextStream& s, const AbstractMetaClass* metaCl s << "}" << endl << endl; } +void CppGenerator::writeEnumConverterFunctions(QTextStream& s, const AbstractMetaEnum* metaEnum) +{ + if (metaEnum->isPrivate() || metaEnum->isAnonymous()) + return; + writeEnumConverterFunctions(s, metaEnum->typeEntry()); +} + +void CppGenerator::writeEnumConverterFunctions(QTextStream& s, const TypeEntry* enumType) +{ + if (!enumType) + return; + QString enumFlagName = enumType->isFlags() ? "flag" : "enum"; + QString typeName = fixedCppTypeName(enumType); + QString cppTypeName = getFullTypeName(enumType).trimmed(); + QString enumPythonType = cpythonTypeNameExt(enumType); + QString code; + QTextStream c(&code); + c << INDENT << "*((" << cppTypeName << "*)cppOut) = "; + if (enumType->isFlags()) + c << cppTypeName << "(QFlag(PySide::QFlags::getValue(reinterpret_cast<PySideQFlagsObject*>(pyIn))))"; + else + c << "(" << cppTypeName << ") Shiboken::Enum::getValue(pyIn)"; + c << ';' << endl; + writePythonToCppFunction(s, code, typeName, typeName); + + QString pyTypeCheck = QString("PyObject_TypeCheck(pyIn, %1)").arg(enumPythonType); + writeIsPythonConvertibleToCppFunction(s, typeName, typeName, pyTypeCheck); + + code.clear(); + + c << INDENT << "long castCppIn = (long) *((" << cppTypeName << "*)cppIn);" << endl; + c << INDENT; + c << "return "; + if (enumType->isFlags()) + c << "reinterpret_cast<PyObject*>(PySide::QFlags::newObject(castCppIn, " << enumPythonType << "))"; + + else + c << "Shiboken::Enum::newItem(" << enumPythonType << ", castCppIn)"; + c << ';' << endl; + writeCppToPythonFunction(s, code, typeName, typeName); + s << endl; + + if (enumType->isFlags()) + return; + + const FlagsTypeEntry* flags = reinterpret_cast<const EnumTypeEntry*>(enumType)->flags(); + if (!flags) + return; + + // QFlags part. + + writeEnumConverterFunctions(s, flags); + + code.clear(); + cppTypeName = getFullTypeName(flags).trimmed(); + c << INDENT << "*((" << cppTypeName << "*)cppOut) = " << cppTypeName; + c << "(QFlag(Shiboken::Enum::getValue(pyIn)));" << endl; + + QString flagsTypeName = fixedCppTypeName(flags); + writePythonToCppFunction(s, code, typeName, flagsTypeName); + writeIsPythonConvertibleToCppFunction(s, typeName, flagsTypeName, pyTypeCheck); + + code.clear(); + c << INDENT << "Shiboken::AutoDecRef pyLong(PyNumber_Long(pyIn));" << endl; + c << INDENT << "*((" << cppTypeName << "*)cppOut) = " << cppTypeName; + c << "(QFlag(PyLong_AsLong(pyLong.object())));" << endl; + writePythonToCppFunction(s, code, "number", flagsTypeName); + writeIsPythonConvertibleToCppFunction(s, "number", flagsTypeName, "PyNumber_Check(pyIn)"); +} + void CppGenerator::writeConverterFunctions(QTextStream& s, const AbstractMetaClass* metaClass) { + s << "// Type conversion functions." << endl << endl; + + AbstractMetaEnumList classEnums = metaClass->enums(); + foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) + lookForEnumsInClassesNotToBeGenerated(classEnums, innerClass); + if (!classEnums.isEmpty()) + s << "// Python to C++ enum conversion." << endl; + foreach (const AbstractMetaEnum* metaEnum, classEnums) + writeEnumConverterFunctions(s, metaEnum); + if (metaClass->isNamespace()) return; - s << "// Type conversion functions." << endl << endl; QString typeName = getFullTypeName(metaClass); QString cpythonType = cpythonTypeName(metaClass); @@ -1053,8 +1111,13 @@ void CppGenerator::writeConverterFunctions(QTextStream& s, const AbstractMetaCla typeCheck = cpythonCheckFunction(sourceType); bool isUserPrimitiveWithoutTargetLangName = isUserPrimitive(sourceType) && sourceType->typeEntry()->targetLangApiName() == sourceType->typeEntry()->name(); - if (!isWrapperType(sourceType) && !isUserPrimitiveWithoutTargetLangName && !sourceType->typeEntry()->isContainer()) + if (!isWrapperType(sourceType) + && !isUserPrimitiveWithoutTargetLangName + && !sourceType->typeEntry()->isEnum() + && !sourceType->typeEntry()->isFlags() + && !sourceType->typeEntry()->isContainer()) { typeCheck += '('; + } if (isWrapperType(sourceType)) { typeCheck = QString("%1pyIn)").arg(typeCheck); toCppConv = QString("%1%2") @@ -1066,16 +1129,12 @@ void CppGenerator::writeConverterFunctions(QTextStream& s, const AbstractMetaCla } else { typeCheck = QString("%1pyIn)").arg(typeCheck); } - //QTextStream pc(&toCppPreConv); - //pc << INDENT << getFullTypeNameWithoutModifiers(sourceType) << " cppIn"; - //qDebug() << sourceType->cppSignature(); - //writeMinimalConstructorExpression(pc, sourceType); - //pc << ';' << endl; - //writeToCppConversion(pc, sourceType, 0, "pyIn", "cppIn"); - //pc << ';'; - //toCppConv.append("cppIn"); - - if (isUserPrimitive(sourceType) || isCppPrimitive(sourceType) || sourceType->typeEntry()->isContainer()) { + + if (isUserPrimitive(sourceType) + || isCppPrimitive(sourceType) + || sourceType->typeEntry()->isContainer() + || sourceType->typeEntry()->isEnum() + || sourceType->typeEntry()->isFlags()) { QTextStream pc(&toCppPreConv); pc << INDENT << getFullTypeNameWithoutModifiers(sourceType) << " cppIn"; writeMinimalConstructorExpression(pc, sourceType); @@ -1259,10 +1318,7 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream& s, OverloadData& over if (pythonFunctionWrapperUsesListOfArguments(overloadData)) s << "[] = { 0" << QString(", 0").repeated(maxArgs-1) << " }"; s << ';' << endl; - // TODO-CONVERTER: remove this later. - // Make a check that ask something like: "there's no conversions in the overloads?". writeUnusedVariableCast(s, PYTHON_TO_CPP_VAR); - // TODO-CONVERTER: RANDOM THOUGHT: I gave that decisor some overloads. Decisors love overloads. } if (usesNamedArguments && !rfunc->isCallOperator()) @@ -1270,7 +1326,6 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream& s, OverloadData& over if (initPythonArguments) { s << INDENT << "int numArgs = "; - // TODO-CONVERTER: review rfunc->isConstructor() if (minArgs == 0 && maxArgs == 1 && !rfunc->isConstructor() && !pythonFunctionWrapperUsesListOfArguments(overloadData)) s << "(" PYTHON_ARG " == 0 ? 0 : 1);" << endl; else @@ -1347,22 +1402,12 @@ void CppGenerator::writeConstructorWrapper(QTextStream& s, const AbstractMetaFun s << endl; - bool hasPythonConvertion = metaClass->typeEntry()->hasTargetConversionRule(); - if (hasPythonConvertion) { - s << INDENT << "// Try python conversion rules" << endl; - s << INDENT << "cptr = Shiboken::PythonConverter< ::" << metaClass->qualifiedCppName() << " >::transformFromPython(" PYTHON_ARGS "[0]);" << endl; - s << INDENT << "if (!cptr) {" << endl; - } - if (overloadData.maxArgs() > 0) writeOverloadedFunctionDecisor(s, overloadData); writeFunctionCalls(s, overloadData); s << endl; - if (hasPythonConvertion) - s << INDENT << "}" << endl; - s << INDENT << "if (PyErr_Occurred() || !Shiboken::Object::setCppPointer(sbkSelf, Shiboken::SbkType< ::" << metaClass->qualifiedCppName() << " >(), cptr)) {" << endl; { Indentation indent(INDENT); @@ -1806,6 +1851,7 @@ void CppGenerator::writeTypeCheck(QTextStream& s, const AbstractMetaType* argTyp argType = metaType; } + // TODO-CONVERTER: merge this with the code below. QString typeCheck; if (customCheck.isEmpty()) typeCheck = cpythonIsConvertibleFunction(argType, argType->isEnum() ? false : isNumber); @@ -1814,10 +1860,10 @@ void CppGenerator::writeTypeCheck(QTextStream& s, const AbstractMetaType* argTyp typeCheck.append(QString("(%1)").arg(argumentName)); // TODO-CONVERTER ----------------------------------------------------------------------- - if (customCheck.isEmpty() && (isWrapperType(argType) || isUserPrimitive(argType) || isCppPrimitive(argType) || argType->typeEntry()->isContainer())) { + if (customCheck.isEmpty() && !argType->typeEntry()->isCustom()) { typeCheck = QString("(%1 = %2))").arg(pythonToCppConverterForArgumentName(argumentName)).arg(typeCheck); if (!isNumber && argType->typeEntry()->isCppPrimitive()) - typeCheck.prepend(QString("/*BOZOisNumber*/ %1(%2) && ").arg(cpythonCheckFunction(argType)).arg(argumentName)); + typeCheck.prepend(QString("%1(%2) && ").arg(cpythonCheckFunction(argType)).arg(argumentName)); } // TODO-CONVERTER ----------------------------------------------------------------------- @@ -1928,96 +1974,71 @@ void CppGenerator::writePythonToCppTypeConversion(QTextStream& s, const AbstractMetaClass* context, const QString& defaultValue) { - // TODO-CONVERTER - is this needed here? If so, at least raise a generator warning. - if (type->typeEntry()->isCustom() || type->typeEntry()->isVarargs()) + const TypeEntry* typeEntry = type->typeEntry(); + if (typeEntry->isCustom() || typeEntry->isVarargs()) return; QString cppOutAux = QString("%1_local").arg(cppOut); - // TODO-CONVERTER ----------------------------------------------------------------------- - if (!type->typeEntry()->isEnum() && !type->typeEntry()->isFlags()) { - - bool treatAsPointer = isValueTypeWithCopyConstructorOnly(type); - bool isPointerOrObjectType = (isObjectType(type) || isPointer(type)) && /*TODO-CONVERTERS: is this really needed?*/ !isUserPrimitive(type) && !isCppPrimitive(type); - bool mayHaveImplicitConversion = type->isReference() - && !isUserPrimitive(type) - && !isCppPrimitive(type) - && !type->typeEntry()->isContainer() - && !(treatAsPointer || isPointerOrObjectType); - QString typeName = getFullTypeNameWithoutModifiers(type); - if (mayHaveImplicitConversion) { - s << INDENT << typeName << ' ' << cppOutAux; - writeMinimalConstructorExpression(s, type, defaultValue); - s << ';' << endl; - } - - s << INDENT << typeName; - if (treatAsPointer || isPointerOrObjectType) { - s << "* " << cppOut << (defaultValue.isEmpty() ? "" : QString(" = %1").arg(defaultValue)); - } else if (type->isReference() && !type->typeEntry()->isPrimitive() && !type->typeEntry()->isContainer()) { - s << "* " << cppOut << " = &" << cppOutAux; - } else { - s << ' ' << cppOut; - if (isUserPrimitive(type)) - writeMinimalConstructorExpression(s, type->typeEntry(), defaultValue); - else if (!type->isContainer()) - writeMinimalConstructorExpression(s, type, defaultValue); - } + bool treatAsPointer = isValueTypeWithCopyConstructorOnly(type); + bool isPointerOrObjectType = (isObjectType(type) || isPointer(type)) && !isUserPrimitive(type) && !isCppPrimitive(type); + bool isNotContainerEnumOrFlags = !typeEntry->isContainer() && !typeEntry->isEnum() && !typeEntry->isFlags(); + bool mayHaveImplicitConversion = type->isReference() + && !isUserPrimitive(type) + && !isCppPrimitive(type) + && isNotContainerEnumOrFlags + && !(treatAsPointer || isPointerOrObjectType); + QString typeName = getFullTypeNameWithoutModifiers(type); + if (mayHaveImplicitConversion) { + s << INDENT << typeName << ' ' << cppOutAux; + writeMinimalConstructorExpression(s, type, defaultValue); s << ';' << endl; + } - QString pythonToCppFunc = pythonToCppConverterForArgumentName(pyIn); - - s << INDENT; - if (!defaultValue.isEmpty()) - s << "if (" << pythonToCppFunc << ") "; - - QString pythonToCppCall = QString("%1(%2, &%3)").arg(pythonToCppFunc).arg(pyIn).arg(cppOut); - if (!mayHaveImplicitConversion) { - s << pythonToCppCall << ';' << endl; - return; - } + s << INDENT << typeName; + if (treatAsPointer || isPointerOrObjectType) { + s << "* " << cppOut << (defaultValue.isEmpty() ? "" : QString(" = %1").arg(defaultValue)); + } else if (type->isReference() && !typeEntry->isPrimitive() && isNotContainerEnumOrFlags) { + s << "* " << cppOut << " = &" << cppOutAux; + } else { + s << ' ' << cppOut; + if (isUserPrimitive(type) || typeEntry->isEnum() || typeEntry->isFlags()) + writeMinimalConstructorExpression(s, typeEntry, defaultValue); + else if (!type->isContainer()) + writeMinimalConstructorExpression(s, type, defaultValue); + } + s << ';' << endl; - if (!defaultValue.isEmpty()) - s << '{' << endl << INDENT; + QString pythonToCppFunc = pythonToCppConverterForArgumentName(pyIn); - s << "if (Shiboken::Conversions::isImplicitConversion((SbkObjectType*)"; - s << cpythonTypeNameExt(type) << ", " << pythonToCppFunc << "))" << endl; - { - Indentation indent(INDENT); - s << INDENT << pythonToCppFunc << '(' << pyIn << ", &" << cppOutAux << ");" << endl; - } - s << INDENT << "else" << endl; - { - Indentation indent(INDENT); - s << INDENT << pythonToCppCall << ';' << endl; - } + s << INDENT; + if (!defaultValue.isEmpty()) + s << "if (" << pythonToCppFunc << ") "; - if (!defaultValue.isEmpty()) - s << INDENT << '}'; - s << endl; + QString pythonToCppCall = QString("%1(%2, &%3)").arg(pythonToCppFunc).arg(pyIn).arg(cppOut); + if (!mayHaveImplicitConversion) { + s << pythonToCppCall << ';' << endl; return; } - // TODO-CONVERTER ----------------------------------------------------------------------- - - QString conversion; - QTextStream c(&conversion); - - writeToCppConversion(c, type, context, pyIn, "/*BOZO-1944*/"); - - // Value type that has default value. - if (type->isValue() && !defaultValue.isEmpty()) - s << INDENT << type->typeEntry()->name() << ' ' << cppOutAux << " = " << defaultValue << ';' << endl; - // exclude const on Objects - Options flags = getConverterOptions(type); - QString typeName = translateTypeForWrapperMethod(type, context, flags).trimmed(); + if (!defaultValue.isEmpty()) + s << '{' << endl << INDENT; - if (!defaultValue.isEmpty()) { - conversion.prepend(QString("%1 ? ").arg(pyIn)); - conversion.append(QString(" : %1").arg(type->isValue() ? cppOutAux : defaultValue)); + s << "if (Shiboken::Conversions::isImplicitConversion((SbkObjectType*)"; + s << cpythonTypeNameExt(type) << ", " << pythonToCppFunc << "))" << endl; + { + Indentation indent(INDENT); + s << INDENT << pythonToCppFunc << '(' << pyIn << ", &" << cppOutAux << ");" << endl; + } + s << INDENT << "else" << endl; + { + Indentation indent(INDENT); + s << INDENT << pythonToCppCall << ';' << endl; } - s << INDENT << typeName << " " << cppOut << " = " << conversion << ';' << endl; + if (!defaultValue.isEmpty()) + s << INDENT << '}'; + s << endl; } static void addConversionRuleCodeSnippet(CodeSnipList& snippetList, QString& rule, @@ -2262,7 +2283,6 @@ void CppGenerator::writeFunctionCalls(QTextStream& s, const OverloadData& overlo } else { for (int i = 0; i < overloads.count(); i++) { const AbstractMetaFunction* func = overloads.at(i); - //s << INDENT << "case " << i << ": // " << func->minimalSignature() << endl; s << INDENT << "case " << i << ": // " << func->signature() << endl; s << INDENT << '{' << endl; { @@ -3129,6 +3149,60 @@ void CppGenerator::writePrimitiveConverterInitialization(QTextStream& s, const C writeCustomConverterRegister(s, customConversion, converterObject(type)); } +void CppGenerator::writeEnumConverterInitialization(QTextStream& s, const AbstractMetaEnum* metaEnum) +{ + if (metaEnum->isPrivate() || metaEnum->isAnonymous()) + return; + writeEnumConverterInitialization(s, metaEnum->typeEntry()); +} + +void CppGenerator::writeEnumConverterInitialization(QTextStream& s, const TypeEntry* enumType) +{ + if (!enumType) + return; + QString enumFlagName = enumType->isFlags() ? "flag" : "enum"; + QString enumPythonType = cpythonTypeNameExt(enumType); + + const FlagsTypeEntry* flags = 0; + if (enumType->isFlags()) + flags = reinterpret_cast<const FlagsTypeEntry*>(enumType); + + s << INDENT << "// Register converter for " << enumFlagName << " '" << enumType->qualifiedCppName() << "'." << endl; + s << INDENT << '{' << endl; + { + Indentation indent(INDENT); + QString typeName = fixedCppTypeName(enumType); + s << INDENT << "SbkConverter* converter = Shiboken::Conversions::createConverter(" << enumPythonType << ',' << endl; + { + Indentation indent(INDENT); + s << INDENT << cppToPythonFunctionName(typeName, typeName) << ");" << endl; + } + + if (flags) { + QString enumTypeName = fixedCppTypeName(flags->originator()); + QString toCpp = pythonToCppFunctionName(enumTypeName, typeName); + QString isConv = convertibleToCppFunctionName(enumTypeName, typeName); + writeAddPythonToCppConversion(s, "converter", toCpp, isConv); + } + + QString toCpp = pythonToCppFunctionName(typeName, typeName); + QString isConv = convertibleToCppFunctionName(typeName, typeName); + writeAddPythonToCppConversion(s, "converter", toCpp, isConv); + + if (flags) { + QString toCpp = pythonToCppFunctionName("number", typeName); + QString isConv = convertibleToCppFunctionName("number", typeName); + writeAddPythonToCppConversion(s, "converter", toCpp, isConv); + } + + s << INDENT << "Shiboken::Enum::setTypeConverter(" << enumPythonType << ", converter);" << endl; + } + s << INDENT << '}' << endl; + + if (!flags) + writeEnumConverterInitialization(s, reinterpret_cast<const EnumTypeEntry*>(enumType)->flags()); +} + void CppGenerator::writeContainerConverterInitialization(QTextStream& s, const AbstractMetaType* type) { s << INDENT << "// Register converter for type '" << type->cppSignature() << "'." << endl; @@ -3601,9 +3675,15 @@ void CppGenerator::writeGetterFunction(QTextStream& s, const AbstractMetaField* cppField.append(')'); } } - if (isCppIntegralPrimitive(fieldType)) { + if (isCppIntegralPrimitive(fieldType) || fieldType->isEnum() || fieldType->isFlags()) { s << INDENT << getFullTypeNameWithoutModifiers(fieldType) << " cppOut_local = " << cppField << ';' << endl; cppField = "cppOut_local"; + } else if (avoidProtectedHack() && metaField->isProtected()) { + s << INDENT << getFullTypeNameWithoutModifiers(fieldType); + if ((!fieldType->isConstant() && !fieldType->isEnum() && !fieldType->isPrimitive()) || fieldType->indirections() == 1) + s << '*'; + s << " fieldValue = " << cppField << ';' << endl; + cppField = "fieldValue"; } s << INDENT << "PyObject* pyOut = "; @@ -3639,9 +3719,7 @@ void CppGenerator::writeSetterFunction(QTextStream& s, const AbstractMetaField* AbstractMetaType* fieldType = metaField->type(); - if (!fieldType->typeEntry()->isEnum() && !fieldType->typeEntry()->isFlags()) - s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR << ';' << endl; - + s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR << ';' << endl; s << INDENT << "if (!"; writeTypeCheck(s, fieldType, "pyIn", isNumber(fieldType->typeEntry())); s << ") {" << endl; @@ -3669,15 +3747,15 @@ void CppGenerator::writeSetterFunction(QTextStream& s, const AbstractMetaField* s << INDENT << QString("((%1*)%2)->%3(cppOut)").arg(wrapperName(metaField->enclosingClass())) .arg(CPP_SELF_VAR) .arg(protectedFieldSetterName(metaField)); - } else if (isCppIntegralPrimitive(fieldType)) { + } else if (isCppIntegralPrimitive(fieldType) || fieldType->typeEntry()->isEnum() || fieldType->typeEntry()->isFlags()) { s << getFullTypeNameWithoutModifiers(fieldType) << " cppOut_local = " << cppField << ';' << endl; s << INDENT << PYTHON_TO_CPP_VAR << "(pyIn, &cppOut_local);" << endl; s << INDENT << cppField << " = cppOut_local"; - } else if (fieldType->typeEntry()->isEnum() || fieldType->typeEntry()->isFlags()) { - s << cppField << " = "; - writeToCppConversion(s, fieldType, metaField->enclosingClass(), "pyIn", ""); } else { - writeToCppConversion(s, fieldType, metaField->enclosingClass(), "pyIn", cppField); + s << getFullTypeNameWithoutModifiers(fieldType); + s << QString("*").repeated(fieldType->indirections()) << "& cppOut_ptr = "; + s << cppField << ';' << endl; + s << INDENT << PYTHON_TO_CPP_VAR << "(pyIn, &cppOut_ptr)"; } s << ';' << endl << endl; @@ -3700,10 +3778,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream& s, const AbstractMetaCl writeUnusedVariableCast(s, CPP_SELF_VAR); s << INDENT << "PyObject* " PYTHON_RETURN_VAR " = 0;" << endl; s << INDENT << "PythonToCppFunc " PYTHON_TO_CPP_VAR << ';' << endl; - // TODO-CONVERTER: remove this later. - // Make a check that ask something like: "there's no conversions in the overloads?". writeUnusedVariableCast(s, PYTHON_TO_CPP_VAR); - // TODO-CONVERTER: RANDOM THOUGHT: I gave that decisor some overloads. Decisors love overloads. s << endl; s << INDENT << "switch (op) {" << endl; @@ -3956,7 +4031,12 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu if (!cppEnum->isAnonymous()) writeRegisterType(s, cppEnum); - s << INDENT << "// End of '" << cppEnum->name() << "' enum." << endl << endl; + writeEnumConverterInitialization(s, cppEnum); + + s << INDENT << "// End of '" << cppEnum->name() << "' enum"; + if (cppEnum->typeEntry()->flags()) + s << "/flags"; + s << '.' << endl << endl; } void CppGenerator::writeSignalInitialization(QTextStream& s, const AbstractMetaClass* metaClass) @@ -4596,6 +4676,7 @@ void CppGenerator::finishGeneration() foreach (const AbstractMetaEnum* cppEnum, globalEnums) { if (cppEnum->isAnonymous() || cppEnum->isPrivate()) continue; + writeEnumConverterFunctions(s, cppEnum); s << endl; } diff --git a/generator/cppgenerator.h b/generator/cppgenerator.h index 1f49315..8f77e77 100644 --- a/generator/cppgenerator.h +++ b/generator/cppgenerator.h @@ -51,6 +51,8 @@ private: void writeMetaObjectMethod(QTextStream& s, const AbstractMetaClass* metaClass); void writeMetaCast(QTextStream& s, const AbstractMetaClass* metaClass); + void writeEnumConverterFunctions(QTextStream& s, const TypeEntry* enumType); + void writeEnumConverterFunctions(QTextStream& s, const AbstractMetaEnum* metaEnum); void writeConverterFunctions(QTextStream& s, const AbstractMetaClass* metaClass); void writeCustomConverterFunctions(QTextStream& s, const CustomConversion* customConversion); void writeConverterRegister(QTextStream& s, const AbstractMetaClass* metaClass); @@ -249,6 +251,8 @@ private: void writeSpecialCastFunction(QTextStream& s, const AbstractMetaClass* metaClass); void writePrimitiveConverterInitialization(QTextStream& s, const CustomConversion* customConversion); + void writeEnumConverterInitialization(QTextStream& s, const TypeEntry* enumType); + void writeEnumConverterInitialization(QTextStream& s, const AbstractMetaEnum* metaEnum); void writeContainerConverterInitialization(QTextStream& s, const AbstractMetaType* type); void writeExtendedConverterInitialization(QTextStream& s, const TypeEntry* externalType, const QList<const AbstractMetaClass*>& conversions); diff --git a/generator/shibokengenerator.cpp b/generator/shibokengenerator.cpp index 3c889b3..d5b734f 100644 --- a/generator/shibokengenerator.cpp +++ b/generator/shibokengenerator.cpp @@ -40,7 +40,6 @@ #define USE_ISNULL_AS_NB_NONZERO "use-isnull-as-nb_nonzero" //static void dumpFunction(AbstractMetaFunctionList lst); -static QString baseConversionString(QString typeName); QHash<QString, QString> ShibokenGenerator::m_pythonPrimitiveTypeName = QHash<QString, QString>(); QHash<QString, QString> ShibokenGenerator::m_pythonOperators = QHash<QString, QString>(); @@ -532,77 +531,12 @@ QString ShibokenGenerator::getFunctionReturnType(const AbstractMetaFunction* fun return func->ownerClass()->qualifiedCppName() + '*'; return translateTypeForWrapperMethod(func->type(), func->implementingClass()); - - //TODO: check these lines - //QString modifiedReturnType = QString(func->typeReplaced(0)); - //return modifiedReturnType.isNull() ? - //translateType(func->type(), func->implementingClass()) : modifiedReturnType; -} - -static QString baseConversionString(QString typeName) -{ - return QString("Shiboken::Converter< %1 >::").arg(typeName); -} - -void ShibokenGenerator::writeBaseConversion(QTextStream& s, const TypeEntry* type) -{ - QString typeName; - - if (avoidProtectedHack() && type->isEnum()) { - const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(type); - if (metaEnum && metaEnum->isProtected()) - typeName = protectedEnumSurrogateName(metaEnum); - } else { - typeName = getFullTypeName(type).trimmed(); - if (isObjectType(type)) - typeName.append('*'); - } - s << baseConversionString(typeName); -} - -void ShibokenGenerator::writeBaseConversion(QTextStream& s, const AbstractMetaType* type, - const AbstractMetaClass* context, Options options) -{ - QString typeName; - if (type->isPrimitive()) { - const PrimitiveTypeEntry* ptype = (const PrimitiveTypeEntry*) type->typeEntry(); - if (ptype->basicAliasedTypeEntry()) - ptype = ptype->basicAliasedTypeEntry(); - typeName = ptype->name(); - if (!ptype->isCppPrimitive()) - typeName.prepend("::"); - } else { - if (!isCString(type)) { - options |= Generator::ExcludeConst; - if (type->typeEntry()->isPrimitive() - || type->isContainer() - || type->isFlags() - || type->isEnum() - || (type->isConstant() && type->isReference())) { - options |= Generator::ExcludeReference; - } - } - typeName = translateTypeForWrapperMethod(type, context, options).trimmed(); - } - - s << baseConversionString(typeName); } void ShibokenGenerator::writeToPythonConversion(QTextStream& s, const AbstractMetaType* type, const AbstractMetaClass* context, const QString& argumentName) { - // TODO-CONVERTER ----------------------------------------------------------------------- - if (!type->typeEntry()->isEnum() && !type->typeEntry()->isFlags()) { - QString toPythonFunc = cpythonToPythonConversionFunction(type); - // Remove final '&' if argument name is a function call. - // It is expected that this function call returns a pointer. - if (argumentName.endsWith("()")) - toPythonFunc.chop(1); - s << toPythonFunc << argumentName << ')'; - return; - } - // TODO-CONVERTER ----------------------------------------------------------------------- - s << cpythonToPythonConversionFunction(type, context) << '(' << argumentName << ')'; + s << cpythonToPythonConversionFunction(type) << argumentName << ')'; } void ShibokenGenerator::writeToCppConversion(QTextStream& s, const AbstractMetaClass* metaClass, @@ -614,24 +548,18 @@ void ShibokenGenerator::writeToCppConversion(QTextStream& s, const AbstractMetaC void ShibokenGenerator::writeToCppConversion(QTextStream& s, const AbstractMetaType* type, const AbstractMetaClass* context, const QString& inArgName, const QString& outArgName) { - // TODO-CONVERTER ----------------------------------------------------------------------- - if (!type->typeEntry()->isEnum() && !type->typeEntry()->isFlags()) { - s << cpythonToCppConversionFunction(type, context) << inArgName << ", &" << outArgName << ')'; - return; - } - // TODO-CONVERTER ----------------------------------------------------------------------- - s << cpythonToCppConversionFunction(type, context) << '(' << inArgName << ')'; + s << cpythonToCppConversionFunction(type, context) << inArgName << ", &" << outArgName << ')'; } bool ShibokenGenerator::shouldRejectNullPointerArgument(const AbstractMetaFunction* func, int argIndex) { if (argIndex < 0 || argIndex >= func->arguments().count()) return false; - // TODO-CONVERTER ----------------------------------------------------------------------- + const AbstractMetaArgument* arg = func->arguments().at(argIndex); if (isValueTypeWithCopyConstructorOnly(arg->type())) return true; - // TODO-CONVERTER ----------------------------------------------------------------------- + // Argument type is not a pointer, a None rejection should not be // necessary because the type checking would handle that already. if (!isPointer(arg->type())) @@ -781,7 +709,7 @@ QString ShibokenGenerator::converterObject(const TypeEntry* type) { if (isCppPrimitive(type)) return QString("Shiboken::Conversions::PrimitiveTypeConverter<%1>()").arg(type->qualifiedCppName()); - if (isWrapperType(type)) + if (isWrapperType(type) || type->isEnum() || type->isFlags()) return QString("SBK_CONVERTER(%1)").arg(cpythonTypeNameExt(type)); return QString("%1[%2]").arg(convertersVariableName(type->targetLangPackage())).arg(getTypeIndexVariableName(type)); } @@ -1036,7 +964,6 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType return customCheck; } - // TODO-CONVERTER ----------------------------------------------------------------------- if (isCppPrimitive(metaType)) { if (isCString(metaType)) return "SbkString_Check"; @@ -1081,23 +1008,8 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType } } return typeCheck; - } else if (!metaType->typeEntry()->isEnum() && !metaType->typeEntry()->isFlags()) { - return cpythonCheckFunction(metaType->typeEntry(), genericNumberType); } - // TODO-CONVERTER ----------------------------------------------------------------------- - - QString baseName = cpythonBaseName(metaType); - if (isNumber(baseName)) - return genericNumberType ? QString("SbkNumber_Check") : QString("%1_Check").arg(baseName); - - - baseName.clear(); - QTextStream b(&baseName); - // exclude const on Objects - Options flags = getConverterOptions(metaType); - writeBaseConversion(b, metaType, 0, flags); - - return QString("%1checkType").arg(baseName); + return cpythonCheckFunction(metaType->typeEntry(), genericNumberType); } QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry* type, bool genericNumberType) @@ -1111,35 +1023,16 @@ QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry* type, bool gene return customCheck; } - // TODO-CONVERTER ----------------------------------------------------------------------- - if (isWrapperType(type)) { + if (type->isEnum() || type->isFlags() || isWrapperType(type)) return QString("SbkObject_TypeCheck(%1, ").arg(cpythonTypeNameExt(type)); - } else if (isCppPrimitive(type)) { + else if (isCppPrimitive(type)) return QString("%1_Check").arg(pythonPrimitiveTypeName((const PrimitiveTypeEntry*)type)); - } else if (!type->isEnum() && !type->isFlags()) { - QString typeCheck; - if (type->targetLangApiName() == type->name()) - typeCheck = cpythonIsConvertibleFunction(type); - else - typeCheck = QString("%1_Check").arg(type->targetLangApiName()); - return typeCheck; - } - // TODO-CONVERTER ----------------------------------------------------------------------- - QString typeCheck; - if (!type->targetLangApiName().isEmpty()) + if (type->targetLangApiName() == type->name()) + typeCheck = cpythonIsConvertibleFunction(type); + else typeCheck = QString("%1_Check").arg(type->targetLangApiName()); return typeCheck; -/* - QString baseName = cpythonBaseName(type); - if (isNumber(baseName)) - return genericNumberType ? "SbkNumber_Check" : baseName+"_Check"; - - baseName.clear(); - QTextStream b(&baseName); - writeBaseConversion(b, type); - return QString("%1checkType").arg(baseName); -*/ } QString ShibokenGenerator::guessCPythonCheckFunction(const QString& type, AbstractMetaType** metaType) @@ -1175,29 +1068,15 @@ QString ShibokenGenerator::guessCPythonIsConvertible(const QString& type) QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntry* type, bool genericNumberType, bool checkExact) { - // TODO-CONVERTER ----------------------------------------------------------------------- if (isWrapperType(type)) { QString isConv = (type->isValue() && !isValueTypeWithCopyConstructorOnly(type)) ? "isPythonToCppValueConvertible" : "isPythonToCppPointerConvertible"; return QString("Shiboken::Conversions::%1((SbkObjectType*)%2, ") .arg(isConv).arg(cpythonTypeNameExt(type)); - } else if (!type->isEnum() && !type->isFlags()) { - return QString("Shiboken::Conversions::isPythonToCppConvertible(%1, ") - .arg(converterObject(type)); } - // TODO-CONVERTER ----------------------------------------------------------------------- - - if (checkExact) - return cpythonCheckFunction(type, genericNumberType); - - if (type->isCustom()) - return guessCPythonIsConvertible(type->name()); - - QString baseName; - QTextStream b(&baseName); - writeBaseConversion(b, type); - return QString("%1isConvertible").arg(baseName); + return QString("Shiboken::Conversions::isPythonToCppConvertible(%1, ") + .arg(converterObject(type)); } QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType* metaType, bool genericNumberType) { @@ -1211,7 +1090,6 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType* return customCheck; } - // TODO-CONVERTER ----------------------------------------------------------------------- if (isWrapperType(metaType)) { QString isConv; if (isPointer(metaType) || isValueTypeWithCopyConstructorOnly(metaType)) @@ -1222,20 +1100,9 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType* isConv = "isPythonToCppValueConvertible"; return QString("Shiboken::Conversions::%1((SbkObjectType*)%2, ") .arg(isConv).arg(cpythonTypeNameExt(metaType)); - } else if (!metaType->typeEntry()->isEnum() && !metaType->typeEntry()->isFlags()) { - return QString("Shiboken::Conversions::isPythonToCppConvertible(%1, ") - .arg(converterObject(metaType)); } - // TODO-CONVERTER ----------------------------------------------------------------------- - - QString baseName = cpythonBaseName(metaType); - if (isNumber(baseName)) - return genericNumberType ? QString("SbkNumber_Check") : QString("%1_Check").arg(baseName); - - baseName.clear(); - QTextStream b(&baseName); - writeBaseConversion(b, metaType); - return QString("%1isConvertible").arg(baseName); + return QString("Shiboken::Conversions::isPythonToCppConvertible(%1, ") + .arg(converterObject(metaType)); } QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaClass* metaClass) @@ -1245,25 +1112,17 @@ QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaClas } QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaType* type, const AbstractMetaClass* context) { - // TODO-CONVERTER ----------------------------------------------------------------------- if (isWrapperType(type)) { return QString("Shiboken::Conversions::pythonToCpp%1((SbkObjectType*)%2, ") .arg(isPointer(type) ? "Pointer" : "Copy") .arg(cpythonTypeNameExt(type)); - } else if (!type->typeEntry()->isEnum() && !type->typeEntry()->isFlags()) { - return QString("Shiboken::Conversions::pythonToCpp(%1, ") - .arg(converterObject(type)); } - // TODO-CONVERTER ----------------------------------------------------------------------- - QString base; - QTextStream b(&base); - writeBaseConversion(b, type, context); - return QString("%1toCpp").arg(base); + return QString("Shiboken::Conversions::pythonToCpp(%1, ") + .arg(converterObject(type)); } QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaType* type, const AbstractMetaClass* context) { - // TODO-CONVERTER ----------------------------------------------------------------------- if (isWrapperType(type)) { QString conversion; if (type->isReference() && !isPointer(type)) @@ -1274,18 +1133,10 @@ QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaT conversion = "pointer"; return QString("Shiboken::Conversions::%1ToPython((SbkObjectType*)%2, %3") .arg(conversion).arg(cpythonTypeNameExt(type)).arg(conversion == "pointer" ? "" : "&"); - } else if (!type->typeEntry()->isEnum() && !type->typeEntry()->isFlags()) { - return QString("Shiboken::Conversions::copyToPython(%1, %2") - .arg(converterObject(type)) - .arg((isCString(type) || isVoidPointer(type)) ? "" : "&"); } - // TODO-CONVERTER ----------------------------------------------------------------------- - // exclude const on Objects - Options flags = getConverterOptions(type); - QString base; - QTextStream b(&base); - writeBaseConversion(b, type, context, flags); - return QString("%1toPython").arg(base); + return QString("Shiboken::Conversions::copyToPython(%1, %2") + .arg(converterObject(type)) + .arg((isCString(type) || isVoidPointer(type)) ? "" : "&"); } QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaClass* metaClass) @@ -1295,7 +1146,6 @@ QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaC QString ShibokenGenerator::cpythonToPythonConversionFunction(const TypeEntry* type) { - // TODO-CONVERTER ----------------------------------------------------------------------- if (isWrapperType(type)) { QString conversion; if (type->isValue()) @@ -1304,14 +1154,9 @@ QString ShibokenGenerator::cpythonToPythonConversionFunction(const TypeEntry* ty conversion = "pointer"; return QString("Shiboken::Conversions::%1ToPython((SbkObjectType*)%2, %3") .arg(conversion).arg(cpythonTypeNameExt(type)).arg(conversion == "pointer" ? "" : "&"); - } else if (!type->isEnum() && !type->isFlags()) { - return QString("Shiboken::Conversions::copyToPython(%1, &").arg(converterObject(type)); } - // TODO-CONVERTER ----------------------------------------------------------------------- - QString base; - QTextStream b(&base); - writeBaseConversion(b, type); - return QString("%1toPython").arg(base); + + return QString("Shiboken::Conversions::copyToPython(%1, &").arg(converterObject(type)); } QString ShibokenGenerator::argumentString(const AbstractMetaFunction *func, @@ -1612,12 +1457,10 @@ ShibokenGenerator::ArgumentVarReplacementList ShibokenGenerator::getArgumentRepl argValue = hasConversionRule ? QString("%1"CONV_RULE_OUT_VAR_SUFFIX).arg(arg->name()) : QString(CPP_ARG"%1").arg(argPos); - // TODO-CONVERTER ----------------------------------------------------------------------- if (isWrapperType(type)) { if (type->isReference() && !isPointer(type)) argValue.prepend('*'); } - // TODO-CONVERTER ----------------------------------------------------------------------- } } } else { @@ -1789,7 +1632,6 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s, foreach (ArgumentVarReplacementPair pair, argReplacements) { const AbstractMetaArgument* arg = pair.first; int idx = arg->argumentIndex() + 1; - // TODO-CONVERTER ----------------------------------------------------------------------- AbstractMetaType* type = arg->type(); QString typeReplaced = func->typeReplaced(arg->argumentIndex() + 1); if (!typeReplaced.isEmpty()) { @@ -1804,7 +1646,6 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s, if (type->isReference() || isPointer(type)) code.replace(QString("%%1.").arg(idx), QString("%1->").arg(replacement)); } - // TODO-CONVERTER ----------------------------------------------------------------------- code.replace(QString("%%1").arg(idx), pair.second); } @@ -1932,10 +1773,6 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa QString varType = code.mid(start, end - start); conversionString = varType + list.first(); varType = miniNormalizer(varType); - if (conversionType->typeEntry()->isEnum() || conversionType->typeEntry()->isFlags()) { - c << varType << ' ' << list.at(1) << " = " << cpythonToCppConversionFunction(conversionType) << '('; - break; - } QString varName = list.at(1).trimmed(); if (!varType.isEmpty()) { if (varType != conversionType->cppSignature()) { @@ -1974,12 +1811,6 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa if (conversion.isEmpty()) conversion = cpythonToPythonConversionFunction(conversionType); default: { - // TODO-CONVERTER ----------------------------------------------------------------------- - if (conversionType->typeEntry()->isEnum() || conversionType->typeEntry()->isFlags()) { - c << '('; - break; - } - // TODO-CONVERTER ----------------------------------------------------------------------- QString arg = getConverterTypeSystemVariableArgument(code, pos); conversionString += arg; if (converterVariable == TypeSystemToPythonFunction && !isVariable(arg)) { @@ -1990,8 +1821,6 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa conversion.prepend('('); conversion.replace("%in", arg); } else { - //if (conversionType->isPrimitive() && converterVariable == TypeSystemCheckFunction) - //conversion.append('('); c << arg; } } diff --git a/generator/shibokengenerator.h b/generator/shibokengenerator.h index fa7689d..cd273ea 100644 --- a/generator/shibokengenerator.h +++ b/generator/shibokengenerator.h @@ -248,10 +248,6 @@ public: const AbstractMetaClass* getMultipleInheritingClass(const AbstractMetaClass* metaClass); - void writeBaseConversion(QTextStream& s, const AbstractMetaType* type, - const AbstractMetaClass* context = 0, Options options = NoOption); - /// Simpler version of writeBaseConversion, uses only the base name of the type. - void writeBaseConversion(QTextStream& s, const TypeEntry* type); void writeToPythonConversion(QTextStream& s, const AbstractMetaType* type, const AbstractMetaClass* context, const QString& argumentName); void writeToCppConversion(QTextStream& s, const AbstractMetaType* type, const AbstractMetaClass* context, const QString& inArgName, const QString& outArgName); diff --git a/libshiboken/sbkenum.cpp b/libshiboken/sbkenum.cpp index 39ffb34..c2f6ce0 100644 --- a/libshiboken/sbkenum.cpp +++ b/libshiboken/sbkenum.cpp @@ -550,6 +550,18 @@ long int getValue(PyObject* enumItem) return reinterpret_cast<SbkEnumObject*>(enumItem)->ob_value; } +void setTypeConverter(PyTypeObject* enumType, SbkConverter* converter) +{ + //reinterpret_cast<SbkEnumType*>(enumType)->converter = converter; + SBK_CONVERTER(enumType) = converter; +} + +SbkConverter* getTypeConverter(PyTypeObject* enumType) +{ + //return reinterpret_cast<SbkEnumType*>(enumType)->converter; + return SBK_CONVERTER(enumType); +} + } // namespace Enum DeclaredEnumTypes& DeclaredEnumTypes::instance() diff --git a/libshiboken/sbkenum.h b/libshiboken/sbkenum.h index afe9141..b0ff269 100644 --- a/libshiboken/sbkenum.h +++ b/libshiboken/sbkenum.h @@ -31,6 +31,7 @@ extern "C" extern LIBSHIBOKEN_API PyTypeObject SbkEnumType_Type; struct SbkObjectType; +struct SbkConverter; } // extern "C" @@ -88,6 +89,11 @@ namespace Enum LIBSHIBOKEN_API long getValue(PyObject* enumItem); LIBSHIBOKEN_API PyObject* getEnumItemFromValue(PyTypeObject* enumType, long itemValue); + + /// Sets the enum's type converter. + LIBSHIBOKEN_API void setTypeConverter(PyTypeObject* enumType, SbkConverter* converter); + /// Returns the converter assigned to the enum \p type. + LIBSHIBOKEN_API SbkConverter* getTypeConverter(PyTypeObject* enumType); } } // namespace Shiboken |