aboutsummaryrefslogtreecommitdiffstats
path: root/sources
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2021-09-10 14:58:54 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2021-09-11 07:57:17 +0200
commitacaa0e5ce430d87eea1d76620e3b9e3584a55f86 (patch)
treecce83caa766e7d69de3be3bee5990b2b3e79baea /sources
parenta4a23da2df6af79f03f0d10bd10a18b3cb437396 (diff)
shiboken6: Refactor handling of values with copy constructor only
ShibokenGenerato::valueTypeWithCopyConstructorOnly() is frequently called when writing argument conversions. Instead of repeatedly searching for classes and looping its functions, determine the value once in AbstractMetaBuilder and set it as a boolean flag on class and type entry. Move the functions from ShibokenGenerator to AbstractMetaType. Task-number: PYSIDE-1605 Change-Id: If6701ff87b8dd23039f1d35daa6c9291acd0aa87 Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources')
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp4
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.cpp19
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.h2
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetatype.cpp16
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetatype.h6
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.cpp14
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.h4
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp8
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp42
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.h17
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,