aboutsummaryrefslogtreecommitdiffstats
path: root/sources
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-11-13 10:37:09 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-11-14 18:55:16 +0000
commita6dd968379935452462b5785e937c37b3561425f (patch)
treea5948a790b2a0f765a1b0e10231b0484b7502fd4 /sources
parentd06005c8b0acbb52c0ee74f2ccb8bc64fd482d18 (diff)
shiboken6: Use std::optional for returning AbstractMetaType
Remove its invalid state. Remove a few checks that apparently originated from the old code where AbstractMetaType * = 0 meant void. Change-Id: Ifc938c011f07f4b5316f708f6cce1e98bcaa8125 Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources')
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp275
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.h15
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h24
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetatype.cpp11
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetatype.h4
-rw-r--r--sources/shiboken6/ApiExtractor/propertyspec.cpp8
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp4
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testcontainer.cpp1
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp4
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testtemplates.cpp5
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp79
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h6
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp91
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.h12
14 files changed, 258 insertions, 281 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
index 89a9a80c0..b0b449f0c 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
@@ -184,11 +184,12 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(const ArgumentMod
AbstractMetaClass *currentClass)
{
AbstractMetaClass *returned = nullptr;
- AbstractMetaType type = translateType(argument->type(), currentClass);
- if (type && type.typeEntry() && type.typeEntry()->isComplex()) {
- const TypeEntry *entry = type.typeEntry();
+ auto type = translateType(argument->type(), currentClass);
+ if (!type.has_value())
+ return returned;
+ const TypeEntry *entry = type->typeEntry();
+ if (entry && entry->isComplex())
returned = AbstractMetaClass::findClass(m_metaClasses, entry);
- }
return returned;
}
@@ -252,8 +253,8 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte
baseoperandClass = argumentToClass(arguments.at(1), currentClass);
firstArgumentIsSelf = false;
} else {
- AbstractMetaType type = translateType(item->type(), currentClass);
- const TypeEntry *retType = type ? type.typeEntry() : nullptr;
+ auto type = translateType(item->type(), currentClass);
+ const TypeEntry *retType = type.has_value() ? type->typeEntry() : nullptr;
AbstractMetaClass *otherArgClass = argumentToClass(arguments.at(1), currentClass);
if (otherArgClass && retType
&& (retType->isValue() || retType->isObject())
@@ -1158,9 +1159,9 @@ std::optional<AbstractMetaField>
metaField.setEnclosingClass(cls);
TypeInfo fieldType = field->type();
- AbstractMetaType metaType = translateType(fieldType, cls);
+ auto metaType = translateType(fieldType, cls);
- if (!metaType) {
+ if (!metaType.has_value()) {
const QString type = TypeInfo::resolveType(fieldType, currentScope()).qualifiedName().join(colonColon());
if (cls->typeEntry()->generateCode()) {
qCWarning(lcShiboken, "%s",
@@ -1169,7 +1170,7 @@ std::optional<AbstractMetaField>
return {};
}
- metaField.setType(metaType);
+ metaField.setType(metaType.value());
AbstractMetaAttributes::Attributes attr;
if (field->isStatic())
@@ -1500,8 +1501,8 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
{
QString errorMessage;
- AbstractMetaType returnType = translateType(addedFunc->returnType(), metaClass, {}, &errorMessage);
- if (!returnType) {
+ auto returnType = translateType(addedFunc->returnType(), metaClass, {}, &errorMessage);
+ if (!returnType.has_value()) {
qCWarning(lcShiboken, "%s",
qPrintable(msgAddedFunctionInvalidReturnType(addedFunc->name(),
addedFunc->returnType().qualifiedName(),
@@ -1511,14 +1512,14 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
}
auto metaFunction = new AbstractMetaFunction(addedFunc);
- metaFunction->setType(returnType);
+ metaFunction->setType(returnType.value());
const auto &args = addedFunc->arguments();
for (int i = 0; i < args.count(); ++i) {
const AddedFunction::Argument &arg = args.at(i);
- AbstractMetaType type = translateType(arg.typeInfo, metaClass, {}, &errorMessage);
- if (Q_UNLIKELY(!type)) {
+ auto type = translateType(arg.typeInfo, metaClass, {}, &errorMessage);
+ if (Q_UNLIKELY(!type.has_value())) {
qCWarning(lcShiboken, "%s",
qPrintable(msgAddedFunctionInvalidArgType(addedFunc->name(),
arg.typeInfo.qualifiedName(), i + 1,
@@ -1527,12 +1528,12 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
delete metaFunction;
return nullptr;
}
- type.decideUsagePattern();
+ type->decideUsagePattern();
AbstractMetaArgument metaArg;
if (!args.at(i).name.isEmpty())
metaArg.setName(args.at(i).name);
- metaArg.setType(type);
+ metaArg.setType(type.value());
metaArg.setArgumentIndex(i);
metaArg.setDefaultValueExpression(arg.defaultValue);
metaArg.setOriginalDefaultValueExpression(arg.defaultValue);
@@ -1806,8 +1807,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
return nullptr;
}
- AbstractMetaType type = translateType(returnType, currentClass, {}, &errorMessage);
- if (!type) {
+ auto type = translateType(returnType, currentClass, {}, &errorMessage);
+ if (!type.has_value()) {
const QString reason = msgUnmatchedReturnType(functionItem, errorMessage);
qCWarning(lcShiboken, "%s",
qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason)));
@@ -1816,7 +1817,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
return nullptr;
}
- metaFunction->setType(type);
+ metaFunction->setType(type.value());
}
break;
}
@@ -1839,8 +1840,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
return nullptr;
}
- AbstractMetaType metaType = translateType(arg->type(), currentClass, {}, &errorMessage);
- if (!metaType) {
+ auto metaTypeO = translateType(arg->type(), currentClass, {}, &errorMessage);
+ if (!metaTypeO.has_value()) {
// If an invalid argument has a default value, simply remove it
// unless the function is virtual (since the override in the
// wrapper can then not correctly be generated).
@@ -1851,7 +1852,6 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
}
break;
}
- Q_ASSERT(!metaType);
const QString reason = msgUnmatchedParameterType(arg, i, errorMessage);
qCWarning(lcShiboken, "%s",
qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason)));
@@ -1862,6 +1862,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
return nullptr;
}
+ auto metaType = metaTypeO.value();
// Add view substitution for simple view types of function arguments
// std::string_view -> std::string for foo(std::string_view)
auto viewOnTypeEntry = metaType.typeEntry()->viewOn();
@@ -1897,7 +1898,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
AbstractMetaArgument &metaArg = metaArguments[i];
const QString originalDefaultExpression =
- fixDefaultValue(arg, metaArg.type(), metaFunction, currentClass, i);
+ fixDefaultValue(arg, metaArg.type(), currentClass, i);
metaArg.setOriginalDefaultValueExpression(originalDefaultExpression);
metaArg.setDefaultValueExpression(originalDefaultExpression);
@@ -2060,10 +2061,11 @@ const AbstractMetaClass *AbstractMetaBuilderPrivate::resolveTypeSystemTypeDef(co
return nullptr;
}
-AbstractMetaType AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei,
- AbstractMetaClass *currentClass,
- TranslateTypeFlags flags,
- QString *errorMessage)
+std::optional<AbstractMetaType>
+ AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei,
+ AbstractMetaClass *currentClass,
+ TranslateTypeFlags flags,
+ QString *errorMessage)
{
return translateTypeStatic(_typei, currentClass, this, flags, errorMessage);
}
@@ -2074,11 +2076,12 @@ static bool isNumber(const QString &s)
[](QChar c) { return c.isDigit(); });
}
-AbstractMetaType AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei,
- AbstractMetaClass *currentClass,
- AbstractMetaBuilderPrivate *d,
- TranslateTypeFlags flags,
- QString *errorMessageIn)
+std::optional<AbstractMetaType>
+ AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei,
+ AbstractMetaClass *currentClass,
+ AbstractMetaBuilderPrivate *d,
+ TranslateTypeFlags flags,
+ QString *errorMessageIn)
{
if (_typei.isVoid())
return AbstractMetaType::createVoid();
@@ -2087,11 +2090,11 @@ AbstractMetaType AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
// type system
const bool resolveType = !flags.testFlag(AbstractMetaBuilder::DontResolveType);
if (resolveType) {
- AbstractMetaType resolved =
+ auto resolved =
translateTypeStatic(_typei, currentClass, d,
flags | AbstractMetaBuilder::DontResolveType,
errorMessageIn);
- if (resolved)
+ if (resolved.has_value())
return resolved;
}
@@ -2150,8 +2153,8 @@ AbstractMetaType AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
newInfo.setReferenceType(typeInfo.referenceType());
newInfo.setVolatile(typeInfo.isVolatile());
- AbstractMetaType elementType = translateTypeStatic(newInfo, currentClass, d, flags, &errorMessage);
- if (!elementType) {
+ auto elementType = translateTypeStatic(newInfo, currentClass, d, flags, &errorMessage);
+ if (!elementType.has_value()) {
if (errorMessageIn) {
errorMessage.prepend(QLatin1String("Unable to translate array element: "));
*errorMessageIn = msgUnableToTranslateType(_typei, errorMessage);
@@ -2161,7 +2164,7 @@ AbstractMetaType AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
for (int i = typeInfo.arrayElements().size() - 1; i >= 0; --i) {
AbstractMetaType arrayType;
- arrayType.setArrayElementType(elementType);
+ arrayType.setArrayElementType(elementType.value());
const QString &arrayElement = typeInfo.arrayElements().at(i);
if (!arrayElement.isEmpty()) {
bool _ok;
@@ -2171,7 +2174,7 @@ AbstractMetaType AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
if (_ok)
arrayType.setArrayElementCount(int(elems));
}
- auto elementTypeEntry = elementType.typeEntry();
+ auto elementTypeEntry = elementType->typeEntry();
arrayType.setTypeEntry(new ArrayTypeEntry(elementTypeEntry, elementTypeEntry->version(),
elementTypeEntry->parent()));
arrayType.decideUsagePattern();
@@ -2221,10 +2224,10 @@ AbstractMetaType AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
const auto &templateArguments = typeInfo.instantiations();
for (int t = 0, size = templateArguments.size(); t < size; ++t) {
const TypeInfo &ti = templateArguments.at(t);
- AbstractMetaType targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage);
+ auto targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage);
// For non-type template parameters, create a dummy type entry on the fly
// as is done for classes.
- if (!targType) {
+ if (!targType.has_value()) {
const QString value = ti.qualifiedName().join(colonColon());
if (isNumber(value)) {
TypeDatabase::instance()->addConstantValueTypeEntry(value, type->typeSystemTypeEntry());
@@ -2237,7 +2240,7 @@ AbstractMetaType AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
return {};
}
- metaType.addInstantiation(targType);
+ metaType.addInstantiation(targType.value());
}
if (typeEntryType == TypeEntry::SmartPointerType) {
@@ -2283,24 +2286,25 @@ AbstractMetaType AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo
}
}
- Q_ASSERT(metaType.typeUsagePattern() != AbstractMetaType::InvalidPattern);
return metaType;
}
-AbstractMetaType AbstractMetaBuilder::translateType(const TypeInfo &_typei,
- AbstractMetaClass *currentClass,
- TranslateTypeFlags flags,
- QString *errorMessage)
+std::optional<AbstractMetaType>
+ AbstractMetaBuilder::translateType(const TypeInfo &_typei,
+ AbstractMetaClass *currentClass,
+ TranslateTypeFlags flags,
+ QString *errorMessage)
{
return AbstractMetaBuilderPrivate::translateTypeStatic(_typei, currentClass,
nullptr, flags,
errorMessage);
}
-AbstractMetaType AbstractMetaBuilder::translateType(const QString &t,
- AbstractMetaClass *currentClass,
- TranslateTypeFlags flags,
- QString *errorMessageIn)
+std::optional<AbstractMetaType>
+ AbstractMetaBuilder::translateType(const QString &t,
+ AbstractMetaClass *currentClass,
+ TranslateTypeFlags flags,
+ QString *errorMessageIn)
{
QString errorMessage;
TypeInfo typeInfo = TypeParser::parse(t, &errorMessage);
@@ -2355,7 +2359,6 @@ qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringV
QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &item,
const AbstractMetaType &type,
- AbstractMetaFunction *fnc,
AbstractMetaClass *implementingClass,
int /* argumentIndex */)
{
@@ -2363,85 +2366,76 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite
if (expr.isEmpty())
return expr;
- if (type) {
- if (type.isPrimitive()) {
- if (type.name() == QLatin1String("boolean")) {
- if (expr != QLatin1String("false") && expr != QLatin1String("true")) {
- bool ok = false;
- int number = expr.toInt(&ok);
- if (ok && number)
- expr = QLatin1String("true");
- else
- expr = QLatin1String("false");
- }
- } else {
- // This can be an enum or flag so I need to delay the
- // translation untill all namespaces are completly
- // processed. This is done in figureOutEnumValues()
- }
- } else if (type.isFlags() || type.isEnum()) {
- bool isNumber;
- expr.toInt(&isNumber);
- if (!isNumber && expr.indexOf(colonColon()) < 0) {
- // Add the enum/flag scope to default value, making it usable
- // from other contexts beside its owner class hierarchy
- static const QRegularExpression typeRegEx(QStringLiteral("[^<]*[<]([^:]*::).*"));
- Q_ASSERT(typeRegEx.isValid());
- const QRegularExpressionMatch match = typeRegEx.match(type.minimalSignature());
- if (match.hasMatch())
- expr.prepend(match.captured(1));
+ if (type.isPrimitive()) {
+ if (type.name() == QLatin1String("boolean")) {
+ if (expr != QLatin1String("false") && expr != QLatin1String("true")) {
+ bool ok = false;
+ int number = expr.toInt(&ok);
+ if (ok && number)
+ expr = QLatin1String("true");
+ else
+ expr = QLatin1String("false");
}
- } else if (type.isContainer() && expr.contains(QLatin1Char('<'))) {
- static const QRegularExpression typeRegEx(QStringLiteral("[^<]*<(.*)>"));
- Q_ASSERT(typeRegEx.isValid());
- const QRegularExpressionMatch typeMatch = typeRegEx.match(type.minimalSignature());
- static const QRegularExpression defaultRegEx(QLatin1String("([^<]*<).*(>[^>]*)"));
- Q_ASSERT(defaultRegEx.isValid());
- const QRegularExpressionMatch defaultMatch = defaultRegEx.match(expr);
- if (typeMatch.hasMatch() && defaultMatch.hasMatch())
- expr = defaultMatch.captured(1) + typeMatch.captured(1) + defaultMatch.captured(2);
} else {
- // Here the default value is supposed to be a constructor,
- // a class field, or a constructor receiving a class field
- static const QRegularExpression defaultRegEx(QStringLiteral("([^\\(]*\\(|)([^\\)]*)(\\)|)"));
- Q_ASSERT(defaultRegEx.isValid());
- const QRegularExpressionMatch defaultMatch = defaultRegEx.match(expr);
- QString defaultValueCtorName = defaultMatch.hasMatch() ? defaultMatch.captured(1) : QString();
- if (defaultValueCtorName.endsWith(QLatin1Char('(')))
- defaultValueCtorName.chop(1);
-
- // Fix the scope for constructor using the already
- // resolved argument type as a reference.
- // The following regular expression extracts any
- // use of namespaces/scopes from the type string.
- static const QRegularExpression typeRegEx(QLatin1String("^(?:const[\\s]+|)([\\w:]*::|)([A-Za-z_]\\w*)\\s*[&\\*]?$"));
+ // This can be an enum or flag so I need to delay the
+ // translation until all namespaces are completely
+ // processed. This is done in figureOutEnumValues()
+ }
+ } else if (type.isFlags() || type.isEnum()) {
+ bool isNumber;
+ expr.toInt(&isNumber);
+ if (!isNumber && expr.indexOf(colonColon()) < 0) {
+ // Add the enum/flag scope to default value, making it usable
+ // from other contexts beside its owner class hierarchy
+ static const QRegularExpression typeRegEx(QStringLiteral("[^<]*[<]([^:]*::).*"));
Q_ASSERT(typeRegEx.isValid());
- const QRegularExpressionMatch typeMatch = typeRegEx.match(type.minimalSignature());
-
- QString typeNamespace = typeMatch.hasMatch() ? typeMatch.captured(1) : QString();
- QString typeCtorName = typeMatch.hasMatch() ? typeMatch.captured(2) : QString();
- if (!typeNamespace.isEmpty() && defaultValueCtorName == typeCtorName)
- expr.prepend(typeNamespace);
-
- // Fix scope if the parameter is a field of the current class
- if (implementingClass) {
- const AbstractMetaFieldList &fields = implementingClass->fields();
- for (const AbstractMetaField &field : fields) {
- if (defaultMatch.hasMatch() && defaultMatch.captured(2) == field.name()) {
- expr = defaultMatch.captured(1) + implementingClass->name()
- + colonColon() + defaultMatch.captured(2) + defaultMatch.captured(3);
- break;
- }
+ const QRegularExpressionMatch match = typeRegEx.match(type.minimalSignature());
+ if (match.hasMatch())
+ expr.prepend(match.captured(1));
+ }
+ } else if (type.isContainer() && expr.contains(QLatin1Char('<'))) {
+ static const QRegularExpression typeRegEx(QStringLiteral("[^<]*<(.*)>"));
+ Q_ASSERT(typeRegEx.isValid());
+ const QRegularExpressionMatch typeMatch = typeRegEx.match(type.minimalSignature());
+ static const QRegularExpression defaultRegEx(QLatin1String("([^<]*<).*(>[^>]*)"));
+ Q_ASSERT(defaultRegEx.isValid());
+ const QRegularExpressionMatch defaultMatch = defaultRegEx.match(expr);
+ if (typeMatch.hasMatch() && defaultMatch.hasMatch())
+ expr = defaultMatch.captured(1) + typeMatch.captured(1) + defaultMatch.captured(2);
+ } else {
+ // Here the default value is supposed to be a constructor,
+ // a class field, or a constructor receiving a class field
+ static const QRegularExpression defaultRegEx(QStringLiteral("([^\\(]*\\(|)([^\\)]*)(\\)|)"));
+ Q_ASSERT(defaultRegEx.isValid());
+ const QRegularExpressionMatch defaultMatch = defaultRegEx.match(expr);
+ QString defaultValueCtorName = defaultMatch.hasMatch() ? defaultMatch.captured(1) : QString();
+ if (defaultValueCtorName.endsWith(QLatin1Char('(')))
+ defaultValueCtorName.chop(1);
+
+ // Fix the scope for constructor using the already resolved argument
+ // type as a reference. The following regular expression extracts any
+ // use of namespaces/scopes from the type string.
+ static const QRegularExpression
+ typeRegEx(QLatin1String(R"(^(?:const[\s]+|)([\w:]*::|)([A-Za-z_]\w*)\s*[&\*]?$)"));
+ Q_ASSERT(typeRegEx.isValid());
+ const QRegularExpressionMatch typeMatch = typeRegEx.match(type.minimalSignature());
+
+ QString typeNamespace = typeMatch.hasMatch() ? typeMatch.captured(1) : QString();
+ QString typeCtorName = typeMatch.hasMatch() ? typeMatch.captured(2) : QString();
+ if (!typeNamespace.isEmpty() && defaultValueCtorName == typeCtorName)
+ expr.prepend(typeNamespace);
+
+ // Fix scope if the parameter is a field of the current class
+ if (implementingClass) {
+ const AbstractMetaFieldList &fields = implementingClass->fields();
+ for (const AbstractMetaField &field : fields) {
+ if (defaultMatch.hasMatch() && defaultMatch.captured(2) == field.name()) {
+ expr = defaultMatch.captured(1) + implementingClass->name()
+ + colonColon() + defaultMatch.captured(2) + defaultMatch.captured(3);
+ break;
}
}
}
- } else {
- const QString className = implementingClass ? implementingClass->qualifiedCppName() : QString();
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("undefined type for default value '%3' of argument in function '%1', class '%2'")
- .arg(fnc->name(), className, item->defaultValueExpression());
-
- expr.clear();
}
return expr;
@@ -2526,11 +2520,10 @@ bool AbstractMetaBuilderPrivate::ancestorHasPrivateCopyConstructor(const Abstrac
return false;
}
-AbstractMetaType AbstractMetaBuilderPrivate::inheritTemplateType(const AbstractMetaTypeList &templateTypes,
- const AbstractMetaType &metaType)
+std::optional<AbstractMetaType>
+ AbstractMetaBuilderPrivate::inheritTemplateType(const AbstractMetaTypeList &templateTypes,
+ const AbstractMetaType &metaType)
{
- Q_ASSERT(metaType);
-
auto returned = metaType;
if (!metaType.typeEntry()->isTemplateArgument() && !metaType.hasInstantiations())
@@ -2544,7 +2537,7 @@ AbstractMetaType AbstractMetaBuilderPrivate::inheritTemplateType(const AbstractM
// If the template is intantiated with void we special case this as rejecting the functions that use this
// parameter from the instantiation.
const AbstractMetaType &templateType = templateTypes.value(tae->ordinal());
- if (!templateType || templateType.typeEntry()->isVoid())
+ if (templateType.typeEntry()->isVoid())
return {};
AbstractMetaType t = returned;
@@ -2558,10 +2551,10 @@ AbstractMetaType AbstractMetaBuilderPrivate::inheritTemplateType(const AbstractM
if (returned.hasInstantiations()) {
AbstractMetaTypeList instantiations = returned.instantiations();
for (int i = 0; i < instantiations.count(); ++i) {
- instantiations[i] =
- inheritTemplateType(templateTypes, instantiations.at(i));
- if (!instantiations.at(i))
+ auto ins = inheritTemplateType(templateTypes, instantiations.at(i));
+ if (!ins.has_value())
return {};
+ instantiations[i] = ins.value();
}
returned.setInstantiations(instantiations);
}
@@ -2655,19 +2648,19 @@ void AbstractMetaBuilderPrivate::inheritTemplateFunctions(AbstractMetaClass *sub
f->setArguments(AbstractMetaArgumentList());
if (!function->isVoid()) {
- AbstractMetaType returnType = inheritTemplateType(templateTypes, function->type());
- if (!returnType)
+ auto returnType = inheritTemplateType(templateTypes, function->type());
+ if (!returnType.has_value())
continue;
- f->setType(returnType);
+ f->setType(returnType.value());
}
const AbstractMetaArgumentList &arguments = function->arguments();
for (const AbstractMetaArgument &argument : arguments) {
- AbstractMetaType argType = inheritTemplateType(templateTypes, argument.type());
- if (!argType)
+ auto argType = inheritTemplateType(templateTypes, argument.type());
+ if (!argType.has_value())
break;
AbstractMetaArgument arg = argument;
- arg.setType(argType);
+ arg.setType(argType.value());
f->addArgument(arg);
}
@@ -2738,10 +2731,10 @@ void AbstractMetaBuilderPrivate::inheritTemplateFunctions(AbstractMetaClass *sub
AbstractMetaField f = field;
f.setEnclosingClass(subclass);
- AbstractMetaType fieldType = inheritTemplateType(templateTypes, field.type());
- if (!fieldType)
+ auto fieldType = inheritTemplateType(templateTypes, field.type());
+ if (!fieldType.has_value())
continue;
- f.setType(fieldType);
+ f.setType(fieldType.value());
subclass->addField(f);
}
}
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.h b/sources/shiboken6/ApiExtractor/abstractmetabuilder.h
index a11f2ec4f..45459a16e 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.h
@@ -99,15 +99,12 @@ public:
};
Q_DECLARE_FLAGS(TranslateTypeFlags, TranslateTypeFlag);
- static AbstractMetaType translateType(const TypeInfo &_typei,
- AbstractMetaClass *currentClass = nullptr,
- TranslateTypeFlags flags = {},
- QString *errorMessage = nullptr);
- static AbstractMetaType translateType(const QString &t,
- AbstractMetaClass *currentClass = nullptr,
- TranslateTypeFlags flags = {},
- QString *errorMessage = nullptr);
-
+ static std::optional<AbstractMetaType>
+ translateType(const TypeInfo &_typei, AbstractMetaClass *currentClass = nullptr,
+ TranslateTypeFlags flags = {}, QString *errorMessage = nullptr);
+ static std::optional<AbstractMetaType>
+ translateType(const QString &t, AbstractMetaClass *currentClass = nullptr,
+ TranslateTypeFlags flags = {}, QString *errorMessage = nullptr);
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const;
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
index b943ad628..2789c88bd 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
@@ -144,18 +144,15 @@ public:
void setupFunctionDefaults(AbstractMetaFunction *metaFunction,
AbstractMetaClass *metaClass);
- QString fixDefaultValue(const ArgumentModelItem &item, const AbstractMetaType &type,
- AbstractMetaFunction *fnc, AbstractMetaClass *,
+ QString fixDefaultValue(const ArgumentModelItem &item, const AbstractMetaType &type, AbstractMetaClass *,
int argumentIndex);
- AbstractMetaType translateType(const TypeInfo &type,
- AbstractMetaClass *currentClass,
- TranslateTypeFlags flags = {},
- QString *errorMessage = nullptr);
- static AbstractMetaType translateTypeStatic(const TypeInfo &type,
- AbstractMetaClass *current,
- AbstractMetaBuilderPrivate *d = nullptr,
- TranslateTypeFlags flags = {},
- QString *errorMessageIn = nullptr);
+ std::optional<AbstractMetaType>
+ translateType(const TypeInfo &type, AbstractMetaClass *currentClass,
+ TranslateTypeFlags flags = {}, QString *errorMessage = nullptr);
+ static std::optional<AbstractMetaType>
+ translateTypeStatic(const TypeInfo &type, AbstractMetaClass *current,
+ AbstractMetaBuilderPrivate *d = nullptr, TranslateTypeFlags flags = {},
+ QString *errorMessageIn = nullptr);
static TypeEntries findTypeEntriesHelper(const QString &qualifiedName, const QString &name,
AbstractMetaClass *currentClass = nullptr,
AbstractMetaBuilderPrivate *d = nullptr);
@@ -176,8 +173,9 @@ public:
const AbstractMetaClass *templateClass,
const TypeInfo &info);
void inheritTemplateFunctions(AbstractMetaClass *subclass);
- AbstractMetaType inheritTemplateType(const AbstractMetaTypeList &templateTypes,
- const AbstractMetaType &metaType);
+ std::optional<AbstractMetaType>
+ inheritTemplateType(const AbstractMetaTypeList &templateTypes,
+ const AbstractMetaType &metaType);
bool isQObject(const FileModelItem &dom, const QString &qualifiedName);
bool isEnum(const FileModelItem &dom, const QStringList &qualifiedName);
diff --git a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
index 9e515d4b4..362ae22ef 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
@@ -67,7 +67,7 @@ public:
AbstractMetaTypeCPtr m_viewOn;
AbstractMetaType::Indirections m_indirections;
- AbstractMetaType::TypeUsagePattern m_pattern = AbstractMetaType::InvalidPattern;
+ AbstractMetaType::TypeUsagePattern m_pattern = AbstractMetaType::VoidPattern;
uint m_constant : 1;
uint m_volatile : 1;
uint m_signaturesDirty : 1;
@@ -104,11 +104,6 @@ AbstractMetaType &AbstractMetaType::operator=(AbstractMetaType &&) = default;
AbstractMetaType::~AbstractMetaType() = default;
-bool AbstractMetaType::isValid() const
-{
- return d->m_pattern != AbstractMetaType::InvalidPattern;
-}
-
QString AbstractMetaType::package() const
{
return d->m_typeEntry->targetLangPackage();
@@ -685,10 +680,6 @@ AbstractMetaType AbstractMetaType::createVoid()
#ifndef QT_NO_DEBUG_STREAM
void AbstractMetaType::formatDebug(QDebug &debug) const
{
- if (!isValid()) {
- debug << "Invalid";
- return;
- }
debug << '"' << name() << '"';
if (debug.verbosity() > 2) {
auto te = typeEntry();
diff --git a/sources/shiboken6/ApiExtractor/abstractmetatype.h b/sources/shiboken6/ApiExtractor/abstractmetatype.h
index c92a7652a..e321ad546 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetatype.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetatype.h
@@ -48,7 +48,6 @@ public:
using Indirections = QVector<Indirection>;
enum TypeUsagePattern {
- InvalidPattern,
PrimitivePattern,
FlagsPattern,
EnumPattern,
@@ -75,9 +74,6 @@ public:
AbstractMetaType &operator=(AbstractMetaType &&);
~AbstractMetaType();
- bool isValid() const;
- operator bool() const { return isValid(); }
-
QString package() const;
QString name() const;
QString fullName() const;
diff --git a/sources/shiboken6/ApiExtractor/propertyspec.cpp b/sources/shiboken6/ApiExtractor/propertyspec.cpp
index fb45830b1..f66eeeaf6 100644
--- a/sources/shiboken6/ApiExtractor/propertyspec.cpp
+++ b/sources/shiboken6/ApiExtractor/propertyspec.cpp
@@ -272,8 +272,8 @@ std::optional<QPropertySpec>
return {};
}
- AbstractMetaType type = b->translateType(info, metaClass, {}, &typeError);
- if (!type) {
+ auto type = b->translateType(info, metaClass, {}, &typeError);
+ if (!type.has_value()) {
const QStringList qualifiedName = info.qualifiedName();
for (int j = scopes.size(); j >= 0 && !type; --j) {
info.setQualifiedName(scopes.mid(0, j) + qualifiedName);
@@ -281,11 +281,11 @@ std::optional<QPropertySpec>
}
}
- if (!type) {
+ if (!type.has_value()) {
*errorMessage = msgPropertyTypeParsingFailed(ts.name, ts.type, typeError);
return {};
}
- return QPropertySpec(ts, type);
+ return QPropertySpec(ts, type.value());
}
// Convenience to create a QPropertySpec from a Q_PROPERTY macro
diff --git a/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp b/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp
index 0fab1bf07..e65b0f214 100644
--- a/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp
@@ -77,7 +77,7 @@ void TestAbstractMetaType::testConstCharPtrType()
AbstractMetaFunction *func = builder->globalFunctions().constFirst();
AbstractMetaType rtype = func->type();
// Test properties of const char*
- QVERIFY(rtype);
+ QVERIFY(!rtype.isVoid());
QCOMPARE(rtype.package(), QLatin1String("Foo"));
QCOMPARE(rtype.name(), QLatin1String("char"));
QVERIFY(rtype.isConstant());
@@ -150,7 +150,7 @@ void TestAbstractMetaType::testCharType()
AbstractMetaFunction *func = functions.constFirst();
AbstractMetaType rtype = func->type();
// Test properties of const char*
- QVERIFY(rtype);
+ QVERIFY(!rtype.isVoid());
QCOMPARE(rtype.package(), QLatin1String("Foo"));
QCOMPARE(rtype.name(), QLatin1String("char"));
QVERIFY(!rtype.isConstant());
diff --git a/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp b/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp
index 515eb520e..3ee39e4ec 100644
--- a/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp
@@ -94,7 +94,6 @@ void TestContainer::testListOfValueType()
QCOMPARE(classA->templateBaseClassInstantiations().count(), 1);
const AbstractMetaType templateInstanceType =
classA->templateBaseClassInstantiations().constFirst();
- QVERIFY(templateInstanceType);
QCOMPARE(templateInstanceType.indirections(), 0);
QVERIFY(!templateInstanceType.typeEntry()->isObject());
diff --git a/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp b/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp
index 54984620b..d613074fe 100644
--- a/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp
@@ -62,13 +62,11 @@ void TestNumericalTypedef::testNumericalTypedef()
QCOMPARE(funcReal->minimalSignature(), QLatin1String("funcReal(real)"));
const AbstractMetaType doubleType = funcDouble->arguments().constFirst().type();
- QVERIFY(doubleType);
QCOMPARE(doubleType.cppSignature(), QLatin1String("double"));
QVERIFY(doubleType.isPrimitive());
QVERIFY(doubleType.typeEntry()->isCppPrimitive());
const AbstractMetaType realType = funcReal->arguments().constFirst().type();
- QVERIFY(realType);
QCOMPARE(realType.cppSignature(), QLatin1String("real"));
QVERIFY(realType.isPrimitive());
QVERIFY(realType.typeEntry()->isCppPrimitive());
@@ -104,13 +102,11 @@ void TestNumericalTypedef::testUnsignedNumericalTypedef()
QCOMPARE(funcUShort->minimalSignature(), QLatin1String("funcUShort(custom_ushort)"));
const AbstractMetaType unsignedShortType = funcUnsignedShort->arguments().constFirst().type();
- QVERIFY(unsignedShortType);
QCOMPARE(unsignedShortType.cppSignature(), QLatin1String("unsigned short"));
QVERIFY(unsignedShortType.isPrimitive());
QVERIFY(unsignedShortType.typeEntry()->isCppPrimitive());
const AbstractMetaType ushortType = funcUShort->arguments().constFirst().type();
- QVERIFY(ushortType);
QCOMPARE(ushortType.cppSignature(), QLatin1String("custom_ushort"));
QVERIFY(ushortType.isPrimitive());
QVERIFY(ushortType.typeEntry()->isCppPrimitive());
diff --git a/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp
index 38199a869..2ddccc900 100644
--- a/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp
@@ -79,7 +79,7 @@ namespace Internet {
QVERIFY(classB);
const AbstractMetaFunction* func = classB->findFunction(QLatin1String("list"));
AbstractMetaType funcType = func->type();
- QVERIFY(funcType);
+ QVERIFY(!funcType.isVoid());
QCOMPARE(funcType.cppSignature(), QLatin1String("QList<Internet::Url >"));
}
@@ -397,7 +397,6 @@ typedef BaseTemplateClass<TypeOne> TypeOneClass;
AbstractMetaTypeList instantiations = one->templateBaseClassInstantiations();
QCOMPARE(instantiations.count(), 1);
const AbstractMetaType &inst = instantiations.constFirst();
- QVERIFY(inst);
QVERIFY(!inst.isEnum());
QVERIFY(!inst.typeEntry()->isEnum());
QVERIFY(inst.typeEntry()->isEnumValue());
@@ -446,7 +445,7 @@ typedef Vector<int> IntVector;
const AbstractMetaFunction* otherMethod = vector->findFunction(QLatin1String("otherMethod"));
QVERIFY(otherMethod);
QCOMPARE(otherMethod->signature(), QLatin1String("otherMethod()"));
- QVERIFY(otherMethod->type());
+ QVERIFY(!otherMethod->type().isVoid());
QCOMPARE(otherMethod->type().cppSignature(), QLatin1String("Vector<int >"));
}
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index b3759df61..0fd59b1b7 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -90,7 +90,7 @@ static const char *typeNameOf(const T &t)
// utility functions
inline AbstractMetaType getTypeWithoutContainer(const AbstractMetaType &arg)
{
- if (arg && arg.typeEntry()->isContainer()) {
+ if (arg.typeEntry()->isContainer()) {
// only support containers with 1 type
if (arg.instantiations().size() == 1)
return arg.instantiations().constFirst();
@@ -261,7 +261,8 @@ const AbstractMetaFunction *CppGenerator::boolCast(const AbstractMetaClass *meta
&& func->arguments().isEmpty() ? func : nullptr;
}
-AbstractMetaType CppGenerator::findSmartPointerInstantiation(const TypeEntry *entry) const
+std::optional<AbstractMetaType>
+ CppGenerator::findSmartPointerInstantiation(const TypeEntry *entry) const
{
for (const auto &i : instantiatedSmartPointers()) {
if (i.instantiations().at(0).typeEntry() == entry)
@@ -574,11 +575,11 @@ void CppGenerator::generateClass(QTextStream &s, const GeneratorContext &classCo
// @TODO: This possibly leaks, but there are a bunch of other places where this
// is done, so this will be fixed in bulk with all the other cases, because the
// ownership of the pointers is not clear at the moment.
- AbstractMetaType pointerToInnerType =
+ auto pointerToInnerType =
buildAbstractMetaTypeFromString(pointerToInnerTypeName);
-
+ Q_ASSERT(pointerToInnerType.has_value());
AbstractMetaFunction *mutableRfunc = overloads.constFirst();
- mutableRfunc->setType(pointerToInnerType);
+ mutableRfunc->setType(pointerToInnerType.value());
} else if (smartPointerTypeEntry->refCountMethodName().isEmpty()
|| smartPointerTypeEntry->refCountMethodName() != rfunc->name()) {
// Skip all public methods of the smart pointer except for the raw getter and
@@ -834,7 +835,7 @@ static bool allArgumentsRemoved(const AbstractMetaFunction *func)
QString CppGenerator::getVirtualFunctionReturnTypeName(const AbstractMetaFunction *func)
{
- if (!func->type())
+ if (func->type().isVoid())
return QLatin1String("\"\"");
if (!func->typeReplaced(0).isEmpty())
@@ -1780,8 +1781,9 @@ void CppGenerator::writeSmartPointerConverterFunctions(QTextStream &s, const Abs
for (auto k : classes) {
if (smartPointerTypeEntry->matchesInstantiation(k->typeEntry())) {
if (auto smartTargetType = findSmartPointerInstantiation(k->typeEntry())) {
- s << INDENT << "// SmartPointer derived class: " << smartTargetType.cppSignature() << "\n";
- writePythonToCppConversionFunctions(s, smartPointerType, smartTargetType, {}, {}, {});
+ s << INDENT << "// SmartPointer derived class: "
+ << smartTargetType->cppSignature() << "\n";
+ writePythonToCppConversionFunctions(s, smartPointerType, smartTargetType.value(), {}, {}, {});
}
}
}
@@ -2359,9 +2361,10 @@ void CppGenerator::writeTypeCheck(QTextStream &s, AbstractMetaType argType,
AbstractMetaType metaType;
// PYSIDE-795: Note: XML-Overrides are handled in this shibokengenerator function!
// This enables iterables for QMatrix4x4 for instance.
- customCheck = guessCPythonCheckFunction(customType, &metaType);
- if (metaType)
- argType = metaType;
+ auto customCheckResult = guessCPythonCheckFunction(customType);
+ customCheck = customCheckResult.checkFunction;
+ if (customCheckResult.type.has_value())
+ argType = customCheckResult.type.value();
}
// TODO-CONVERTER: merge this with the code below.
@@ -2388,8 +2391,7 @@ void CppGenerator::writeTypeCheck(QTextStream &s, AbstractMetaType argType,
static void checkTypeViability(const AbstractMetaFunction *func, const AbstractMetaType &type, int argIdx)
{
- if (!type
- || type.isVoid()
+ if (type.isVoid()
|| !type.typeEntry()->isPrimitive()
|| type.indirections() == 0
|| (type.indirections() == 1 && type.typeUsagePattern() == AbstractMetaType::NativePointerAsArrayPattern)
@@ -2467,7 +2469,8 @@ void CppGenerator::writeArgumentConversion(QTextStream &s,
writeUnusedVariableCast(s, argName);
}
-const AbstractMetaType CppGenerator::getArgumentType(const AbstractMetaFunction *func, int argPos)
+std::optional<AbstractMetaType>
+ CppGenerator::getArgumentType(const AbstractMetaFunction *func, int argPos)
{
if (argPos < 0 || argPos > func->arguments().size()) {
qCWarning(lcShiboken).noquote().nospace()
@@ -2484,7 +2487,7 @@ const AbstractMetaType CppGenerator::getArgumentType(const AbstractMetaFunction
}
auto argType = buildAbstractMetaTypeFromString(typeReplaced);
- if (!argType && !m_knownPythonTypes.contains(typeReplaced)) {
+ if (!argType.has_value() && !m_knownPythonTypes.contains(typeReplaced)) {
qCWarning(lcShiboken).noquote().nospace()
<< QString::fromLatin1("Unknown type '%1' used as argument type replacement "\
"in function '%2', the generated code may be broken.")
@@ -2947,14 +2950,16 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s,
}
if (hasConversionRule)
continue;
- const AbstractMetaType argType = getArgumentType(func, argIdx + 1);
- if (!argType || (mayHaveUnunsedArguments && !injectedCodeUsesArgument(func, argIdx)))
+ auto argType = getArgumentType(func, argIdx + 1);
+ if (!argType.has_value() || (mayHaveUnunsedArguments && !injectedCodeUsesArgument(func, argIdx)))
continue;
int argPos = argIdx - removedArgs;
QString argName = QLatin1String(CPP_ARG) + QString::number(argPos);
QString pyArgName = usePyArgs ? pythonArgsAt(argPos) : QLatin1String(PYTHON_ARG);
QString defaultValue = guessScopeForDefaultValue(func, arg);
- writeArgumentConversion(s, argType, argName, pyArgName, func->implementingClass(), defaultValue, func->isUserAdded());
+ writeArgumentConversion(s, argType.value(), argName, pyArgName,
+ func->implementingClass(), defaultValue,
+ func->isUserAdded());
}
s << Qt::endl;
@@ -3329,18 +3334,15 @@ QString CppGenerator::argumentNameFromIndex(const AbstractMetaFunction *func, in
} else {
int realIndex = argIndex - 1 - OverloadData::numberOfRemovedArguments(func, argIndex - 1);
AbstractMetaType argType = getTypeWithoutContainer(func->arguments().at(realIndex).type());
-
- if (argType) {
- *wrappedClass = AbstractMetaClass::findClass(classes(), argType.typeEntry());
- if (*wrappedClass == nullptr && errorMessage != nullptr)
- *errorMessage = msgClassNotFound(argType.typeEntry());
- if (argIndex == 1
- && !func->isConstructor()
- && OverloadData::isSingleArgument(getFunctionGroups(func->implementingClass())[func->name()]))
- pyArgName = QLatin1String(PYTHON_ARG);
- else
- pyArgName = pythonArgsAt(argIndex - 1);
- }
+ *wrappedClass = AbstractMetaClass::findClass(classes(), argType.typeEntry());
+ if (*wrappedClass == nullptr && errorMessage != nullptr)
+ *errorMessage = msgClassNotFound(argType.typeEntry());
+ if (argIndex == 1
+ && !func->isConstructor()
+ && OverloadData::isSingleArgument(getFunctionGroups(func->implementingClass())[func->name()]))
+ pyArgName = QLatin1String(PYTHON_ARG);
+ else
+ pyArgName = pythonArgsAt(argIndex - 1);
}
return pyArgName;
}
@@ -4040,11 +4042,13 @@ void CppGenerator::writeSmartPointerConverterInitialization(QTextStream &s, cons
s << Qt::endl;
for (auto k : classes) {
- if (auto smartTargetType = findSmartPointerInstantiation(k->typeEntry()))
- {
- s << INDENT << "// Convert to SmartPointer derived class: [" << smartTargetType.cppSignature() << "]\n";
- const QString converter = QLatin1String("Shiboken::Conversions::getConverter(\"%1\")").arg(smartTargetType.cppSignature());
- writeConversionRegister(type, fixedCppTypeName(smartTargetType), converter);
+ auto smartTargetType = findSmartPointerInstantiation(k->typeEntry());
+ if (smartTargetType.has_value()) {
+ s << INDENT << "// Convert to SmartPointer derived class: ["
+ << smartTargetType->cppSignature() << "]\n";
+ const QString converter =
+ QLatin1String("Shiboken::Conversions::getConverter(\"%1\")").arg(smartTargetType->cppSignature());
+ writeConversionRegister(type, fixedCppTypeName(smartTargetType.value()), converter);
} else {
s << INDENT << "// Class not found:" << type.instantiations().at(0).cppSignature();
}
@@ -4790,9 +4794,10 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, const GeneratorConte
const AbstractMetaFunction *func = od->referenceFunction();
if (func->isStatic())
continue;
- const AbstractMetaType argType = getArgumentType(func, 1);
- if (!argType)
+ auto argTypeO = getArgumentType(func, 1);
+ if (!argTypeO.has_value())
continue;
+ auto argType = argTypeO.value();
if (!first) {
s << " else ";
} else {
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h
index 276759f7f..22f93e12f 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.h
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.h
@@ -155,7 +155,8 @@ private:
* \param newType It is set to true if the type returned is a new object that must be deallocated.
* \return The type of the argument indicated by \p argPos.
*/
- const AbstractMetaType getArgumentType(const AbstractMetaFunction *func, int argPos);
+ std::optional<AbstractMetaType>
+ getArgumentType(const AbstractMetaFunction *func, int argPos);
void writePythonToCppTypeConversion(QTextStream &s,
const AbstractMetaType &type,
@@ -380,7 +381,8 @@ private:
bool hasBoolCast(const AbstractMetaClass *metaClass) const
{ return boolCast(metaClass) != nullptr; }
- AbstractMetaType findSmartPointerInstantiation(const TypeEntry *entry) const;
+ std::optional<AbstractMetaType>
+ findSmartPointerInstantiation(const TypeEntry *entry) const;
// Number protocol structure members names.
static QHash<QString, QString> m_nbFuncs;
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
index b8e31d8d5..aa2b551c7 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -1181,14 +1181,12 @@ bool ShibokenGenerator::isNullPtr(const QString &value)
QString ShibokenGenerator::cpythonCheckFunction(AbstractMetaType metaType, bool genericNumberType)
{
- QString customCheck;
if (metaType.typeEntry()->isCustom()) {
- AbstractMetaType type;
- customCheck = guessCPythonCheckFunction(metaType.typeEntry()->name(), &type);
- if (type)
- metaType = type;
- if (!customCheck.isEmpty())
- return customCheck;
+ auto customCheckResult = guessCPythonCheckFunction(metaType.typeEntry()->name());
+ if (!customCheckResult.checkFunction.isEmpty())
+ return customCheckResult.checkFunction;
+ if (customCheckResult.type.has_value())
+ metaType = customCheckResult.type.value();
}
if (isCppPrimitive(metaType)) {
@@ -1246,15 +1244,12 @@ QString ShibokenGenerator::cpythonCheckFunction(AbstractMetaType metaType, bool
QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry *type, bool genericNumberType)
{
- QString customCheck;
if (type->isCustom()) {
AbstractMetaType metaType;
- customCheck = guessCPythonCheckFunction(type->name(), &metaType);
- if (metaType) {
- const QString result = cpythonCheckFunction(metaType, genericNumberType);
- return result;
- }
- return customCheck;
+ auto customCheckResult = guessCPythonCheckFunction(type->name());
+ if (customCheckResult.type.has_value())
+ return cpythonCheckFunction(customCheckResult.type.value(), genericNumberType);
+ return customCheckResult.checkFunction;
}
if (type->isEnum() || type->isFlags() || isWrapperType(type))
@@ -1273,28 +1268,28 @@ QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry *type, bool gene
return typeCheck;
}
-QString ShibokenGenerator::guessCPythonCheckFunction(const QString &type, AbstractMetaType *metaType)
+ShibokenGenerator::CPythonCheckFunctionResult
+ ShibokenGenerator::guessCPythonCheckFunction(const QString &type)
{
- *metaType = {};
// PYSIDE-795: We abuse PySequence for iterables.
// This part handles the overrides in the XML files.
if (type == QLatin1String("PySequence"))
- return QLatin1String("Shiboken::String::checkIterable");
+ return {QLatin1String("Shiboken::String::checkIterable"), {}};
if (type == QLatin1String("PyTypeObject"))
- return QLatin1String("PyType_Check");
+ return {QLatin1String("PyType_Check"), {}};
if (type == QLatin1String("PyBuffer"))
- return QLatin1String("Shiboken::Buffer::checkType");
+ return {QLatin1String("Shiboken::Buffer::checkType"), {}};
if (type == QLatin1String("str"))
- return QLatin1String("Shiboken::String::check");
-
- *metaType = buildAbstractMetaTypeFromString(type);
- if (*metaType && !metaType->typeEntry()->isCustom())
- return QString();
+ return {QLatin1String("Shiboken::String::check"), {}};
- return type + QLatin1String("_Check");
+ CPythonCheckFunctionResult result;
+ result.type = buildAbstractMetaTypeFromString(type);
+ if (!result.type.has_value() || result.type->typeEntry()->isCustom())
+ result.checkFunction = type + QLatin1String("_Check");
+ return result;
}
QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntry *type,
@@ -1316,14 +1311,12 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntry *type,
QString ShibokenGenerator::cpythonIsConvertibleFunction(AbstractMetaType metaType,
bool /* genericNumberType */)
{
- QString customCheck;
if (metaType.typeEntry()->isCustom()) {
- AbstractMetaType type;
- customCheck = guessCPythonCheckFunction(metaType.typeEntry()->name(), &type);
- if (type)
- metaType = type;
- if (!customCheck.isEmpty())
- return customCheck;
+ auto customCheckResult = guessCPythonCheckFunction(metaType.typeEntry()->name());
+ if (!customCheckResult.checkFunction.isEmpty())
+ return customCheckResult.checkFunction;
+ if (customCheckResult.type.has_value())
+ metaType = customCheckResult.type.value();
}
QString result = QLatin1String("Shiboken::Conversions::");
@@ -1750,9 +1743,9 @@ ShibokenGenerator::ArgumentVarReplacementList ShibokenGenerator::getArgumentRepl
AbstractMetaType type = arg.type();
QString typeReplaced = func->typeReplaced(arg.argumentIndex() + 1);
if (!typeReplaced.isEmpty()) {
- AbstractMetaType builtType = buildAbstractMetaTypeFromString(typeReplaced);
- if (builtType)
- type = builtType;
+ auto builtType = buildAbstractMetaTypeFromString(typeReplaced);
+ if (builtType.has_value())
+ type = builtType.value();
}
if (type.typeEntry()->isCustom()) {
argValue = usePyArgs
@@ -1972,9 +1965,9 @@ void ShibokenGenerator::writeCodeSnips(QTextStream &s,
AbstractMetaType type = arg.type();
QString typeReplaced = func->typeReplaced(arg.argumentIndex() + 1);
if (!typeReplaced.isEmpty()) {
- AbstractMetaType builtType = buildAbstractMetaTypeFromString(typeReplaced);
- if (builtType)
- type = builtType;
+ auto builtType = buildAbstractMetaTypeFromString(typeReplaced);
+ if (builtType.has_value())
+ type = builtType.value();
}
if (isWrapperType(type)) {
QString replacement = pair.second;
@@ -2098,12 +2091,13 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
QString conversionString = list.constFirst();
const QString &conversionTypeName = list.constLast();
QString message;
- const AbstractMetaType conversionType = buildAbstractMetaTypeFromString(conversionTypeName, &message);
- if (!conversionType) {
+ const auto conversionTypeO = buildAbstractMetaTypeFromString(conversionTypeName, &message);
+ if (!conversionTypeO.has_value()) {
qFatal("%s", qPrintable(msgCannotFindType(conversionTypeName,
m_typeSystemConvName[converterVariable],
message)));
}
+ const auto conversionType = conversionTypeO.value();
QString conversion;
QTextStream c(&conversion);
switch (converterVariable) {
@@ -2397,8 +2391,9 @@ bool ShibokenGenerator::isCopyable(const AbstractMetaClass *metaClass)
return metaClass->typeEntry()->copyable() == ComplexTypeEntry::CopyableSet;
}
-AbstractMetaType ShibokenGenerator::buildAbstractMetaTypeFromString(QString typeSignature,
- QString *errorMessage)
+std::optional<AbstractMetaType>
+ ShibokenGenerator::buildAbstractMetaTypeFromString(QString typeSignature,
+ QString *errorMessage)
{
typeSignature = typeSignature.trimmed();
if (typeSignature.startsWith(QLatin1String("::")))
@@ -2406,14 +2401,14 @@ AbstractMetaType ShibokenGenerator::buildAbstractMetaTypeFromString(QString type
auto it = m_metaTypeFromStringCache.find(typeSignature);
if (it == m_metaTypeFromStringCache.end()) {
- AbstractMetaType metaType =
+ auto metaType =
AbstractMetaBuilder::translateType(typeSignature, nullptr, {}, errorMessage);
- if (Q_UNLIKELY(!metaType)) {
+ if (Q_UNLIKELY(!metaType.has_value())) {
if (errorMessage)
errorMessage->prepend(msgCannotBuildMetaType(typeSignature));
return {};
}
- it = m_metaTypeFromStringCache.insert(typeSignature, metaType);
+ it = m_metaTypeFromStringCache.insert(typeSignature, metaType.value());
}
return it.value();
}
@@ -2688,9 +2683,9 @@ void ShibokenGenerator::collectContainerTypesFromConverterMacros(const QString &
start += offset;
if (code.at(start) != QLatin1Char('%')) {
QString typeString = code.mid(start, end - start);
- if (AbstractMetaType type =
- buildAbstractMetaTypeFromString(typeString, &errorMessage)) {
- addInstantiatedContainersAndSmartPointers(type, type.originalTypeDescription());
+ auto type = buildAbstractMetaTypeFromString(typeString, &errorMessage);
+ if (type.has_value()) {
+ addInstantiatedContainersAndSmartPointers(type.value(), type->originalTypeDescription());
} else {
qFatal("%s: Cannot translate type \"%s\": %s", __FUNCTION__,
qPrintable(typeString), qPrintable(errorMessage));
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h
index 55d8c00db..8384dbfcd 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.h
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h
@@ -327,7 +327,12 @@ protected:
* \return A custom check if \p type is a custom type, or an empty string if \p metaType
* receives an existing type object.
*/
- QString guessCPythonCheckFunction(const QString &type, AbstractMetaType *metaType);
+ struct CPythonCheckFunctionResult
+ {
+ QString checkFunction;
+ std::optional<AbstractMetaType> type;
+ };
+ CPythonCheckFunctionResult guessCPythonCheckFunction(const QString &type);
QString cpythonIsConvertibleFunction(const TypeEntry *type, bool genericNumberType = false, bool checkExact = false);
QString cpythonIsConvertibleFunction(AbstractMetaType metaType, bool genericNumberType = false);
QString cpythonIsConvertibleFunction(const AbstractMetaArgument &metaArg, bool genericNumberType = false);
@@ -408,8 +413,9 @@ protected:
* \return A new AbstractMetaType object that must be deleted by the caller,
* or a nullptr pointer in case of failure.
*/
- AbstractMetaType buildAbstractMetaTypeFromString(QString typeSignature,
- QString *errorMessage = nullptr);
+ std::optional<AbstractMetaType>
+ buildAbstractMetaTypeFromString(QString typeSignature,
+ QString *errorMessage = nullptr);
/// Creates an AbstractMetaType object from a TypeEntry.
AbstractMetaType buildAbstractMetaTypeFromTypeEntry(const TypeEntry *typeEntry);