diff options
10 files changed, 80 insertions, 52 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp index 43597234b..f9cd7f1d4 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp @@ -506,6 +506,10 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) cls->addDefaultConstructor(); if (cls->canAddDefaultCopyConstructor()) cls->addDefaultCopyConstructor(); + + const bool vco = AbstractMetaClass::determineValueTypeWithCopyConstructorOnly(cls); + cls->setValueTypeWithCopyConstructorOnly(vco); + cls->typeEntry()->setValueTypeWithCopyConstructorOnly(vco); } const auto &allEntries = types->entries(); diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp index 6c4200395..3e42f40ac 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp @@ -71,6 +71,7 @@ public: m_hasCloneOperator(false), m_isTypeDef(false), m_hasToStringCapability(false), + m_valueTypeWithCopyConstructorOnly(false), m_hasCachedWrapper(false) { } @@ -107,6 +108,7 @@ public: uint m_hasCloneOperator : 1; uint m_isTypeDef : 1; uint m_hasToStringCapability : 1; + uint m_valueTypeWithCopyConstructorOnly : 1; mutable uint m_hasCachedWrapper : 1; Documentation m_doc; @@ -1787,11 +1789,22 @@ bool AbstractMetaClass::isCopyable() const bool AbstractMetaClass::isValueTypeWithCopyConstructorOnly() const { - if (!typeEntry()->isValue()) + return d->m_valueTypeWithCopyConstructorOnly; +} + +void AbstractMetaClass::setValueTypeWithCopyConstructorOnly(bool v) +{ + d->m_valueTypeWithCopyConstructorOnly = v; +} + +bool AbstractMetaClass::determineValueTypeWithCopyConstructorOnly(const AbstractMetaClass *c) +{ + + if (!c->typeEntry()->isValue()) return false; - if (attributes().testFlag(AbstractMetaClass::HasRejectedDefaultConstructor)) + if (c->attributes().testFlag(AbstractMetaClass::HasRejectedDefaultConstructor)) return false; - const auto ctors = queryFunctions(FunctionQueryOption::Constructors); + const auto ctors = c->queryFunctions(FunctionQueryOption::Constructors); bool copyConstructorFound = false; for (const auto &ctor : ctors) { switch (ctor->functionType()) { diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.h b/sources/shiboken6/ApiExtractor/abstractmetalang.h index f08ed2039..cc7fd7cec 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken6/ApiExtractor/abstractmetalang.h @@ -348,6 +348,8 @@ public: bool isObjectType() const; bool isCopyable() const; bool isValueTypeWithCopyConstructorOnly() const; + void setValueTypeWithCopyConstructorOnly(bool v); + static bool determineValueTypeWithCopyConstructorOnly(const AbstractMetaClass *c); static AbstractMetaClass *findClass(const AbstractMetaClassList &classes, const QString &name); diff --git a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp index dd61421e2..cdec02513 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp +++ b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp @@ -752,6 +752,22 @@ bool AbstractMetaType::isExtendedCppPrimitive() const return d->m_typeEntry->isExtendedCppPrimitive(); } +bool AbstractMetaType::isValueTypeWithCopyConstructorOnly() const +{ + bool result = false; + if (d->m_typeEntry->isComplex()) { + const auto *cte = static_cast<const ComplexTypeEntry *>(d->m_typeEntry); + result = cte->isValueTypeWithCopyConstructorOnly(); + } + return result; +} + +bool AbstractMetaType::valueTypeWithCopyConstructorOnlyPassed() const +{ + return (passByValue() || passByConstRef()) + && isValueTypeWithCopyConstructorOnly(); +} + #ifndef QT_NO_DEBUG_STREAM void AbstractMetaType::formatDebug(QDebug &debug) const { diff --git a/sources/shiboken6/ApiExtractor/abstractmetatype.h b/sources/shiboken6/ApiExtractor/abstractmetatype.h index 599321262..4ec4f302c 100644 --- a/sources/shiboken6/ApiExtractor/abstractmetatype.h +++ b/sources/shiboken6/ApiExtractor/abstractmetatype.h @@ -222,6 +222,12 @@ public: /// Returns true if the type is an extended C++ primitive, a void*, /// a const char*, or a std::string (cf isCppPrimitive()). bool isExtendedCppPrimitive() const; + /// Returns whether the underlying type is a value type with copy constructor only + bool isValueTypeWithCopyConstructorOnly() const; + /// Returns whether the type (function argument) is a value type with + /// copy constructor only is passed as value or const-ref and thus + /// no default value can be constructed. + bool valueTypeWithCopyConstructorOnlyPassed() const; #ifndef QT_NO_DEBUG_STREAM void formatDebug(QDebug &debug) const; diff --git a/sources/shiboken6/ApiExtractor/typesystem.cpp b/sources/shiboken6/ApiExtractor/typesystem.cpp index d445febfa..80ebdb962 100644 --- a/sources/shiboken6/ApiExtractor/typesystem.cpp +++ b/sources/shiboken6/ApiExtractor/typesystem.cpp @@ -1181,6 +1181,8 @@ public: TypeSystem::SnakeCase m_snakeCase = TypeSystem::SnakeCase::Unspecified; TypeSystem::BoolCast m_operatorBoolMode = TypeSystem::BoolCast::Unspecified; TypeSystem::BoolCast m_isNullMode = TypeSystem::BoolCast::Unspecified; + // Determined by AbstractMetaBuilder from the code model. + bool m_isValueTypeWithCopyConstructorOnly = false; }; ComplexTypeEntry::ComplexTypeEntry(const QString &entryName, TypeEntry::Type t, @@ -1471,6 +1473,18 @@ void ComplexTypeEntry::setSnakeCase(TypeSystem::SnakeCase sc) d->m_snakeCase = sc; } +bool ComplexTypeEntry::isValueTypeWithCopyConstructorOnly() const +{ + S_D(const ComplexTypeEntry); + return d->m_isValueTypeWithCopyConstructorOnly; +} + +void ComplexTypeEntry::setValueTypeWithCopyConstructorOnly(bool v) +{ + S_D(ComplexTypeEntry); + d->m_isValueTypeWithCopyConstructorOnly = v; +} + TypeEntry *ComplexTypeEntry::clone() const { S_D(const ComplexTypeEntry); diff --git a/sources/shiboken6/ApiExtractor/typesystem.h b/sources/shiboken6/ApiExtractor/typesystem.h index fada1fea3..52ad0d435 100644 --- a/sources/shiboken6/ApiExtractor/typesystem.h +++ b/sources/shiboken6/ApiExtractor/typesystem.h @@ -582,6 +582,10 @@ public: TypeSystem::SnakeCase snakeCase() const; void setSnakeCase(TypeSystem::SnakeCase sc); + // Determined by AbstractMetaBuilder from the code model. + bool isValueTypeWithCopyConstructorOnly() const; + void setValueTypeWithCopyConstructorOnly(bool v); + #ifndef QT_NO_DEBUG_STREAM void formatDebug(QDebug &debug) const override; #endif diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index a0fe11cc7..1cda61c93 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -2492,7 +2492,7 @@ void CppGenerator::writeTypeCheck(TextStream &s, bool numberType = numericTypes.count() == 1 || ShibokenGenerator::isPyInt(argType); QString customType = (overloadData->hasArgumentTypeReplace() ? overloadData->argumentTypeReplaced() : QString()); bool rejectNull = - shouldRejectNullPointerArgument(api(), overloadData->referenceFunction(), overloadData->argPos()); + shouldRejectNullPointerArgument(overloadData->referenceFunction(), overloadData->argPos()); writeTypeCheck(s, argType, argumentName, numberType, customType, rejectNull); } @@ -2610,7 +2610,7 @@ void CppGenerator::writePythonToCppTypeConversion(TextStream &s, const bool isPrimitive = typeEntry->isPrimitive(); const bool isEnum = typeEntry->isEnum(); const bool isFlags = typeEntry->isFlags(); - bool treatAsPointer = valueTypeWithCopyConstructorOnlyPassed(api(), type); + const bool treatAsPointer = type.valueTypeWithCopyConstructorOnlyPassed(); bool isPointerOrObjectType = (type.isObjectType() || type.isPointer()) && !type.isUserPrimitive() && !type.isExtendedCppPrimitive() && !isEnum && !isFlags; @@ -3328,7 +3328,7 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s, const Abst for (int i = 0; i < containerType.instantiations().count(); ++i) { const AbstractMetaType &type = containerType.instantiations().at(i); QString typeName = getFullTypeName(type); - if (valueTypeWithCopyConstructorOnlyPassed(api(), type)) { + if (type.valueTypeWithCopyConstructorOnlyPassed()) { for (int pos = 0; ; ) { const QRegularExpressionMatch match = convertToCppRegEx().match(code, pos); if (!match.hasMatch()) @@ -3597,7 +3597,7 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr userArgs.append(arg.name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX)); } else { const int idx = arg.argumentIndex() - removedArgs; - const bool deRef = valueTypeWithCopyConstructorOnlyPassed(api(), arg.type()) + const bool deRef = arg.type().valueTypeWithCopyConstructorOnlyPassed() || arg.type().isObjectTypeUsedAsValueType() || arg.type().shouldDereferencePointer(); QString argName; diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp index 4dca52fa4..3f776f7ad 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp @@ -612,14 +612,14 @@ void ShibokenGenerator::writeToCppConversion(TextStream &s, const AbstractMetaTy s << cpythonToCppConversionFunction(type, context) << inArgName << ", &" << outArgName << ')'; } -bool ShibokenGenerator::shouldRejectNullPointerArgument(const ApiExtractorResult &api, - const AbstractMetaFunctionCPtr &func, int argIndex) +bool ShibokenGenerator::shouldRejectNullPointerArgument(const AbstractMetaFunctionCPtr &func, + int argIndex) { if (argIndex < 0 || argIndex >= func->arguments().count()) return false; const AbstractMetaArgument &arg = func->arguments().at(argIndex); - if (isValueTypeWithCopyConstructorOnly(api, arg.type())) + if (arg.type().isValueTypeWithCopyConstructorOnly()) return true; // Argument type is not a pointer, a None rejection should not be @@ -991,29 +991,6 @@ bool ShibokenGenerator::isPyInt(const AbstractMetaType &type) return isPyInt(type.typeEntry()); } -bool ShibokenGenerator::isValueTypeWithCopyConstructorOnly(const ApiExtractorResult &api, - const TypeEntry *type) -{ - if (!type || !type->isValue()) - return false; - auto klass = AbstractMetaClass::findClass(api.classes(), type); - return klass != nullptr && klass->isValueTypeWithCopyConstructorOnly(); -} - -bool ShibokenGenerator::isValueTypeWithCopyConstructorOnly(const ApiExtractorResult &api, - const AbstractMetaType &type) -{ - return type.typeEntry()->isValue() - && isValueTypeWithCopyConstructorOnly(api, type.typeEntry()); -} - -bool ShibokenGenerator::valueTypeWithCopyConstructorOnlyPassed(const ApiExtractorResult &api, - const AbstractMetaType &type) -{ - return (type.passByValue() || type.passByConstRef()) - && isValueTypeWithCopyConstructorOnly(api, type); -} - bool ShibokenGenerator::isNullPtr(const QString &value) { return value == QLatin1String("0") || value == QLatin1String("nullptr") @@ -1104,7 +1081,7 @@ QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry *type, bool gene } QString typeCheck; if (type->targetLangApiName() == type->name()) - typeCheck = cpythonIsConvertibleFunction(api(), type); + typeCheck = cpythonIsConvertibleFunction(type); else if (type->targetLangApiName() == QLatin1String("PyUnicode")) typeCheck = QLatin1String("Shiboken::String::check"); else @@ -1150,13 +1127,18 @@ ShibokenGenerator::CPythonCheckFunctionResult return result; } -QString ShibokenGenerator::cpythonIsConvertibleFunction(const ApiExtractorResult &api, const TypeEntry *type, +QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntry *type, bool /* genericNumberType */, bool /* checkExact */) { if (type->isWrapperType()) { QString result = QLatin1String("Shiboken::Conversions::"); - result += (type->isValue() && !isValueTypeWithCopyConstructorOnly(api, type)) + bool isValue = false; + if (type->isValue()) { + const auto *cte = static_cast<const ComplexTypeEntry *>(type); + isValue = !cte->isValueTypeWithCopyConstructorOnly(); + } + result += isValue ? QLatin1String("isPythonToCppValueConvertible") : QLatin1String("isPythonToCppPointerConvertible"); result += QLatin1String("(reinterpret_cast<SbkObjectType *>(") @@ -1179,7 +1161,7 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(AbstractMetaType metaTyp QString result = QLatin1String("Shiboken::Conversions::"); if (metaType.isWrapperType()) { - if (metaType.isPointer() || isValueTypeWithCopyConstructorOnly(api(), metaType)) + if (metaType.isPointer() || metaType.isValueTypeWithCopyConstructorOnly()) result += QLatin1String("isPythonToCppPointerConvertible"); else if (metaType.referenceType() == LValueReference) result += QLatin1String("isPythonToCppReferenceConvertible"); diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h index 504420fdf..9bb3327ac 100644 --- a/sources/shiboken6/generator/shiboken/shibokengenerator.h +++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h @@ -189,8 +189,7 @@ protected: const QString &outArgName); /// Returns true if the argument is a pointer that rejects nullptr values. - static bool shouldRejectNullPointerArgument(const ApiExtractorResult &api, - const AbstractMetaFunctionCPtr &func, + static bool shouldRejectNullPointerArgument(const AbstractMetaFunctionCPtr &func, int argIndex); /// Verifies if the class should have a C++ wrapper generated for it, instead of only a Python wrapper. @@ -226,17 +225,6 @@ protected: static bool isPyInt(const TypeEntry *type); static bool isPyInt(const AbstractMetaType &type); - /// Returns whether the underlying type is a value type with copy constructor only - static bool isValueTypeWithCopyConstructorOnly(const ApiExtractorResult &api, - const TypeEntry *type); - static bool isValueTypeWithCopyConstructorOnly(const ApiExtractorResult &api, - const AbstractMetaType &type); - /// Returns whether the type (function argument) is a value type with - /// copy constructor only is passed as value or const-ref and thus - /// no default value can be constructed. - static bool valueTypeWithCopyConstructorOnlyPassed(const ApiExtractorResult &api, - const AbstractMetaType &type); - static bool isNullPtr(const QString &value); static QString converterObject(const AbstractMetaType &type) ; @@ -267,8 +255,7 @@ protected: std::optional<AbstractMetaType> type; }; static CPythonCheckFunctionResult guessCPythonCheckFunction(const QString &type); - static QString cpythonIsConvertibleFunction(const ApiExtractorResult &api, - const TypeEntry *type, + static QString cpythonIsConvertibleFunction(const TypeEntry *type, bool genericNumberType = false, bool checkExact = false); QString cpythonIsConvertibleFunction(AbstractMetaType metaType, |