From 3aa406eb69290686b6a1693abd33d9abb419ae20 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 16 Oct 2020 13:12:31 +0200 Subject: shiboken2: AbstractMetaType: use QSharedData[Pointer] Previously, shiboken2 kept AbstractMetaType by a raw pointer. The data were copied numerous times by AbstractMetaType::copy() when adding the inherited functions to a AbstractMetaClass or specializing templates, sometimes with a bool flag indicating ownership. To get rid of the copies and ownership issues, change the type to be based on QSharedData[Pointer]. It can then be passed around and treated like a C++ value type, with Qt sharing the data when possible behind the scenes. - Extract AbstractMetaType to a separate header/source - Remove unused AbstractMetaType::setInstantiationInCpp() - Remove unused member m_package - Rewrite the comparison of AbstractMetaType which becomes relevant for checking/detaching to do a complete comparison. It was previously unused, intended for a different implementation of view types with special cases. - Rework debug formatting - Invalid meta types are indicated by the "Invalid" usage pattern instead of null pointers Change-Id: Ic4b1feecafb4f0355f39e178c2703b104e45cf6c Reviewed-by: Cristian Maureira-Fredes --- sources/shiboken2/ApiExtractor/CMakeLists.txt | 1 + .../shiboken2/ApiExtractor/abstractmetabuilder.cpp | 291 ++++---- .../shiboken2/ApiExtractor/abstractmetabuilder.h | 16 +- .../shiboken2/ApiExtractor/abstractmetabuilder_p.h | 32 +- .../shiboken2/ApiExtractor/abstractmetalang.cpp | 473 +------------ sources/shiboken2/ApiExtractor/abstractmetalang.h | 341 +--------- .../ApiExtractor/abstractmetalang_typedefs.h | 4 +- .../shiboken2/ApiExtractor/abstractmetatype.cpp | 752 +++++++++++++++++++++ sources/shiboken2/ApiExtractor/abstractmetatype.h | 221 ++++++ sources/shiboken2/ApiExtractor/doxygenparser.cpp | 6 +- sources/shiboken2/ApiExtractor/propertyspec.cpp | 17 +- sources/shiboken2/ApiExtractor/propertyspec.h | 10 +- sources/shiboken2/ApiExtractor/qtdocparser.cpp | 28 +- .../ApiExtractor/tests/testabstractmetatype.cpp | 60 +- .../ApiExtractor/tests/testaddfunction.cpp | 14 +- .../ApiExtractor/tests/testarrayargument.cpp | 18 +- .../shiboken2/ApiExtractor/tests/testcontainer.cpp | 16 +- .../ApiExtractor/tests/testconversionoperator.cpp | 8 +- sources/shiboken2/ApiExtractor/tests/testenum.cpp | 10 +- .../ApiExtractor/tests/testimplicitconversions.cpp | 4 +- .../ApiExtractor/tests/testmodifyfunction.cpp | 2 +- .../ApiExtractor/tests/testnestedtypes.cpp | 3 +- .../ApiExtractor/tests/testnumericaltypedef.cpp | 32 +- .../ApiExtractor/tests/testreferencetopointer.cpp | 2 +- .../ApiExtractor/tests/testremoveimplconv.cpp | 2 +- .../shiboken2/ApiExtractor/tests/testtemplates.cpp | 58 +- sources/shiboken2/generator/generator.cpp | 201 +++--- sources/shiboken2/generator/generator.h | 42 +- .../shiboken2/generator/qtdoc/qtdocgenerator.cpp | 19 +- sources/shiboken2/generator/qtdoc/qtdocgenerator.h | 2 +- .../shiboken2/generator/shiboken2/cppgenerator.cpp | 418 ++++++------ .../shiboken2/generator/shiboken2/cppgenerator.h | 32 +- .../generator/shiboken2/headergenerator.cpp | 57 +- .../generator/shiboken2/headergenerator.h | 2 +- .../shiboken2/generator/shiboken2/overloaddata.cpp | 64 +- .../shiboken2/generator/shiboken2/overloaddata.h | 6 +- .../generator/shiboken2/shibokengenerator.cpp | 273 ++++---- .../generator/shiboken2/shibokengenerator.h | 62 +- 38 files changed, 1917 insertions(+), 1682 deletions(-) create mode 100644 sources/shiboken2/ApiExtractor/abstractmetatype.cpp create mode 100644 sources/shiboken2/ApiExtractor/abstractmetatype.h (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/ApiExtractor/CMakeLists.txt b/sources/shiboken2/ApiExtractor/CMakeLists.txt index cbe3310a4..043f3830d 100644 --- a/sources/shiboken2/ApiExtractor/CMakeLists.txt +++ b/sources/shiboken2/ApiExtractor/CMakeLists.txt @@ -8,6 +8,7 @@ set(CMAKE_AUTOMOC ON) set(apiextractor_SRC apiextractor.cpp abstractmetabuilder.cpp +abstractmetatype.cpp abstractmetalang.cpp fileout.cpp graph.cpp diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 75fd6af5b..1f126ba57 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -225,12 +225,11 @@ 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(); + AbstractMetaType type = translateType(argument->type(), currentClass); + if (type && type.typeEntry() && type.typeEntry()->isComplex()) { + const TypeEntry *entry = type.typeEntry(); returned = AbstractMetaClass::findClass(m_metaClasses, entry); } - delete type; return returned; } @@ -294,8 +293,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; + AbstractMetaType type = translateType(item->type(), currentClass); + const TypeEntry *retType = type ? type.typeEntry() : nullptr; AbstractMetaClass *otherArgClass = argumentToClass(arguments.at(1), currentClass); if (otherArgClass && retType && (retType->isValue() || retType->isObject()) @@ -304,7 +303,6 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte baseoperandClass = AbstractMetaClass::findClass(m_metaClasses, retType); firstArgumentIsSelf = false; } - delete type; } if (baseoperandClass) { @@ -314,7 +312,7 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte AbstractMetaArgumentList arguments = metaFunction->arguments(); if (firstArgumentIsSelf || unaryOperator) { AbstractMetaArgument *first = arguments.takeFirst(); - if (!unaryOperator && first->type()->indirections()) + if (!unaryOperator && first->type().indirections()) metaFunction->setPointerOperator(true); delete first; metaFunction->setArguments(arguments); @@ -325,7 +323,7 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte // All operator overloads that operate over a class are already // being added as member functions of that class by the API Extractor. AbstractMetaArgument *last = arguments.takeLast(); - if (last->type()->indirections()) + if (last->type().indirections()) metaFunction->setPointerOperator(true); delete last; @@ -1005,11 +1003,11 @@ void AbstractMetaBuilderPrivate::traverseTypesystemTypedefs() // mapping the instantiations to the typedef entry. // Synthesize a AbstractMetaType which would be found by an // instantiation. - auto sourceType = new AbstractMetaType; - sourceType->setTypeEntry(metaClass->templateBaseClass()->typeEntry()); - sourceType->setInstantiations(metaClass->templateBaseClassInstantiations()); - sourceType->decideUsagePattern(); - m_typeSystemTypeDefs.append({AbstractMetaTypeCPtr(sourceType), metaClass}); + AbstractMetaType sourceType; + sourceType.setTypeEntry(metaClass->templateBaseClass()->typeEntry()); + sourceType.setInstantiations(metaClass->templateBaseClassInstantiations()); + sourceType.decideUsagePattern(); + m_typeSystemTypeDefs.append({sourceType, metaClass}); } } } @@ -1200,7 +1198,7 @@ AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(const VariableModel metaField->setEnclosingClass(cls); TypeInfo fieldType = field->type(); - AbstractMetaType *metaType = translateType(fieldType, cls); + AbstractMetaType metaType = translateType(fieldType, cls); if (!metaType) { const QString type = TypeInfo::resolveType(fieldType, currentScope()).qualifiedName().join(colonColon()); @@ -1278,9 +1276,9 @@ void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaF if (!retType) return; - auto metaType = new AbstractMetaType(retType); - metaType->decideUsagePattern(); - metaFunction->replaceType(metaType); + AbstractMetaType metaType(retType); + metaType.decideUsagePattern(); + metaFunction->setType(metaType); } AbstractMetaFunctionList AbstractMetaBuilderPrivate::classFunctionList(const ScopeModelItem &scopeItem, @@ -1320,7 +1318,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem, QPropertySpec *read = nullptr; if (!metaFunction->isSignal() && (read = metaClass->propertySpecForRead(metaFunction->name()))) { // Property reader must be in the form " name()" - if (read->typeEntry() == metaFunction->type()->typeEntry() + if (read->typeEntry() == metaFunction->type().typeEntry() && metaFunction->arguments().isEmpty()) { *metaFunction += AbstractMetaAttributes::PropertyReader; metaFunction->setPropertySpec(read); @@ -1330,7 +1328,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem, // Make sure the function was created with all arguments; some argument can be // missing during the parsing because of errors in the typesystem. if (metaFunction->isVoid() && metaFunction->arguments().size() == 1 - && (write->typeEntry() == metaFunction->arguments().at(0)->type()->typeEntry())) { + && (write->typeEntry() == metaFunction->arguments().at(0)->type().typeEntry())) { *metaFunction += AbstractMetaAttributes::PropertyWriter; metaFunction->setPropertySpec(write); } @@ -1536,7 +1534,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu { QString errorMessage; - AbstractMetaType *returnType = translateType(addedFunc->returnType(), &errorMessage); + AbstractMetaType returnType = translateType(addedFunc->returnType(), &errorMessage); if (!returnType) { qCWarning(lcShiboken, "%s", qPrintable(msgAddedFunctionInvalidReturnType(addedFunc->name(), @@ -1554,7 +1552,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu for (int i = 0; i < args.count(); ++i) { const AddedFunction::TypeInfo& typeInfo = args.at(i).typeInfo; auto *metaArg = new AbstractMetaArgument; - AbstractMetaType *type = translateType(typeInfo, &errorMessage); + AbstractMetaType type = translateType(typeInfo, &errorMessage); if (Q_UNLIKELY(!type)) { qCWarning(lcShiboken, "%s", qPrintable(msgAddedFunctionInvalidArgType(addedFunc->name(), @@ -1563,7 +1561,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu delete metaFunction; return nullptr; } - type->decideUsagePattern(); + type.decideUsagePattern(); if (!args.at(i).name.isEmpty()) metaArg->setName(args.at(i).name); metaArg->setType(type); @@ -1579,7 +1577,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu qCWarning(lcShiboken) << "An operator overload need to have 0, 1 or 2 arguments if it's reverse."; } else if (metaArguments.size() == 2) { // Check if it's a reverse operator - if (metaArguments[1]->type()->typeEntry() == metaClass->typeEntry()) { + if (metaArguments[1]->type().typeEntry() == metaClass->typeEntry()) { metaFunction->setReverseOperator(true); // we need to call these two function to cache the old signature (with two args) // we do this buggy behaviour to comply with the original apiextractor buggy behaviour. @@ -1615,7 +1613,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu if (metaFunction->name() == metaClass->name()) { metaFunction->setFunctionType(AbstractMetaFunction::ConstructorFunction); if (fargs.size() == 1) { - const TypeEntry *te = fargs.constFirst()->type()->typeEntry(); + const TypeEntry *te = fargs.constFirst()->type().typeEntry(); if (te->isCustom()) metaFunction->setExplicit(true); if (te->name() == metaFunction->name()) @@ -1718,10 +1716,12 @@ static bool applyArrayArgumentModifications(const FunctionModificationList &func QLatin1String("Index out of range.")); return false; } - if (!func->arguments().at(i)->type()->applyArrayModification(errorMessage)) { + auto t = func->arguments().at(i)->type(); + if (!t.applyArrayModification(errorMessage)) { *errorMessage = msgCannotSetArrayUsage(func->minimalSignature(), i, *errorMessage); return false; } + func->arguments()[i]->setType(t); } } } @@ -1839,7 +1839,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio return nullptr; } - AbstractMetaType *type = translateType(returnType, currentClass, {}, &errorMessage); + AbstractMetaType type = translateType(returnType, currentClass, {}, &errorMessage); if (!type) { const QString reason = msgUnmatchedReturnType(functionItem, errorMessage); qCWarning(lcShiboken, "%s", @@ -1874,7 +1874,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio return nullptr; } - AbstractMetaType *metaType = translateType(arg->type(), currentClass, {}, &errorMessage); + AbstractMetaType metaType = translateType(arg->type(), currentClass, {}, &errorMessage); if (!metaType) { // If an invalid argument has a default value, simply remove it // unless the function is virtual (since the override in the @@ -1886,7 +1886,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio } break; } - Q_ASSERT(metaType == nullptr); + Q_ASSERT(!metaType); const QString reason = msgUnmatchedParameterType(arg, i, errorMessage); qCWarning(lcShiboken, "%s", qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason))); @@ -1899,13 +1899,13 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio // 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(); - if (viewOnTypeEntry != nullptr && metaType->indirections() == 0 - && metaType->arrayElementType() == nullptr - && !metaType->hasInstantiations()) { - auto viewOn = new AbstractMetaType(*metaType); - viewOn->setTypeEntry(viewOnTypeEntry); - metaType->setViewOn(viewOn); + auto viewOnTypeEntry = metaType.typeEntry()->viewOn(); + if (viewOnTypeEntry != nullptr && metaType.indirections() == 0 + && metaType.arrayElementType() == nullptr + && !metaType.hasInstantiations()) { + auto viewOn = metaType; + viewOn.setTypeEntry(viewOnTypeEntry); + metaType.setViewOn(viewOn); } auto *metaArgument = new AbstractMetaArgument; @@ -1964,15 +1964,15 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio // Determine class special functions if (currentClass && metaFunction->arguments().size() == 1) { - const AbstractMetaType *argType = metaFunction->arguments().constFirst()->type(); - if (argType->typeEntry() == currentClass->typeEntry() && argType->indirections() == 0) { + const AbstractMetaType &argType = metaFunction->arguments().constFirst()->type(); + if (argType.typeEntry() == currentClass->typeEntry() && argType.indirections() == 0) { if (metaFunction->name() == QLatin1String("operator=")) { - switch (argType->referenceType()) { + switch (argType.referenceType()) { case NoReference: metaFunction->setFunctionType(AbstractMetaFunction::AssignmentOperatorFunction); break; case LValueReference: - if (argType->isConstant()) + if (argType.isConstant()) metaFunction->setFunctionType(AbstractMetaFunction::AssignmentOperatorFunction); break; case RValueReference: @@ -1985,7 +1985,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio return metaFunction; } -AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction::TypeInfo &typeInfo, +AbstractMetaType AbstractMetaBuilderPrivate::translateType(const AddedFunction::TypeInfo &typeInfo, QString *errorMessage) { Q_ASSERT(!typeInfo.name.isEmpty()); @@ -2007,7 +2007,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: QStringList parsedType = parseTemplateType(typeInfo.name); if (parsedType.isEmpty()) { *errorMessage = QStringLiteral("Template type parsing failed for '%1'").arg(typeInfo.name); - return nullptr; + return {}; } const QString name = parsedType.takeFirst(); templateArgs = parsedType; @@ -2040,25 +2040,25 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: for (const QString& candidate : qAsConst(candidates)) str << " " << candidate << '\n'; } - return nullptr; + return {}; } // These are only implicit and should not appear in code... - auto *metaType = new AbstractMetaType(type); - metaType->setIndirections(typeInfo.indirections); + AbstractMetaType metaType(type); + metaType.setIndirections(typeInfo.indirections); if (typeInfo.isReference) - metaType->setReferenceType(LValueReference); - metaType->setConstant(typeInfo.isConstant); + metaType.setReferenceType(LValueReference); + metaType.setConstant(typeInfo.isConstant); if (isTemplate) { for (const QString& templateArg : qAsConst(templateArgs)) { - AbstractMetaType *metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg), errorMessage); + AbstractMetaType metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg), errorMessage); if (!metaArgType) - return nullptr; - metaType->addInstantiation(metaArgType); + return {}; + metaType.addInstantiation(metaArgType); } - metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern); + metaType.setTypeUsagePattern(AbstractMetaType::ContainerPattern); } else { - metaType->decideUsagePattern(); + metaType.decideUsagePattern(); } return metaType; @@ -2124,10 +2124,10 @@ TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualified // Reverse lookup of AbstractMetaType representing a template specialization // found during traversing function arguments to its type system typedef'ed // class. -const AbstractMetaClass *AbstractMetaBuilderPrivate::resolveTypeSystemTypeDef(const AbstractMetaType *t) const +const AbstractMetaClass *AbstractMetaBuilderPrivate::resolveTypeSystemTypeDef(const AbstractMetaType &t) const { - if (t->hasInstantiations()) { - auto pred = [t](const TypeClassEntry &e) { return e.type->compare(*t); }; + if (t.hasInstantiations()) { + auto pred = [t](const TypeClassEntry &e) { return e.type.equals(t); }; auto it = std::find_if(m_typeSystemTypeDefs.cbegin(), m_typeSystemTypeDefs.cend(), pred); if (it != m_typeSystemTypeDefs.cend()) return it->klass; @@ -2135,7 +2135,7 @@ const AbstractMetaClass *AbstractMetaBuilderPrivate::resolveTypeSystemTypeDef(co return nullptr; } -AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei, +AbstractMetaType AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei, AbstractMetaClass *currentClass, TranslateTypeFlags flags, QString *errorMessage) @@ -2149,7 +2149,7 @@ static bool isNumber(const QString &s) [](QChar c) { return c.isDigit(); }); } -AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei, +AbstractMetaType AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei, AbstractMetaClass *currentClass, AbstractMetaBuilderPrivate *d, TranslateTypeFlags flags, @@ -2162,7 +2162,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo // type system const bool resolveType = !flags.testFlag(AbstractMetaBuilder::DontResolveType); if (resolveType) { - AbstractMetaType *resolved = + AbstractMetaType resolved = translateTypeStatic(_typei, currentClass, d, flags | AbstractMetaBuilder::DontResolveType, errorMessageIn); @@ -2189,7 +2189,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo if (typeInfo.isFunctionPointer()) { if (errorMessageIn) *errorMessageIn = msgUnableToTranslateType(_typei, QLatin1String("Unsupported function pointer.")); - return nullptr; + return {}; } QString errorMessage; @@ -2225,18 +2225,18 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo newInfo.setReferenceType(typeInfo.referenceType()); newInfo.setVolatile(typeInfo.isVolatile()); - AbstractMetaType *elementType = translateTypeStatic(newInfo, currentClass, d, flags, &errorMessage); + AbstractMetaType elementType = translateTypeStatic(newInfo, currentClass, d, flags, &errorMessage); if (!elementType) { if (errorMessageIn) { errorMessage.prepend(QLatin1String("Unable to translate array element: ")); *errorMessageIn = msgUnableToTranslateType(_typei, errorMessage); } - return nullptr; + return {}; } for (int i = typeInfo.arrayElements().size() - 1; i >= 0; --i) { - auto *arrayType = new AbstractMetaType; - arrayType->setArrayElementType(elementType); + AbstractMetaType arrayType; + arrayType.setArrayElementType(elementType); const QString &arrayElement = typeInfo.arrayElements().at(i); if (!arrayElement.isEmpty()) { bool _ok; @@ -2244,12 +2244,12 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo ? d->findOutValueFromString(arrayElement, _ok) : arrayElement.toLongLong(&_ok, 0); if (_ok) - arrayType->setArrayElementCount(int(elems)); + arrayType.setArrayElementCount(int(elems)); } - auto elementTypeEntry = elementType->typeEntry(); - arrayType->setTypeEntry(new ArrayTypeEntry(elementTypeEntry, elementTypeEntry->version(), - elementTypeEntry->parent())); - arrayType->decideUsagePattern(); + auto elementTypeEntry = elementType.typeEntry(); + arrayType.setTypeEntry(new ArrayTypeEntry(elementTypeEntry, elementTypeEntry->version(), + elementTypeEntry->parent())); + arrayType.decideUsagePattern(); elementType = arrayType; } @@ -2264,7 +2264,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo *errorMessageIn = errorMessage; else qCWarning(lcShiboken,"%s", qPrintable(errorMessage)); - return nullptr; + return {}; } QString qualifiedName = qualifierList.join(colonColon()); @@ -2282,23 +2282,23 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo *errorMessageIn = msgUnableToTranslateType(_typei, msgCannotFindTypeEntry(qualifiedName)); } - return nullptr; + return {}; } const TypeEntry *type = types.constFirst(); const TypeEntry::Type typeEntryType = type->type(); - QScopedPointer metaType(new AbstractMetaType); - metaType->setIndirectionsV(typeInfo.indirectionsV()); - metaType->setReferenceType(typeInfo.referenceType()); - metaType->setConstant(typeInfo.isConstant()); - metaType->setVolatile(typeInfo.isVolatile()); - metaType->setOriginalTypeDescription(_typei.toString()); + AbstractMetaType metaType; + metaType.setIndirectionsV(typeInfo.indirectionsV()); + metaType.setReferenceType(typeInfo.referenceType()); + metaType.setConstant(typeInfo.isConstant()); + metaType.setVolatile(typeInfo.isVolatile()); + metaType.setOriginalTypeDescription(_typei.toString()); 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); + AbstractMetaType 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) { @@ -2311,10 +2311,10 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo if (!targType) { if (errorMessageIn) *errorMessageIn = msgCannotTranslateTemplateArgument(t, ti, errorMessage); - return nullptr; + return {}; } - metaType->addInstantiation(targType, true); + metaType.addInstantiation(targType); } if (types.size() > 1) { @@ -2324,7 +2324,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo if (!sameType) { if (errorMessageIn) *errorMessageIn = msgAmbiguousVaryingTypesFound(qualifiedName, types); - return nullptr; + return {}; } // Ambiguous primitive/smart pointer types are possible (when // including type systems). @@ -2332,18 +2332,18 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo && typeEntryType != TypeEntry::SmartPointerType) { if (errorMessageIn) *errorMessageIn = msgAmbiguousTypesFound(qualifiedName, types); - return nullptr; + return {}; } } if (typeEntryType == TypeEntry::SmartPointerType) { // Find a matching instantiation - if (metaType->instantiations().size() != 1) { + if (metaType.instantiations().size() != 1) { if (errorMessageIn) *errorMessageIn = msgInvalidSmartPointerType(_typei); - return nullptr; + return {}; } - auto instantiationType = metaType->instantiations().constFirst()->typeEntry(); + auto instantiationType = metaType.instantiations().constFirst().typeEntry(); if (instantiationType->type() == TypeEntry::TemplateArgumentType) { // Member functions of the template itself, SharedPtr(const SharedPtr &) type = instantiationType; @@ -2356,47 +2356,47 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo if (it == types.cend()) { if (errorMessageIn) *errorMessageIn = msgCannotFindSmartPointerInstantion(_typei); - return nullptr; + return {}; } type =*it; } } - metaType->setTypeEntry(type); + metaType.setTypeEntry(type); // The usage pattern *must* be decided *after* the possible template // instantiations have been determined, or else the absence of // such instantiations will break the caching scheme of // AbstractMetaType::cppSignature(). - metaType->decideUsagePattern(); + metaType.decideUsagePattern(); if (d) { // Reverse lookup of type system typedefs. Replace by class. - if (auto klass = d->resolveTypeSystemTypeDef(metaType.data())) { - metaType.reset(new AbstractMetaType); - metaType->setTypeEntry(klass->typeEntry()); - metaType->decideUsagePattern(); + if (auto klass = d->resolveTypeSystemTypeDef(metaType)) { + metaType = AbstractMetaType{}; + metaType.setTypeEntry(klass->typeEntry()); + metaType.decideUsagePattern(); } } - Q_ASSERT(metaType->typeUsagePattern() != AbstractMetaType::InvalidPattern); - return metaType.take(); + Q_ASSERT(metaType.typeUsagePattern() != AbstractMetaType::InvalidPattern); + return metaType; } -AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei, - AbstractMetaClass *currentClass, - TranslateTypeFlags flags, - QString *errorMessage) +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) +AbstractMetaType AbstractMetaBuilder::translateType(const QString &t, + AbstractMetaClass *currentClass, + TranslateTypeFlags flags, + QString *errorMessageIn) { QString errorMessage; TypeInfo typeInfo = TypeParser::parse(t, &errorMessage); @@ -2406,7 +2406,7 @@ AbstractMetaType *AbstractMetaBuilder::translateType(const QString &t, *errorMessageIn = errorMessage; else qCWarning(lcShiboken, "%s", qPrintable(errorMessage)); - return nullptr; + return {}; } return translateType(typeInfo, currentClass, flags, errorMessageIn); } @@ -2449,7 +2449,7 @@ qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringV } QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &item, - AbstractMetaType *type, + const AbstractMetaType &type, AbstractMetaFunction *fnc, AbstractMetaClass *implementingClass, int /* argumentIndex */) @@ -2459,8 +2459,8 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite return expr; if (type) { - if (type->isPrimitive()) { - if (type->name() == QLatin1String("boolean")) { + if (type.isPrimitive()) { + if (type.name() == QLatin1String("boolean")) { if (expr != QLatin1String("false") && expr != QLatin1String("true")) { bool ok = false; int number = expr.toInt(&ok); @@ -2474,7 +2474,7 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite // translation untill all namespaces are completly // processed. This is done in figureOutEnumValues() } - } else if (type->isFlags() || type->isEnum()) { + } else if (type.isFlags() || type.isEnum()) { bool isNumber; expr.toInt(&isNumber); if (!isNumber && expr.indexOf(colonColon()) < 0) { @@ -2482,14 +2482,14 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite // from other contexts beside its owner class hierarchy static const QRegularExpression typeRegEx(QStringLiteral("[^<]*[<]([^:]*::).*")); Q_ASSERT(typeRegEx.isValid()); - const QRegularExpressionMatch match = typeRegEx.match(type->minimalSignature()); + const QRegularExpressionMatch match = typeRegEx.match(type.minimalSignature()); if (match.hasMatch()) expr.prepend(match.captured(1)); } - } else if (type->isContainer() && expr.contains(QLatin1Char('<'))) { + } else if (type.isContainer() && expr.contains(QLatin1Char('<'))) { static const QRegularExpression typeRegEx(QStringLiteral("[^<]*<(.*)>")); Q_ASSERT(typeRegEx.isValid()); - const QRegularExpressionMatch typeMatch = typeRegEx.match(type->minimalSignature()); + const QRegularExpressionMatch typeMatch = typeRegEx.match(type.minimalSignature()); static const QRegularExpression defaultRegEx(QLatin1String("([^<]*<).*(>[^>]*)")); Q_ASSERT(defaultRegEx.isValid()); const QRegularExpressionMatch defaultMatch = defaultRegEx.match(expr); @@ -2511,7 +2511,7 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &ite // use of namespaces/scopes from the type string. static const QRegularExpression typeRegEx(QLatin1String("^(?:const[\\s]+|)([\\w:]*::|)([A-Za-z_]\\w*)\\s*[&\\*]?$")); Q_ASSERT(typeRegEx.isValid()); - const QRegularExpressionMatch typeMatch = typeRegEx.match(type->minimalSignature()); + const QRegularExpressionMatch typeMatch = typeRegEx.match(type.minimalSignature()); QString typeNamespace = typeMatch.hasMatch() ? typeMatch.captured(1) : QString(); QString typeCtorName = typeMatch.hasMatch() ? typeMatch.captured(2) : QString(); @@ -2621,48 +2621,47 @@ bool AbstractMetaBuilderPrivate::ancestorHasPrivateCopyConstructor(const Abstrac return false; } -AbstractMetaType * - AbstractMetaBuilderPrivate::inheritTemplateType(const AbstractMetaTypeList &templateTypes, - const AbstractMetaType *metaType) +AbstractMetaType AbstractMetaBuilderPrivate::inheritTemplateType(const AbstractMetaTypeList &templateTypes, + const AbstractMetaType &metaType) { Q_ASSERT(metaType); - QScopedPointer returned(metaType->copy()); + auto returned = metaType; - if (!metaType->typeEntry()->isTemplateArgument() && !metaType->hasInstantiations()) - return returned.take(); + if (!metaType.typeEntry()->isTemplateArgument() && !metaType.hasInstantiations()) + return returned; - returned->setOriginalTemplateType(metaType); + returned.setOriginalTemplateType(metaType); - if (returned->typeEntry()->isTemplateArgument()) { - const auto *tae = static_cast(returned->typeEntry()); + if (returned.typeEntry()->isTemplateArgument()) { + const auto *tae = static_cast(returned.typeEntry()); // 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()) - return nullptr; + const AbstractMetaType &templateType = templateTypes.value(tae->ordinal()); + if (!templateType || templateType.typeEntry()->isVoid()) + return {}; - AbstractMetaType* t = returned->copy(); - t->setTypeEntry(templateType->typeEntry()); - t->setIndirections(templateType->indirections() + t->indirections() ? 1 : 0); - t->decideUsagePattern(); + AbstractMetaType t = returned; + t.setTypeEntry(templateType.typeEntry()); + t.setIndirections(templateType.indirections() + t.indirections() ? 1 : 0); + t.decideUsagePattern(); return inheritTemplateType(templateTypes, t); } - if (returned->hasInstantiations()) { - AbstractMetaTypeList instantiations = returned->instantiations(); + 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)) - return nullptr; + return {}; } - returned->setInstantiations(instantiations, true); + returned.setInstantiations(instantiations); } - return returned.take(); + return returned; } bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, @@ -2702,11 +2701,11 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, } if (t) { - auto *temporaryType = new AbstractMetaType(t); - temporaryType->setConstant(i.isConstant()); - temporaryType->setReferenceType(i.referenceType()); - temporaryType->setIndirectionsV(i.indirectionsV()); - temporaryType->decideUsagePattern(); + AbstractMetaType temporaryType(t); + temporaryType.setConstant(i.isConstant()); + temporaryType.setReferenceType(i.referenceType()); + temporaryType.setIndirectionsV(i.indirectionsV()); + temporaryType.decideUsagePattern(); templateTypes << temporaryType; } else { qCWarning(lcShiboken).noquote().nospace() @@ -2751,19 +2750,19 @@ void AbstractMetaBuilderPrivate::inheritTemplateFunctions(AbstractMetaClass *sub f->setArguments(AbstractMetaArgumentList()); if (!function->isVoid()) { - AbstractMetaType *returnType = inheritTemplateType(templateTypes, function->type()); + AbstractMetaType returnType = inheritTemplateType(templateTypes, function->type()); if (!returnType) continue; - f->replaceType(returnType); + f->setType(returnType); } const AbstractMetaArgumentList &arguments = function->arguments(); for (AbstractMetaArgument *argument : arguments) { - AbstractMetaType *argType = inheritTemplateType(templateTypes, argument->type()); + AbstractMetaType argType = inheritTemplateType(templateTypes, argument->type()); if (!argType) break; AbstractMetaArgument *arg = argument->copy(); - arg->replaceType(argType); + arg->setType(argType); f->addArgument(arg); } @@ -2833,10 +2832,10 @@ void AbstractMetaBuilderPrivate::inheritTemplateFunctions(AbstractMetaClass *sub QScopedPointer f(field->copy()); f->setEnclosingClass(subclass); - AbstractMetaType *fieldType = inheritTemplateType(templateTypes, field->type()); + AbstractMetaType fieldType = inheritTemplateType(templateTypes, field->type()); if (!fieldType) continue; - f->replaceType(fieldType); + f->setType(fieldType); subclass->addField(f.take()); } } @@ -2927,7 +2926,7 @@ void AbstractMetaBuilderPrivate::setupExternalConversion(AbstractMetaClass *cls) for (AbstractMetaFunction *func : convOps) { if (func->isModifiedRemoved()) continue; - AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, func->type()->typeEntry()); + AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, func->type().typeEntry()); if (!metaClass) continue; metaClass->addExternalConversionOperator(func); @@ -3084,8 +3083,8 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const // Check methods with default args: If a class is instantiated by value, // ("QString s = QString()"), add a dependency. if (!arg->originalDefaultValueExpression().isEmpty() - && arg->type()->isValue()) { - addClassDependency(arg->type()->typeEntry(), clazz, classIndex, + && arg->type().isValue()) { + addClassDependency(arg->type().typeEntry(), clazz, classIndex, map, &graph); } } @@ -3093,7 +3092,7 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const // Member fields need to be initialized const AbstractMetaFieldList &fields = clazz->fields(); for (AbstractMetaField *field : fields) { - addClassDependency(field->type()->typeEntry(), clazz, classIndex, + addClassDependency(field->type().typeEntry(), clazz, classIndex, map, &graph); } } diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h index d2dc080a2..09c49b4fb 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h @@ -97,14 +97,14 @@ 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 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); #ifndef QT_NO_DEBUG_STREAM diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h index 846895089..1854b8b56 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h @@ -46,7 +46,7 @@ class AbstractMetaBuilderPrivate public: struct TypeClassEntry { - AbstractMetaTypeCPtr type; + AbstractMetaType type; const AbstractMetaClass *klass; }; @@ -139,20 +139,20 @@ public: void setupFunctionDefaults(AbstractMetaFunction *metaFunction, AbstractMetaClass *metaClass); - QString fixDefaultValue(const ArgumentModelItem &item, AbstractMetaType *type, + QString fixDefaultValue(const ArgumentModelItem &item, const AbstractMetaType &type, AbstractMetaFunction *fnc, AbstractMetaClass *, int argumentIndex); - AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo, - QString *errorMessage); - 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); + AbstractMetaType translateType(const AddedFunction::TypeInfo &typeInfo, + QString *errorMessage); + 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); static TypeEntries findTypeEntries(const QString &qualifiedName, const QString &name, AbstractMetaClass *currentClass = nullptr, AbstractMetaBuilderPrivate *d = nullptr); @@ -169,8 +169,8 @@ public: const AbstractMetaClass *templateClass, const TypeInfo &info); void inheritTemplateFunctions(AbstractMetaClass *subclass); - AbstractMetaType *inheritTemplateType(const AbstractMetaTypeList &templateTypes, - const AbstractMetaType *metaType); + AbstractMetaType inheritTemplateType(const AbstractMetaTypeList &templateTypes, + const AbstractMetaType &metaType); bool isQObject(const FileModelItem &dom, const QString &qualifiedName); bool isEnum(const FileModelItem &dom, const QStringList &qualifiedName); @@ -181,7 +181,7 @@ public: void fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods); void fillAddedFunctions(AbstractMetaClass *metaClass); - const AbstractMetaClass *resolveTypeSystemTypeDef(const AbstractMetaType *t) const; + const AbstractMetaClass *resolveTypeSystemTypeDef(const AbstractMetaType &t) const; AbstractMetaBuilder *q; AbstractMetaClassList m_metaClasses; diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index c0b6fa481..4ffe24cb3 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -41,6 +41,7 @@ #endif #include +#include #include #include @@ -137,16 +138,13 @@ void Documentation::setFormat(Documentation::Format f) AbstractMetaVariable::AbstractMetaVariable() = default; -AbstractMetaVariable::~AbstractMetaVariable() -{ - delete m_type; -} +AbstractMetaVariable::~AbstractMetaVariable() = default; void AbstractMetaVariable::assignMetaVariable(const AbstractMetaVariable &other) { m_originalName = other.m_originalName; m_name = other.m_name; - m_type = other.m_type->copy(); + m_type = other.m_type; m_hasName = other.m_hasName; m_doc = other.m_doc; } @@ -159,7 +157,7 @@ QDebug operator<<(QDebug d, const AbstractMetaVariable *av) d.nospace(); d << "AbstractMetaVariable("; if (av) { - d << av->type()->name() << ' ' << av->name(); + d << av->type().name() << ' ' << av->name(); } else { d << '0'; } @@ -182,301 +180,6 @@ void AbstractMetaAttributes::assignMetaAttributes(const AbstractMetaAttributes & m_doc = other.m_doc; } -/******************************************************************************* - * AbstractMetaType - */ - -AbstractMetaType::AbstractMetaType(const TypeEntry *t) : - m_typeEntry(t), - m_constant(false), - m_volatile(false), - m_cppInstantiation(true), - m_reserved(0) -{ -} - -AbstractMetaType::AbstractMetaType(const AbstractMetaType &rhs) = default; - -AbstractMetaType::~AbstractMetaType() -{ - qDeleteAll(m_children); - m_instantiations.clear(); - delete m_viewOn; -} - -QString AbstractMetaType::package() const -{ - return m_typeEntry->targetLangPackage(); -} - -QString AbstractMetaType::name() const -{ - return m_typeEntry->targetLangEntryName(); -} - -QString AbstractMetaType::fullName() const -{ - return m_typeEntry->qualifiedTargetLangName(); -} - -AbstractMetaType *AbstractMetaType::copy() const -{ - auto *cpy = new AbstractMetaType(typeEntry()); - - cpy->setTypeUsagePattern(typeUsagePattern()); - cpy->setConstant(isConstant()); - cpy->setVolatile(isVolatile()); - cpy->setReferenceType(referenceType()); - cpy->setIndirectionsV(indirectionsV()); - cpy->setInstantiations(instantiations()); - cpy->setArrayElementCount(arrayElementCount()); - cpy->setOriginalTypeDescription(originalTypeDescription()); - cpy->setOriginalTemplateType(originalTemplateType() ? originalTemplateType()->copy() : nullptr); - - cpy->setArrayElementType(arrayElementType() ? arrayElementType()->copy() : nullptr); - - return cpy; -} - -// For applying the function argument modification: change into a type -// where "int *" becomes "int[]". -bool AbstractMetaType::applyArrayModification(QString *errorMessage) -{ - if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern) { - *errorMessage = QLatin1String(" modification already applied."); - return false; - } - if (m_arrayElementType != nullptr) { - QTextStream(errorMessage) << "The type \"" << cppSignature() - << "\" is an array of " << m_arrayElementType->name() << '.'; - return false; - } - if (m_indirections.isEmpty()) { - QTextStream(errorMessage) << "The type \"" << cppSignature() - << "\" does not have indirections."; - return false; - } - // Element type to be used for ArrayHandle<>, strip constness. - auto elementType = copy(); - elementType->m_indirections.pop_front(); - elementType->setConstant(false); - elementType->setVolatile(false); - elementType->decideUsagePattern(); - m_arrayElementType = elementType; - setTypeUsagePattern(AbstractMetaType::NativePointerAsArrayPattern); - return true; -} - -AbstractMetaTypeCList AbstractMetaType::nestedArrayTypes() const -{ - AbstractMetaTypeCList result; - switch (m_pattern) { - case ArrayPattern: - for (const AbstractMetaType *t = this; t->typeUsagePattern() == ArrayPattern; ) { - const AbstractMetaType *elt = t->arrayElementType(); - result.append(elt); - t = elt; - } - break; - case NativePointerAsArrayPattern: - result.append(m_arrayElementType); - break; - default: - break; - } - return result; -} - -bool AbstractMetaType::passByConstRef() const -{ - return isConstant() && m_referenceType == LValueReference && indirections() == 0; -} - -bool AbstractMetaType::passByValue() const -{ - return m_referenceType == NoReference && indirections() == 0; -} - -QString AbstractMetaType::cppSignature() const -{ - if (m_cachedCppSignature.isEmpty()) - m_cachedCppSignature = formatSignature(false); - return m_cachedCppSignature; -} - -QString AbstractMetaType::pythonSignature() const -{ - // PYSIDE-921: Handle container returntypes correctly. - // This is now a clean reimplementation. - if (m_cachedPythonSignature.isEmpty()) - m_cachedPythonSignature = formatPythonSignature(); - return m_cachedPythonSignature; -} - -AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() const -{ - if (m_typeEntry->isTemplateArgument()) - return TemplateArgument; - - if (m_typeEntry->type() == TypeEntry::ConstantValueType) - return NonTypeTemplateArgument; - - if (m_typeEntry->isPrimitive() && (actualIndirections() == 0 || passByConstRef())) - return PrimitivePattern; - - if (m_typeEntry->isVoid()) { - return m_arrayElementCount < 0 && m_referenceType == NoReference - && m_indirections.isEmpty() && m_constant == 0 && m_volatile == 0 - ? VoidPattern : NativePointerPattern; - } - - if (m_typeEntry->isVarargs()) - return VarargsPattern; - - if (m_typeEntry->isEnum() && (actualIndirections() == 0 || passByConstRef())) - return EnumPattern; - - if (m_typeEntry->isObject()) { - if (indirections() == 0 && m_referenceType == NoReference) - return ValuePattern; - return ObjectPattern; - } - - if (m_typeEntry->isContainer() && indirections() == 0) - return ContainerPattern; - - if (m_typeEntry->isSmartPointer() && indirections() == 0) - return SmartPointerPattern; - - if (m_typeEntry->isFlags() && (actualIndirections() == 0 || passByConstRef())) - return FlagsPattern; - - if (m_typeEntry->isArray()) - return ArrayPattern; - - if (m_typeEntry->isValue()) - return indirections() == 1 ? ValuePointerPattern : ValuePattern; - - return NativePointerPattern; -} - -void AbstractMetaType::decideUsagePattern() -{ - TypeUsagePattern pattern = determineUsagePattern(); - if (m_typeEntry->isObject() && indirections() == 1 - && m_referenceType == LValueReference && isConstant()) { - // const-references to pointers can be passed as pointers - setReferenceType(NoReference); - setConstant(false); - pattern = ObjectPattern; - } - setTypeUsagePattern(pattern); -} - -bool AbstractMetaType::hasTemplateChildren() const -{ - QStack children; - children << m_children; - - // Recursively iterate over the children / descendants of the type, to check if any of them - // corresponds to a template argument type. - while (!children.isEmpty()) { - AbstractMetaType *child = children.pop(); - if (child->typeEntry()->isTemplateArgument()) - return true; - children << child->m_children; - } - - return false; -} - -bool AbstractMetaType::compare(const AbstractMetaType &rhs, ComparisonFlags flags) const -{ - if (m_typeEntry != rhs.m_typeEntry - || m_indirections != rhs.m_indirections - || m_instantiations.size() != rhs.m_instantiations.size() - || m_arrayElementCount != rhs.m_arrayElementCount) { - return false; - } - - if (m_constant != rhs.m_constant || m_referenceType != rhs.m_referenceType) { - if (!flags.testFlag(ConstRefMatchesValue) - || !(passByValue() || passByConstRef()) - || !(rhs.passByValue() || rhs.passByConstRef())) { - return false; - } - } - - if ((m_arrayElementType != nullptr) != (rhs.m_arrayElementType != nullptr) - || (m_arrayElementType != nullptr && !m_arrayElementType->compare(*rhs.m_arrayElementType, flags))) { - return false; - } - for (int i = 0, size = m_instantiations.size(); i < size; ++i) { - if (!m_instantiations.at(i)->compare(*rhs.m_instantiations.at(i), flags)) - return false; - } - return true; -} - -AbstractMetaType *AbstractMetaType::createVoid() -{ - static const TypeEntry *voidTypeEntry = TypeDatabase::instance()->findType(QLatin1String("void")); - Q_ASSERT(voidTypeEntry); - auto *metaType = new AbstractMetaType(voidTypeEntry); - metaType->decideUsagePattern(); - return metaType; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaType *at) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaType("; - if (at) { - d << at->name(); - if (d.verbosity() > 2) { - d << ", typeEntry=" << at->typeEntry() << ", signature=\"" - << at->cppSignature() << "\", pattern=" - << at->typeUsagePattern(); - const auto indirections = at->indirectionsV(); - if (!indirections.isEmpty()) { - d << ", indirections="; - for (auto i : indirections) - d << ' ' << TypeInfo::indirectionKeyword(i); - } - if (at->referenceType()) - d << ", reftype=" << at->referenceType(); - if (at->isConstant()) - d << ", [const]"; - if (at->isVolatile()) - d << ", [volatile]"; - if (at->isArray()) { - d << ", array of \"" << at->arrayElementType()->cppSignature() - << "\", arrayElementCount=" << at->arrayElementCount(); - } - const auto &instantiations = at->instantiations(); - if (const int instantiationsSize = instantiations.size()) { - d << ", instantiations[" << instantiationsSize << "]=<"; - for (int i = 0; i < instantiationsSize; ++i) { - if (i) - d << ", "; - d << instantiations.at(i); - } - } - d << '>'; - if (at->viewOn()) - d << ", views " << at->viewOn()->name(); - } - } else { - d << '0'; - } - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - /******************************************************************************* * AbstractMetaArgument */ @@ -553,7 +256,6 @@ AbstractMetaFunction::AbstractMetaFunction() AbstractMetaFunction::~AbstractMetaFunction() { qDeleteAll(m_arguments); - delete m_type; } /******************************************************************************* @@ -596,9 +298,7 @@ AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const Abstra result |= EqualAttributes; // Compare types - AbstractMetaType *t = type(); - AbstractMetaType *ot = other->type(); - if ((!t && !ot) || ((t && ot && t->name() == ot->name()))) + if (type().name() == other->type().name()) result |= EqualReturnType; // Compare names @@ -632,7 +332,7 @@ AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const Abstra if (i < minCount) { const AbstractMetaArgument *min_arg = minArguments.at(i); const AbstractMetaArgument *max_arg = maxArguments.at(i); - if (min_arg->type()->name() != max_arg->type()->name() + if (min_arg->type().name() != max_arg->type().name() && (min_arg->defaultValueExpression().isEmpty() || max_arg->defaultValueExpression().isEmpty())) { same = false; break; @@ -661,7 +361,7 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const cpy->setImplementingClass(implementingClass()); cpy->setFunctionType(functionType()); cpy->setDeclaringClass(declaringClass()); - cpy->setType(type()->copy()); + cpy->setType(type()); cpy->setConstant(isConstant()); cpy->setExceptionSpecification(m_exceptionSpecification); cpy->setAllowThreadModification(m_allowThreadModification); @@ -670,9 +370,6 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const for (AbstractMetaArgument *arg : m_arguments) cpy->addArgument(arg->copy()); - - Q_ASSERT(type()->instantiations() == cpy->type()->instantiations()); - return cpy; } @@ -680,10 +377,10 @@ bool AbstractMetaFunction::usesRValueReferences() const { if (m_functionType == MoveConstructorFunction || m_functionType == MoveAssignmentOperatorFunction) return true; - if (m_type->referenceType() == RValueReference) + if (m_type.referenceType() == RValueReference) return true; for (const AbstractMetaArgument *a : m_arguments) { - if (a->type()->referenceType() == RValueReference) + if (a->type().referenceType() == RValueReference) return true; } return false; @@ -699,7 +396,7 @@ QStringList AbstractMetaFunction::introspectionCompatibleSignatures(const QStrin QStringList returned; AbstractMetaArgument *argument = arguments.at(resolvedArguments.size()); - QStringList minimalTypeSignature = argument->type()->minimalSignature().split(QLatin1String("::")); + QStringList minimalTypeSignature = argument->type().minimalSignature().split(QLatin1String("::")); for (int i = 0; i < minimalTypeSignature.size(); ++i) { returned += introspectionCompatibleSignatures(QStringList(resolvedArguments) << QStringList(minimalTypeSignature.mid(minimalTypeSignature.size() - i - 1)).join(QLatin1String("::"))); @@ -717,11 +414,11 @@ QString AbstractMetaFunction::signature() const for (int i = 0; i < m_arguments.count(); ++i) { AbstractMetaArgument *a = m_arguments.at(i); - AbstractMetaType *t = a->type(); - if (t) { + const AbstractMetaType &t = a->type(); + if (!t.isVoid()) { if (i > 0) m_cachedSignature += QLatin1String(", "); - m_cachedSignature += t->cppSignature(); + m_cachedSignature += t.cppSignature(); // We need to have the argument names in the qdoc files m_cachedSignature += QLatin1Char(' '); m_cachedSignature += a->name(); @@ -963,11 +660,11 @@ QString AbstractMetaFunction::minimalSignature() const AbstractMetaArgumentList arguments = this->arguments(); for (int i = 0; i < arguments.count(); ++i) { - AbstractMetaType *t = arguments.at(i)->type(); - if (t) { + const AbstractMetaType &t = arguments.at(i)->type(); + if (!t.isVoid()) { if (i > 0) minimalSignature += QLatin1Char(','); - minimalSignature += t->minimalSignature(); + minimalSignature += t.minimalSignature(); } else { qCWarning(lcShiboken).noquote().nospace() << QString::fromLatin1("No abstract meta type found for argument '%1' while constructing" @@ -1420,7 +1117,6 @@ AbstractMetaClass::~AbstractMetaClass() qDeleteAll(m_fields); qDeleteAll(m_enums); qDeleteAll(m_propertySpecs); - qDeleteAll(m_baseTemplateInstantiations); } /******************************************************************************* @@ -1844,7 +1540,7 @@ static void formatMetaAttributes(QDebug &d, AbstractMetaAttributes::Attributes v static void formatMetaField(QDebug &d, const AbstractMetaField *af) { formatMetaAttributes(d, af->attributes()); - d << ' ' << af->type()->name() << " \"" << af->name() << '"'; + d << ' ' << af->type().name() << " \"" << af->name() << '"'; } QDebug operator<<(QDebug d, const AbstractMetaField *af) @@ -1958,10 +1654,10 @@ void AbstractMetaClass::addDefaultCopyConstructor(bool isPrivate) f->setFunctionType(AbstractMetaFunction::CopyConstructorFunction); f->setDeclaringClass(this); - auto argType = new AbstractMetaType(typeEntry()); - argType->setReferenceType(LValueReference); - argType->setConstant(true); - argType->setTypeUsagePattern(AbstractMetaType::ValuePattern); + AbstractMetaType argType(typeEntry()); + argType.setReferenceType(LValueReference); + argType.setConstant(true); + argType.setTypeUsagePattern(AbstractMetaType::ValuePattern); auto arg = new AbstractMetaArgument; arg->setType(argType); @@ -2172,13 +1868,11 @@ void AbstractMetaClass::getFunctionsFromInvisibleNamespacesToBeGenerated(Abstrac } } -static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractMetaType *type) +static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractMetaType &type) { - if (!type) - return; Q_ASSERT(metaClass); - const TypeEntry *entry = (type ? type->typeEntry() : nullptr); + const TypeEntry *entry = type.typeEntry(); if (entry && entry->isComplex()) { const auto *centry = static_cast(entry); ComplexTypeEntry *class_entry = metaClass->typeEntry(); @@ -2186,8 +1880,8 @@ static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractM class_entry->addExtraInclude(centry->include()); } - if (type->hasInstantiations()) { - for (const AbstractMetaType *instantiation : type->instantiations()) + if (type.hasInstantiations()) { + for (const AbstractMetaType &instantiation : type.instantiations()) addExtraIncludeForType(metaClass, instantiation); } } @@ -2396,121 +2090,6 @@ void AbstractMetaClass::fixFunctions() setFunctions(funcs); } -static inline QString formatArraySize(int e) -{ - QString result; - result += QLatin1Char('['); - if (e >= 0) - result += QString::number(e); - result += QLatin1Char(']'); - return result; -} - -QString AbstractMetaType::formatSignature(bool minimal) const -{ - QString result; - if (isConstant()) - result += QLatin1String("const "); - if (isVolatile()) - result += QLatin1String("volatile "); - if (isArray()) { - // Build nested array dimensions a[2][3] in correct order - result += m_arrayElementType->minimalSignature(); - const int arrayPos = result.indexOf(QLatin1Char('[')); - if (arrayPos != -1) - result.insert(arrayPos, formatArraySize(m_arrayElementCount)); - else - result.append(formatArraySize(m_arrayElementCount)); - } else { - result += typeEntry()->qualifiedCppName(); - } - if (!m_instantiations.isEmpty()) { - result += QLatin1Char('<'); - if (minimal) - result += QLatin1Char(' '); - for (int i = 0, size = m_instantiations.size(); i < size; ++i) { - if (i > 0) - result += QLatin1Char(','); - result += m_instantiations.at(i)->minimalSignature(); - } - result += QLatin1String(" >"); - } - - if (!minimal && (!m_indirections.isEmpty() || m_referenceType != NoReference)) - result += QLatin1Char(' '); - for (Indirection i : m_indirections) - result += TypeInfo::indirectionKeyword(i); - switch (referenceType()) { - case NoReference: - break; - case LValueReference: - result += QLatin1Char('&'); - break; - case RValueReference: - result += QLatin1String("&&"); - break; - } - return result; -} - -QString AbstractMetaType::formatPythonSignature() const -{ - /* - * This is a version of the above, more suitable for Python. - * We avoid extra keywords that are not needed in Python. - * We prepend the package name, unless it is a primitive type. - * - * Primitive types like 'int', 'char' etc.: - * When we have a primitive with an indirection, we use that '*' - * character for later postprocessing, since those indirections - * need to be modified into a result tuple. - * Smart pointer instantiations: Drop the package - */ - QString result; - if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern) - result += QLatin1String("array "); - // We no longer use the "const" qualifier for heuristics. Instead, - // NativePointerAsArrayPattern indicates when we have in XML. - // if (m_typeEntry->isPrimitive() && isConstant()) - // result += QLatin1String("const "); - if (!m_typeEntry->isPrimitive() && !m_typeEntry->isSmartPointer() && !package().isEmpty()) - result += package() + QLatin1Char('.'); - if (isArray()) { - // Build nested array dimensions a[2][3] in correct order - result += m_arrayElementType->formatPythonSignature(); - const int arrayPos = result.indexOf(QLatin1Char('[')); - if (arrayPos != -1) - result.insert(arrayPos, formatArraySize(m_arrayElementCount)); - else - result.append(formatArraySize(m_arrayElementCount)); - } else { - result += typeEntry()->targetLangName(); - } - if (!m_instantiations.isEmpty()) { - result += QLatin1Char('['); - for (int i = 0, size = m_instantiations.size(); i < size; ++i) { - if (i > 0) - result += QLatin1String(", "); - result += m_instantiations.at(i)->formatPythonSignature(); - } - result += QLatin1Char(']'); - } - if (m_typeEntry->isPrimitive()) - for (Indirection i : m_indirections) - result += TypeInfo::indirectionKeyword(i); - // If it is a flags type, we replace it with the full name: - // "PySide2.QtCore.Qt.ItemFlags" instead of "PySide2.QtCore.QFlags" - if (m_typeEntry->isFlags()) - result = fullName(); - result.replace(QLatin1String("::"), QLatin1String(".")); - return result; -} - -bool AbstractMetaType::isCppPrimitive() const -{ - return m_pattern == PrimitivePattern && m_typeEntry->isCppPrimitive(); -} - /******************************************************************************* * Other stuff... */ @@ -2635,7 +2214,7 @@ void AbstractMetaClass::format(QDebug &d) const const auto &instantiatedTypes = templateBaseClassInstantiations(); d << ", instantiates \"" << templateBase->name(); for (int i = 0, count = instantiatedTypes.size(); i < count; ++i) - d << (i ? ',' : '<') << instantiatedTypes.at(i)->name(); + d << (i ? ',' : '<') << instantiatedTypes.at(i).name(); d << ">\""; } if (const int count = m_propertySpecs.size()) { diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index 49078b07f..4f5b1476b 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -30,6 +30,7 @@ #define ABSTRACTMETALANG_H #include "abstractmetalang_typedefs.h" +#include "abstractmetatype.h" #include "sourcelocation.h" #include "typesystem_enums.h" #include "typesystem_typedefs.h" @@ -39,6 +40,7 @@ #include #include +#include #include QT_FORWARD_DECLARE_CLASS(QDebug) @@ -47,7 +49,6 @@ class AbstractMeta; class AbstractMetaClass; class AbstractMetaField; class AbstractMetaFunction; -class AbstractMetaType; class AbstractMetaVariable; class AbstractMetaArgument; class AbstractMetaEnumValue; @@ -274,315 +275,6 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaAttributes::Attributes) QDebug operator<<(QDebug d, const AbstractMetaAttributes *aa); #endif -class AbstractMetaType -{ - Q_GADGET -public: - using Indirections = QVector; - - enum TypeUsagePattern { - InvalidPattern, - PrimitivePattern, - FlagsPattern, - EnumPattern, - ValuePattern, - ObjectPattern, - ValuePointerPattern, - NativePointerPattern, - NativePointerAsArrayPattern, // "int*" as "int[]" - ContainerPattern, - SmartPointerPattern, - VarargsPattern, - ArrayPattern, - VoidPattern, // Plain "void", no "void *" or similar. - TemplateArgument, // 'T' in std::array - NonTypeTemplateArgument // '2' in in std::array - }; - Q_ENUM(TypeUsagePattern) - - enum ComparisonFlag { - ConstRefMatchesValue = 0x1 - }; - Q_DECLARE_FLAGS(ComparisonFlags, ComparisonFlag); - - explicit AbstractMetaType(const TypeEntry *t = nullptr); - AbstractMetaType(const AbstractMetaType &); - ~AbstractMetaType(); - - QString package() const; - QString name() const; - QString fullName() const; - - void setTypeUsagePattern(TypeUsagePattern pattern) - { - m_pattern = pattern; - } - TypeUsagePattern typeUsagePattern() const - { - return m_pattern; - } - - // true when use pattern is container - bool hasInstantiations() const - { - return !m_instantiations.isEmpty(); - } - - void addInstantiation(AbstractMetaType* inst, bool owner = false) - { - if (owner) - m_children << inst; - m_instantiations << inst; - } - - void setInstantiations(const AbstractMetaTypeList &insts, bool owner = false) - { - m_instantiations = insts; - if (owner) { - m_children.clear(); - m_children = insts; - } - } - - const AbstractMetaTypeList &instantiations() const - { - return m_instantiations; - } - - void setInstantiationInCpp(bool incpp) - { - m_cppInstantiation = incpp; - } - - QString minimalSignature() const { return formatSignature(true); } - - // returns true if the typs is used as a non complex primitive, no & or *'s - bool isPrimitive() const - { - return m_pattern == PrimitivePattern; - } - - bool isCppPrimitive() const; - - // returns true if the type is used as an enum - bool isEnum() const - { - return m_pattern == EnumPattern; - } - - // returns true if the type is used as an object, e.g. Xxx * - bool isObject() const - { - return m_pattern == ObjectPattern; - } - - // returns true if the type is used as an array, e.g. Xxx[42] - bool isArray() const - { - return m_pattern == ArrayPattern; - } - - // returns true if the type is used as a value type (X or const X &) - bool isValue() const - { - return m_pattern == ValuePattern; - } - - bool isValuePointer() const - { - return m_pattern == ValuePointerPattern; - } - - // returns true for more complex types... - bool isNativePointer() const - { - return m_pattern == NativePointerPattern; - } - - // return true if the type was originally a varargs - bool isVarargs() const - { - return m_pattern == VarargsPattern; - } - - // returns true if the type was used as a container - bool isContainer() const - { - return m_pattern == ContainerPattern; - } - - // returns true if the type was used as a smart pointer - bool isSmartPointer() const { return m_pattern == SmartPointerPattern; } - - // returns true if the type was used as a flag - bool isFlags() const - { - return m_pattern == FlagsPattern; - } - - bool isVoid() const { return m_pattern == VoidPattern; } - - bool isConstant() const - { - return m_constant; - } - void setConstant(bool constant) - { - m_constant = constant; - } - - bool isVolatile() const { return m_volatile; } - void setVolatile(bool v) { m_volatile = v; } - - bool passByConstRef() const; - bool passByValue() const; - - ReferenceType referenceType() const { return m_referenceType; } - void setReferenceType(ReferenceType ref) { m_referenceType = ref; } - - int actualIndirections() const - { - return m_indirections.size() + (m_referenceType == LValueReference ? 1 : 0); - } - - Indirections indirectionsV() const { return m_indirections; } - void setIndirectionsV(const Indirections &i) { m_indirections = i; } - void clearIndirections() { m_indirections.clear(); } - - // "Legacy"? - int indirections() const { return m_indirections.size(); } - void setIndirections(int indirections) - { - m_indirections = Indirections(indirections, Indirection::Pointer); - } - void addIndirection(Indirection i = Indirection::Pointer) - { m_indirections.append(i); } - - void setArrayElementCount(int n) - { - m_arrayElementCount = n; - } - int arrayElementCount() const - { - return m_arrayElementCount; - } - - const AbstractMetaType *arrayElementType() const - { - return m_arrayElementType; - } - void setArrayElementType(const AbstractMetaType *t) - { - m_arrayElementType = t; - } - - AbstractMetaTypeCList nestedArrayTypes() const; - - QString cppSignature() const; - - QString pythonSignature() const; - - AbstractMetaType *copy() const; - bool applyArrayModification(QString *errorMessage); - - const TypeEntry *typeEntry() const - { - return m_typeEntry; - } - void setTypeEntry(const TypeEntry *type) - { - m_typeEntry = type; - } - - void setOriginalTypeDescription(const QString &otd) - { - m_originalTypeDescription = otd; - } - QString originalTypeDescription() const - { - return m_originalTypeDescription; - } - - void setOriginalTemplateType(const AbstractMetaType *type) - { - m_originalTemplateType = type; - } - const AbstractMetaType *originalTemplateType() const - { - return m_originalTemplateType; - } - - AbstractMetaType *getSmartPointerInnerType() const - { - Q_ASSERT(isSmartPointer()); - const AbstractMetaTypeList &instantiations = this->instantiations(); - Q_ASSERT(!instantiations.isEmpty()); - AbstractMetaType *innerType = instantiations.at(0); - return innerType; - } - - QString getSmartPointerInnerTypeName() const - { - Q_ASSERT(isSmartPointer()); - AbstractMetaType *innerType = getSmartPointerInnerType(); - Q_ASSERT(innerType); - return innerType->name(); - } - - /// Decides and sets the proper usage patter for the current meta type. - void decideUsagePattern(); - - bool hasTemplateChildren() const; - - bool compare(const AbstractMetaType &rhs, ComparisonFlags = {}) const; - - // View on: Type to use for function argument conversion, fex - // std::string_view -> std::string for foo(std::string_view); - // cf TypeEntry::viewOn() - const AbstractMetaType *viewOn() const { return m_viewOn; } - void setViewOn(const AbstractMetaType *v) { m_viewOn = v; } - - static AbstractMetaType *createVoid(); - -private: - TypeUsagePattern determineUsagePattern() const; - QString formatSignature(bool minimal) const; - QString formatPythonSignature() const; - - const TypeEntry *m_typeEntry; - AbstractMetaTypeList m_instantiations; - QString m_package; - mutable QString m_cachedCppSignature; - mutable QString m_cachedPythonSignature; - QString m_originalTypeDescription; - - int m_arrayElementCount = -1; - const AbstractMetaType *m_arrayElementType = nullptr; - const AbstractMetaType *m_originalTemplateType = nullptr; - const AbstractMetaType *m_viewOn = nullptr; - Indirections m_indirections; - - TypeUsagePattern m_pattern = InvalidPattern; - uint m_constant : 1; - uint m_volatile : 1; - uint m_cppInstantiation : 1; - uint m_reserved : 29; // unused - - ReferenceType m_referenceType = NoReference; - AbstractMetaTypeList m_children; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaType::ComparisonFlags); - -inline bool operator==(const AbstractMetaType &t1, const AbstractMetaType &t2) -{ return t1.compare(t2); } -inline bool operator!=(const AbstractMetaType &t1, const AbstractMetaType &t2) -{ return !t1.compare(t2); } - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaType *at); -#endif - class AbstractMetaVariable { Q_DISABLE_COPY(AbstractMetaVariable) @@ -591,18 +283,12 @@ public: virtual ~AbstractMetaVariable(); - AbstractMetaType *type() const + const AbstractMetaType &type() const { return m_type; } - void setType(AbstractMetaType *type) - { - Q_ASSERT(m_type == nullptr); - m_type = type; - } - void replaceType(AbstractMetaType *type) + void setType(const AbstractMetaType &type) { - delete m_type; m_type = type; } @@ -642,7 +328,7 @@ protected: private: QString m_originalName; QString m_name; - AbstractMetaType *m_type = nullptr; + AbstractMetaType m_type; bool m_hasName = false; Documentation m_doc; @@ -686,7 +372,7 @@ public: QString toString() const { - return type()->name() + QLatin1Char(' ') + AbstractMetaVariable::name() + + return type().name() + QLatin1Char(' ') + AbstractMetaVariable::name() + (m_expression.isEmpty() ? QString() : QLatin1String(" = ") + m_expression); } @@ -894,20 +580,13 @@ public: bool isModifiedRemoved(int types = TypeSystem::All) const; - bool isVoid() const { return m_type->isVoid(); } - AbstractMetaType *type() const + bool isVoid() const { return m_type.isVoid(); } + const AbstractMetaType &type() const { return m_type; } - void setType(AbstractMetaType *type) - { - Q_ASSERT(m_type == nullptr); - m_type = type; - } - - void replaceType(AbstractMetaType *type) + void setType(const AbstractMetaType &type) { - delete m_type; m_type = type; } @@ -1113,7 +792,7 @@ private: FunctionTypeEntry* m_typeEntry = nullptr; FunctionType m_functionType = NormalFunction; - AbstractMetaType *m_type = nullptr; + AbstractMetaType m_type; const AbstractMetaClass *m_class = nullptr; const AbstractMetaClass *m_implementingClass = nullptr; const AbstractMetaClass *m_declaringClass = nullptr; diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h b/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h index f8bca07c1..418b9ba09 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h @@ -46,8 +46,6 @@ using AbstractMetaEnumList = QVector; using AbstractMetaEnumValueList = QVector; using AbstractMetaFieldList = QVector; using AbstractMetaFunctionList = QVector; -using AbstractMetaTypeCPtr = QSharedPointer; -using AbstractMetaTypeList = QVector; -using AbstractMetaTypeCList = QVector; +using AbstractMetaTypeList = QVector; #endif // ABSTRACTMETALANG_TYPEDEFS_H diff --git a/sources/shiboken2/ApiExtractor/abstractmetatype.cpp b/sources/shiboken2/ApiExtractor/abstractmetatype.cpp new file mode 100644 index 000000000..8ad2a937f --- /dev/null +++ b/sources/shiboken2/ApiExtractor/abstractmetatype.cpp @@ -0,0 +1,752 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "abstractmetatype.h" +#include "typedatabase.h" +#include "typesystem.h" +#include "parser/codemodel.h" + +#ifndef QT_NO_DEBUG_STREAM +# include +#endif + +#include +#include +#include + +using AbstractMetaTypeCPtr = QSharedPointer; + +class AbstractMetaTypeData : public QSharedData +{ +public: + AbstractMetaTypeData(const TypeEntry *t); + + int actualIndirections() const; + bool passByConstRef() const; + bool passByValue() const; + AbstractMetaType::TypeUsagePattern determineUsagePattern() const; + bool hasTemplateChildren() const; + QString formatSignature(bool minimal) const; + QString formatPythonSignature() const; + bool equals(const AbstractMetaTypeData &rhs) const; + + const TypeEntry *m_typeEntry; + AbstractMetaTypeList m_instantiations; + mutable QString m_cachedCppSignature; + mutable QString m_cachedPythonSignature; + QString m_originalTypeDescription; + + int m_arrayElementCount = -1; + AbstractMetaTypeCPtr m_arrayElementType; + AbstractMetaTypeCPtr m_originalTemplateType; + AbstractMetaTypeCPtr m_viewOn; + AbstractMetaType::Indirections m_indirections; + + AbstractMetaType::TypeUsagePattern m_pattern = AbstractMetaType::InvalidPattern; + uint m_constant : 1; + uint m_volatile : 1; + uint m_signaturesDirty : 1; + uint m_reserved : 29; // unused + + ReferenceType m_referenceType = NoReference; + AbstractMetaTypeList m_children; +}; + +AbstractMetaTypeData::AbstractMetaTypeData(const TypeEntry *t) : + m_typeEntry(t), + m_constant(false), + m_volatile(false), + m_signaturesDirty(true), + m_reserved(0) +{ +} + +AbstractMetaType::AbstractMetaType(const TypeEntry *t) : d(new AbstractMetaTypeData(t)) +{ +} + +AbstractMetaType::AbstractMetaType() : d(new AbstractMetaTypeData(nullptr)) +{ +} + +AbstractMetaType &AbstractMetaType::operator=(const AbstractMetaType &) = default; + +AbstractMetaType::AbstractMetaType(const AbstractMetaType &rhs) = default; + +AbstractMetaType::AbstractMetaType(AbstractMetaType &&) = default; + +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(); +} + +QString AbstractMetaType::name() const +{ + return d->m_typeEntry->targetLangEntryName(); +} + +QString AbstractMetaType::fullName() const +{ + return d->m_typeEntry->qualifiedTargetLangName(); +} + +void AbstractMetaType::setTypeUsagePattern(AbstractMetaType::TypeUsagePattern pattern) +{ + if (d->m_pattern != pattern) + d->m_pattern = pattern; +} + +AbstractMetaType::TypeUsagePattern AbstractMetaType::typeUsagePattern() const +{ + return d->m_pattern; +} + +bool AbstractMetaType::hasInstantiations() const +{ + return !d->m_instantiations.isEmpty(); +} + +void AbstractMetaType::addInstantiation(const AbstractMetaType &inst) +{ + d->m_instantiations << inst; +} + +void AbstractMetaType::setInstantiations(const AbstractMetaTypeList &insts) +{ + if (insts != d->m_instantiations) + d->m_instantiations = insts; +} + +const AbstractMetaTypeList &AbstractMetaType::instantiations() const +{ + return d->m_instantiations; +} + +// For applying the function argument modification: change into a type +// where "int *" becomes "int[]". +bool AbstractMetaType::applyArrayModification(QString *errorMessage) +{ + + if (d->m_pattern == AbstractMetaType::NativePointerAsArrayPattern) { + *errorMessage = QLatin1String(" modification already applied."); + return false; + } + if (!d->m_arrayElementType.isNull()) { + QTextStream(errorMessage) << "The type \"" << cppSignature() + << "\" is an array of " << d->m_arrayElementType->name() << '.'; + return false; + } + if (d->m_indirections.isEmpty()) { + QTextStream(errorMessage) << "The type \"" << cppSignature() + << "\" does not have indirections."; + return false; + } + // Element type to be used for ArrayHandle<>, strip constness. + + auto elementType = new AbstractMetaType(*this); + auto indir = indirectionsV(); + indir.pop_front(); + elementType->setIndirectionsV(indir); + elementType->setConstant(false); + elementType->setVolatile(false); + elementType->decideUsagePattern(); + d->m_arrayElementType.reset(elementType); + d->m_pattern = AbstractMetaType::NativePointerAsArrayPattern; + return true; +} + +const TypeEntry *AbstractMetaType::typeEntry() const +{ + return d->m_typeEntry; +} + +void AbstractMetaType::setTypeEntry(const TypeEntry *type) +{ + if (d->m_typeEntry != type) + d->m_typeEntry = type; +} + +void AbstractMetaType::setOriginalTypeDescription(const QString &otd) +{ + if (d->m_originalTypeDescription != otd) + d->m_originalTypeDescription = otd; +} + +QString AbstractMetaType::originalTypeDescription() const +{ + return d->m_originalTypeDescription; +} + +void AbstractMetaType::setOriginalTemplateType(const AbstractMetaType &type) +{ + if (d->m_originalTemplateType.isNull() || *d->m_originalTemplateType != type) + d->m_originalTemplateType.reset(new AbstractMetaType(type)); +} + +const AbstractMetaType *AbstractMetaType::originalTemplateType() const +{ + return d->m_originalTemplateType.data(); +} + +AbstractMetaType AbstractMetaType::getSmartPointerInnerType() const +{ + Q_ASSERT(isSmartPointer()); + Q_ASSERT(!d->m_instantiations.isEmpty()); + AbstractMetaType innerType = d->m_instantiations.at(0); + return innerType; +} + +QString AbstractMetaType::getSmartPointerInnerTypeName() const +{ + Q_ASSERT(isSmartPointer()); + return getSmartPointerInnerType().name(); +} + +AbstractMetaTypeList AbstractMetaType::nestedArrayTypes() const +{ + AbstractMetaTypeList result; + switch (d->m_pattern) { + case ArrayPattern: + for (AbstractMetaType t = *this; t.typeUsagePattern() == ArrayPattern; ) { + const AbstractMetaType *elt = t.arrayElementType(); + result.append(*elt); + t = *elt; + } + break; + case NativePointerAsArrayPattern: + result.append(*d->m_arrayElementType.data()); + break; + default: + break; + } + return result; +} + +bool AbstractMetaTypeData::passByConstRef() const +{ + return m_constant && m_referenceType == LValueReference && m_indirections.isEmpty(); +} + +bool AbstractMetaType::passByConstRef() const +{ + return d->passByConstRef(); +} + +bool AbstractMetaTypeData::passByValue() const +{ + return m_referenceType == NoReference && m_indirections.isEmpty(); +} + +bool AbstractMetaType::passByValue() const +{ + return d->passByValue(); +} + +ReferenceType AbstractMetaType::referenceType() const +{ + return d->m_referenceType; +} + +void AbstractMetaType::setReferenceType(ReferenceType ref) +{ + if (d->m_referenceType != ref) { + d->m_referenceType = ref; + d->m_signaturesDirty = true; + } +} + +int AbstractMetaTypeData::actualIndirections() const +{ + return m_indirections.size() + (m_referenceType == LValueReference ? 1 : 0); +} + +int AbstractMetaType::actualIndirections() const +{ + return d->actualIndirections(); +} + +AbstractMetaType::Indirections AbstractMetaType::indirectionsV() const +{ + return d->m_indirections; +} + +void AbstractMetaType::setIndirectionsV(const AbstractMetaType::Indirections &i) +{ + if (d->m_indirections != i) { + d->m_indirections = i; + d->m_signaturesDirty = true; + } +} + +void AbstractMetaType::clearIndirections() +{ + if (!d->m_indirections.isEmpty()) { + d->m_indirections.clear(); + d->m_signaturesDirty = true; + } +} + +int AbstractMetaType::indirections() const +{ + return d->m_indirections.size(); +} + +void AbstractMetaType::setIndirections(int indirections) +{ + const Indirections newValue(indirections, Indirection::Pointer); + if (d->m_indirections != newValue) { + d->m_indirections = newValue; + d->m_signaturesDirty = true; + } +} + +void AbstractMetaType::addIndirection(Indirection i) +{ + d->m_indirections.append(i); +} + +void AbstractMetaType::setArrayElementCount(int n) +{ + if (d->m_arrayElementCount != n) { + d->m_arrayElementCount = n; + d->m_signaturesDirty = true; + } +} + +int AbstractMetaType::arrayElementCount() const +{ + return d->m_arrayElementCount; +} + +const AbstractMetaType *AbstractMetaType::arrayElementType() const +{ + return d->m_arrayElementType.data(); +} + +void AbstractMetaType::setArrayElementType(const AbstractMetaType &t) +{ + if (d->m_arrayElementType.isNull() || *d->m_arrayElementType != t) { + d->m_arrayElementType.reset(new AbstractMetaType(t)); + d->m_signaturesDirty = true; + } +} + +QString AbstractMetaType::cppSignature() const +{ + const AbstractMetaTypeData *cd = d.constData(); + if (cd->m_cachedCppSignature.isEmpty() || cd->m_signaturesDirty) + cd->m_cachedCppSignature = formatSignature(false); + return cd->m_cachedCppSignature; +} + +QString AbstractMetaType::pythonSignature() const +{ + // PYSIDE-921: Handle container returntypes correctly. + // This is now a clean reimplementation. + const AbstractMetaTypeData *cd = d.constData(); + if (cd->m_cachedPythonSignature.isEmpty() || cd->m_signaturesDirty) + cd->m_cachedPythonSignature = formatPythonSignature(); + return cd->m_cachedPythonSignature; +} + +AbstractMetaType::TypeUsagePattern AbstractMetaTypeData::determineUsagePattern() const +{ + if (m_typeEntry->isTemplateArgument()) + return AbstractMetaType::TemplateArgument; + + if (m_typeEntry->type() == TypeEntry::ConstantValueType) + return AbstractMetaType::NonTypeTemplateArgument; + + if (m_typeEntry->isPrimitive() && (actualIndirections() == 0 || passByConstRef())) + return AbstractMetaType::PrimitivePattern; + + if (m_typeEntry->isVoid()) { + return m_arrayElementCount < 0 && m_referenceType == NoReference + && m_indirections.isEmpty() && m_constant == 0 && m_volatile == 0 + ? AbstractMetaType::VoidPattern : AbstractMetaType::NativePointerPattern; + } + + if (m_typeEntry->isVarargs()) + return AbstractMetaType::VarargsPattern; + + if (m_typeEntry->isEnum() && (actualIndirections() == 0 || passByConstRef())) + return AbstractMetaType::EnumPattern; + + if (m_typeEntry->isObject()) { + if (m_indirections.isEmpty() && m_referenceType == NoReference) + return AbstractMetaType::ValuePattern; + return AbstractMetaType::ObjectPattern; + } + + if (m_typeEntry->isContainer() && m_indirections.isEmpty()) + return AbstractMetaType::ContainerPattern; + + if (m_typeEntry->isSmartPointer() && m_indirections.isEmpty()) + return AbstractMetaType::SmartPointerPattern; + + if (m_typeEntry->isFlags() && (actualIndirections() == 0 || passByConstRef())) + return AbstractMetaType::FlagsPattern; + + if (m_typeEntry->isArray()) + return AbstractMetaType::ArrayPattern; + + if (m_typeEntry->isValue()) + return m_indirections.size() == 1 ? AbstractMetaType::ValuePointerPattern : AbstractMetaType::ValuePattern; + + return AbstractMetaType::NativePointerPattern; +} + +AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() const +{ + return d->determineUsagePattern(); +} + +void AbstractMetaType::decideUsagePattern() +{ + TypeUsagePattern pattern = determineUsagePattern(); + if (d->m_typeEntry->isObject() && indirections() == 1 + && d->m_referenceType == LValueReference && isConstant()) { + // const-references to pointers can be passed as pointers + setReferenceType(NoReference); + setConstant(false); + pattern = ObjectPattern; + } + setTypeUsagePattern(pattern); +} + +bool AbstractMetaTypeData::hasTemplateChildren() const +{ + QStack children; + children << m_instantiations; + + // Recursively iterate over the children / descendants of the type, to check if any of them + // corresponds to a template argument type. + while (!children.isEmpty()) { + AbstractMetaType child = children.pop(); + if (child.typeEntry()->isTemplateArgument()) + return true; + children << child.instantiations(); + } + return false; +} + +bool AbstractMetaType::hasTemplateChildren() const +{ + return d->hasTemplateChildren(); +} + +static inline QString formatArraySize(int e) +{ + QString result; + result += QLatin1Char('['); + if (e >= 0) + result += QString::number(e); + result += QLatin1Char(']'); + return result; +} + +QString AbstractMetaTypeData::formatSignature(bool minimal) const +{ + QString result; + if (m_constant) + result += QLatin1String("const "); + if (m_volatile) + result += QLatin1String("volatile "); + if (m_pattern == AbstractMetaType::ArrayPattern) { + // Build nested array dimensions a[2][3] in correct order + result += m_arrayElementType->minimalSignature(); + const int arrayPos = result.indexOf(QLatin1Char('[')); + if (arrayPos != -1) + result.insert(arrayPos, formatArraySize(m_arrayElementCount)); + else + result.append(formatArraySize(m_arrayElementCount)); + } else { + result += m_typeEntry->qualifiedCppName(); + } + if (!m_instantiations.isEmpty()) { + result += QLatin1Char('<'); + if (minimal) + result += QLatin1Char(' '); + for (int i = 0, size = m_instantiations.size(); i < size; ++i) { + if (i > 0) + result += QLatin1Char(','); + result += m_instantiations.at(i).minimalSignature(); + } + result += QLatin1String(" >"); + } + + if (!minimal && (!m_indirections.isEmpty() || m_referenceType != NoReference)) + result += QLatin1Char(' '); + for (Indirection i : m_indirections) + result += TypeInfo::indirectionKeyword(i); + switch (m_referenceType) { + case NoReference: + break; + case LValueReference: + result += QLatin1Char('&'); + break; + case RValueReference: + result += QLatin1String("&&"); + break; + } + return result; +} + +QString AbstractMetaType::formatSignature(bool minimal) const +{ + return d->formatSignature(minimal); +} + +QString AbstractMetaTypeData::formatPythonSignature() const +{ + /* + * This is a version of the above, more suitable for Python. + * We avoid extra keywords that are not needed in Python. + * We prepend the package name, unless it is a primitive type. + * + * Primitive types like 'int', 'char' etc.: + * When we have a primitive with an indirection, we use that '*' + * character for later postprocessing, since those indirections + * need to be modified into a result tuple. + * Smart pointer instantiations: Drop the package + */ + QString result; + if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern) + result += QLatin1String("array "); + // We no longer use the "const" qualifier for heuristics. Instead, + // NativePointerAsArrayPattern indicates when we have in XML. + // if (m_typeEntry->isPrimitive() && isConstant()) + // result += QLatin1String("const "); + if (!m_typeEntry->isPrimitive() && !m_typeEntry->isSmartPointer()) { + const QString package = m_typeEntry->targetLangPackage(); + if (!package.isEmpty()) + result += package + QLatin1Char('.'); + } + if (m_pattern == AbstractMetaType::ArrayPattern) { + // Build nested array dimensions a[2][3] in correct order + result += m_arrayElementType->formatPythonSignature(); + const int arrayPos = result.indexOf(QLatin1Char('[')); + if (arrayPos != -1) + result.insert(arrayPos, formatArraySize(m_arrayElementCount)); + else + result.append(formatArraySize(m_arrayElementCount)); + } else { + result += m_typeEntry->targetLangName(); + } + if (!m_instantiations.isEmpty()) { + result += QLatin1Char('['); + for (int i = 0, size = m_instantiations.size(); i < size; ++i) { + if (i > 0) + result += QLatin1String(", "); + result += m_instantiations.at(i).formatPythonSignature(); + } + result += QLatin1Char(']'); + } + if (m_typeEntry->isPrimitive()) + for (Indirection i : m_indirections) + result += TypeInfo::indirectionKeyword(i); + // If it is a flags type, we replace it with the full name: + // "PySide2.QtCore.Qt.ItemFlags" instead of "PySide2.QtCore.QFlags" + if (m_typeEntry->isFlags()) + result = m_typeEntry->qualifiedTargetLangName(); + result.replace(QLatin1String("::"), QLatin1String(".")); + return result; +} + +QString AbstractMetaType::formatPythonSignature() const +{ + return d->formatPythonSignature(); +} + +bool AbstractMetaType::isCppPrimitive() const +{ + return d->m_pattern == PrimitivePattern && d->m_typeEntry->isCppPrimitive(); +} + +bool AbstractMetaType::isConstant() const +{ + return d->m_constant; +} + +void AbstractMetaType::setConstant(bool constant) +{ + if (d->m_constant != constant) { + d->m_constant = constant; + d->m_signaturesDirty = true; + } +} + +bool AbstractMetaType::isVolatile() const +{ + return d->m_volatile; +} + +void AbstractMetaType::setVolatile(bool v) +{ + if (d->m_volatile != v) { + d->m_volatile = v; + d->m_signaturesDirty = true;\ + } +} + +static bool equalsCPtr(const AbstractMetaTypeCPtr &t1, const AbstractMetaTypeCPtr &t2) +{ + if (t1.isNull() != t2.isNull()) + return false; + return t1.isNull() || *t1 == *t2; +} + +bool AbstractMetaTypeData::equals(const AbstractMetaTypeData &rhs) const +{ + if (m_typeEntry != rhs.m_typeEntry + || m_indirections != rhs.m_indirections + || m_arrayElementCount != rhs.m_arrayElementCount) { + return false; + } + + if (m_constant != rhs.m_constant || m_volatile != rhs.m_volatile + || m_referenceType != rhs.m_referenceType) { + return false; + } + + if (!equalsCPtr(m_arrayElementType, rhs.m_arrayElementType)) + return false; + + if (!equalsCPtr(m_viewOn, rhs.m_viewOn)) + return false; + + if (m_instantiations != rhs.m_instantiations) + return false; + return true; +} + +bool AbstractMetaType::equals(const AbstractMetaType &rhs) const +{ + return d->equals(*rhs.d); +} + +const AbstractMetaType *AbstractMetaType::viewOn() const +{ + return d->m_viewOn.data(); +} + +void AbstractMetaType::setViewOn(const AbstractMetaType &v) +{ + if (d->m_viewOn.isNull() || *d->m_viewOn != v) + d->m_viewOn.reset(new AbstractMetaType(v)); +} + +AbstractMetaType AbstractMetaType::createVoid() +{ + static QScopedPointer metaType; + if (metaType.isNull()) { + static const TypeEntry *voidTypeEntry = TypeDatabase::instance()->findType(QLatin1String("void")); + Q_ASSERT(voidTypeEntry); + metaType.reset(new AbstractMetaType(voidTypeEntry)); + metaType->decideUsagePattern(); + } + return *metaType.data(); +} + +#ifndef QT_NO_DEBUG_STREAM +void AbstractMetaType::formatDebug(QDebug &debug) const +{ + debug << '"' << name() << '"'; + if (debug.verbosity() > 2) { + auto te = typeEntry(); + debug << ", typeEntry="; + if (debug.verbosity() > 3) + debug << te; + else + debug << "(\"" << te->qualifiedCppName() << "\", " << te->type() << ')'; + debug << ", signature=\"" << cppSignature() << "\", pattern=" + << typeUsagePattern(); + const auto indirections = indirectionsV(); + if (!indirections.isEmpty()) { + debug << ", indirections="; + for (auto i : indirections) + debug << ' ' << TypeInfo::indirectionKeyword(i); + } + if (referenceType()) + debug << ", reftype=" << referenceType(); + if (isConstant()) + debug << ", [const]"; + if (isVolatile()) + debug << ", [volatile]"; + if (isArray()) { + debug << ", array of \"" << arrayElementType()->cppSignature() + << "\", arrayElementCount=" << arrayElementCount(); + } + const auto &instantiations = this->instantiations(); + if (const int instantiationsSize = instantiations.size()) { + debug << ", instantiations[" << instantiationsSize << "]=<"; + for (int i = 0; i < instantiationsSize; ++i) { + if (i) + debug << ", "; + instantiations.at(i).formatDebug(debug); + } + } + debug << '>'; + if (viewOn()) + debug << ", views " << viewOn()->name(); + } +} + +QDebug operator<<(QDebug d, const AbstractMetaType &at) +{ + QDebugStateSaver saver(d); + d.noquote(); + d.nospace(); + d << "AbstractMetaType("; + at.formatDebug(d); + d << ')'; + return d; +} + +QDebug operator<<(QDebug d, const AbstractMetaType *at) +{ + QDebugStateSaver saver(d); + d.noquote(); + d.nospace(); + if (at) + d << *at; + else + d << "AbstractMetaType(0)"; + return d; +} + +#endif // !QT_NO_DEBUG_STREAM diff --git a/sources/shiboken2/ApiExtractor/abstractmetatype.h b/sources/shiboken2/ApiExtractor/abstractmetatype.h new file mode 100644 index 000000000..c92a7652a --- /dev/null +++ b/sources/shiboken2/ApiExtractor/abstractmetatype.h @@ -0,0 +1,221 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ABSTRACTMETATYPE_H +#define ABSTRACTMETATYPE_H + +#include "abstractmetalang_typedefs.h" +#include "parser/codemodel_enums.h" + +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QDebug) + +class AbstractMetaTypeData; +class TypeEntry; + +class AbstractMetaType +{ + Q_GADGET +public: + using Indirections = QVector; + + enum TypeUsagePattern { + InvalidPattern, + PrimitivePattern, + FlagsPattern, + EnumPattern, + ValuePattern, + ObjectPattern, + ValuePointerPattern, + NativePointerPattern, + NativePointerAsArrayPattern, // "int*" as "int[]" + ContainerPattern, + SmartPointerPattern, + VarargsPattern, + ArrayPattern, + VoidPattern, // Plain "void", no "void *" or similar. + TemplateArgument, // 'T' in std::array + NonTypeTemplateArgument // '2' in in std::array + }; + Q_ENUM(TypeUsagePattern) + + AbstractMetaType(); + explicit AbstractMetaType(const TypeEntry *t); + AbstractMetaType(const AbstractMetaType &); + AbstractMetaType &operator=(const AbstractMetaType &); + AbstractMetaType(AbstractMetaType &&); + AbstractMetaType &operator=(AbstractMetaType &&); + ~AbstractMetaType(); + + bool isValid() const; + operator bool() const { return isValid(); } + + QString package() const; + QString name() const; + QString fullName() const; + + void setTypeUsagePattern(TypeUsagePattern pattern); + TypeUsagePattern typeUsagePattern() const; + + // true when use pattern is container + bool hasInstantiations() const; + + const AbstractMetaTypeList &instantiations() const; + void addInstantiation(const AbstractMetaType &inst); + void setInstantiations(const AbstractMetaTypeList &insts); + + QString minimalSignature() const { return formatSignature(true); } + + // returns true if the typs is used as a non complex primitive, no & or *'s + bool isPrimitive() const { return typeUsagePattern() == PrimitivePattern; } + + bool isCppPrimitive() const; + + // returns true if the type is used as an enum + bool isEnum() const { return typeUsagePattern() == EnumPattern; } + + // returns true if the type is used as an object, e.g. Xxx * + bool isObject() const { return typeUsagePattern() == ObjectPattern; } + + // returns true if the type is used as an array, e.g. Xxx[42] + bool isArray() const { return typeUsagePattern() == ArrayPattern; } + + // returns true if the type is used as a value type (X or const X &) + bool isValue() const { return typeUsagePattern() == ValuePattern; } + + bool isValuePointer() const { return typeUsagePattern() == ValuePointerPattern; } + + // returns true for more complex types... + bool isNativePointer() const { return typeUsagePattern() == NativePointerPattern; } + + // return true if the type was originally a varargs + bool isVarargs() const { return typeUsagePattern() == VarargsPattern; } + + // returns true if the type was used as a container + bool isContainer() const { return typeUsagePattern() == ContainerPattern; } + + // returns true if the type was used as a smart pointer + bool isSmartPointer() const { return typeUsagePattern() == SmartPointerPattern; } + + // returns true if the type was used as a flag + bool isFlags() const { return typeUsagePattern() == FlagsPattern; } + + bool isVoid() const { return typeUsagePattern() == VoidPattern; } + + bool isConstant() const; + void setConstant(bool constant); + + bool isVolatile() const; + void setVolatile(bool v); + + bool passByConstRef() const; + bool passByValue() const; + + ReferenceType referenceType() const; + void setReferenceType(ReferenceType ref); + + int actualIndirections() const; + + Indirections indirectionsV() const; + void setIndirectionsV(const Indirections &i); + void clearIndirections(); + + // "Legacy"? + int indirections() const; + void setIndirections(int indirections); + void addIndirection(Indirection i = Indirection::Pointer); + + void setArrayElementCount(int n); + int arrayElementCount() const; + + const AbstractMetaType *arrayElementType() const; + void setArrayElementType(const AbstractMetaType &t); + + AbstractMetaTypeList nestedArrayTypes() const; + + QString cppSignature() const; + + QString pythonSignature() const; + + bool applyArrayModification(QString *errorMessage); + + const TypeEntry *typeEntry() const; + void setTypeEntry(const TypeEntry *type); + + void setOriginalTypeDescription(const QString &otd); + QString originalTypeDescription() const; + + void setOriginalTemplateType(const AbstractMetaType &type); + const AbstractMetaType *originalTemplateType() const; + + AbstractMetaType getSmartPointerInnerType() const; + + QString getSmartPointerInnerTypeName() const; + + /// Decides and sets the proper usage patter for the current meta type. + void decideUsagePattern(); + + bool hasTemplateChildren() const; + + bool equals(const AbstractMetaType &rhs) const; + + // View on: Type to use for function argument conversion, fex + // std::string_view -> std::string for foo(std::string_view); + // cf TypeEntry::viewOn() + const AbstractMetaType *viewOn() const; + void setViewOn(const AbstractMetaType &v); + + static AbstractMetaType createVoid(); + +#ifndef QT_NO_DEBUG_STREAM + void formatDebug(QDebug &debug) const; +#endif + +private: + friend class AbstractMetaTypeData; + QSharedDataPointer d; + + TypeUsagePattern determineUsagePattern() const; + QString formatSignature(bool minimal) const; + QString formatPythonSignature() const; +}; + +inline bool operator==(const AbstractMetaType &t1, const AbstractMetaType &t2) +{ return t1.equals(t2); } +inline bool operator!=(const AbstractMetaType &t1, const AbstractMetaType &t2) +{ return !t1.equals(t2); } + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const AbstractMetaType &at); +QDebug operator<<(QDebug d, const AbstractMetaType *at); +#endif + +#endif // ABSTRACTMETALANG_H diff --git a/sources/shiboken2/ApiExtractor/doxygenparser.cpp b/sources/shiboken2/ApiExtractor/doxygenparser.cpp index cf152720e..c6bc3b440 100644 --- a/sources/shiboken2/ApiExtractor/doxygenparser.cpp +++ b/sources/shiboken2/ApiExtractor/doxygenparser.cpp @@ -138,15 +138,15 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass) int i = 1; const AbstractMetaArgumentList &arguments = func->arguments(); for (AbstractMetaArgument *arg : arguments) { - if (!arg->type()->isPrimitive()) { + if (!arg->type().isPrimitive()) { query += QLatin1String("/../param[") + QString::number(i) + QLatin1String("]/type/ref[text()=\"") - + arg->type()->cppSignature().toHtmlEscaped() + + arg->type().cppSignature().toHtmlEscaped() + QLatin1String("\"]/../.."); } else { query += QLatin1String("/../param[") + QString::number(i) + QLatin1String("]/type[text(), \"") - + arg->type()->cppSignature().toHtmlEscaped() + + arg->type().cppSignature().toHtmlEscaped() + QLatin1String("\"]/.."); } ++i; diff --git a/sources/shiboken2/ApiExtractor/propertyspec.cpp b/sources/shiboken2/ApiExtractor/propertyspec.cpp index f86a31d5b..d15647fda 100644 --- a/sources/shiboken2/ApiExtractor/propertyspec.cpp +++ b/sources/shiboken2/ApiExtractor/propertyspec.cpp @@ -42,7 +42,7 @@ #include QPropertySpec::QPropertySpec(const TypeSystemProperty &ts, - const AbstractMetaType *type) : + const AbstractMetaType &type) : m_name(ts.name), m_read(ts.read), m_write(ts.write), @@ -53,19 +53,16 @@ QPropertySpec::QPropertySpec(const TypeSystemProperty &ts, { } -QPropertySpec::~QPropertySpec() -{ - delete m_type; -} +QPropertySpec::~QPropertySpec() = default; bool QPropertySpec::isValid() const { - return m_type != nullptr && !m_name.isEmpty() && !m_read.isEmpty(); + return m_type.isValid() && !m_name.isEmpty() && !m_read.isEmpty(); } const TypeEntry *QPropertySpec::typeEntry() const { - return m_type->typeEntry(); + return m_type.typeEntry(); } // Parse a Q_PROPERTY macro @@ -161,10 +158,10 @@ QPropertySpec *QPropertySpec::fromTypeSystemProperty(AbstractMetaBuilderPrivate return nullptr; } - AbstractMetaType *type = b->translateType(info, metaClass, {}, &typeError); + AbstractMetaType type = b->translateType(info, metaClass, {}, &typeError); if (!type) { const QStringList qualifiedName = info.qualifiedName(); - for (int j = scopes.size(); j >= 0 && type == nullptr; --j) { + for (int j = scopes.size(); j >= 0 && !type; --j) { info.setQualifiedName(scopes.mid(0, j) + qualifiedName); type = b->translateType(info, metaClass, {}, &typeError); } @@ -195,7 +192,7 @@ QPropertySpec *QPropertySpec::parseQ_Property(AbstractMetaBuilderPrivate *b, #ifndef QT_NO_DEBUG_STREAM void QPropertySpec::formatDebug(QDebug &d) const { - d << '#' << m_index << " \"" << m_name << "\" (" << m_type->cppSignature(); + d << '#' << m_index << " \"" << m_name << "\" (" << m_type.cppSignature(); d << "), read=" << m_read; if (!m_write.isEmpty()) d << ", write=" << m_write; diff --git a/sources/shiboken2/ApiExtractor/propertyspec.h b/sources/shiboken2/ApiExtractor/propertyspec.h index 611d4726e..d26f7e826 100644 --- a/sources/shiboken2/ApiExtractor/propertyspec.h +++ b/sources/shiboken2/ApiExtractor/propertyspec.h @@ -29,6 +29,8 @@ #ifndef PROPERTYSPEC_H #define PROPERTYSPEC_H +#include "abstractmetatype.h" + #include class AbstractMetaClass; @@ -46,7 +48,7 @@ public: Q_DISABLE_COPY_MOVE(QPropertySpec) explicit QPropertySpec(const TypeSystemProperty &ts, - const AbstractMetaType *type); + const AbstractMetaType &type); ~QPropertySpec(); static TypeSystemProperty typeSystemPropertyFromQ_Property(const QString &declarationIn, @@ -66,8 +68,8 @@ public: bool isValid() const; - const AbstractMetaType *type() const { return m_type; } - void setType(AbstractMetaType *t) { m_type = t; } + const AbstractMetaType &type() const { return m_type; } + void setType(const AbstractMetaType &t) { m_type = t; } const TypeEntry *typeEntry() const; @@ -103,7 +105,7 @@ private: QString m_write; QString m_designable; QString m_reset; - const AbstractMetaType *m_type = nullptr; + AbstractMetaType m_type; int m_index = -1; // Indicates whether actual code is generated instead of relying on libpyside. bool m_generateGetSetDef = false; diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.cpp b/sources/shiboken2/ApiExtractor/qtdocparser.cpp index d439b3fd5..9318ef18b 100644 --- a/sources/shiboken2/ApiExtractor/qtdocparser.cpp +++ b/sources/shiboken2/ApiExtractor/qtdocparser.cpp @@ -48,49 +48,49 @@ Documentation QtDocParser::retrieveModuleDocumentation() static void formatFunctionArgTypeQuery(QTextStream &str, const AbstractMetaArgument *arg) { - const AbstractMetaType *metaType = arg->type(); - if (metaType->isConstant()) + const AbstractMetaType &metaType = arg->type(); + if (metaType.isConstant()) str << "const " ; - switch (metaType->typeUsagePattern()) { + switch (metaType.typeUsagePattern()) { case AbstractMetaType::FlagsPattern: { // Modify qualified name "QFlags" with name "Alignment" // to "Qt::Alignment" as seen by qdoc. - const auto *flagsEntry = static_cast(metaType->typeEntry()); + const auto *flagsEntry = static_cast(metaType.typeEntry()); QString name = flagsEntry->qualifiedCppName(); if (name.endsWith(QLatin1Char('>')) && name.startsWith(QLatin1String("QFlags<"))) { const int lastColon = name.lastIndexOf(QLatin1Char(':')); if (lastColon != -1) { - name.replace(lastColon + 1, name.size() - lastColon - 1, metaType->name()); + name.replace(lastColon + 1, name.size() - lastColon - 1, metaType.name()); name.remove(0, 7); } else { - name = metaType->name(); // QFlags<> of enum in global namespace + name = metaType.name(); // QFlags<> of enum in global namespace } } str << name; } break; case AbstractMetaType::ContainerPattern: { // QVector - str << metaType->typeEntry()->qualifiedCppName() << '<'; - const auto instantiations = metaType->instantiations(); + str << metaType.typeEntry()->qualifiedCppName() << '<'; + const auto instantiations = metaType.instantiations(); for (int i = 0, size = instantiations.size(); i < size; ++i) { if (i) str << ", "; - str << instantiations.at(i)->typeEntry()->qualifiedCppName(); + str << instantiations.at(i).typeEntry()->qualifiedCppName(); } str << '>'; } break; default: // Fully qualify enums (Qt::AlignmentFlag), nested classes, etc. - str << metaType->typeEntry()->qualifiedCppName(); + str << metaType.typeEntry()->qualifiedCppName(); break; } - if (metaType->referenceType() == LValueReference) + if (metaType.referenceType() == LValueReference) str << " &"; - else if (metaType->referenceType() == RValueReference) + else if (metaType.referenceType() == RValueReference) str << " &&"; - else if (metaType->indirections()) - str << ' ' << QByteArray(metaType->indirections(), '*'); + else if (metaType.indirections()) + str << ' ' << QByteArray(metaType.indirections(), '*'); } enum FunctionMatchFlags diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp index 980d08489..cbbda70b8 100644 --- a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp @@ -74,20 +74,20 @@ void TestAbstractMetaType::testConstCharPtrType() QVERIFY(!builder.isNull()); QCOMPARE(builder->globalFunctions().size(), 1); AbstractMetaFunction *func = builder->globalFunctions().constFirst(); - AbstractMetaType* rtype = func->type(); + AbstractMetaType rtype = func->type(); // Test properties of const char* QVERIFY(rtype); - QCOMPARE(rtype->package(), QLatin1String("Foo")); - QCOMPARE(rtype->name(), QLatin1String("char")); - QVERIFY(rtype->isConstant()); - QVERIFY(!rtype->isArray()); - QVERIFY(!rtype->isContainer()); - QVERIFY(!rtype->isObject()); - QVERIFY(!rtype->isPrimitive()); // const char* differs from char, so it's not considered a primitive type by apiextractor - QVERIFY(rtype->isNativePointer()); - QCOMPARE(rtype->referenceType(), NoReference); - QVERIFY(!rtype->isValue()); - QVERIFY(!rtype->isValuePointer()); + QCOMPARE(rtype.package(), QLatin1String("Foo")); + QCOMPARE(rtype.name(), QLatin1String("char")); + QVERIFY(rtype.isConstant()); + QVERIFY(!rtype.isArray()); + QVERIFY(!rtype.isContainer()); + QVERIFY(!rtype.isObject()); + QVERIFY(!rtype.isPrimitive()); // const char* differs from char, so it's not considered a primitive type by apiextractor + QVERIFY(rtype.isNativePointer()); + QCOMPARE(rtype.referenceType(), NoReference); + QVERIFY(!rtype.isValue()); + QVERIFY(!rtype.isValuePointer()); } void TestAbstractMetaType::testApiVersionSupported() @@ -147,20 +147,20 @@ void TestAbstractMetaType::testCharType() AbstractMetaFunctionList functions = builder->globalFunctions(); QCOMPARE(functions.size(), 1); AbstractMetaFunction *func = functions.constFirst(); - AbstractMetaType* rtype = func->type(); + AbstractMetaType rtype = func->type(); // Test properties of const char* QVERIFY(rtype); - QCOMPARE(rtype->package(), QLatin1String("Foo")); - QCOMPARE(rtype->name(), QLatin1String("char")); - QVERIFY(!rtype->isConstant()); - QVERIFY(!rtype->isArray()); - QVERIFY(!rtype->isContainer()); - QVERIFY(!rtype->isObject()); - QVERIFY(rtype->isPrimitive()); - QVERIFY(!rtype->isNativePointer()); - QCOMPARE(rtype->referenceType(), NoReference); - QVERIFY(!rtype->isValue()); - QVERIFY(!rtype->isValuePointer()); + QCOMPARE(rtype.package(), QLatin1String("Foo")); + QCOMPARE(rtype.name(), QLatin1String("char")); + QVERIFY(!rtype.isConstant()); + QVERIFY(!rtype.isArray()); + QVERIFY(!rtype.isContainer()); + QVERIFY(!rtype.isObject()); + QVERIFY(rtype.isPrimitive()); + QVERIFY(!rtype.isNativePointer()); + QCOMPARE(rtype.referenceType(), NoReference); + QVERIFY(!rtype.isValue()); + QVERIFY(!rtype.isValuePointer()); } void TestAbstractMetaType::testTypedef() @@ -210,8 +210,8 @@ void TestAbstractMetaType::testTypedefWithTemplates() AbstractMetaArgumentList args = function->arguments(); QCOMPARE(args.count(), 1); AbstractMetaArgument *arg = args.constFirst(); - AbstractMetaType* metaType = arg->type(); - QCOMPARE(metaType->cppSignature(), QLatin1String("A")); + AbstractMetaType metaType = arg->type(); + QCOMPARE(metaType.cppSignature(), QLatin1String("A")); } @@ -238,10 +238,10 @@ void TestAbstractMetaType::testObjectTypeUsedAsValue() AbstractMetaArgumentList args = method->arguments(); QCOMPARE(args.count(), 1); AbstractMetaArgument* arg = args.constFirst(); - AbstractMetaType* metaType = arg->type(); - QCOMPARE(metaType->cppSignature(), QLatin1String("A")); - QVERIFY(metaType->isValue()); - QVERIFY(metaType->typeEntry()->isObject()); + AbstractMetaType metaType = arg->type(); + QCOMPARE(metaType.cppSignature(), QLatin1String("A")); + QVERIFY(metaType.isValue()); + QVERIFY(metaType.typeEntry()->isObject()); } QTEST_APPLESS_MAIN(TestAbstractMetaType) diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp index 46307f94c..4289b4e49 100644 --- a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp @@ -112,13 +112,13 @@ struct A { QVERIFY(!addedFunc->isSlot()); QVERIFY(!addedFunc->isStatic()); - AbstractMetaType* returnType = addedFunc->type(); - QCOMPARE(returnType->typeEntry(), typeDb->findPrimitiveType(QLatin1String("int"))); + AbstractMetaType returnType = addedFunc->type(); + QCOMPARE(returnType.typeEntry(), typeDb->findPrimitiveType(QLatin1String("int"))); AbstractMetaArgumentList args = addedFunc->arguments(); QCOMPARE(args.count(), 3); - QCOMPARE(args[0]->type()->typeEntry(), returnType->typeEntry()); + QCOMPARE(args[0]->type().typeEntry(), returnType.typeEntry()); QCOMPARE(args[1]->defaultValueExpression(), QLatin1String("4.6")); - QCOMPARE(args[2]->type()->typeEntry(), typeDb->findType(QLatin1String("B"))); + QCOMPARE(args[2]->type().typeEntry(), typeDb->findType(QLatin1String("B"))); auto addedCallOperator = classA->findFunction(QLatin1String("operator()")); QVERIFY(addedCallOperator); @@ -313,8 +313,8 @@ void TestAddFunction::testAddFunctionWithVarargs() const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("func")); QVERIFY(addedFunc); const AbstractMetaArgument *arg = addedFunc->arguments().constLast(); - QVERIFY(arg->type()->isVarargs()); - QVERIFY(arg->type()->typeEntry()->isVarargs()); + QVERIFY(arg->type().isVarargs()); + QVERIFY(arg->type().typeEntry()->isVarargs()); } void TestAddFunction::testAddStaticFunction() @@ -460,7 +460,7 @@ void TestAddFunction::testAddFunctionWithTemplateArg() QCOMPARE(builder->globalFunctions().size(), 1); AbstractMetaFunction *func = builder->globalFunctions().constFirst(); AbstractMetaArgument *arg = func->arguments().constFirst(); - QCOMPARE(arg->type()->instantiations().count(), 1); + QCOMPARE(arg->type().instantiations().count(), 1); } QTEST_APPLESS_MAIN(TestAddFunction) diff --git a/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp b/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp index b7b5ead17..ab05802b3 100644 --- a/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp @@ -53,9 +53,9 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByInteger() QVERIFY(classA); const AbstractMetaArgument *arg = classA->functions().constLast()->arguments().constFirst(); - QVERIFY(arg->type()->isArray()); - QCOMPARE(arg->type()->arrayElementCount(), 3); - QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double")); + QVERIFY(arg->type().isArray()); + QCOMPARE(arg->type().arrayElementCount(), 3); + QCOMPARE(arg->type().arrayElementType()->name(), QLatin1String("double")); } static QString functionMinimalSignature(const AbstractMetaClass *c, const QString &name) @@ -132,9 +132,9 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValue() QVERIFY(nvalues); const AbstractMetaArgument *arg = classA->functions().constLast()->arguments().constFirst(); - QVERIFY(arg->type()->isArray()); - QCOMPARE(arg->type()->arrayElementCount(), nvalues->value().value()); - QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double")); + QVERIFY(arg->type().isArray()); + QCOMPARE(arg->type().arrayElementCount(), nvalues->value().value()); + QCOMPARE(arg->type().arrayElementType()->name(), QLatin1String("double")); }; void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnum() @@ -163,9 +163,9 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnu QVERIFY(nvalues); const AbstractMetaArgument *arg = classA->functions().constLast()->arguments().constFirst(); - QVERIFY(arg->type()->isArray()); - QCOMPARE(arg->type()->arrayElementCount(), nvalues->value().value()); - QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double")); + QVERIFY(arg->type().isArray()); + QCOMPARE(arg->type().arrayElementCount(), nvalues->value().value()); + QCOMPARE(arg->type().arrayElementType()->name(), QLatin1String("double")); }; QTEST_APPLESS_MAIN(TestArrayArgument) diff --git a/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp b/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp index 0da16924a..3c33c7d1e 100644 --- a/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp @@ -91,17 +91,17 @@ void TestContainer::testListOfValueType() const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); QVERIFY(classA); QCOMPARE(classA->templateBaseClassInstantiations().count(), 1); - const AbstractMetaType *templateInstanceType = + const AbstractMetaType templateInstanceType = classA->templateBaseClassInstantiations().constFirst(); QVERIFY(templateInstanceType); - QCOMPARE(templateInstanceType->indirections(), 0); - QVERIFY(!templateInstanceType->typeEntry()->isObject()); - QVERIFY(templateInstanceType->typeEntry()->isValue()); - QCOMPARE(templateInstanceType->referenceType(), NoReference); - QVERIFY(!templateInstanceType->isObject()); - QVERIFY(!templateInstanceType->isValuePointer()); - QVERIFY(templateInstanceType->isValue()); + QCOMPARE(templateInstanceType.indirections(), 0); + QVERIFY(!templateInstanceType.typeEntry()->isObject()); + QVERIFY(templateInstanceType.typeEntry()->isValue()); + QCOMPARE(templateInstanceType.referenceType(), NoReference); + QVERIFY(!templateInstanceType.isObject()); + QVERIFY(!templateInstanceType.isValuePointer()); + QVERIFY(templateInstanceType.isValue()); } QTEST_APPLESS_MAIN(TestContainer) diff --git a/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp b/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp index 2af427294..8e4eebcb5 100644 --- a/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp @@ -148,12 +148,12 @@ void TestConversionOperator::testConversionOperatorReturningReference() QCOMPARE(classA->functions().count(), 2); QCOMPARE(classB->functions().count(), 3); QCOMPARE(classA->externalConversionOperators().count(), 1); - QCOMPARE(classA->externalConversionOperators().constFirst()->type()->cppSignature(), + QCOMPARE(classA->externalConversionOperators().constFirst()->type().cppSignature(), QLatin1String("A")); QCOMPARE(classA->externalConversionOperators().constFirst()->ownerClass()->name(), QLatin1String("B")); QCOMPARE(classA->implicitConversions().count(), 1); - QCOMPARE(classA->implicitConversions().constFirst()->type()->cppSignature(), + QCOMPARE(classA->implicitConversions().constFirst()->type().cppSignature(), QLatin1String("A")); QCOMPARE(classA->implicitConversions().constFirst()->ownerClass()->name(), QLatin1String("B")); @@ -182,12 +182,12 @@ void TestConversionOperator::testConversionOperatorReturningConstReference() QCOMPARE(classA->functions().count(), 2); QCOMPARE(classB->functions().count(), 3); QCOMPARE(classA->externalConversionOperators().count(), 1); - QCOMPARE(classA->externalConversionOperators().constFirst()->type()->cppSignature(), + QCOMPARE(classA->externalConversionOperators().constFirst()->type().cppSignature(), QLatin1String("A")); QCOMPARE(classA->externalConversionOperators().constFirst()->ownerClass()->name(), QLatin1String("B")); QCOMPARE(classA->implicitConversions().count(), 1); - QCOMPARE(classA->implicitConversions().constFirst()->type()->cppSignature(), + QCOMPARE(classA->implicitConversions().constFirst()->type().cppSignature(), QLatin1String("A")); QCOMPARE(classA->implicitConversions().constFirst()->ownerClass()->name(), QLatin1String("B")); diff --git a/sources/shiboken2/ApiExtractor/tests/testenum.cpp b/sources/shiboken2/ApiExtractor/tests/testenum.cpp index 82cdd291c..607a8f627 100644 --- a/sources/shiboken2/ApiExtractor/tests/testenum.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testenum.cpp @@ -64,7 +64,7 @@ void TestEnum::testEnumCppSignature() AbstractMetaFunctionList functions = builder->globalFunctions(); QCOMPARE(functions.count(), 1); QCOMPARE(functions.constFirst()->arguments().count(), 1); - QCOMPARE(functions.constFirst()->arguments().constFirst()->type()->cppSignature(), + QCOMPARE(functions.constFirst()->arguments().constFirst()->type().cppSignature(), QLatin1String("A::ClassEnum")); // enum as parameter of a method @@ -75,12 +75,12 @@ void TestEnum::testEnumCppSignature() AbstractMetaFunction *method = funcs.constFirst(); QVERIFY(method); AbstractMetaArgument *arg = method->arguments().constFirst(); - QCOMPARE(arg->type()->name(), QLatin1String("ClassEnum")); - QCOMPARE(arg->type()->cppSignature(), QLatin1String("A::ClassEnum")); + QCOMPARE(arg->type().name(), QLatin1String("ClassEnum")); + QCOMPARE(arg->type().cppSignature(), QLatin1String("A::ClassEnum")); QCOMPARE(functions.constFirst()->arguments().count(), 1); arg = functions.constFirst()->arguments().constFirst(); - QCOMPARE(arg->type()->name(), QLatin1String("ClassEnum")); - QCOMPARE(arg->type()->cppSignature(), QLatin1String("A::ClassEnum")); + QCOMPARE(arg->type().name(), QLatin1String("ClassEnum")); + QCOMPARE(arg->type().cppSignature(), QLatin1String("A::ClassEnum")); AbstractMetaEnumList classEnums = classA->enums(); QCOMPARE(classEnums.constFirst()->name(), QLatin1String("ClassEnum")); diff --git a/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp b/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp index f960fca2f..a48298bf7 100644 --- a/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp @@ -59,7 +59,7 @@ void TestImplicitConversions::testWithPrivateCtors() const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, QLatin1String("C")); AbstractMetaFunctionList implicitConvs = classA->implicitConversions(); QCOMPARE(implicitConvs.count(), 1); - QCOMPARE(implicitConvs.constFirst()->arguments().constFirst()->type()->typeEntry(), + QCOMPARE(implicitConvs.constFirst()->arguments().constFirst()->type().typeEntry(), classC->typeEntry()); } @@ -89,7 +89,7 @@ void TestImplicitConversions::testWithModifiedVisibility() const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); AbstractMetaFunctionList implicitConvs = classA->implicitConversions(); QCOMPARE(implicitConvs.count(), 1); - QCOMPARE(implicitConvs.constFirst()->arguments().constFirst()->type()->typeEntry(), + QCOMPARE(implicitConvs.constFirst()->arguments().constFirst()->type().typeEntry(), classB->typeEntry()); } diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp index 77bc6b5c9..cca0370e6 100644 --- a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp @@ -312,7 +312,7 @@ void TestModifyFunction::testGlobalFunctionModification() QVERIFY(func); QCOMPARE(func->arguments().count(), 1); const AbstractMetaArgument *arg = func->arguments().constFirst(); - QCOMPARE(arg->type()->cppSignature(), QLatin1String("A *")); + QCOMPARE(arg->type().cppSignature(), QLatin1String("A *")); QCOMPARE(arg->originalDefaultValueExpression(), QLatin1String("0")); QCOMPARE(arg->defaultValueExpression(), QLatin1String("A()")); } diff --git a/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp b/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp index 446c6f431..43d4b2f33 100644 --- a/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp @@ -75,7 +75,8 @@ void TestNestedTypes::testNestedTypesModifications() QVERIFY(addedFunc->isUserAdded()); QCOMPARE(addedFunc->visibility(), AbstractMetaFunction::Public); QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction); - QCOMPARE(addedFunc->type()->minimalSignature(), QLatin1String("OuterNamespace::InnerNamespace::SomeClass")); + QCOMPARE(addedFunc->type().minimalSignature(), + QLatin1String("OuterNamespace::InnerNamespace::SomeClass")); QCOMPARE(addedFunc->modifications().size(), 1); QVERIFY(addedFunc->modifications().constFirst().isCodeInjection()); diff --git a/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp b/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp index 03129073a..ab91e2c3b 100644 --- a/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp @@ -60,17 +60,17 @@ void TestNumericalTypedef::testNumericalTypedef() QCOMPARE(funcDouble->minimalSignature(), QLatin1String("funcDouble(double)")); QCOMPARE(funcReal->minimalSignature(), QLatin1String("funcReal(real)")); - const AbstractMetaType *doubleType = funcDouble->arguments().constFirst()->type(); + const AbstractMetaType doubleType = funcDouble->arguments().constFirst()->type(); QVERIFY(doubleType); - QCOMPARE(doubleType->cppSignature(), QLatin1String("double")); - QVERIFY(doubleType->isPrimitive()); - QVERIFY(doubleType->typeEntry()->isCppPrimitive()); + QCOMPARE(doubleType.cppSignature(), QLatin1String("double")); + QVERIFY(doubleType.isPrimitive()); + QVERIFY(doubleType.typeEntry()->isCppPrimitive()); - const AbstractMetaType *realType = funcReal->arguments().constFirst()->type(); + const AbstractMetaType realType = funcReal->arguments().constFirst()->type(); QVERIFY(realType); - QCOMPARE(realType->cppSignature(), QLatin1String("real")); - QVERIFY(realType->isPrimitive()); - QVERIFY(realType->typeEntry()->isCppPrimitive()); + QCOMPARE(realType.cppSignature(), QLatin1String("real")); + QVERIFY(realType.isPrimitive()); + QVERIFY(realType.typeEntry()->isCppPrimitive()); } void TestNumericalTypedef::testUnsignedNumericalTypedef() @@ -102,17 +102,17 @@ void TestNumericalTypedef::testUnsignedNumericalTypedef() QCOMPARE(funcUnsignedShort->minimalSignature(), QLatin1String("funcUnsignedShort(unsigned short)")); QCOMPARE(funcUShort->minimalSignature(), QLatin1String("funcUShort(custom_ushort)")); - const AbstractMetaType *unsignedShortType = funcUnsignedShort->arguments().constFirst()->type(); + const AbstractMetaType unsignedShortType = funcUnsignedShort->arguments().constFirst()->type(); QVERIFY(unsignedShortType); - QCOMPARE(unsignedShortType->cppSignature(), QLatin1String("unsigned short")); - QVERIFY(unsignedShortType->isPrimitive()); - QVERIFY(unsignedShortType->typeEntry()->isCppPrimitive()); + QCOMPARE(unsignedShortType.cppSignature(), QLatin1String("unsigned short")); + QVERIFY(unsignedShortType.isPrimitive()); + QVERIFY(unsignedShortType.typeEntry()->isCppPrimitive()); - const AbstractMetaType *ushortType = funcUShort->arguments().constFirst()->type(); + const AbstractMetaType ushortType = funcUShort->arguments().constFirst()->type(); QVERIFY(ushortType); - QCOMPARE(ushortType->cppSignature(), QLatin1String("custom_ushort")); - QVERIFY(ushortType->isPrimitive()); - QVERIFY(ushortType->typeEntry()->isCppPrimitive()); + QCOMPARE(ushortType.cppSignature(), QLatin1String("custom_ushort")); + QVERIFY(ushortType.isPrimitive()); + QVERIFY(ushortType.typeEntry()->isCppPrimitive()); } QTEST_APPLESS_MAIN(TestNumericalTypedef) diff --git a/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp b/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp index 228bfaecd..b9997b90e 100644 --- a/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp @@ -51,7 +51,7 @@ void TestReferenceToPointer::testReferenceToPointerArgument() QVERIFY(classB); const AbstractMetaFunction* func = classB->findFunction(QLatin1String("dummy")); QVERIFY(func); - QCOMPARE(func->arguments().constFirst()->type()->minimalSignature(), QLatin1String("A*&")); + QCOMPARE(func->arguments().constFirst()->type().minimalSignature(), QLatin1String("A*&")); } QTEST_APPLESS_MAIN(TestReferenceToPointer) diff --git a/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp b/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp index 20170089a..e3ea3cbb0 100644 --- a/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp @@ -63,7 +63,7 @@ void TestRemoveImplConv::testRemoveImplConv() QVERIFY(classC); AbstractMetaFunctionList implConv = classC->implicitConversions(); QCOMPARE(implConv.count(), 1); - QCOMPARE(implConv.constFirst()->arguments().constFirst()->type()->typeEntry(), + QCOMPARE(implConv.constFirst()->arguments().constFirst()->type().typeEntry(), classB->typeEntry()); } diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp index f6c70a651..217b31256 100644 --- a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp @@ -76,9 +76,9 @@ namespace Internet { AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("Bookmarks")); QVERIFY(classB); const AbstractMetaFunction* func = classB->findFunction(QLatin1String("list")); - AbstractMetaType* funcType = func->type(); + AbstractMetaType funcType = func->type(); QVERIFY(funcType); - QCOMPARE(funcType->cppSignature(), QLatin1String("QList")); + QCOMPARE(funcType.cppSignature(), QLatin1String("QList")); } void TestTemplates::testTemplateOnContainers() @@ -115,17 +115,17 @@ namespace Namespace { QVERIFY(!classB->baseClass()); QVERIFY(classB->baseClassName().isEmpty()); const AbstractMetaFunction* func = classB->findFunction(QLatin1String("foo")); - AbstractMetaType* argType = func->arguments().constFirst()->type(); - QCOMPARE(argType->instantiations().count(), 1); - QCOMPARE(argType->typeEntry()->qualifiedCppName(), QLatin1String("QList")); + AbstractMetaType argType = func->arguments().constFirst()->type(); + QCOMPARE(argType.instantiations().count(), 1); + QCOMPARE(argType.typeEntry()->qualifiedCppName(), QLatin1String("QList")); - const AbstractMetaType* instance1 = argType->instantiations().constFirst(); - QCOMPARE(instance1->instantiations().count(), 1); - QCOMPARE(instance1->typeEntry()->qualifiedCppName(), QLatin1String("Namespace::A")); + const AbstractMetaType &instance1 = argType.instantiations().constFirst(); + QCOMPARE(instance1.instantiations().count(), 1); + QCOMPARE(instance1.typeEntry()->qualifiedCppName(), QLatin1String("Namespace::A")); - const AbstractMetaType* instance2 = instance1->instantiations().constFirst(); - QCOMPARE(instance2->instantiations().count(), 0); - QCOMPARE(instance2->typeEntry()->qualifiedCppName(), QLatin1String("Namespace::E1")); + const AbstractMetaType &instance2 = instance1.instantiations().constFirst(); + QCOMPARE(instance2.instantiations().count(), 0); + QCOMPARE(instance2.typeEntry()->qualifiedCppName(), QLatin1String("Namespace::E1")); } void TestTemplates::testTemplateValueAsArgument() @@ -149,7 +149,7 @@ void func(List arg) {} AbstractMetaFunction *func = globalFuncs.constFirst(); QCOMPARE(func->minimalSignature(), QLatin1String("func(List)")); - QCOMPARE(func->arguments().constFirst()->type()->cppSignature(), + QCOMPARE(func->arguments().constFirst()->type().cppSignature(), QLatin1String("List")); } @@ -174,7 +174,7 @@ void func(List* arg) {} AbstractMetaFunction* func = globalFuncs.constFirst(); QCOMPARE(func->minimalSignature(), QLatin1String("func(List*)")); - QCOMPARE(func->arguments().constFirst()->type()->cppSignature(), + QCOMPARE(func->arguments().constFirst()->type().cppSignature(), QLatin1String("List *")); } @@ -199,7 +199,7 @@ void func(List& arg) {} AbstractMetaFunction* func = globalFuncs.constFirst(); QCOMPARE(func->minimalSignature(), QLatin1String("func(List&)")); - QCOMPARE(func->arguments().constFirst()->type()->cppSignature(), + QCOMPARE(func->arguments().constFirst()->type().cppSignature(), QLatin1String("List &")); } @@ -231,13 +231,13 @@ struct List { const AbstractMetaFunction *append = list->findFunction(QStringLiteral("append")); QVERIFY(append); QCOMPARE(append->arguments().size(), 1); - QCOMPARE(append->arguments().at(0)->type()->cppSignature(), QLatin1String("List")); + QCOMPARE(append->arguments().at(0)->type().cppSignature(), QLatin1String("List")); // Verify that the parameter of "void erase(Iterator)" is not modified const AbstractMetaFunction *erase = list->findFunction(QStringLiteral("erase")); QVERIFY(erase); QCOMPARE(erase->arguments().size(), 1); QEXPECT_FAIL("", "Clang: Some other code changes the parameter type", Abort); - QCOMPARE(erase->arguments().at(0)->type()->cppSignature(), QLatin1String("List::Iterator")); + QCOMPARE(erase->arguments().at(0)->type().cppSignature(), QLatin1String("List::Iterator")); } void TestTemplates::testInheritanceFromContainterTemplate() @@ -394,12 +394,12 @@ typedef BaseTemplateClass TypeOneClass; QVERIFY(one->hasTemplateBaseClassInstantiations()); AbstractMetaTypeList instantiations = one->templateBaseClassInstantiations(); QCOMPARE(instantiations.count(), 1); - const AbstractMetaType *inst = instantiations.constFirst(); + const AbstractMetaType &inst = instantiations.constFirst(); QVERIFY(inst); - QVERIFY(!inst->isEnum()); - QVERIFY(!inst->typeEntry()->isEnum()); - QVERIFY(inst->typeEntry()->isEnumValue()); - QCOMPARE(inst->cppSignature(), QLatin1String("NSpace::TypeOne")); + QVERIFY(!inst.isEnum()); + QVERIFY(!inst.typeEntry()->isEnum()); + QVERIFY(inst.typeEntry()->isEnumValue()); + QCOMPARE(inst.cppSignature(), QLatin1String("NSpace::TypeOne")); } void TestTemplates::testContainerTypeIncompleteArgument() @@ -445,7 +445,7 @@ typedef Vector IntVector; QVERIFY(otherMethod); QCOMPARE(otherMethod->signature(), QLatin1String("otherMethod()")); QVERIFY(otherMethod->type()); - QCOMPARE(otherMethod->type()->cppSignature(), QLatin1String("Vector")); + QCOMPARE(otherMethod->type().cppSignature(), QLatin1String("Vector")); } void TestTemplates::testNonTypeTemplates() @@ -474,7 +474,7 @@ Array foo(); QCOMPARE(functions.count(), 1); auto foo = functions.constFirst(); QCOMPARE(foo->name(), QLatin1String("foo")); - QCOMPARE(foo->type()->name(), QLatin1String("Array")); + QCOMPARE(foo->type().name(), QLatin1String("Array")); } // Perform checks on template inheritance; a typedef of a template class @@ -574,25 +574,25 @@ void TestTemplates::testTemplateTypeDefs() const AbstractMetaFunction *valueMethod = optionalInt->findFunction(QLatin1String("value")); QVERIFY(valueMethod); - QCOMPARE(valueMethod->type()->cppSignature(), QLatin1String("int")); + QCOMPARE(valueMethod->type().cppSignature(), QLatin1String("int")); // ditto for typesystem XML const AbstractMetaFunction *xmlValueMethod = xmlOptionalInt->findFunction(QLatin1String("value")); QVERIFY(xmlValueMethod); - QCOMPARE(xmlValueMethod->type()->cppSignature(), QLatin1String("int")); + QCOMPARE(xmlValueMethod->type().cppSignature(), QLatin1String("int")); // Check whether the m_value field is of type 'int' const AbstractMetaField *valueField = optionalInt->findField(QLatin1String("m_value")); QVERIFY(valueField); - QCOMPARE(valueField->type()->cppSignature(), QLatin1String("int")); + QCOMPARE(valueField->type().cppSignature(), QLatin1String("int")); // ditto for typesystem XML const AbstractMetaField *xmlValueField = xmlOptionalInt->findField(QLatin1String("m_value")); QVERIFY(xmlValueField); - QCOMPARE(xmlValueField->type()->cppSignature(), QLatin1String("int")); + QCOMPARE(xmlValueField->type().cppSignature(), QLatin1String("int")); } void TestTemplates::testTemplateTypeAliases() @@ -635,8 +635,8 @@ public: auto fields = testClass->fields(); QCOMPARE(fields.count(), 1); auto fieldType = testClass->fields().at(0)->type(); - QCOMPARE(fieldType->name(), QLatin1String("Container1")); - QCOMPARE(fieldType->instantiations().size(), 1); + QCOMPARE(fieldType.name(), QLatin1String("Container1")); + QCOMPARE(fieldType.instantiations().size(), 1); auto derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived")); QVERIFY(derived); diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp index 2418f51fe..94b0f93b2 100644 --- a/sources/shiboken2/generator/generator.cpp +++ b/sources/shiboken2/generator/generator.cpp @@ -155,7 +155,7 @@ QString DefaultValue::constructorParameter() const QString GeneratorContext::smartPointerWrapperName() const { Q_ASSERT(m_type == SmartPointer); - return m_preciseClassType->cppSignature(); + return m_preciseClassType.cppSignature(); } struct Generator::GeneratorPrivate @@ -166,8 +166,8 @@ struct Generator::GeneratorPrivate QString licenseComment; QString moduleName; QStringList instantiatedContainersNames; - QVector instantiatedContainers; - QVector instantiatedSmartPointers; + QVector instantiatedContainers; + QVector instantiatedSmartPointers; AbstractMetaClassList m_invisibleTopNamespaces; }; @@ -203,15 +203,15 @@ bool Generator::setup(const ApiExtractor &extractor) return doSetup(); } -QString Generator::getSimplifiedContainerTypeName(const AbstractMetaType *type) +QString Generator::getSimplifiedContainerTypeName(const AbstractMetaType &type) { - const QString signature = type->cppSignature(); - if (!type->typeEntry()->isContainer() && !type->typeEntry()->isSmartPointer()) + const QString signature = type.cppSignature(); + if (!type.typeEntry()->isContainer() && !type.typeEntry()->isSmartPointer()) return signature; QString typeName = signature; - if (type->isConstant()) + if (type.isConstant()) typeName.remove(0, sizeof("const ") / sizeof(char) - 1); - switch (type->referenceType()) { + switch (type.referenceType()) { case NoReference: break; case LValueReference: @@ -227,48 +227,46 @@ QString Generator::getSimplifiedContainerTypeName(const AbstractMetaType *type) } // Strip a "const QSharedPtr &" or similar to "QSharedPtr" (PYSIDE-1016/454) -const AbstractMetaType *canonicalSmartPtrInstantiation(const AbstractMetaType *type) +AbstractMetaType canonicalSmartPtrInstantiation(const AbstractMetaType &type) { - const AbstractMetaTypeList &instantiations = type->instantiations(); + const AbstractMetaTypeList &instantiations = type.instantiations(); Q_ASSERT(instantiations.size() == 1); - const bool needsFix = type->isConstant() || type->referenceType() != NoReference; - const bool pointeeNeedsFix = instantiations.constFirst()->isConstant(); + const bool needsFix = type.isConstant() || type.referenceType() != NoReference; + const bool pointeeNeedsFix = instantiations.constFirst().isConstant(); if (!needsFix && !pointeeNeedsFix) return type; - auto fixedType = type->copy(); - fixedType->setReferenceType(NoReference); - fixedType->setConstant(false); + auto fixedType = type; + fixedType.setReferenceType(NoReference); + fixedType.setConstant(false); if (pointeeNeedsFix) { - auto fixedPointeeType = instantiations.constFirst()->copy(); - fixedPointeeType->setConstant(false); - fixedType->setInstantiations(AbstractMetaTypeList(1, fixedPointeeType)); + auto fixedPointeeType = instantiations.constFirst(); + fixedPointeeType.setConstant(false); + fixedType.setInstantiations(AbstractMetaTypeList(1, fixedPointeeType)); } return fixedType; } -static inline const TypeEntry *pointeeTypeEntry(const AbstractMetaType *smartPtrType) +static inline const TypeEntry *pointeeTypeEntry(const AbstractMetaType &smartPtrType) { - return smartPtrType->instantiations().constFirst()->typeEntry(); + return smartPtrType.instantiations().constFirst().typeEntry(); } -void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType *type, +void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType &type, const QString &context) { - if (!type) - return; - for (const auto *t : type->instantiations()) + for (const auto &t : type.instantiations()) addInstantiatedContainersAndSmartPointers(t, context); - const auto typeEntry = type->typeEntry(); + const auto typeEntry = type.typeEntry(); const bool isContainer = typeEntry->isContainer(); if (!isContainer && !(typeEntry->isSmartPointer() && typeEntry->generateCode())) { return; } - if (type->hasTemplateChildren()) { + if (type.hasTemplateChildren()) { QString piece = isContainer ? QStringLiteral("container") : QStringLiteral("smart pointer"); QString warning = QString::fromLatin1("Skipping instantiation of %1 '%2' because it has template" - " arguments.").arg(piece, type->originalTypeDescription()); + " arguments.").arg(piece, type.originalTypeDescription()); if (!context.isEmpty()) warning.append(QStringLiteral(" Calling context: %1").arg(context)); @@ -287,7 +285,7 @@ void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType auto pt = pointeeTypeEntry(type); const bool present = std::any_of(m_d->instantiatedSmartPointers.cbegin(), m_d->instantiatedSmartPointers.cend(), - [pt] (const AbstractMetaType *t) { + [pt] (const AbstractMetaType &t) { return pointeeTypeEntry(t) == pt; }); if (!present) @@ -327,12 +325,12 @@ void Generator::collectInstantiatedContainersAndSmartPointers() collectInstantiatedContainersAndSmartPointers(metaClass); } -QVector Generator::instantiatedContainers() const +QVector Generator::instantiatedContainers() const { return m_d->instantiatedContainers; } -QVector Generator::instantiatedSmartPointers() const +QVector Generator::instantiatedSmartPointers() const { return m_d->instantiatedSmartPointers; } @@ -387,9 +385,9 @@ const AbstractMetaEnum *Generator::findAbstractMetaEnum(const TypeEntry *typeEnt return m_d->apiextractor->findAbstractMetaEnum(typeEntry); } -const AbstractMetaEnum *Generator::findAbstractMetaEnum(const AbstractMetaType *metaType) const +const AbstractMetaEnum *Generator::findAbstractMetaEnum(const AbstractMetaType &metaType) const { - return m_d->apiextractor->findAbstractMetaEnum(metaType->typeEntry()); + return m_d->apiextractor->findAbstractMetaEnum(metaType.typeEntry()); } QString Generator::licenseComment() const @@ -446,14 +444,14 @@ bool Generator::generateFileForContext(const GeneratorContext &context) return fileOut.done() != FileOut::Failure; } -QString Generator::getFileNameBaseForSmartPointer(const AbstractMetaType *smartPointerType, +QString Generator::getFileNameBaseForSmartPointer(const AbstractMetaType &smartPointerType, const AbstractMetaClass *smartPointerClass) const { - const AbstractMetaType *innerType = smartPointerType->getSmartPointerInnerType(); + const AbstractMetaType innerType = smartPointerType.getSmartPointerInnerType(); QString fileName = smartPointerClass->qualifiedCppName().toLower(); fileName.replace(QLatin1String("::"), QLatin1String("_")); fileName.append(QLatin1String("_")); - fileName.append(innerType->name().toLower()); + fileName.append(innerType.name().toLower()); return fileName; } @@ -466,7 +464,7 @@ GeneratorContext Generator::contextForClass(const AbstractMetaClass *c) const } GeneratorContext Generator::contextForSmartPointer(const AbstractMetaClass *c, - const AbstractMetaType *t) const + const AbstractMetaType &t) const { GeneratorContext result; result.m_metaClass = c; @@ -484,12 +482,12 @@ bool Generator::generate() } const auto smartPointers = m_d->apiextractor->smartPointers(); - for (const AbstractMetaType *type : qAsConst(m_d->instantiatedSmartPointers)) { + for (const AbstractMetaType &type : qAsConst(m_d->instantiatedSmartPointers)) { AbstractMetaClass *smartPointerClass = - AbstractMetaClass::findClass(smartPointers, type->typeEntry()); + AbstractMetaClass::findClass(smartPointers, type.typeEntry()); if (!smartPointerClass) { qCWarning(lcShiboken, "%s", - qPrintable(msgCannotFindSmartPointer(type->cppSignature(), + qPrintable(msgCannotFindSmartPointer(type.cppSignature(), smartPointers))); return false; } @@ -570,9 +568,9 @@ AbstractMetaFunctionList Generator::implicitConversions(const TypeEntry *type) c return AbstractMetaFunctionList(); } -AbstractMetaFunctionList Generator::implicitConversions(const AbstractMetaType *metaType) const +AbstractMetaFunctionList Generator::implicitConversions(const AbstractMetaType &metaType) const { - return implicitConversions(metaType->typeEntry()); + return implicitConversions(metaType.typeEntry()); } bool Generator::isObjectType(const TypeEntry *type) @@ -589,30 +587,30 @@ bool Generator::isObjectType(const AbstractMetaClass *metaClass) { return Generator::isObjectType(metaClass->typeEntry()); } -bool Generator::isObjectType(const AbstractMetaType *metaType) +bool Generator::isObjectType(const AbstractMetaType &metaType) { - return isObjectType(metaType->typeEntry()); + return isObjectType(metaType.typeEntry()); } -bool Generator::isPointer(const AbstractMetaType *type) +bool Generator::isPointer(const AbstractMetaType &type) { - return type->indirections() > 0 - || type->isNativePointer() - || type->isValuePointer(); + return type.indirections() > 0 + || type.isNativePointer() + || type.isValuePointer(); } -bool Generator::isCString(const AbstractMetaType *type) +bool Generator::isCString(const AbstractMetaType &type) { - return type->isNativePointer() - && type->indirections() == 1 - && type->name() == QLatin1String("char"); + return type.isNativePointer() + && type.indirections() == 1 + && type.name() == QLatin1String("char"); } -bool Generator::isVoidPointer(const AbstractMetaType *type) +bool Generator::isVoidPointer(const AbstractMetaType &type) { - return type->isNativePointer() - && type->indirections() == 1 - && type->name() == QLatin1String("void"); + return type.isNativePointer() + && type.indirections() == 1 + && type.name() == QLatin1String("void"); } QString Generator::getFullTypeName(const TypeEntry *type) const @@ -625,20 +623,20 @@ QString Generator::getFullTypeName(const TypeEntry *type) const return result; } -QString Generator::getFullTypeName(const AbstractMetaType *type) const +QString Generator::getFullTypeName(const AbstractMetaType &type) const { if (isCString(type)) return QLatin1String("const char*"); if (isVoidPointer(type)) return QLatin1String("void*"); - if (type->typeEntry()->isContainer()) - return QLatin1String("::") + type->cppSignature(); + if (type.typeEntry()->isContainer()) + return QLatin1String("::") + type.cppSignature(); QString typeName; - if (type->typeEntry()->isComplex() && type->hasInstantiations()) + if (type.typeEntry()->isComplex() && type.hasInstantiations()) typeName = getFullTypeNameWithoutModifiers(type); else - typeName = getFullTypeName(type->typeEntry()); - return typeName + QString::fromLatin1("*").repeated(type->indirections()); + typeName = getFullTypeName(type.typeEntry()); + return typeName + QString::fromLatin1("*").repeated(type.indirections()); } QString Generator::getFullTypeName(const AbstractMetaClass *metaClass) const @@ -646,18 +644,18 @@ QString Generator::getFullTypeName(const AbstractMetaClass *metaClass) const return QLatin1String("::") + metaClass->qualifiedCppName(); } -QString Generator::getFullTypeNameWithoutModifiers(const AbstractMetaType *type) const +QString Generator::getFullTypeNameWithoutModifiers(const AbstractMetaType &type) const { if (isCString(type)) return QLatin1String("const char*"); if (isVoidPointer(type)) return QLatin1String("void*"); - if (!type->hasInstantiations()) - return getFullTypeName(type->typeEntry()); - QString typeName = type->cppSignature(); - if (type->isConstant()) + if (!type.hasInstantiations()) + return getFullTypeName(type.typeEntry()); + QString typeName = type.cppSignature(); + if (type.isConstant()) typeName.remove(0, sizeof("const ") / sizeof(char) - 1); - switch (type->referenceType()) { + switch (type.referenceType()) { case NoReference: break; case LValueReference: @@ -672,13 +670,13 @@ QString Generator::getFullTypeNameWithoutModifiers(const AbstractMetaType *type) return QLatin1String("::") + typeName; } -DefaultValue Generator::minimalConstructor(const AbstractMetaType *type) const +DefaultValue Generator::minimalConstructor(const AbstractMetaType &type) const { - if (!type || (type->referenceType() == LValueReference && Generator::isObjectType(type))) + if (type.referenceType() == LValueReference && Generator::isObjectType(type)) return DefaultValue(DefaultValue::Error); - if (type->isContainer()) { - QString ctor = type->cppSignature(); + if (type.isContainer()) { + QString ctor = type.cppSignature(); if (ctor.endsWith(QLatin1Char('*'))) { ctor.chop(1); return DefaultValue(DefaultValue::Pointer, ctor.trimmed()); @@ -692,20 +690,20 @@ DefaultValue Generator::minimalConstructor(const AbstractMetaType *type) const return DefaultValue(DefaultValue::DefaultConstructor, QLatin1String("::") + ctor); } - if (type->isNativePointer()) - return DefaultValue(DefaultValue::Pointer, type->typeEntry()->qualifiedCppName()); + if (type.isNativePointer()) + return DefaultValue(DefaultValue::Pointer, type.typeEntry()->qualifiedCppName()); if (Generator::isPointer(type)) - return DefaultValue(DefaultValue::Pointer, QLatin1String("::") + type->typeEntry()->qualifiedCppName()); + return DefaultValue(DefaultValue::Pointer, QLatin1String("::") + type.typeEntry()->qualifiedCppName()); - if (type->typeEntry()->isSmartPointer()) - return minimalConstructor(type->typeEntry()); + if (type.typeEntry()->isSmartPointer()) + return minimalConstructor(type.typeEntry()); - if (type->typeEntry()->isComplex()) { - auto cType = static_cast(type->typeEntry()); + if (type.typeEntry()->isComplex()) { + auto cType = static_cast(type.typeEntry()); if (cType->hasDefaultConstructor()) return DefaultValue(DefaultValue::Custom, cType->defaultConstructor()); auto ctor = minimalConstructor(AbstractMetaClass::findClass(classes(), cType)); - if (ctor.isValid() && type->hasInstantiations()) { + if (ctor.isValid() && type.hasInstantiations()) { QString v = ctor.value(); v.replace(getFullTypeName(cType), getFullTypeNameWithoutModifiers(type)); ctor.setValue(v); @@ -713,7 +711,7 @@ DefaultValue Generator::minimalConstructor(const AbstractMetaType *type) const return ctor; } - return minimalConstructor(type->typeEntry()); + return minimalConstructor(type.typeEntry()); } DefaultValue Generator::minimalConstructor(const TypeEntry *type) const @@ -802,7 +800,7 @@ DefaultValue Generator::minimalConstructor(const AbstractMetaClass *metaClass) c for (int i = 0, size = arguments.size(); suitable && i < size && !arguments.at(i)->hasOriginalDefaultValueExpression(); ++i) { const AbstractMetaArgument *arg = arguments.at(i); - const TypeEntry *aType = arg->type()->typeEntry(); + const TypeEntry *aType = arg->type().typeEntry(); suitable &= aType != cType; simple &= aType->isCppPrimitive() || aType->isEnum() || isPointer(arg->type()); } @@ -835,11 +833,11 @@ DefaultValue Generator::minimalConstructor(const AbstractMetaClass *metaClass) c } // Should int be used for a (protected) enum when generating the public wrapper? -bool Generator::useEnumAsIntForProtectedHack(const AbstractMetaType *metaType) const +bool Generator::useEnumAsIntForProtectedHack(const AbstractMetaType &metaType) const { - if (metaType->isFlags()) + if (metaType.isFlags()) return true; - if (!metaType->isEnum()) + if (!metaType.isEnum()) return false; const AbstractMetaEnum *metaEnum = findAbstractMetaEnum(metaType); if (!metaEnum) @@ -853,28 +851,28 @@ bool Generator::useEnumAsIntForProtectedHack(const AbstractMetaType *metaType) c return true; } -QString Generator::translateType(const AbstractMetaType *cType, +QString Generator::translateType(AbstractMetaType cType, const AbstractMetaClass *context, Options options) const { QString s; static int constLen = strlen("const"); - if (context && cType && + if (context && context->typeEntry()->isGenericClass() && - cType->originalTemplateType()) { - cType = cType->originalTemplateType(); + cType.originalTemplateType()) { + cType = *cType.originalTemplateType(); } - if (!cType) { + if (cType.isVoid()) { s = QLatin1String("void"); - } else if (cType->isArray()) { - s = translateType(cType->arrayElementType(), context, options) + QLatin1String("[]"); + } else if (cType.isArray()) { + s = translateType(*cType.arrayElementType(), context, options) + QLatin1String("[]"); } else if ((options & Generator::EnumAsInts) && useEnumAsIntForProtectedHack(cType)) { s = intT(); } else { if (options & Generator::OriginalName) { - s = cType->originalTypeDescription().trimmed(); + s = cType.originalTypeDescription().trimmed(); if ((options & Generator::ExcludeReference) && s.endsWith(QLatin1Char('&'))) s.chop(1); @@ -886,20 +884,19 @@ QString Generator::translateType(const AbstractMetaType *cType, s = s.remove(index, constLen); } } else if (options & Generator::ExcludeConst || options & Generator::ExcludeReference) { - AbstractMetaType *copyType = cType->copy(); + AbstractMetaType copyType = cType; if (options & Generator::ExcludeConst) - copyType->setConstant(false); + copyType.setConstant(false); if (options & Generator::ExcludeReference) - copyType->setReferenceType(NoReference); + copyType.setReferenceType(NoReference); - s = copyType->cppSignature(); - if (!copyType->typeEntry()->isVoid() && !copyType->typeEntry()->isCppPrimitive()) + s = copyType.cppSignature(); + if (!copyType.typeEntry()->isVoid() && !copyType.typeEntry()->isCppPrimitive()) s.prepend(QLatin1String("::")); - delete copyType; } else { - s = cType->cppSignature(); + s = cType.cppSignature(); } } @@ -951,16 +948,16 @@ QString getClassTargetFullName(const AbstractMetaEnum *metaEnum, bool includePac return getClassTargetFullName_(metaEnum, includePackageName); } -QString getClassTargetFullName(const AbstractMetaType *metaType, bool includePackageName) +QString getClassTargetFullName(const AbstractMetaType &metaType, bool includePackageName) { - QString name = metaType->cppSignature(); + QString name = metaType.cppSignature(); name.replace(QLatin1String("::"), QLatin1String("_")); name.replace(QLatin1Char('<'), QLatin1Char('_')); name.remove(QLatin1Char('>')); name.remove(QLatin1Char(' ')); if (includePackageName) { name.prepend(QLatin1Char('.')); - name.prepend(metaType->package()); + name.prepend(metaType.package()); } return name; } diff --git a/sources/shiboken2/generator/generator.h b/sources/shiboken2/generator/generator.h index cf6df528f..90470100e 100644 --- a/sources/shiboken2/generator/generator.h +++ b/sources/shiboken2/generator/generator.h @@ -30,7 +30,7 @@ #define GENERATOR_H #include "indentor.h" -#include +#include #include #include #include @@ -61,7 +61,7 @@ void verifyDirectoryFor(const QString &file); QString getClassTargetFullName(const AbstractMetaClass *metaClass, bool includePackageName = true); QString getClassTargetFullName(const AbstractMetaEnum *metaEnum, bool includePackageName = true); -QString getClassTargetFullName(const AbstractMetaType *metaType, bool includePackageName = true); +QString getClassTargetFullName(const AbstractMetaType &metaType, bool includePackageName = true); QString getFilteredCppSignatureString(QString signature); /** @@ -154,7 +154,7 @@ public: GeneratorContext() = default; const AbstractMetaClass *metaClass() const { return m_metaClass; } - const AbstractMetaType *preciseType() const { return m_preciseClassType; } + const AbstractMetaType &preciseType() const { return m_preciseClassType; } bool forSmartPointer() const { return m_type == SmartPointer; } bool useWrapper() const { return m_type == WrappedClass; } @@ -169,7 +169,7 @@ public: private: const AbstractMetaClass *m_metaClass = nullptr; - const AbstractMetaType *m_preciseClassType = nullptr; + AbstractMetaType m_preciseClassType; QString m_wrappername; Type m_type = Class; }; @@ -264,21 +264,21 @@ public: AbstractMetaFunctionList implicitConversions(const TypeEntry *type) const; /// Convenience function for implicitConversions(const TypeEntry *type). - AbstractMetaFunctionList implicitConversions(const AbstractMetaType *metaType) const; + AbstractMetaFunctionList implicitConversions(const AbstractMetaType &metaType) const; /// Check if type is a pointer. - static bool isPointer(const AbstractMetaType *type); + static bool isPointer(const AbstractMetaType &type); /// Tells if the type or class is an Object (or QObject) Type. static bool isObjectType(const TypeEntry *type); static bool isObjectType(const ComplexTypeEntry *type); - static bool isObjectType(const AbstractMetaType *metaType); + static bool isObjectType(const AbstractMetaType &metaType); static bool isObjectType(const AbstractMetaClass *metaClass); /// Returns true if the type is a C string (const char *). - static bool isCString(const AbstractMetaType *type); + static bool isCString(const AbstractMetaType &type); /// Returns true if the type is a void pointer. - static bool isVoidPointer(const AbstractMetaType *type); + static bool isVoidPointer(const AbstractMetaType &type); protected: /// Returns the classes, topologically ordered, used to generate the binding code. @@ -303,17 +303,17 @@ protected: const AbstractMetaEnum *findAbstractMetaEnum(const TypeEntry *typeEntry) const; /// Returns an AbstractMetaEnum for a given AbstractMetaType that holds an EnumTypeEntry, or nullptr if not found. - const AbstractMetaEnum *findAbstractMetaEnum(const AbstractMetaType *metaType) const; + const AbstractMetaEnum *findAbstractMetaEnum(const AbstractMetaType &metaType) const; virtual GeneratorContext contextForClass(const AbstractMetaClass *c) const; GeneratorContext contextForSmartPointer(const AbstractMetaClass *c, - const AbstractMetaType *t) const; + const AbstractMetaType &t) const; /// Generates a file for given AbstractMetaClass or AbstractMetaType (smart pointer case). bool generateFileForContext(const GeneratorContext &context); /// Returns the file base name for a smart pointer. - QString getFileNameBaseForSmartPointer(const AbstractMetaType *smartPointerType, + QString getFileNameBaseForSmartPointer(const AbstractMetaType &smartPointerType, const AbstractMetaClass *smartPointerClass) const; /// Returns true if the generator should generate any code for the TypeEntry. @@ -332,7 +332,7 @@ protected: * \param option some extra options * \return the metatype translated to binding source format */ - QString translateType(const AbstractMetaType *metatype, + QString translateType(AbstractMetaType metatype, const AbstractMetaClass *context, Options options = NoOption) const; @@ -360,7 +360,7 @@ protected: // Returns the full name of the type. QString getFullTypeName(const TypeEntry *type) const; - QString getFullTypeName(const AbstractMetaType *type) const; + QString getFullTypeName(const AbstractMetaType &type) const; QString getFullTypeName(const AbstractMetaClass *metaClass) const; /** @@ -368,7 +368,7 @@ protected: * as 'const', '&', and '*' (except if the class is not derived from a template). * This is useful for instantiated templates. */ - QString getFullTypeNameWithoutModifiers(const AbstractMetaType *type) const; + QString getFullTypeNameWithoutModifiers(const AbstractMetaType &type) const; /** * Tries to build a minimal constructor for the type. @@ -376,7 +376,7 @@ protected: * Returns a null string if it fails. */ DefaultValue minimalConstructor(const TypeEntry *type) const; - DefaultValue minimalConstructor(const AbstractMetaType *type) const; + DefaultValue minimalConstructor(const AbstractMetaType &type) const; DefaultValue minimalConstructor(const AbstractMetaClass *metaClass) const; /** @@ -411,15 +411,15 @@ protected: */ virtual QString subDirectoryForPackage(QString packageName = QString()) const; - QVector instantiatedContainers() const; - QVector instantiatedSmartPointers() const; + QVector instantiatedContainers() const; + QVector instantiatedSmartPointers() const; - static QString getSimplifiedContainerTypeName(const AbstractMetaType *type); - void addInstantiatedContainersAndSmartPointers(const AbstractMetaType *type, + static QString getSimplifiedContainerTypeName(const AbstractMetaType &type); + void addInstantiatedContainersAndSmartPointers(const AbstractMetaType &type, const QString &context); private: - bool useEnumAsIntForProtectedHack(const AbstractMetaType *cType) const; + bool useEnumAsIntForProtectedHack(const AbstractMetaType &cType) const; struct GeneratorPrivate; GeneratorPrivate *m_d; diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp index 81b404239..f091860ca 100644 --- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp +++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp @@ -88,7 +88,7 @@ static bool shouldSkip(const AbstractMetaFunction* func) const AbstractMetaArgumentList fargs = f->arguments(); for (int i = 0, max = funcArgs.count(); i < max; ++i) { - if (funcArgs.at(i)->type()->typeEntry() != fargs.at(i)->type()->typeEntry()) { + if (funcArgs.at(i)->type().typeEntry() != fargs.at(i)->type().typeEntry()) { cloneFound = false; break; } @@ -1529,7 +1529,7 @@ QString QtDocGenerator::fileNameForContext(const GeneratorContext &context) cons if (!context.forSmartPointer()) { return metaClass->name() + fileNameSuffix(); } - const AbstractMetaType *smartPointerType = context.preciseType(); + const AbstractMetaType &smartPointerType = context.preciseType(); QString fileNameBase = getFileNameBaseForSmartPointer(smartPointerType, metaClass); return fileNameBase + fileNameSuffix(); } @@ -1876,7 +1876,7 @@ QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass* /* cppClass */ defValue.replace(QLatin1String("::"), QLatin1String(".")); if (defValue == QLatin1String("nullptr")) defValue = none(); - else if (defValue == QLatin1String("0") && arg->type()->isObject()) + else if (defValue == QLatin1String("0") && arg->type().isObject()) defValue = none(); } ret += QLatin1Char('=') + defValue; @@ -2003,13 +2003,14 @@ QString QtDocGenerator::functionSignature(const AbstractMetaClass* cppClass, con + QLatin1Char(')'); } -QString QtDocGenerator::translateToPythonType(const AbstractMetaType* type, const AbstractMetaClass* cppClass) +QString QtDocGenerator::translateToPythonType(const AbstractMetaType &type, + const AbstractMetaClass* cppClass) { static const QStringList nativeTypes = {boolT(), floatT(), intT(), QLatin1String("object"), QLatin1String("str") }; - const QString name = type->name(); + const QString name = type.name(); if (nativeTypes.contains(name)) return name; @@ -2032,13 +2033,13 @@ QString QtDocGenerator::translateToPythonType(const AbstractMetaType* type, cons return found.value(); QString strType; - if (type->isConstant() && name == QLatin1String("char") && type->indirections() == 1) { + if (type.isConstant() && name == QLatin1String("char") && type.indirections() == 1) { strType = QLatin1String("str"); } else if (name.startsWith(unsignedShortT())) { strType = intT(); } else if (name.startsWith(unsignedT())) { // uint and ulong strType = intT(); - } else if (type->isContainer()) { + } else if (type.isContainer()) { QString strType = translateType(type, cppClass, Options(ExcludeConst) | ExcludeReference); strType.remove(QLatin1Char('*')); strType.remove(QLatin1Char('>')); @@ -2055,8 +2056,8 @@ QString QtDocGenerator::translateToPythonType(const AbstractMetaType* type, cons .arg(types[0], types[1]); } } else { - const AbstractMetaClass *k = AbstractMetaClass::findClass(classes(), type->typeEntry()); - strType = k ? k->fullName() : type->name(); + const AbstractMetaClass *k = AbstractMetaClass::findClass(classes(), type.typeEntry()); + strType = k ? k->fullName() : type.name(); strType = QStringLiteral(":any:`") + strType + QLatin1Char('`'); } return strType; diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h index b0f4c2552..a562fe6be 100644 --- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h +++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h @@ -271,7 +271,7 @@ private: void writeAdditionalDocumentation(); QString parseArgDocStyle(const AbstractMetaClass *cppClass, const AbstractMetaFunction *func); - QString translateToPythonType(const AbstractMetaType *type, const AbstractMetaClass *cppClass); + QString translateToPythonType(const AbstractMetaType &type, const AbstractMetaClass *cppClass); QString m_docDataDir; QString m_libSourceDir; diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index ee57c9e2c..5d1924818 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -82,12 +82,12 @@ static const char *typeNameOf(const T &t) )CPP"; // utility functions -inline AbstractMetaType *getTypeWithoutContainer(AbstractMetaType *arg) +inline AbstractMetaType getTypeWithoutContainer(const AbstractMetaType &arg) { - if (arg && arg->typeEntry()->isContainer()) { + if (arg && arg.typeEntry()->isContainer()) { // only support containers with 1 type - if (arg->instantiations().size() == 1) - return arg->instantiations().constFirst(); + if (arg.instantiations().size() == 1) + return arg.instantiations().constFirst(); } return arg; } @@ -204,7 +204,7 @@ QString CppGenerator::fileNameForContext(const GeneratorContext &context) const fileNameBase.replace(QLatin1String("::"), QLatin1String("_")); return fileNameBase + fileNameSuffix(); } - const AbstractMetaType *smartPointerType = context.preciseType(); + const AbstractMetaType &smartPointerType = context.preciseType(); QString fileNameBase = getFileNameBaseForSmartPointer(smartPointerType, metaClass); return fileNameBase + fileNameSuffix(); } @@ -246,22 +246,22 @@ const AbstractMetaFunction *CppGenerator::boolCast(const AbstractMetaClass *meta return nullptr; // TODO: This could be configurable someday const AbstractMetaFunction *func = metaClass->findFunction(QLatin1String("isNull")); - if (!func || func->isVoid() || !func->type()->typeEntry()->isPrimitive() || !func->isPublic()) + if (!func || func->isVoid() || !func->type().typeEntry()->isPrimitive() || !func->isPublic()) return nullptr; - auto pte = static_cast(func->type()->typeEntry()); + auto pte = static_cast(func->type().typeEntry()); while (pte->referencedTypeEntry()) pte = pte->referencedTypeEntry(); return func && func->isConstant() && pte->name() == QLatin1String("bool") && func->arguments().isEmpty() ? func : nullptr; } -const AbstractMetaType *CppGenerator::findSmartPointerInstantiation(const TypeEntry *entry) const +AbstractMetaType CppGenerator::findSmartPointerInstantiation(const TypeEntry *entry) const { - for (auto i : instantiatedSmartPointers()) { - if (i->instantiations().at(0)->typeEntry() == entry) + for (const auto &i : instantiatedSmartPointers()) { + if (i.instantiations().at(0).typeEntry() == entry) return i; } - return nullptr; + return {}; } using FunctionGroupMap = QMap; @@ -284,17 +284,17 @@ static QString chopType(QString s) // Helper for field setters: Check for "const QWidget *" (settable field), // but not "int *const" (read-only field). -static bool isPointerToConst(const AbstractMetaType *t) +static bool isPointerToConst(const AbstractMetaType &t) { - const AbstractMetaType::Indirections &indirections = t->indirectionsV(); - return t->isConstant() && !indirections.isEmpty() + const AbstractMetaType::Indirections &indirections = t.indirectionsV(); + return t.isConstant() && !indirections.isEmpty() && indirections.constLast() != Indirection::ConstPointer; } static inline bool canGenerateFieldSetter(const AbstractMetaField *field) { - const AbstractMetaType *type = field->type(); - return !type->isConstant() || isPointerToConst(type); + const AbstractMetaType &type = field->type(); + return !type.isConstant() || isPointerToConst(type); } static bool isStdSetterName(QString setterName, QString propertyName) @@ -438,7 +438,7 @@ void CppGenerator::generateClass(QTextStream &s, const GeneratorContext &classCo if (classContext.forSmartPointer()) { const auto *typeEntry = static_cast(classContext.preciseType() - ->typeEntry()); + .typeEntry()); QString rawGetter = typeEntry->getter(); s << "static const char * " << SMART_POINTER_GETTER << " = \"" << rawGetter << "\";"; } @@ -557,22 +557,22 @@ void CppGenerator::generateClass(QTextStream &s, const GeneratorContext &classCo if (classContext.forSmartPointer()) { const auto *smartPointerTypeEntry = static_cast( - classContext.preciseType()->typeEntry()); + classContext.preciseType().typeEntry()); if (smartPointerTypeEntry->getter() == rfunc->name()) { // Replace the return type of the raw pointer getter method with the actual // return type. QString innerTypeName = - classContext.preciseType()->getSmartPointerInnerType()->cppSignature(); + classContext.preciseType().getSmartPointerInnerType().cppSignature(); QString pointerToInnerTypeName = innerTypeName + QLatin1Char('*'); // @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 = + AbstractMetaType pointerToInnerType = buildAbstractMetaTypeFromString(pointerToInnerTypeName); AbstractMetaFunction *mutableRfunc = overloads.constFirst(); - mutableRfunc->replaceType(pointerToInnerType); + mutableRfunc->setType(pointerToInnerType); } else if (smartPointerTypeEntry->refCountMethodName().isEmpty() || smartPointerTypeEntry->refCountMethodName() != rfunc->name()) { // Skip all public methods of the smart pointer except for the raw getter and @@ -835,7 +835,7 @@ QString CppGenerator::getVirtualFunctionReturnTypeName(const AbstractMetaFunctio return QLatin1Char('"') + func->typeReplaced(0) + QLatin1Char('"'); // SbkType would return null when the type is a container. - auto typeEntry = func->type()->typeEntry(); + auto typeEntry = func->type().typeEntry(); if (typeEntry->isContainer()) { return QLatin1Char('"') + reinterpret_cast(typeEntry)->typeName() @@ -850,8 +850,8 @@ QString CppGenerator::getVirtualFunctionReturnTypeName(const AbstractMetaFunctio return QLatin1Char('"') + protectedEnumSurrogateName(metaEnum) + QLatin1Char('"'); } - if (func->type()->isPrimitive()) - return QLatin1Char('"') + func->type()->name() + QLatin1Char('"'); + if (func->type().isPrimitive()) + return QLatin1Char('"') + func->type().name() + QLatin1Char('"'); return QLatin1String("reinterpret_cast(Shiboken::SbkType< ") + typeEntry->qualifiedCppName() + QLatin1String(" >())->tp_name"); @@ -902,7 +902,7 @@ QString CppGenerator::virtualMethodReturn(QTextStream &s, { if (func->isVoid()) return QLatin1String("return;"); - const AbstractMetaType *returnType = func->type(); + const AbstractMetaType &returnType = func->type(); for (const FunctionModification &mod : functionModifications) { for (const ArgumentModification &argMod : mod.argument_mods) { if (argMod.index == 0 && !argMod.replacedDefaultExpression.isEmpty()) { @@ -933,12 +933,12 @@ QString CppGenerator::virtualMethodReturn(QTextStream &s, if (const AbstractMetaClass *c = func->implementingClass()) errorMsg += c->qualifiedCppName() + QLatin1String("::"); errorMsg += func->signature(); - errorMsg = msgCouldNotFindMinimalConstructor(errorMsg, func->type()->cppSignature()); + errorMsg = msgCouldNotFindMinimalConstructor(errorMsg, func->type().cppSignature()); qCWarning(lcShiboken).noquote().nospace() << errorMsg; s << Qt::endl << INDENT << "#error " << errorMsg << Qt::endl; } - if (returnType->referenceType() == LValueReference) { - s << INDENT << "static " << returnType->typeEntry()->qualifiedCppName() + if (returnType.referenceType() == LValueReference) { + s << INDENT << "static " << returnType.typeEntry()->qualifiedCppName() << " result;\n"; return QLatin1String("return result;"); } @@ -955,7 +955,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, ((func->name() == QLatin1String("metaObject")) || (func->name() == QLatin1String("qt_metacall")))) return; - const TypeEntry *retType = func->type()->typeEntry(); + const TypeEntry *retType = func->type().typeEntry(); const QString funcName = func->isOperatorOverload() ? pythonOperatorFunctionName(func) : func->name(); QString prefix = wrapperName(func->ownerClass()) + QLatin1String("::"); @@ -1055,20 +1055,21 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, QString argConv; QTextStream ac(&argConv); - auto argType = static_cast(arg->type()->typeEntry()); - bool convert = argType->isObject() - || argType->isValue() - || arg->type()->isValuePointer() - || arg->type()->isNativePointer() - || argType->isFlags() - || argType->isEnum() - || argType->isContainer() - || arg->type()->referenceType() == LValueReference; - - if (!convert && argType->isPrimitive()) { - if (argType->basicReferencedTypeEntry()) - argType = argType->basicReferencedTypeEntry(); - convert = !m_formatUnits.contains(argType->name()); + const auto &argType = arg->type(); + auto argTypeEntry = static_cast(argType.typeEntry()); + bool convert = argTypeEntry->isObject() + || argTypeEntry->isValue() + || argType.isValuePointer() + || argType.isNativePointer() + || argTypeEntry->isFlags() + || argTypeEntry->isEnum() + || argTypeEntry->isContainer() + || argType.referenceType() == LValueReference; + + if (!convert && argTypeEntry->isPrimitive()) { + if (argTypeEntry->basicReferencedTypeEntry()) + argTypeEntry = argTypeEntry->basicReferencedTypeEntry(); + convert = !m_formatUnits.contains(argTypeEntry->name()); } Indentor nested; @@ -1157,7 +1158,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, s << INDENT << "// Check return type\n"; s << INDENT << "bool typeIsValid = "; writeTypeCheck(s, func->type(), QLatin1String(PYTHON_RETURN_VAR), - isNumber(func->type()->typeEntry()), func->typeReplaced(0)); + isNumber(func->type().typeEntry()), func->typeReplaced(0)); s << ";\n"; s << INDENT << "if (!typeIsValid"; if (isPointerToWrapperType(func->type())) @@ -1228,7 +1229,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, s << '(' << typeCast << ')'; } } - if (func->type()->referenceType() == LValueReference && !isPointer(func->type())) + if (func->type().referenceType() == LValueReference && !isPointer(func->type())) s << " *"; s << CPP_RETURN_VAR << ";\n"; } @@ -1464,7 +1465,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla if (!classContext.forSmartPointer()) targetTypeName = metaClass->name(); else - targetTypeName = classContext.preciseType()->name(); + targetTypeName = classContext.preciseType().name(); sourceTypeName = targetTypeName + QLatin1String("_COPY"); @@ -1489,7 +1490,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla if (!classContext.forSmartPointer()) sourceTypeName = metaClass->name(); else - sourceTypeName = classContext.preciseType()->name(); + sourceTypeName = classContext.preciseType().name(); targetTypeName = QStringLiteral("%1_COPY").arg(sourceTypeName); code.clear(); @@ -1525,7 +1526,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla if (!implicitConvs.isEmpty()) s << "// Implicit conversions.\n"; - AbstractMetaType *targetType = buildAbstractMetaTypeFromAbstractMetaClass(metaClass); + AbstractMetaType targetType = buildAbstractMetaTypeFromAbstractMetaClass(metaClass); for (const AbstractMetaFunction *conv : qAsConst(implicitConvs)) { if (conv->isModifiedRemoved()) continue; @@ -1541,22 +1542,22 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla // Constructor that does implicit conversion. if (!conv->typeReplaced(1).isEmpty() || conv->isModifiedToArray(1)) continue; - const AbstractMetaType *sourceType = conv->arguments().constFirst()->type(); + const AbstractMetaType sourceType = conv->arguments().constFirst()->type(); typeCheck = cpythonCheckFunction(sourceType); bool isUserPrimitiveWithoutTargetLangName = isUserPrimitive(sourceType) - && sourceType->typeEntry()->targetLangApiName() == sourceType->typeEntry()->name(); + && sourceType.typeEntry()->targetLangApiName() == sourceType.typeEntry()->name(); if (!isWrapperType(sourceType) && !isUserPrimitiveWithoutTargetLangName - && !sourceType->typeEntry()->isEnum() - && !sourceType->typeEntry()->isFlags() - && !sourceType->typeEntry()->isContainer()) { + && !sourceType.typeEntry()->isEnum() + && !sourceType.typeEntry()->isFlags() + && !sourceType.typeEntry()->isContainer()) { typeCheck += QLatin1Char('('); } if (isWrapperType(sourceType)) { typeCheck += QLatin1String("pyIn)"); - toCppConv = (sourceType->referenceType() == LValueReference || !isPointerToWrapperType(sourceType)) + toCppConv = (sourceType.referenceType() == LValueReference || !isPointerToWrapperType(sourceType)) ? QLatin1String(" *") : QString(); - toCppConv += cpythonWrapperCPtr(sourceType->typeEntry(), QLatin1String("pyIn")); + toCppConv += cpythonWrapperCPtr(sourceType.typeEntry(), QLatin1String("pyIn")); } else if (typeCheck.contains(QLatin1String("%in"))) { typeCheck.replace(QLatin1String("%in"), QLatin1String("pyIn")); typeCheck.append(QLatin1Char(')')); @@ -1566,9 +1567,9 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla if (isUserPrimitive(sourceType) || isCppPrimitive(sourceType) - || sourceType->typeEntry()->isContainer() - || sourceType->typeEntry()->isEnum() - || sourceType->typeEntry()->isFlags()) { + || sourceType.typeEntry()->isContainer() + || sourceType.typeEntry()->isEnum() + || sourceType.typeEntry()->isFlags()) { QTextStream pc(&toCppPreConv); pc << nested << getFullTypeNameWithoutModifiers(sourceType) << " cppIn"; writeMinimalConstructorExpression(pc, sourceType); @@ -1583,9 +1584,9 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla } - const AbstractMetaType *sourceType = conv->isConversionOperator() - ? buildAbstractMetaTypeFromAbstractMetaClass(conv->ownerClass()) - : conv->arguments().constFirst()->type(); + const AbstractMetaType sourceType = conv->isConversionOperator() + ? buildAbstractMetaTypeFromAbstractMetaClass(conv->ownerClass()) + : conv->arguments().constFirst()->type(); writePythonToCppConversionFunctions(s, sourceType, targetType, typeCheck, toCppConv, toCppPreConv); } @@ -1653,8 +1654,8 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas if (!classContext.forSmartPointer()) { writeConversionsForType(metaClass->qualifiedCppName()); } else { - const QString &smartPointerType = classContext.preciseType()->instantiations().at(0)->cppSignature(); - const QString &smartPointerName = classContext.preciseType()->typeEntry()->name(); + const QString &smartPointerType = classContext.preciseType().instantiations().at(0).cppSignature(); + const QString &smartPointerName = classContext.preciseType().typeEntry()->name(); QStringList lst = smartPointerType.split(QLatin1String("::"), Qt::SkipEmptyParts); @@ -1672,7 +1673,7 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas if (!classContext.forSmartPointer()) qualifiedCppNameInvocation = metaClass->qualifiedCppName(); else - qualifiedCppNameInvocation = classContext.preciseType()->cppSignature(); + qualifiedCppNameInvocation = classContext.preciseType().cppSignature(); s << qualifiedCppNameInvocation << ").name());\n"; @@ -1710,11 +1711,11 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas if (!implicitConvs.isEmpty()) s << INDENT << "// Add implicit conversions to type converter.\n"; - AbstractMetaType *targetType = buildAbstractMetaTypeFromAbstractMetaClass(metaClass); + AbstractMetaType targetType = buildAbstractMetaTypeFromAbstractMetaClass(metaClass); for (const AbstractMetaFunction *conv : qAsConst(implicitConvs)) { if (conv->isModifiedRemoved()) continue; - const AbstractMetaType *sourceType; + AbstractMetaType sourceType; if (conv->isConversionOperator()) { sourceType = buildAbstractMetaTypeFromAbstractMetaClass(conv->ownerClass()); } else { @@ -1746,20 +1747,20 @@ void CppGenerator::writeCustomConverterRegister(QTextStream &s, const CustomConv } } -void CppGenerator::writeContainerConverterFunctions(QTextStream &s, const AbstractMetaType *containerType) +void CppGenerator::writeContainerConverterFunctions(QTextStream &s, const AbstractMetaType &containerType) { writeCppToPythonFunction(s, containerType); writePythonToCppConversionFunctions(s, containerType); } -void CppGenerator::writeSmartPointerConverterFunctions(QTextStream &s, const AbstractMetaType *smartPointerType) +void CppGenerator::writeSmartPointerConverterFunctions(QTextStream &s, const AbstractMetaType &smartPointerType) { - const AbstractMetaClass *targetClass = AbstractMetaClass::findClass(classes(), smartPointerType->instantiations().at(0)->typeEntry()); + const AbstractMetaClass *targetClass = AbstractMetaClass::findClass(classes(), smartPointerType.instantiations().at(0).typeEntry()); if (targetClass) { const auto *smartPointerTypeEntry = static_cast( - smartPointerType->typeEntry()); + smartPointerType.typeEntry()); // TODO: Missing conversion to smart pointer pointer type: @@ -1768,7 +1769,7 @@ 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"; + s << INDENT << "// SmartPointer derived class: " << smartTargetType.cppSignature() << "\n"; writePythonToCppConversionFunctions(s, smartPointerType, smartTargetType, {}, {}, {}); } } @@ -1797,7 +1798,7 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over if (!context.forSmartPointer()) qualifiedCppName = ownerClass->qualifiedCppName(); else - qualifiedCppName = context.preciseType()->cppSignature(); + qualifiedCppName = context.preciseType().cppSignature(); s << qualifiedCppName << " >()))\n"; Indentation indent(INDENT); @@ -2338,13 +2339,13 @@ static QString pythonToCppConverterForArgumentName(const QString &argumentName) return result; } -void CppGenerator::writeTypeCheck(QTextStream &s, const AbstractMetaType *argType, +void CppGenerator::writeTypeCheck(QTextStream &s, AbstractMetaType argType, const QString &argumentName, bool isNumber, const QString &customType, bool rejectNull) { QString customCheck; if (!customType.isEmpty()) { - AbstractMetaType *metaType; + AbstractMetaType metaType; // PYSIDE-795: Note: XML-Overrides are handled in this shibokengenerator function! // This enables iterables for QMatrix4x4 for instance. customCheck = guessCPythonCheckFunction(customType, &metaType); @@ -2355,15 +2356,15 @@ void CppGenerator::writeTypeCheck(QTextStream &s, const AbstractMetaType *argTyp // TODO-CONVERTER: merge this with the code below. QString typeCheck; if (customCheck.isEmpty()) - typeCheck = cpythonIsConvertibleFunction(argType, argType->isEnum() ? false : isNumber); + typeCheck = cpythonIsConvertibleFunction(argType, argType.isEnum() ? false : isNumber); else typeCheck = customCheck; typeCheck.append(QString::fromLatin1("(%1)").arg(argumentName)); // TODO-CONVERTER ----------------------------------------------------------------------- - if (customCheck.isEmpty() && !argType->typeEntry()->isCustom()) { + if (customCheck.isEmpty() && !argType.typeEntry()->isCustom()) { typeCheck = QString::fromLatin1("(%1 = %2))").arg(pythonToCppConverterForArgumentName(argumentName), typeCheck); - if (!isNumber && argType->typeEntry()->isCppPrimitive()) + if (!isNumber && argType.typeEntry()->isCppPrimitive()) typeCheck.prepend(QString::fromLatin1("%1(%2) && ").arg(cpythonCheckFunction(argType), argumentName)); } // TODO-CONVERTER ----------------------------------------------------------------------- @@ -2374,13 +2375,13 @@ void CppGenerator::writeTypeCheck(QTextStream &s, const AbstractMetaType *argTyp s << typeCheck; } -static void checkTypeViability(const AbstractMetaFunction *func, const AbstractMetaType *type, int argIdx) +static void checkTypeViability(const AbstractMetaFunction *func, const AbstractMetaType &type, int argIdx) { if (!type - || type->isVoid() - || !type->typeEntry()->isPrimitive() - || type->indirections() == 0 - || (type->indirections() == 1 && type->typeUsagePattern() == AbstractMetaType::NativePointerAsArrayPattern) + || type.isVoid() + || !type.typeEntry()->isPrimitive() + || type.indirections() == 0 + || (type.indirections() == 1 && type.typeUsagePattern() == AbstractMetaType::NativePointerAsArrayPattern) || ShibokenGenerator::isCString(type) || func->argumentRemoved(argIdx) || !func->typeReplaced(argIdx).isEmpty() @@ -2393,9 +2394,9 @@ static void checkTypeViability(const AbstractMetaFunction *func, const AbstractM << "There's no user provided way (conversion rule, argument" " removal, custom code, etc) to handle the primitive "; if (argIdx == 0) - str << "return type '" << type->cppSignature() << '\''; + str << "return type '" << type.cppSignature() << '\''; else - str << "type '" << type->cppSignature() << "' of argument " << argIdx; + str << "type '" << type.cppSignature() << "' of argument " << argIdx; str << " in function '"; if (func->ownerClass()) str << func->ownerClass()->qualifiedCppName() << "::"; @@ -2407,8 +2408,7 @@ static void checkTypeViability(const AbstractMetaFunction *func) { if (func->isUserAdded()) return; - const AbstractMetaType *type = func->type(); - checkTypeViability(func, type, 0); + checkTypeViability(func, func->type(), 0); for (int i = 0; i < func->arguments().count(); ++i) checkTypeViability(func, func->arguments().at(i)->type(), i + 1); } @@ -2421,19 +2421,19 @@ void CppGenerator::writeTypeCheck(QTextStream &s, const OverloadData *overloadDa const OverloadData::MetaFunctionList &odOverloads = od->overloads(); for (const AbstractMetaFunction *func : odOverloads) { checkTypeViability(func); - const AbstractMetaType *argType = od->argument(func)->type(); - if (!argType->isPrimitive()) + const AbstractMetaType &argType = od->argument(func)->type(); + if (!argType.isPrimitive()) continue; - if (ShibokenGenerator::isNumber(argType->typeEntry())) - numericTypes << argType->typeEntry(); + if (ShibokenGenerator::isNumber(argType.typeEntry())) + numericTypes << argType.typeEntry(); } } // This condition trusts that the OverloadData object will arrange for // PyInt type to come after the more precise numeric types (e.g. float and bool) - const AbstractMetaType *argType = overloadData->argType(); - if (auto viewOn = argType->viewOn()) - argType = viewOn; + AbstractMetaType argType = overloadData->argType(); + if (auto viewOn = argType.viewOn()) + argType = *viewOn; bool numberType = numericTypes.count() == 1 || ShibokenGenerator::isPyInt(argType); QString customType = (overloadData->hasArgumentTypeReplace() ? overloadData->argumentTypeReplaced() : QString()); bool rejectNull = shouldRejectNullPointerArgument(overloadData->referenceFunction(), overloadData->argPos()); @@ -2441,13 +2441,13 @@ void CppGenerator::writeTypeCheck(QTextStream &s, const OverloadData *overloadDa } void CppGenerator::writeArgumentConversion(QTextStream &s, - const AbstractMetaType *argType, + const AbstractMetaType &argType, const QString &argName, const QString &pyArgName, const AbstractMetaClass *context, const QString &defaultValue, bool castArgumentAsUnused) { - if (argType->typeEntry()->isCustom() || argType->typeEntry()->isVarargs()) + if (argType.typeEntry()->isCustom() || argType.typeEntry()->isVarargs()) return; if (isWrapperType(argType)) writeInvalidPyObjectCheck(s, pyArgName); @@ -2456,12 +2456,12 @@ void CppGenerator::writeArgumentConversion(QTextStream &s, writeUnusedVariableCast(s, argName); } -const AbstractMetaType *CppGenerator::getArgumentType(const AbstractMetaFunction *func, int argPos) +const AbstractMetaType CppGenerator::getArgumentType(const AbstractMetaFunction *func, int argPos) { if (argPos < 0 || argPos > func->arguments().size()) { qCWarning(lcShiboken).noquote().nospace() << QStringLiteral("Argument index for function '%1' out of range.").arg(func->signature()); - return nullptr; + return {}; } QString typeReplaced = func->typeReplaced(argPos); @@ -2469,7 +2469,7 @@ const AbstractMetaType *CppGenerator::getArgumentType(const AbstractMetaFunction if (argPos == 0) return func->type(); auto argType = func->arguments().at(argPos - 1)->type(); - return argType->viewOn() ? argType->viewOn() : argType; + return argType.viewOn() ? *argType.viewOn() : argType; } auto argType = buildAbstractMetaTypeFromString(typeReplaced); @@ -2482,31 +2482,31 @@ const AbstractMetaType *CppGenerator::getArgumentType(const AbstractMetaFunction return argType; } -static inline QString arrayHandleType(const AbstractMetaTypeCList &nestedArrayTypes) +static inline QString arrayHandleType(const AbstractMetaTypeList &nestedArrayTypes) { switch (nestedArrayTypes.size()) { case 1: return QStringLiteral("Shiboken::Conversions::ArrayHandle<") - + nestedArrayTypes.constLast()->minimalSignature() + + nestedArrayTypes.constLast().minimalSignature() + QLatin1Char('>'); case 2: return QStringLiteral("Shiboken::Conversions::Array2Handle<") - + nestedArrayTypes.constLast()->minimalSignature() + + nestedArrayTypes.constLast().minimalSignature() + QStringLiteral(", ") - + QString::number(nestedArrayTypes.constFirst()->arrayElementCount()) + + QString::number(nestedArrayTypes.constFirst().arrayElementCount()) + QLatin1Char('>'); } return QString(); } void CppGenerator::writePythonToCppTypeConversion(QTextStream &s, - const AbstractMetaType *type, + const AbstractMetaType &type, const QString &pyIn, const QString &cppOut, const AbstractMetaClass * /* context */, const QString &defaultValue) { - const TypeEntry *typeEntry = type->typeEntry(); + const TypeEntry *typeEntry = type.typeEntry(); if (typeEntry->isCustom() || typeEntry->isVarargs()) return; @@ -2515,15 +2515,15 @@ void CppGenerator::writePythonToCppTypeConversion(QTextStream &s, 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->referenceType() == LValueReference + bool mayHaveImplicitConversion = type.referenceType() == LValueReference && !isUserPrimitive(type) && !isCppPrimitive(type) && isNotContainerEnumOrFlags && !(treatAsPointer || isPointerOrObjectType); - const AbstractMetaTypeCList nestedArrayTypes = type->nestedArrayTypes(); + const AbstractMetaTypeList &nestedArrayTypes = type.nestedArrayTypes(); const bool isCppPrimitiveArray = !nestedArrayTypes.isEmpty() - && nestedArrayTypes.constLast()->isCppPrimitive(); + && nestedArrayTypes.constLast().isCppPrimitive(); QString typeName = isCppPrimitiveArray ? arrayHandleType(nestedArrayTypes) : getFullTypeNameWithoutModifiers(type); @@ -2534,7 +2534,7 @@ void CppGenerator::writePythonToCppTypeConversion(QTextStream &s, s << INDENT << typeName << ' ' << cppOutAux; writeMinimalConstructorExpression(s, type, defaultValue); s << ";\n"; - } else if (avoidProtectedHack() && type->typeEntry()->isEnum()) { + } else if (avoidProtectedHack() && type.typeEntry()->isEnum()) { const AbstractMetaEnum *metaEnum = findAbstractMetaEnum(type); if (metaEnum && metaEnum->isProtected()) { typeName = QLatin1String("long"); @@ -2549,8 +2549,8 @@ void CppGenerator::writePythonToCppTypeConversion(QTextStream &s, s << " *" << cppOut; if (!defaultValue.isEmpty()) { const bool needsConstCast = !isNullPtr(defaultValue) - && type->indirections() == 1 && type->isConstant() - && type->referenceType() == NoReference; + && type.indirections() == 1 && type.isConstant() + && type.referenceType() == NoReference; s << " = "; if (needsConstCast) s << "const_cast<" << typeName << " *>("; @@ -2558,7 +2558,7 @@ void CppGenerator::writePythonToCppTypeConversion(QTextStream &s, if (needsConstCast) s << ')'; } - } else if (type->referenceType() == LValueReference && !typeEntry->isPrimitive() && isNotContainerEnumOrFlags) { + } else if (type.referenceType() == LValueReference && !typeEntry->isPrimitive() && isNotContainerEnumOrFlags) { s << " *" << cppOut << " = &" << cppOutAux; } else { s << ' ' << cppOut; @@ -2570,7 +2570,7 @@ void CppGenerator::writePythonToCppTypeConversion(QTextStream &s, s << "(long)" << defaultValue; } else if (isUserPrimitive(type) || typeEntry->isEnum() || typeEntry->isFlags()) { writeMinimalConstructorExpression(s, typeEntry, defaultValue); - } else if (!type->isContainer() && !type->isSmartPointer()) { + } else if (!type.isContainer() && !type.isSmartPointer()) { writeMinimalConstructorExpression(s, type, defaultValue); } } @@ -2780,7 +2780,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov OverloadData *od = overloadData; int startArg = od->argPos(); int sequenceArgCount = 0; - while (od && !od->argType()->isVarargs()) { + while (od && !od->argType().isVarargs()) { bool typeReplacedByPyObject = od->argumentTypeReplaced() == QLatin1String("PyObject"); if (!typeReplacedByPyObject) { if (usePyArgs) @@ -2792,7 +2792,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov if (func->isConstructor() && func->arguments().count() == 1) { const AbstractMetaClass *ownerClass = func->ownerClass(); const ComplexTypeEntry *baseContainerType = ownerClass->typeEntry()->baseContainerType(); - if (baseContainerType && baseContainerType == func->arguments().constFirst()->type()->typeEntry() && isCopyable(ownerClass)) { + if (baseContainerType && baseContainerType == func->arguments().constFirst()->type().typeEntry() && isCopyable(ownerClass)) { tck << '!' << cpythonCheckFunction(ownerClass->typeEntry()) << pyArgName << ")\n"; Indentation indent(INDENT); tck << INDENT << "&& "; @@ -2817,7 +2817,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream &s, const Ov if (usePyArgs && signatureFound) { AbstractMetaArgumentList args = refFunc->arguments(); - const bool isVarargs = args.size() > 1 && args.constLast()->type()->isVarargs(); + const bool isVarargs = args.size() > 1 && args.constLast()->type().isVarargs(); int numArgs = args.size() - OverloadData::numberOfRemovedArguments(refFunc); if (isVarargs) --numArgs; @@ -2935,7 +2935,7 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s, } if (hasConversionRule) continue; - const AbstractMetaType *argType = getArgumentType(func, argIdx + 1); + const AbstractMetaType argType = getArgumentType(func, argIdx + 1); if (!argType || (mayHaveUnunsedArguments && !injectedCodeUsesArgument(func, argIdx))) continue; int argPos = argIdx - removedArgs; @@ -2967,7 +2967,7 @@ QString CppGenerator::pythonToCppFunctionName(const QString &sourceTypeName, con { return QString::fromLatin1("%1_PythonToCpp_%2").arg(sourceTypeName, targetTypeName); } -QString CppGenerator::pythonToCppFunctionName(const AbstractMetaType *sourceType, const AbstractMetaType *targetType) +QString CppGenerator::pythonToCppFunctionName(const AbstractMetaType &sourceType, const AbstractMetaType &targetType) { return pythonToCppFunctionName(fixedCppTypeName(sourceType), fixedCppTypeName(targetType)); } @@ -2981,7 +2981,7 @@ QString CppGenerator::convertibleToCppFunctionName(const QString &sourceTypeName { return QString::fromLatin1("is_%1_PythonToCpp_%2_Convertible").arg(sourceTypeName, targetTypeName); } -QString CppGenerator::convertibleToCppFunctionName(const AbstractMetaType *sourceType, const AbstractMetaType *targetType) +QString CppGenerator::convertibleToCppFunctionName(const AbstractMetaType &sourceType, const AbstractMetaType &targetType) { return convertibleToCppFunctionName(fixedCppTypeName(sourceType), fixedCppTypeName(targetType)); } @@ -3020,23 +3020,23 @@ void CppGenerator::writeCppToPythonFunction(QTextStream &s, const CustomConversi replaceCppToPythonVariables(code, getFullTypeName(customConversion->ownerType())); writeCppToPythonFunction(s, code, fixedCppTypeName(customConversion->ownerType())); } -void CppGenerator::writeCppToPythonFunction(QTextStream &s, const AbstractMetaType *containerType) +void CppGenerator::writeCppToPythonFunction(QTextStream &s, const AbstractMetaType &containerType) { - const CustomConversion *customConversion = containerType->typeEntry()->customConversion(); + const CustomConversion *customConversion = containerType.typeEntry()->customConversion(); if (!customConversion) { qFatal("Can't write the C++ to Python conversion function for container type '%s' - "\ "no conversion rule was defined for it in the type system.", - qPrintable(containerType->typeEntry()->qualifiedCppName())); + qPrintable(containerType.typeEntry()->qualifiedCppName())); } - if (!containerType->typeEntry()->isContainer()) { + if (!containerType.typeEntry()->isContainer()) { writeCppToPythonFunction(s, customConversion); return; } QString code = customConversion->nativeToTargetConversion(); - for (int i = 0; i < containerType->instantiations().count(); ++i) { - AbstractMetaType *type = containerType->instantiations().at(i); + for (int i = 0; i < containerType.instantiations().count(); ++i) { + const AbstractMetaType &type = containerType.instantiations().at(i); QString typeName = getFullTypeName(type); - if (type->isConstant()) + if (type.isConstant()) typeName = QLatin1String("const ") + typeName; code.replace(QString::fromLatin1("%INTYPE_%1").arg(i), typeName); } @@ -3084,8 +3084,8 @@ void CppGenerator::writeIsPythonConvertibleToCppFunction(QTextStream &s, } void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s, - const AbstractMetaType *sourceType, - const AbstractMetaType *targetType, + const AbstractMetaType &sourceType, + const AbstractMetaType &targetType, QString typeCheck, QString conversion, const QString &preConversion) @@ -3100,7 +3100,9 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s, conversion = QLatin1Char('*') + cpythonWrapperCPtr(sourceType, QLatin1String("pyIn")); if (!preConversion.isEmpty()) c << nested << preConversion << Qt::endl; - const QString fullTypeName = targetType->isSmartPointer() ? targetType->cppSignature() : getFullTypeName(targetType->typeEntry()); + const QString fullTypeName = targetType.isSmartPointer() + ? targetType.cppSignature() + : getFullTypeName(targetType.typeEntry()); c << nested << "*reinterpret_cast<" << fullTypeName << " *>(cppOut) = " << fullTypeName << '(' << conversion << ");"; QString sourceTypeName = fixedCppTypeName(sourceType); @@ -3169,9 +3171,9 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s, writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, typeCheck); } -void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s, const AbstractMetaType *containerType) +void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s, const AbstractMetaType &containerType) { - const CustomConversion *customConversion = containerType->typeEntry()->customConversion(); + const CustomConversion *customConversion = containerType.typeEntry()->customConversion(); if (!customConversion) { //qFatal return; @@ -3187,10 +3189,10 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream &s, const Abs const QString line = QLatin1String("auto &cppOutRef = *reinterpret_cast<") + cppTypeName + QLatin1String(" *>(cppOut);"); CodeSnipAbstract::prependCode(&code, line); - for (int i = 0; i < containerType->instantiations().count(); ++i) { - const AbstractMetaType *type = containerType->instantiations().at(i); + for (int i = 0; i < containerType.instantiations().count(); ++i) { + const AbstractMetaType &type = containerType.instantiations().at(i); QString typeName = getFullTypeName(type); - if (type->isValue() && isValueTypeWithCopyConstructorOnly(type)) { + if (type.isValue() && isValueTypeWithCopyConstructorOnly(type)) { for (int pos = 0; ; ) { const QRegularExpressionMatch match = convertToCppRegEx().match(code, pos); if (!match.hasMatch()) @@ -3266,7 +3268,7 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream &s, const AbstractMe Indentation indent(INDENT); s << INDENT << pyArgName << " = value;\n"; s << INDENT << "if (!"; - writeTypeCheck(s, arg->type(), pyArgName, isNumber(arg->type()->typeEntry()), func->typeReplaced(arg->argumentIndex() + 1)); + writeTypeCheck(s, arg->type(), pyArgName, isNumber(arg->type().typeEntry()), func->typeReplaced(arg->argumentIndex() + 1)); s << ")\n"; { Indentation indent(INDENT); @@ -3289,14 +3291,14 @@ QString CppGenerator::argumentNameFromIndex(const AbstractMetaFunction *func, in pyArgName = QLatin1String("self"); *wrappedClass = func->implementingClass(); } else if (argIndex == 0) { - AbstractMetaType *funcType = func->type(); - AbstractMetaType *returnType = getTypeWithoutContainer(funcType); - if (!returnType->isVoid()) { + const auto funcType = func->type(); + AbstractMetaType returnType = getTypeWithoutContainer(funcType); + if (!returnType.isVoid()) { pyArgName = QLatin1String(PYTHON_RETURN_VAR); - *wrappedClass = AbstractMetaClass::findClass(classes(), returnType->typeEntry()); + *wrappedClass = AbstractMetaClass::findClass(classes(), returnType.typeEntry()); } else { QString message = QLatin1String("Invalid Argument index (0, return value) on function modification: ") - + (funcType ? funcType->name() : QLatin1String("void")) + QLatin1Char(' '); + + funcType.name() + QLatin1Char(' '); if (const AbstractMetaClass *declaringClass = func->declaringClass()) message += declaringClass->name() + QLatin1String("::"); message += func->name() + QLatin1String("()"); @@ -3304,10 +3306,10 @@ 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()); + AbstractMetaType argType = getTypeWithoutContainer(func->arguments().at(realIndex)->type()); if (argType) { - *wrappedClass = AbstractMetaClass::findClass(classes(), argType->typeEntry()); + *wrappedClass = AbstractMetaClass::findClass(classes(), argType.typeEntry()); if (argIndex == 1 && !func->isConstructor() && OverloadData::isSingleArgument(getFunctionGroups(func->implementingClass())[func->name()])) @@ -3406,7 +3408,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f int idx = arg->argumentIndex() - removedArgs; bool deRef = isValueTypeWithCopyConstructorOnly(arg->type()) || isObjectTypeUsedAsValueType(arg->type()) - || (arg->type()->referenceType() == LValueReference && isWrapperType(arg->type()) && !isPointer(arg->type())); + || (arg->type().referenceType() == LValueReference && isWrapperType(arg->type()) && !isPointer(arg->type())); if (hasConversionRule) { userArgs.append(arg->name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX)); } else { @@ -3518,7 +3520,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f } else { QString methodCallClassName; if (context.forSmartPointer()) - methodCallClassName = context.preciseType()->cppSignature(); + methodCallClassName = context.preciseType().cppSignature(); else if (func->ownerClass()) methodCallClassName = func->ownerClass()->qualifiedCppName(); @@ -3623,7 +3625,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f if (metaEnum->isProtected()) enumName = protectedEnumSurrogateName(metaEnum); else - enumName = func->type()->cppSignature(); + enumName = func->type().cppSignature(); methodCall.prepend(enumName + QLatin1Char('(')); methodCall.append(QLatin1Char(')')); s << enumName; @@ -3631,10 +3633,10 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f } } if (writeReturnType) { - s << func->type()->cppSignature(); + s << func->type().cppSignature(); if (isObjectTypeUsedAsValueType(func->type())) { s << '*'; - methodCall.prepend(QString::fromLatin1("new %1(").arg(func->type()->typeEntry()->qualifiedCppName())); + methodCall.prepend(QString::fromLatin1("new %1(").arg(func->type().typeEntry()->qualifiedCppName())); methodCall.append(QLatin1Char(')')); } } @@ -3656,7 +3658,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f && !injectedCodeHasReturnValueAttribution(func, TypeSystem::TargetLangCode)) { s << INDENT << PYTHON_RETURN_VAR << " = "; if (isObjectTypeUsedAsValueType(func->type())) { - s << "Shiboken::Object::newObject(reinterpret_cast(" << cpythonTypeNameExt(func->type()->typeEntry()) + s << "Shiboken::Object::newObject(reinterpret_cast(" << cpythonTypeNameExt(func->type().typeEntry()) << "), " << CPP_RETURN_VAR << ", true, true)"; } else { writeToPythonConversion(s, func->type(), func->ownerClass(), QLatin1String(CPP_RETURN_VAR)); @@ -3941,16 +3943,16 @@ void CppGenerator::writeEnumConverterInitialization(QTextStream &s, const TypeEn writeEnumConverterInitialization(s, static_cast(enumType)->flags()); } -void CppGenerator::writeContainerConverterInitialization(QTextStream &s, const AbstractMetaType *type) +void CppGenerator::writeContainerConverterInitialization(QTextStream &s, const AbstractMetaType &type) { - QByteArray cppSignature = QMetaObject::normalizedSignature(type->cppSignature().toUtf8()); + QByteArray cppSignature = QMetaObject::normalizedSignature(type.cppSignature().toUtf8()); s << INDENT << "// Register converter for type '" << cppSignature << "'.\n"; QString converter = converterObject(type); s << INDENT << converter << " = Shiboken::Conversions::createConverter("; - if (type->typeEntry()->targetLangApiName() == QLatin1String("PyObject")) { + if (type.typeEntry()->targetLangApiName() == QLatin1String("PyObject")) { s << "&PyBaseObject_Type"; } else { - QString baseName = cpythonBaseName(type->typeEntry()); + QString baseName = cpythonBaseName(type.typeEntry()); if (baseName == QLatin1String("PySequence")) baseName = QLatin1String("PyList"); s << '&' << baseName << "_Type"; @@ -3968,10 +3970,10 @@ void CppGenerator::writeContainerConverterInitialization(QTextStream &s, const A writeAddPythonToCppConversion(s, converterObject(type), toCpp, isConv); } -void CppGenerator::writeSmartPointerConverterInitialization(QTextStream &s, const AbstractMetaType *type) +void CppGenerator::writeSmartPointerConverterInitialization(QTextStream &s, const AbstractMetaType &type) { - const QByteArray cppSignature = type->cppSignature().toUtf8(); - auto writeConversionRegister = [this, &s](const AbstractMetaType *sourceType, const QString &targetTypeName, const QString &targetConverter) + const QByteArray cppSignature = type.cppSignature().toUtf8(); + auto writeConversionRegister = [this, &s](const AbstractMetaType &sourceType, const QString &targetTypeName, const QString &targetConverter) { const QString sourceTypeName = fixedCppTypeName(sourceType); const QString toCpp = pythonToCppFunctionName(sourceTypeName, targetTypeName); @@ -3980,7 +3982,7 @@ void CppGenerator::writeSmartPointerConverterInitialization(QTextStream &s, cons writeAddPythonToCppConversion(s, targetConverter, toCpp, isConv); }; - auto klass = AbstractMetaClass::findClass(classes(), type->instantiations().at(0)->typeEntry()); + auto klass = AbstractMetaClass::findClass(classes(), type.instantiations().at(0).typeEntry()); if (!klass) return; @@ -3995,11 +3997,11 @@ void CppGenerator::writeSmartPointerConverterInitialization(QTextStream &s, cons for (auto k : classes) { if (auto smartTargetType = findSmartPointerInstantiation(k->typeEntry())) { - s << INDENT << "// Convert to SmartPointer derived class: [" << smartTargetType->cppSignature() << "]" << Qt::endl; - const QString converter = QLatin1String("Shiboken::Conversions::getConverter(\"%1\")").arg(smartTargetType->cppSignature()); + 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); } else { - s << INDENT << "// Class not found:" << type->instantiations().at(0)->cppSignature(); + s << INDENT << "// Class not found:" << type.instantiations().at(0).cppSignature(); } } @@ -4512,9 +4514,9 @@ void CppGenerator::writeGetterFunction(QTextStream &s, writeCppSelfDefinition(s, context); - AbstractMetaType *fieldType = metaField->type(); + AbstractMetaType fieldType = metaField->type(); // Force use of pointer to return internal variable memory - bool newWrapperSameObject = !fieldType->isConstant() && isWrapperType(fieldType) && !isPointer(fieldType); + bool newWrapperSameObject = !fieldType.isConstant() && isWrapperType(fieldType) && !isPointer(fieldType); QString cppField; if (avoidProtectedHack() && metaField->isProtected()) { @@ -4528,15 +4530,15 @@ void CppGenerator::writeGetterFunction(QTextStream &s, cppField.append(QLatin1Char(')')); } } - if (isCppIntegralPrimitive(fieldType) || fieldType->isEnum()) { + if (isCppIntegralPrimitive(fieldType) || fieldType.isEnum()) { s << INDENT << getFullTypeNameWithoutModifiers(fieldType) << " cppOut_local = " << cppField << ";\n"; cppField = QLatin1String("cppOut_local"); } else if (avoidProtectedHack() && metaField->isProtected()) { s << INDENT << getFullTypeNameWithoutModifiers(fieldType); - if (fieldType->isContainer() || fieldType->isFlags() || fieldType->isSmartPointer()) { + if (fieldType.isContainer() || fieldType.isFlags() || fieldType.isSmartPointer()) { s << " &"; cppField.prepend(QLatin1Char('*')); - } else if ((!fieldType->isConstant() && !fieldType->isEnum() && !fieldType->isPrimitive()) || fieldType->indirections() == 1) { + } else if ((!fieldType.isConstant() && !fieldType.isEnum() && !fieldType.isPrimitive()) || fieldType.indirections() == 1) { s << " *"; } s << " fieldValue = " << cppField << ";\n"; @@ -4614,7 +4616,7 @@ void CppGenerator::writeGetterFunction(QTextStream &s, const QPropertySpec *prop // Write setter function preamble (type checks on "pyIn") void CppGenerator::writeSetterFunctionPreamble(QTextStream &s, const QString &name, const QString &funcName, - const AbstractMetaType *type, + const AbstractMetaType &type, const GeneratorContext &context) { s << "static int " << funcName << "(PyObject *self, PyObject *pyIn, void *)\n"; @@ -4630,10 +4632,10 @@ void CppGenerator::writeSetterFunctionPreamble(QTextStream &s, const QString &na s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR << "{nullptr};\n"; s << INDENT << "if (!"; - writeTypeCheck(s, type, QLatin1String("pyIn"), isNumber(type->typeEntry())); + writeTypeCheck(s, type, QLatin1String("pyIn"), isNumber(type.typeEntry())); s << ") {\n" << indent(INDENT) << INDENT << "PyErr_SetString(PyExc_TypeError, \"wrong type attributed to '" - << name << "', '" << type->name() << "' or convertible type expected\");\n" + << name << "', '" << type.name() << "' or convertible type expected\");\n" << INDENT << "return -1;\n" << outdent(INDENT) << INDENT<< "}\n\n"; } @@ -4644,7 +4646,7 @@ void CppGenerator::writeSetterFunction(QTextStream &s, { ErrorCode errorCode(0); - AbstractMetaType *fieldType = metaField->type(); + const AbstractMetaType &fieldType = metaField->type(); writeSetterFunctionPreamble(s, metaField->name(), cpythonSetterFunctionName(metaField), fieldType, context); @@ -4652,12 +4654,12 @@ void CppGenerator::writeSetterFunction(QTextStream &s, s << INDENT; if (avoidProtectedHack() && metaField->isProtected()) { s << getFullTypeNameWithoutModifiers(fieldType); - s << (fieldType->indirections() == 1 ? " *" : "") << " cppOut;\n"; + s << (fieldType.indirections() == 1 ? " *" : "") << " cppOut;\n"; s << INDENT << PYTHON_TO_CPP_VAR << "(pyIn, &cppOut);\n"; s << INDENT << "static_cast<" << context.wrapperName() << " *>(" << CPP_SELF_VAR << ")->" << protectedFieldSetterName(metaField) << "(cppOut)"; - } else if (isCppIntegralPrimitive(fieldType) || fieldType->typeEntry()->isEnum() || fieldType->typeEntry()->isFlags()) { + } else if (isCppIntegralPrimitive(fieldType) || fieldType.typeEntry()->isEnum() || fieldType.typeEntry()->isFlags()) { s << getFullTypeNameWithoutModifiers(fieldType) << " cppOut_local = " << cppField << ";\n"; s << INDENT << PYTHON_TO_CPP_VAR << "(pyIn, &cppOut_local);\n"; s << INDENT << cppField << " = cppOut_local"; @@ -4665,7 +4667,7 @@ void CppGenerator::writeSetterFunction(QTextStream &s, if (isPointerToConst(fieldType)) s << "const "; s << getFullTypeNameWithoutModifiers(fieldType); - s << QString::fromLatin1(" *").repeated(fieldType->indirections()) << "& cppOut_ptr = "; + s << QString::fromLatin1(" *").repeated(fieldType.indirections()) << "& cppOut_ptr = "; s << cppField << ";\n"; s << INDENT << PYTHON_TO_CPP_VAR << "(pyIn, &cppOut_ptr)"; } @@ -4732,7 +4734,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, const GeneratorConte int alternativeNumericTypes = 0; for (const AbstractMetaFunction *func : overloads) { if (!func->isStatic() && - ShibokenGenerator::isNumber(func->arguments().at(0)->type()->typeEntry())) + ShibokenGenerator::isNumber(func->arguments().at(0)->type().typeEntry())) alternativeNumericTypes++; } @@ -4743,7 +4745,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, const GeneratorConte const AbstractMetaFunction *func = od->referenceFunction(); if (func->isStatic()) continue; - const AbstractMetaType *argType = getArgumentType(func, 1); + const AbstractMetaType argType = getArgumentType(func, 1); if (!argType) continue; if (!first) { @@ -4776,7 +4778,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, const GeneratorConte if (generateOperatorCode) { s << INDENT; if (!func->isVoid()) - s << func->type()->cppSignature() << " " << CPP_RETURN_VAR << " = "; + s << func->type().cppSignature() << " " << CPP_RETURN_VAR << " = "; // expression if (func->isPointerOperator()) s << '&'; @@ -4896,10 +4898,10 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction args << QLatin1String("self"); const AbstractMetaArgumentList &arguments = f->arguments(); for (const AbstractMetaArgument *arg : arguments) { - const auto *metaType = arg->type(); - if (auto viewOn = metaType->viewOn()) - metaType = viewOn; - QString strArg = metaType->pythonSignature(); + auto metaType = arg->type(); + if (auto viewOn = metaType.viewOn()) + metaType = *viewOn; + QString strArg = metaType.pythonSignature(); if (!arg->defaultValueExpression().isEmpty()) { strArg += QLatin1Char('='); QString e = arg->defaultValueExpression(); @@ -4913,7 +4915,7 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction s << idx-- << ':'; s << funcName << '(' << args.join(QLatin1Char(',')) << ')'; if (!f->isVoid()) - s << "->" << f->type()->pythonSignature(); + s << "->" << f->type().pythonSignature(); s << Qt::endl; } } @@ -5074,12 +5076,12 @@ void CppGenerator::writeSignalInitialization(QTextStream &s, const AbstractMetaC continue; const AbstractMetaArgumentList &arguments = cppSignal->arguments(); for (AbstractMetaArgument *arg : arguments) { - AbstractMetaType *metaType = arg->type(); + AbstractMetaType metaType = arg->type(); const QByteArray origType = - QMetaObject::normalizedType(qPrintable(metaType->originalTypeDescription())); + QMetaObject::normalizedType(qPrintable(metaType.originalTypeDescription())); const QByteArray cppSig = - QMetaObject::normalizedType(qPrintable(metaType->cppSignature())); - if ((origType != cppSig) && (!metaType->isFlags())) { + QMetaObject::normalizedType(qPrintable(metaType.cppSignature())); + if ((origType != cppSig) && (!metaType.isFlags())) { qCWarning(lcShiboken).noquote().nospace() << "Typedef used on signal " << metaClass->qualifiedCppName() << "::" << cppSignal->signature(); @@ -5099,7 +5101,7 @@ void CppGenerator::writeFlagsToLong(QTextStream &s, const AbstractMetaEnum *cppE s << "static PyObject *" << cpythonEnumName(cppEnum) << "_long(PyObject *self)\n"; s << "{\n"; s << INDENT << "int val;\n"; - AbstractMetaType *flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry); + AbstractMetaType flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry); s << INDENT << cpythonToCppConversionFunction(flagsType) << "self, &val);\n"; s << INDENT << "return Shiboken::Conversions::copyToPython(Shiboken::Conversions::PrimitiveTypeConverter(), &val);\n"; s << "}\n"; @@ -5114,7 +5116,7 @@ void CppGenerator::writeFlagsNonZero(QTextStream &s, const AbstractMetaEnum *cpp s << "{\n"; s << INDENT << "int val;\n"; - AbstractMetaType *flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry); + AbstractMetaType flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry); s << INDENT << cpythonToCppConversionFunction(flagsType) << "self, &val);\n"; s << INDENT << "return val != 0;\n"; s << "}\n"; @@ -5169,7 +5171,7 @@ void CppGenerator::writeFlagsBinaryOperator(QTextStream &s, const AbstractMetaEn s << "PyObject *" << cpythonEnumName(cppEnum) << "___" << pyOpName << "__(PyObject *self, PyObject *" << PYTHON_ARG << ")\n{\n"; - AbstractMetaType *flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry); + AbstractMetaType flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry); s << INDENT << "::" << flagsEntry->originalName() << " cppResult, " << CPP_SELF_VAR << ", cppArg;\n"; s << INDENT << CPP_SELF_VAR << " = static_cast<::" << flagsEntry->originalName() << ">(int(PyLong_AsLong(self)));\n"; @@ -5192,7 +5194,7 @@ void CppGenerator::writeFlagsUnaryOperator(QTextStream &s, const AbstractMetaEnu s << "PyObject *" << cpythonEnumName(cppEnum) << "___" << pyOpName << "__(PyObject *self, PyObject *" << PYTHON_ARG << ")\n{\n"; - AbstractMetaType *flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry); + AbstractMetaType flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry); s << INDENT << "::" << flagsEntry->originalName() << " " << CPP_SELF_VAR << ";\n"; s << INDENT << cpythonToCppConversionFunction(flagsType) << "self, &" << CPP_SELF_VAR << ");\n"; s << INDENT; @@ -5225,7 +5227,7 @@ QString CppGenerator::getInitFunctionName(const GeneratorContext &context) const { return !context.forSmartPointer() ? getSimpleClassInitFunctionName(context.metaClass()) - : getFilteredCppSignatureString(context.preciseType()->cppSignature()); + : getFilteredCppSignatureString(context.preciseType().cppSignature()); } void CppGenerator::writeSignatureStrings(QTextStream &s, @@ -5294,7 +5296,7 @@ void CppGenerator::writeClassRegister(QTextStream &s, if (!classContext.forSmartPointer()) typeName = metaClass->name(); else - typeName = classContext.preciseType()->cppSignature(); + typeName = classContext.preciseType().cppSignature(); // 2:typeName s << INDENT << "\"" << typeName << "\",\n"; @@ -5306,7 +5308,7 @@ void CppGenerator::writeClassRegister(QTextStream &s, if (isObjectType(classTypeEntry)) s << '*'; } else { - s << classContext.preciseType()->cppSignature(); + s << classContext.preciseType().cppSignature(); } s << "\",\n"; @@ -5472,7 +5474,7 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, const Generat if (!context.forSmartPointer()) nameVariants << metaClass->name(); else - nameVariants << context.preciseType()->cppSignature(); + nameVariants << context.preciseType().cppSignature(); const AbstractMetaClass *enclosingClass = metaClass->enclosingClass(); while (enclosingClass) { @@ -5485,7 +5487,7 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, const Generat if (!context.forSmartPointer()) className = metaClass->qualifiedCppName(); else - className = context.preciseType()->cppSignature(); + className = context.preciseType().cppSignature(); if (!metaClass->isNamespace() && !metaClass->isAbstract()) { // Qt metatypes are registered only on their first use, so we do this now. @@ -5883,12 +5885,12 @@ bool CppGenerator::finishGeneration() } // Initialize smart pointer types. - const QVector &smartPtrs = instantiatedSmartPointers(); - for (const AbstractMetaType *metaType : smartPtrs) { + const auto &smartPtrs = instantiatedSmartPointers(); + for (const AbstractMetaType &metaType : smartPtrs) { GeneratorContext context = contextForSmartPointer(nullptr, metaType); writeInitFunc(s_classInitDecl, s_classPythonDefines, INDENT, getInitFunctionName(context), - metaType->typeEntry()->targetLangEnclosingEntry()); + metaType.typeEntry()->targetLangEnclosingEntry()); } QString moduleFileName(outputDirectory() + QLatin1Char('/') + subDirectoryForPackage(packageName())); @@ -6023,8 +6025,8 @@ bool CppGenerator::finishGeneration() const TypeEntry *externalType = it.key(); s << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << Qt::endl; for (const AbstractMetaClass *sourceClass : it.value()) { - AbstractMetaType *sourceType = buildAbstractMetaTypeFromAbstractMetaClass(sourceClass); - AbstractMetaType *targetType = buildAbstractMetaTypeFromTypeEntry(externalType); + AbstractMetaType sourceType = buildAbstractMetaTypeFromAbstractMetaClass(sourceClass); + AbstractMetaType targetType = buildAbstractMetaTypeFromTypeEntry(externalType); writePythonToCppConversionFunctions(s, sourceType, targetType); } } @@ -6041,11 +6043,11 @@ bool CppGenerator::finishGeneration() s << Qt::endl; } - const QVector &containers = instantiatedContainers(); + const auto &containers = instantiatedContainers(); if (!containers.isEmpty()) { s << "// Container Type converters.\n\n"; - for (const AbstractMetaType *container : containers) { - s << "// C++ to Python conversion for type '" << container->cppSignature() << "'.\n"; + for (const AbstractMetaType &container : containers) { + s << "// C++ to Python conversion for type '" << container.cppSignature() << "'.\n"; writeContainerConverterFunctions(s, container); } s << Qt::endl; @@ -6055,8 +6057,8 @@ bool CppGenerator::finishGeneration() const auto smartPointersList = instantiatedSmartPointers(); if (!smartPointersList.isEmpty()) { s << "// SmartPointers converters.\n\n"; - for (const AbstractMetaType *smartPointer : smartPointersList) { - s << "// C++ to Python conversion for type '" << smartPointer->cppSignature() << "'.\n"; + for (const AbstractMetaType &smartPointer : smartPointersList) { + s << "// C++ to Python conversion for type '" << smartPointer.cppSignature() << "'.\n"; writeSmartPointerConverterFunctions(s, smartPointer); } s << Qt::endl; @@ -6129,7 +6131,7 @@ bool CppGenerator::finishGeneration() if (!containers.isEmpty()) { s << Qt::endl; - for (const AbstractMetaType *container : containers) { + for (const AbstractMetaType &container : containers) { writeContainerConverterInitialization(s, container); s << Qt::endl; } @@ -6137,7 +6139,7 @@ bool CppGenerator::finishGeneration() if (!smartPointersList.isEmpty()) { s << Qt::endl; - for (const AbstractMetaType *smartPointer : smartPointersList) { + for (const AbstractMetaType &smartPointer : smartPointersList) { writeSmartPointerConverterInitialization(s, smartPointer); s << Qt::endl; } @@ -6289,10 +6291,10 @@ void CppGenerator::writeParentChildManagement(QTextStream &s, const AbstractMeta void CppGenerator::writeReturnValueHeuristics(QTextStream &s, const AbstractMetaFunction *func) { - AbstractMetaType *type = func->type(); + const AbstractMetaType &type = func->type(); if (!useReturnValueHeuristic() || !func->ownerClass() - || type->isVoid() + || type.isVoid() || func->isStatic() || func->isConstructor() || !func->typeReplaced(0).isEmpty()) { @@ -6347,7 +6349,7 @@ void CppGenerator::writeDefaultSequenceMethods(QTextStream &s, const GeneratorCo qFatal("shiboken: %s: Internal error, no instantiations of \"%s\" were found.", __FUNCTION__, qPrintable(metaClass->qualifiedCppName())); } - const AbstractMetaType *itemType = instantiations.constFirst(); + const AbstractMetaType &itemType = instantiations.constFirst(); s << INDENT << "return "; writeToPythonConversion(s, itemType, metaClass, QLatin1String("*_item")); @@ -6363,12 +6365,12 @@ void CppGenerator::writeDefaultSequenceMethods(QTextStream &s, const GeneratorCo s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR << ";\n"; s << INDENT << "if (!"; - writeTypeCheck(s, itemType, QLatin1String("pyArg"), isNumber(itemType->typeEntry())); + writeTypeCheck(s, itemType, QLatin1String("pyArg"), isNumber(itemType.typeEntry())); s << ") {\n"; { Indentation indent(INDENT); s << INDENT << "PyErr_SetString(PyExc_TypeError, \"attributed value with wrong type, '"; - s << itemType->name() << "' or other convertible type expected\");\n"; + s << itemType.name() << "' or other convertible type expected\");\n"; s << INDENT << "return -1;\n"; } s << INDENT << "}\n"; diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h index 41bd17f21..25d4b22db 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.h +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h @@ -79,9 +79,9 @@ private: const GeneratorContext &classContext); void writeCustomConverterRegister(QTextStream &s, const CustomConversion *customConversion, const QString &converterVar); - void writeContainerConverterFunctions(QTextStream &s, const AbstractMetaType *containerType); + void writeContainerConverterFunctions(QTextStream &s, const AbstractMetaType &containerType); - void writeSmartPointerConverterFunctions(QTextStream &s, const AbstractMetaType *smartPointerType); + void writeSmartPointerConverterFunctions(QTextStream &s, const AbstractMetaType &smartPointerType); void writeMethodWrapperPreamble(QTextStream &s, OverloadData &overloadData, const GeneratorContext &context); @@ -107,7 +107,7 @@ private: /// Writes the check section for the validity of wrapped C++ objects. void writeInvalidPyObjectCheck(QTextStream &s, const QString &pyObj); - void writeTypeCheck(QTextStream &s, const AbstractMetaType *argType, const QString &argumentName, + void writeTypeCheck(QTextStream &s, AbstractMetaType argType, const QString &argumentName, bool isNumber = false, const QString &customType = QString(), bool rejectNull = false); void writeTypeCheck(QTextStream& s, const OverloadData *overloadData, QString argumentName); @@ -138,7 +138,7 @@ private: * \param defaultValue an optional default value to be used instead of the conversion result * \param castArgumentAsUnused if true the converted argument is cast as unused to avoid compiler warnings */ - void writeArgumentConversion(QTextStream &s, const AbstractMetaType *argType, + void writeArgumentConversion(QTextStream &s, const AbstractMetaType &argType, const QString &argName, const QString &pyArgName, const AbstractMetaClass *context = nullptr, const QString &defaultValue = QString(), @@ -155,10 +155,10 @@ 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); + const AbstractMetaType getArgumentType(const AbstractMetaFunction *func, int argPos); void writePythonToCppTypeConversion(QTextStream &s, - const AbstractMetaType *type, + const AbstractMetaType &type, const QString &pyIn, const QString &cppOut, const AbstractMetaClass *context = nullptr, @@ -206,18 +206,18 @@ private: /// Returns the name of a Python to C++ conversion function. static QString pythonToCppFunctionName(const QString &sourceTypeName, const QString &targetTypeName); - static QString pythonToCppFunctionName(const AbstractMetaType *sourceType, const AbstractMetaType *targetType); + static QString pythonToCppFunctionName(const AbstractMetaType &sourceType, const AbstractMetaType &targetType); static QString pythonToCppFunctionName(const CustomConversion::TargetToNativeConversion *toNative, const TypeEntry *targetType); /// Returns the name of a Python to C++ convertible check function. static QString convertibleToCppFunctionName(const QString &sourceTypeName, const QString &targetTypeName); - static QString convertibleToCppFunctionName(const AbstractMetaType *sourceType, const AbstractMetaType *targetType); + static QString convertibleToCppFunctionName(const AbstractMetaType &sourceType, const AbstractMetaType &targetType); static QString convertibleToCppFunctionName(const CustomConversion::TargetToNativeConversion *toNative, const TypeEntry *targetType); /// Writes a C++ to Python conversion function. void writeCppToPythonFunction(QTextStream &s, const QString &code, const QString &sourceTypeName, QString targetTypeName = QString()); void writeCppToPythonFunction(QTextStream &s, const CustomConversion *customConversion); - void writeCppToPythonFunction(QTextStream &s, const AbstractMetaType *containerType); + void writeCppToPythonFunction(QTextStream &s, const AbstractMetaType &containerType); /// Writes a Python to C++ conversion function. void writePythonToCppFunction(QTextStream &s, const QString &code, const QString &sourceTypeName, const QString &targetTypeName); @@ -232,8 +232,8 @@ private: /// Writes a pair of Python to C++ conversion and check functions. void writePythonToCppConversionFunctions(QTextStream &s, - const AbstractMetaType *sourceType, - const AbstractMetaType *targetType, + const AbstractMetaType &sourceType, + const AbstractMetaType &targetType, QString typeCheck = QString(), QString conversion = QString(), const QString &preConversion = QString()); @@ -243,7 +243,7 @@ private: const TypeEntry *targetType); /// Writes a pair of Python to C++ conversion and check functions for instantiated container types. - void writePythonToCppConversionFunctions(QTextStream &s, const AbstractMetaType *containerType); + void writePythonToCppConversionFunctions(QTextStream &s, const AbstractMetaType &containerType); void writeAddPythonToCppConversion(QTextStream &s, const QString &converterVar, const QString &pythonToCppFunc, const QString &isConvertibleFunc); @@ -298,7 +298,7 @@ private: void writeSetterFunctionPreamble(QTextStream &s, const QString &name, const QString &funcName, - const AbstractMetaType *type, + const AbstractMetaType &type, const GeneratorContext &context); void writeSetterFunction(QTextStream &s, const AbstractMetaField *metaField, @@ -333,8 +333,8 @@ private: 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 writeSmartPointerConverterInitialization(QTextStream &s, const AbstractMetaType *type); + void writeContainerConverterInitialization(QTextStream &s, const AbstractMetaType &type); + void writeSmartPointerConverterInitialization(QTextStream &s, const AbstractMetaType &ype); void writeExtendedConverterInitialization(QTextStream &s, const TypeEntry *externalType, const QVector& conversions); void writeParentChildManagement(QTextStream &s, const AbstractMetaFunction *func, bool userHeuristicForReturn); @@ -378,7 +378,7 @@ private: bool hasBoolCast(const AbstractMetaClass *metaClass) const { return boolCast(metaClass) != nullptr; } - const AbstractMetaType *findSmartPointerInstantiation(const TypeEntry *entry) const; + AbstractMetaType findSmartPointerInstantiation(const TypeEntry *entry) const; // Number protocol structure members names. static QHash m_nbFuncs; diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.cpp b/sources/shiboken2/generator/shiboken2/headergenerator.cpp index c780df01a..89f02f0b2 100644 --- a/sources/shiboken2/generator/shiboken2/headergenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/headergenerator.cpp @@ -53,8 +53,7 @@ QString HeaderGenerator::fileNameForContext(const GeneratorContext &context) con fileNameBase.replace(QLatin1String("::"), QLatin1String("_")); return fileNameBase + fileNameSuffix(); } - const AbstractMetaType *smartPointerType = context.preciseType(); - QString fileNameBase = getFileNameBaseForSmartPointer(smartPointerType, metaClass); + QString fileNameBase = getFileNameBaseForSmartPointer(context.preciseType(), metaClass); return fileNameBase + fileNameSuffix(); } @@ -68,15 +67,15 @@ void HeaderGenerator::writeCopyCtor(QTextStream &s, const AbstractMetaClass *met void HeaderGenerator::writeProtectedFieldAccessors(QTextStream &s, const AbstractMetaField *field) const { - AbstractMetaType *metaType = field->type(); - QString fieldType = metaType->cppSignature(); + const AbstractMetaType &metaType = field->type(); + QString fieldType = metaType.cppSignature(); QString fieldName = field->enclosingClass()->qualifiedCppName() + QLatin1String("::") + field->name(); // Force use of pointer to return internal variable memory - bool useReference = (!metaType->isConstant() && - !metaType->isEnum() && - !metaType->isPrimitive() && - metaType->indirections() == 0); + bool useReference = (!metaType.isConstant() && + !metaType.isEnum() && + !metaType.isPrimitive() && + metaType.indirections() == 0); // Get function @@ -249,12 +248,12 @@ void HeaderGenerator::writeFunction(QTextStream &s, const AbstractMetaFunction * for (const AbstractMetaArgument *arg : arguments) { QString argName = arg->name(); const TypeEntry *enumTypeEntry = nullptr; - if (arg->type()->isFlags()) - enumTypeEntry = static_cast(arg->type()->typeEntry())->originator(); - else if (arg->type()->isEnum()) - enumTypeEntry = arg->type()->typeEntry(); + if (arg->type().isFlags()) + enumTypeEntry = static_cast(arg->type().typeEntry())->originator(); + else if (arg->type().isEnum()) + enumTypeEntry = arg->type().typeEntry(); if (enumTypeEntry) - argName = QString::fromLatin1("%1(%2)").arg(arg->type()->cppSignature(), argName); + argName = QString::fromLatin1("%1(%2)").arg(arg->type().cppSignature(), argName); args << argName; } s << args.join(QLatin1String(", ")) << ')'; @@ -422,13 +421,13 @@ bool HeaderGenerator::finishGeneration() // Write the smart pointer define indexes. int smartPointerCountIndex = getMaxTypeIndex(); int smartPointerCount = 0; - const QVector &instantiatedSmartPtrs = instantiatedSmartPointers(); - for (const AbstractMetaType *metaType : instantiatedSmartPtrs) { + const QVector &instantiatedSmartPtrs = instantiatedSmartPointers(); + for (const AbstractMetaType &metaType : instantiatedSmartPtrs) { QString indexName = getTypeIndexVariableName(metaType); _writeTypeIndexValue(macrosStream, indexName, smartPointerCountIndex); - macrosStream << ", // " << metaType->cppSignature() << Qt::endl; + macrosStream << ", // " << metaType.cppSignature() << Qt::endl; // Add a the same value for const pointees (shared_ptr). - const auto ptrName = metaType->typeEntry()->entryName(); + const auto ptrName = metaType.typeEntry()->entryName(); int pos = indexName.indexOf(ptrName, 0, Qt::CaseInsensitive); if (pos >= 0) { indexName.insert(pos + ptrName.size() + 1, QLatin1String("CONST")); @@ -467,10 +466,10 @@ bool HeaderGenerator::finishGeneration() _writeTypeIndexValueLine(macrosStream, getTypeIndexVariableName(ptype), pCount++); } - const QVector &containers = instantiatedContainers(); - for (const AbstractMetaType *container : containers) { + const QVector &containers = instantiatedContainers(); + for (const AbstractMetaType &container : containers) { _writeTypeIndexValue(macrosStream, getTypeIndexVariableName(container), pCount); - macrosStream << ", // " << container->cppSignature() << Qt::endl; + macrosStream << ", // " << container.cppSignature() << Qt::endl; pCount++; } @@ -519,8 +518,8 @@ bool HeaderGenerator::finishGeneration() writeSbkTypeFunction(typeFunctions, metaClass); } - for (const AbstractMetaType *metaType : instantiatedSmartPtrs) { - const TypeEntry *classType = metaType->typeEntry(); + for (const AbstractMetaType &metaType : instantiatedSmartPtrs) { + const TypeEntry *classType = metaType.typeEntry(); includes << classType->include(); writeSbkTypeFunction(typeFunctions, metaType); } @@ -628,9 +627,9 @@ void HeaderGenerator::writeSbkTypeFunction(QTextStream &s, const AbstractMetaCla << "{ return reinterpret_cast(" << cpythonTypeNameExt(cppClass->typeEntry()) << "); }\n"; } -void HeaderGenerator::writeSbkTypeFunction(QTextStream &s, const AbstractMetaType *metaType) +void HeaderGenerator::writeSbkTypeFunction(QTextStream &s, const AbstractMetaType &metaType) { - s << "template<> inline PyTypeObject *SbkType< ::" << metaType->cppSignature() << " >() " + s << "template<> inline PyTypeObject *SbkType< ::" << metaType.cppSignature() << " >() " << "{ return reinterpret_cast(" << cpythonTypeNameExt(metaType) << "); }\n"; } @@ -648,12 +647,12 @@ void HeaderGenerator::writeInheritedOverloads(QTextStream &s) for (const AbstractMetaArgument *arg : arguments) { QString argName = arg->name(); const TypeEntry *enumTypeEntry = nullptr; - if (arg->type()->isFlags()) - enumTypeEntry = static_cast(arg->type()->typeEntry())->originator(); - else if (arg->type()->isEnum()) - enumTypeEntry = arg->type()->typeEntry(); + if (arg->type().isFlags()) + enumTypeEntry = static_cast(arg->type().typeEntry())->originator(); + else if (arg->type().isEnum()) + enumTypeEntry = arg->type().typeEntry(); if (enumTypeEntry) - argName = arg->type()->cppSignature() + QLatin1Char('(') + argName + QLatin1Char(')'); + argName = arg->type().cppSignature() + QLatin1Char('(') + argName + QLatin1Char(')'); args << argName; } s << args.join(QLatin1String(", ")) << ')'; diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.h b/sources/shiboken2/generator/shiboken2/headergenerator.h index 30ce06636..d02516b8d 100644 --- a/sources/shiboken2/generator/shiboken2/headergenerator.h +++ b/sources/shiboken2/generator/shiboken2/headergenerator.h @@ -57,7 +57,7 @@ private: void writeFunction(QTextStream &s, const AbstractMetaFunction *func); void writeSbkTypeFunction(QTextStream &s, const AbstractMetaEnum *cppEnum); void writeSbkTypeFunction(QTextStream &s, const AbstractMetaClass *cppClass); - void writeSbkTypeFunction(QTextStream &s, const AbstractMetaType *metaType); + void writeSbkTypeFunction(QTextStream &s, const AbstractMetaType &metaType); void writeTypeIndexValueLine(QTextStream &s, const TypeEntry *typeEntry); void writeTypeIndexValueLines(QTextStream &s, const AbstractMetaClass *metaClass); void writeProtectedEnumSurrogate(QTextStream &s, const AbstractMetaEnum *cppEnum); diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp index 193384853..50e82b1e6 100644 --- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp +++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp @@ -51,14 +51,14 @@ static const TypeEntry *getReferencedTypeEntry(const TypeEntry *typeEntry) return typeEntry; } -static QString getTypeName(const AbstractMetaType *type) +static QString getTypeName(const AbstractMetaType &type) { - const TypeEntry *typeEntry = getReferencedTypeEntry(type->typeEntry()); + const TypeEntry *typeEntry = getReferencedTypeEntry(type.typeEntry()); QString typeName = typeEntry->name(); if (typeEntry->isContainer()) { QStringList types; - for (const auto *cType : type->instantiations()) { - const TypeEntry *typeEntry = getReferencedTypeEntry(cType->typeEntry()); + for (const auto &cType : type.instantiations()) { + const TypeEntry *typeEntry = getReferencedTypeEntry(cType.typeEntry()); types << typeEntry->name(); } typeName += QLatin1Char('<') + types.join(QLatin1Char(',')) + QLatin1String(" >"); @@ -71,15 +71,15 @@ static QString getTypeName(const OverloadData *ov) return ov->hasArgumentTypeReplace() ? ov->argumentTypeReplaced() : getTypeName(ov->argType()); } -static bool typesAreEqual(const AbstractMetaType *typeA, const AbstractMetaType *typeB) +static bool typesAreEqual(const AbstractMetaType &typeA, const AbstractMetaType &typeB) { - if (typeA->typeEntry() == typeB->typeEntry()) { - if (typeA->isContainer() || typeA->isSmartPointer()) { - if (typeA->instantiations().size() != typeB->instantiations().size()) + if (typeA.typeEntry() == typeB.typeEntry()) { + if (typeA.isContainer() || typeA.isSmartPointer()) { + if (typeA.instantiations().size() != typeB.instantiations().size()) return false; - for (int i = 0; i < typeA->instantiations().size(); ++i) { - if (!typesAreEqual(typeA->instantiations().at(i), typeB->instantiations().at(i))) + for (int i = 0; i < typeA.instantiations().size(); ++i) { + if (!typesAreEqual(typeA.instantiations().at(i), typeB.instantiations().at(i))) return false; } return true; @@ -132,8 +132,8 @@ struct OverloadSortData * an instantiation taken either from an implicit conversion expressed by the function argument, * or from the string argument implicitConvTypeName. */ -static QString getImplicitConversionTypeName(const AbstractMetaType *containerType, - const AbstractMetaType *instantiation, +static QString getImplicitConversionTypeName(const AbstractMetaType &containerType, + const AbstractMetaType &instantiation, const AbstractMetaFunction *function, const QString &implicitConvTypeName = QString()) { @@ -146,10 +146,10 @@ static QString getImplicitConversionTypeName(const AbstractMetaType *containerTy impConv = getTypeName(function->arguments().constFirst()->type()); QStringList types; - for (const auto *otherType : containerType->instantiations()) + for (const auto &otherType : containerType.instantiations()) types << (otherType == instantiation ? impConv : getTypeName(otherType)); - return containerType->typeEntry()->qualifiedCppName() + QLatin1Char('<') + return containerType.typeEntry()->qualifiedCppName() + QLatin1Char('<') + types.join(QLatin1String(", ")) + QLatin1String(" >"); } @@ -256,7 +256,7 @@ void OverloadData::sortNextOverloads() qstringIndex = sortData.lastProcessedItemId(); } - for (const auto *instantiation : ov->argType()->instantiations()) { + for (const auto &instantiation : ov->argType().instantiations()) { // Add dependencies for type instantiation of container. QString typeName = getTypeName(instantiation); sortData.mapType(typeName); @@ -266,7 +266,7 @@ void OverloadData::sortNextOverloads() // and being PointF implicitly convertible from Point, an list instantiation with T // as Point must come before the PointF instantiation, or else list will never // be called. In the case of primitive types, list must come before list. - if (instantiation->isPrimitive() && (signedIntegerPrimitives.contains(instantiation->name()))) { + if (instantiation.isPrimitive() && (signedIntegerPrimitives.contains(instantiation.name()))) { for (const QString &primitive : qAsConst(nonIntegerPrimitives)) sortData.mapType(getImplicitConversionTypeName(ov->argType(), instantiation, nullptr, primitive)); } else { @@ -300,7 +300,7 @@ void OverloadData::sortNextOverloads() MetaFunctionList involvedConversions; for (OverloadData *ov : qAsConst(m_nextOverloadData)) { - const AbstractMetaType *targetType = ov->argType(); + const AbstractMetaType &targetType = ov->argType(); const QString targetTypeEntryName(getTypeName(ov)); int targetTypeId = sortData.map[targetTypeEntryName]; @@ -329,8 +329,8 @@ void OverloadData::sortNextOverloads() } // Process inheritance relationships - if (targetType->isValue() || targetType->isObject()) { - const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_generator->classes(), targetType->typeEntry()); + if (targetType.isValue() || targetType.isObject()) { + const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_generator->classes(), targetType.typeEntry()); const AbstractMetaClassList &ancestors = m_generator->getAllAncestors(metaClass); for (const AbstractMetaClass *ancestor : ancestors) { QString ancestorTypeName = ancestor->typeEntry()->name(); @@ -343,14 +343,14 @@ void OverloadData::sortNextOverloads() } // Process template instantiations - for (const auto *instantiation : targetType->instantiations()) { + for (const auto &instantiation : targetType.instantiations()) { if (sortData.map.contains(getTypeName(instantiation))) { int convertible = sortData.map[getTypeName(instantiation)]; if (!graph.containsEdge(targetTypeId, convertible)) // Avoid cyclic dependency. graph.addEdge(convertible, targetTypeId); - if (instantiation->isPrimitive() && (signedIntegerPrimitives.contains(instantiation->name()))) { + if (instantiation.isPrimitive() && (signedIntegerPrimitives.contains(instantiation.name()))) { for (const QString &primitive : qAsConst(nonIntegerPrimitives)) { QString convertibleTypeName = getImplicitConversionTypeName(ov->argType(), instantiation, nullptr, primitive); if (!graph.containsEdge(targetTypeId, sortData.map[convertibleTypeName])) // Avoid cyclic dependency. @@ -396,7 +396,7 @@ void OverloadData::sortNextOverloads() graph.addEdge(targetTypeId, qstringIndex); } - if (targetType->isEnum()) { + if (targetType.isEnum()) { // Enum values must precede primitive types. for (auto id : foundPrimitiveTypeIds) graph.addEdge(targetTypeId, id); @@ -408,8 +408,8 @@ void OverloadData::sortNextOverloads() graph.addEdge(sortData.map.value(qStringT()), sortData.map.value(qByteArrayT())); for (OverloadData *ov : qAsConst(m_nextOverloadData)) { - const AbstractMetaType *targetType = ov->argType(); - if (!targetType->isEnum()) + const AbstractMetaType &targetType = ov->argType(); + if (!targetType.isEnum()) continue; QString targetTypeEntryName = getTypeName(targetType); @@ -500,7 +500,7 @@ OverloadData::OverloadData(const AbstractMetaFunctionList &overloads, const Shib } OverloadData::OverloadData(OverloadData *headOverloadData, const AbstractMetaFunction *func, - const AbstractMetaType *argType, int argPos) + const AbstractMetaType &argType, int argPos) : m_minArgs(256), m_maxArgs(0), m_argPos(argPos), m_argType(argType), m_headOverloadData(headOverloadData), m_previousOverloadData(nullptr), m_generator(nullptr) @@ -537,7 +537,7 @@ void OverloadData::addOverload(const AbstractMetaFunction *func) OverloadData *OverloadData::addOverloadData(const AbstractMetaFunction *func, const AbstractMetaArgument *arg) { - const AbstractMetaType *argType = arg->type(); + const AbstractMetaType &argType = arg->type(); OverloadData *overloadData = nullptr; if (!func->isOperatorOverload()) { for (OverloadData *tmp : qAsConst(m_nextOverloadData)) { @@ -576,7 +576,7 @@ QStringList OverloadData::returnTypes() const if (!func->typeReplaced(0).isEmpty()) retTypes << func->typeReplaced(0); else if (!func->argumentRemoved(0)) - retTypes << func->type()->cppSignature(); + retTypes << func->type().cppSignature(); } return retTypes.values(); } @@ -591,7 +591,7 @@ bool OverloadData::hasVarargs() const { for (const AbstractMetaFunction *func : m_overloads) { AbstractMetaArgumentList args = func->arguments(); - if (args.size() > 1 && args.constLast()->type()->isVarargs()) + if (args.size() > 1 && args.constLast()->type().isVarargs()) return true; } return false; @@ -873,7 +873,7 @@ QString OverloadData::dumpGraph() const s << "legend [fontsize=9 fontname=freemono shape=rect label=\""; for (const AbstractMetaFunction *func : m_overloads) { s << "f" << functionNumber(func) << " : " - << toHtml(func->type()->cppSignature()) + << toHtml(func->type().cppSignature()) << ' ' << toHtml(func->minimalSignature()) << "\\l"; } s << "\"];\n"; @@ -895,7 +895,7 @@ QString OverloadData::dumpGraph() const // Function return type s << "original type" - << toHtml(rfunc->type()->cppSignature()) + << toHtml(rfunc->type().cppSignature()) << ""; // Shows type changes for all function signatures @@ -944,12 +944,12 @@ QString OverloadData::dumpGraph() const s << "arg #" << argPos() << ""; // Argument type information - QString type = hasArgumentTypeReplace() ? argumentTypeReplaced() : argType()->cppSignature(); + QString type = hasArgumentTypeReplace() ? argumentTypeReplaced() : argType().cppSignature(); s << "type"; s << toHtml(type) << ""; if (hasArgumentTypeReplace()) { s << "orig. type"; - s << toHtml(argType()->cppSignature()) << ""; + s << toHtml(argType().cppSignature()) << ""; } // Overloads for the signature to present point diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.h b/sources/shiboken2/generator/shiboken2/overloaddata.h index 9ffb084ff..8c165a0be 100644 --- a/sources/shiboken2/generator/shiboken2/overloaddata.h +++ b/sources/shiboken2/generator/shiboken2/overloaddata.h @@ -52,7 +52,7 @@ public: int maxArgs() const { return m_headOverloadData->m_maxArgs; } int argPos() const { return m_argPos; } - const AbstractMetaType *argType() const { return m_argType; } + const AbstractMetaType &argType() const { return m_argType; } /// Returns a string list containing all the possible return types (including void) for the current OverloadData. QStringList returnTypes() const; @@ -133,7 +133,7 @@ public: private: OverloadData(OverloadData *headOverloadData, const AbstractMetaFunction *func, - const AbstractMetaType *argType, int argPos); + const AbstractMetaType &argType, int argPos); void addOverload(const AbstractMetaFunction *func); OverloadData *addOverloadData(const AbstractMetaFunction *func, const AbstractMetaArgument *arg); @@ -147,7 +147,7 @@ private: int m_minArgs; int m_maxArgs; int m_argPos; - const AbstractMetaType *m_argType; + AbstractMetaType m_argType; QString m_argTypeReplaced; MetaFunctionList m_overloads; diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp index 9ca5145a1..efbb81194 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp @@ -282,14 +282,14 @@ void ShibokenGenerator::initKnownPythonTypes() << QLatin1String("PyObject*") << QLatin1String("PyObject *") << QLatin1String("PyTupleObject*"); } -QString ShibokenGenerator::translateTypeForWrapperMethod(const AbstractMetaType *cType, +QString ShibokenGenerator::translateTypeForWrapperMethod(const AbstractMetaType &cType, const AbstractMetaClass *context, Options options) const { - if (cType->isArray()) - return translateTypeForWrapperMethod(cType->arrayElementType(), context, options) + QLatin1String("[]"); + if (cType.isArray()) + return translateTypeForWrapperMethod(*cType.arrayElementType(), context, options) + QLatin1String("[]"); - if (avoidProtectedHack() && cType->isEnum()) { + if (avoidProtectedHack() && cType.isEnum()) { const AbstractMetaEnum *metaEnum = findAbstractMetaEnum(cType); if (metaEnum && metaEnum->isProtected()) return protectedEnumSurrogateName(metaEnum); @@ -507,9 +507,9 @@ QString ShibokenGenerator::guessScopeForDefaultFlagsValue(const AbstractMetaFunc Q_ASSERT(numberRegEx.isValid()); if (numberRegEx.match(value).hasMatch()) { QString typeName = translateTypeForWrapperMethod(arg->type(), func->implementingClass()); - if (arg->type()->isConstant()) + if (arg->type().isConstant()) typeName.remove(0, sizeof("const ") / sizeof(char) - 1); - switch (arg->type()->referenceType()) { + switch (arg->type().referenceType()) { case NoReference: break; case LValueReference: @@ -579,23 +579,23 @@ QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction // Do not qualify macros by class name, eg QSGGeometry(..., int t = GL_UNSIGNED_SHORT); static const QRegularExpression macroRegEx(QStringLiteral("^[A-Z_][A-Z0-9_]*$")); Q_ASSERT(macroRegEx.isValid()); - if (arg->type()->isPrimitive() && macroRegEx.match(value).hasMatch()) + if (arg->type().isPrimitive() && macroRegEx.match(value).hasMatch()) return value; QString prefix; - if (arg->type()->isEnum()) { + if (arg->type().isEnum()) { if (const AbstractMetaEnum *metaEnum = findAbstractMetaEnum(arg->type())) prefix = resolveScopePrefix(metaEnum, value); - } else if (arg->type()->isFlags()) { + } else if (arg->type().isFlags()) { value = guessScopeForDefaultFlagsValue(func, arg, value); - } else if (arg->type()->typeEntry()->isValue()) { - const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(classes(), arg->type()->typeEntry()); + } else if (arg->type().typeEntry()->isValue()) { + const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(classes(), arg->type().typeEntry()); if (enumValueRegEx.match(value).hasMatch() && value != QLatin1String("NULL")) prefix = resolveScopePrefix(metaClass, value); - } else if (arg->type()->isPrimitive() && arg->type()->name() == intT()) { + } else if (arg->type().isPrimitive() && arg->type().name() == intT()) { if (enumValueRegEx.match(value).hasMatch() && func->implementingClass()) prefix = resolveScopePrefix(func->implementingClass(), value); - } else if(arg->type()->isPrimitive()) { + } else if (arg->type().isPrimitive()) { static const QRegularExpression unknowArgumentRegEx(QStringLiteral("^(?:[A-Za-z_][\\w:]*\\()?([A-Za-z_]\\w*)(?:\\))?$")); // [PrimitiveType(] DESIREDNAME [)] Q_ASSERT(unknowArgumentRegEx.isValid()); const QRegularExpressionMatch match = unknowArgumentRegEx.match(value); @@ -661,12 +661,12 @@ QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaClass *metaClass return cpythonWrapperCPtr(metaClass->typeEntry(), argName); } -QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaType *metaType, +QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaType &metaType, const QString &argName) const { - if (!ShibokenGenerator::isWrapperType(metaType->typeEntry())) + if (!ShibokenGenerator::isWrapperType(metaType.typeEntry())) return QString(); - return QLatin1String("reinterpret_cast< ::") + metaType->cppSignature() + return QLatin1String("reinterpret_cast< ::") + metaType.cppSignature() + QLatin1String(" *>(Shiboken::Conversions::cppPointer(") + cpythonTypeNameExt(metaType) + QLatin1String(", reinterpret_cast(") + argName + QLatin1String(")))"); } @@ -681,7 +681,7 @@ QString ShibokenGenerator::cpythonWrapperCPtr(const TypeEntry *type, + QLatin1String(", reinterpret_cast(") + argName + QLatin1String(")))"); } -void ShibokenGenerator::writeToPythonConversion(QTextStream & s, const AbstractMetaType *type, +void ShibokenGenerator::writeToPythonConversion(QTextStream & s, const AbstractMetaType &type, const AbstractMetaClass * /* context */, const QString &argumentName) { @@ -694,7 +694,7 @@ void ShibokenGenerator::writeToCppConversion(QTextStream &s, const AbstractMetaC s << cpythonToCppConversionFunction(metaClass) << inArgName << ", &" << outArgName << ')'; } -void ShibokenGenerator::writeToCppConversion(QTextStream &s, const AbstractMetaType *type, const AbstractMetaClass *context, +void ShibokenGenerator::writeToCppConversion(QTextStream &s, const AbstractMetaType &type, const AbstractMetaClass *context, const QString &inArgName, const QString &outArgName) { s << cpythonToCppConversionFunction(type, context) << inArgName << ", &" << outArgName << ')'; @@ -736,19 +736,19 @@ QString ShibokenGenerator::getFormatUnitString(const AbstractMetaFunction *func, if (!func->typeReplaced(arg->argumentIndex() + 1).isEmpty()) { result += QLatin1Char(objType); - } else if (arg->type()->isObject() - || arg->type()->isValue() - || arg->type()->isValuePointer() - || arg->type()->isNativePointer() - || arg->type()->isEnum() - || arg->type()->isFlags() - || arg->type()->isContainer() - || arg->type()->isSmartPointer() - || arg->type()->referenceType() == LValueReference) { + } else if (arg->type().isObject() + || arg->type().isValue() + || arg->type().isValuePointer() + || arg->type().isNativePointer() + || arg->type().isEnum() + || arg->type().isFlags() + || arg->type().isContainer() + || arg->type().isSmartPointer() + || arg->type().referenceType() == LValueReference) { result += QLatin1Char(objType); - } else if (arg->type()->isPrimitive()) { + } else if (arg->type().isPrimitive()) { const auto *ptype = - static_cast(arg->type()->typeEntry()); + static_cast(arg->type().typeEntry()); if (ptype->basicReferencedTypeEntry()) ptype = ptype->basicReferencedTypeEntry(); if (m_formatUnits.contains(ptype->name())) @@ -769,11 +769,11 @@ QString ShibokenGenerator::getFormatUnitString(const AbstractMetaFunction *func, return result; } -QString ShibokenGenerator::cpythonBaseName(const AbstractMetaType *type) +QString ShibokenGenerator::cpythonBaseName(const AbstractMetaType &type) { if (isCString(type)) return QLatin1String("PyString"); - return cpythonBaseName(type->typeEntry()); + return cpythonBaseName(type.typeEntry()); } QString ShibokenGenerator::cpythonBaseName(const AbstractMetaClass *metaClass) @@ -847,24 +847,26 @@ QString ShibokenGenerator::cpythonTypeNameExt(const TypeEntry *type) const + getTypeIndexVariableName(type) + QLatin1Char(']'); } -QString ShibokenGenerator::converterObject(const AbstractMetaType *type) +QString ShibokenGenerator::converterObject(const AbstractMetaType &type) { if (isCString(type)) return QLatin1String("Shiboken::Conversions::PrimitiveTypeConverter()"); if (isVoidPointer(type)) return QLatin1String("Shiboken::Conversions::PrimitiveTypeConverter()"); - const AbstractMetaTypeCList nestedArrayTypes = type->nestedArrayTypes(); - if (!nestedArrayTypes.isEmpty() && nestedArrayTypes.constLast()->isCppPrimitive()) { + const AbstractMetaTypeList nestedArrayTypes = type.nestedArrayTypes(); + if (!nestedArrayTypes.isEmpty() && nestedArrayTypes.constLast().isCppPrimitive()) { return QStringLiteral("Shiboken::Conversions::ArrayTypeConverter<") - + nestedArrayTypes.constLast()->minimalSignature() + + nestedArrayTypes.constLast().minimalSignature() + QLatin1String(">(") + QString::number(nestedArrayTypes.size()) + QLatin1Char(')'); } - if (type->typeEntry()->isContainer() || type->typeEntry()->isSmartPointer()) { - return convertersVariableName(type->typeEntry()->targetLangPackage()) + + auto typeEntry = type.typeEntry(); + if (typeEntry->isContainer() || typeEntry->isSmartPointer()) { + return convertersVariableName(typeEntry->targetLangPackage()) + QLatin1Char('[') + getTypeIndexVariableName(type) + QLatin1Char(']'); } - return converterObject(type->typeEntry()); + return converterObject(typeEntry); } QString ShibokenGenerator::converterObject(const TypeEntry *type) @@ -894,9 +896,9 @@ QString ShibokenGenerator::converterObject(const TypeEntry *type) + QLatin1Char('[') + getTypeIndexVariableName(type) + QLatin1Char(']'); } -QString ShibokenGenerator::cpythonTypeNameExt(const AbstractMetaType *type) const +QString ShibokenGenerator::cpythonTypeNameExt(const AbstractMetaType &type) const { - return cppApiVariableName(type->typeEntry()->targetLangPackage()) + QLatin1Char('[') + return cppApiVariableName(type.typeEntry()->targetLangPackage()) + QLatin1Char('[') + getTypeIndexVariableName(type) + QLatin1Char(']'); } @@ -908,9 +910,9 @@ QString ShibokenGenerator::fixedCppTypeName(const CustomConversion::TargetToNati return fixedCppTypeName(toNative->sourceType()); return toNative->sourceTypeName(); } -QString ShibokenGenerator::fixedCppTypeName(const AbstractMetaType *type) +QString ShibokenGenerator::fixedCppTypeName(const AbstractMetaType &type) { - return fixedCppTypeName(type->typeEntry(), type->cppSignature()); + return fixedCppTypeName(type.typeEntry(), type.cppSignature()); } static QString _fixedCppTypeName(QString typeName) @@ -1012,9 +1014,9 @@ bool ShibokenGenerator::isNumber(const TypeEntry *type) return isNumber(pythonPrimitiveTypeName(static_cast(type))); } -bool ShibokenGenerator::isNumber(const AbstractMetaType *type) +bool ShibokenGenerator::isNumber(const AbstractMetaType &type) { - return isNumber(type->typeEntry()); + return isNumber(type.typeEntry()); } bool ShibokenGenerator::isPyInt(const TypeEntry *type) @@ -1025,9 +1027,9 @@ bool ShibokenGenerator::isPyInt(const TypeEntry *type) == QLatin1String("PyInt"); } -bool ShibokenGenerator::isPyInt(const AbstractMetaType *type) +bool ShibokenGenerator::isPyInt(const AbstractMetaType &type) { - return isPyInt(type->typeEntry()); + return isPyInt(type.typeEntry()); } bool ShibokenGenerator::isWrapperType(const TypeEntry *type) @@ -1040,21 +1042,21 @@ bool ShibokenGenerator::isWrapperType(const ComplexTypeEntry *type) { return isObjectType(type) || type->isValue() || type->isSmartPointer(); } -bool ShibokenGenerator::isWrapperType(const AbstractMetaType *metaType) +bool ShibokenGenerator::isWrapperType(const AbstractMetaType &metaType) { return isObjectType(metaType) - || metaType->typeEntry()->isValue() - || metaType->typeEntry()->isSmartPointer(); + || metaType.typeEntry()->isValue() + || metaType.typeEntry()->isSmartPointer(); } -bool ShibokenGenerator::isPointerToWrapperType(const AbstractMetaType *type) +bool ShibokenGenerator::isPointerToWrapperType(const AbstractMetaType &type) { - return (isObjectType(type) && type->indirections() == 1) || type->isValuePointer(); + return (isObjectType(type) && type.indirections() == 1) || type.isValuePointer(); } -bool ShibokenGenerator::isObjectTypeUsedAsValueType(const AbstractMetaType *type) +bool ShibokenGenerator::isObjectTypeUsedAsValueType(const AbstractMetaType &type) { - return type->typeEntry()->isObject() && type->referenceType() == NoReference && type->indirections() == 0; + return type.typeEntry()->isObject() && type.referenceType() == NoReference && type.indirections() == 0; } bool ShibokenGenerator::isValueTypeWithCopyConstructorOnly(const AbstractMetaClass *metaClass) @@ -1090,11 +1092,10 @@ bool ShibokenGenerator::isValueTypeWithCopyConstructorOnly(const TypeEntry *type return isValueTypeWithCopyConstructorOnly(AbstractMetaClass::findClass(classes(), type)); } -bool ShibokenGenerator::isValueTypeWithCopyConstructorOnly(const AbstractMetaType *type) const +bool ShibokenGenerator::isValueTypeWithCopyConstructorOnly(const AbstractMetaType &type) const { - if (!type || !type->typeEntry()->isValue()) - return false; - return isValueTypeWithCopyConstructorOnly(type->typeEntry()); + return type.typeEntry()->isValue() + && isValueTypeWithCopyConstructorOnly(type.typeEntry()); } bool ShibokenGenerator::isUserPrimitive(const TypeEntry *type) @@ -1108,11 +1109,11 @@ bool ShibokenGenerator::isUserPrimitive(const TypeEntry *type) && trueType->qualifiedCppName() != QLatin1String("std::string"); } -bool ShibokenGenerator::isUserPrimitive(const AbstractMetaType *type) +bool ShibokenGenerator::isUserPrimitive(const AbstractMetaType &type) { - if (type->indirections() != 0) + if (type.indirections() != 0) return false; - return isUserPrimitive(type->typeEntry()); + return isUserPrimitive(type.typeEntry()); } bool ShibokenGenerator::isCppPrimitive(const TypeEntry *type) @@ -1127,13 +1128,13 @@ bool ShibokenGenerator::isCppPrimitive(const TypeEntry *type) return trueType->qualifiedCppName() == QLatin1String("std::string"); } -bool ShibokenGenerator::isCppPrimitive(const AbstractMetaType *type) +bool ShibokenGenerator::isCppPrimitive(const AbstractMetaType &type) { if (isCString(type) || isVoidPointer(type)) return true; - if (type->indirections() != 0) + if (type.indirections() != 0) return false; - return isCppPrimitive(type->typeEntry()); + return isCppPrimitive(type.typeEntry()); } bool ShibokenGenerator::shouldDereferenceArgumentPointer(const AbstractMetaArgument *arg) @@ -1141,9 +1142,9 @@ bool ShibokenGenerator::shouldDereferenceArgumentPointer(const AbstractMetaArgum return shouldDereferenceAbstractMetaTypePointer(arg->type()); } -bool ShibokenGenerator::shouldDereferenceAbstractMetaTypePointer(const AbstractMetaType *metaType) +bool ShibokenGenerator::shouldDereferenceAbstractMetaTypePointer(const AbstractMetaType &metaType) { - return metaType->referenceType() == LValueReference && isWrapperType(metaType) && !isPointer(metaType); + return metaType.referenceType() == LValueReference && isWrapperType(metaType) && !isPointer(metaType); } bool ShibokenGenerator::visibilityModifiedToPrivate(const AbstractMetaFunction *func) @@ -1162,12 +1163,12 @@ bool ShibokenGenerator::isNullPtr(const QString &value) || value == QLatin1String("NULLPTR") || value == QLatin1String("{}"); } -QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType *metaType, bool genericNumberType) +QString ShibokenGenerator::cpythonCheckFunction(AbstractMetaType metaType, bool genericNumberType) { QString customCheck; - if (metaType->typeEntry()->isCustom()) { - AbstractMetaType *type; - customCheck = guessCPythonCheckFunction(metaType->typeEntry()->name(), &type); + if (metaType.typeEntry()->isCustom()) { + AbstractMetaType type; + customCheck = guessCPythonCheckFunction(metaType.typeEntry()->name(), &type); if (type) metaType = type; if (!customCheck.isEmpty()) @@ -1179,9 +1180,9 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType *metaType return QLatin1String("Shiboken::String::check"); if (isVoidPointer(metaType)) return QLatin1String("PyObject_Check"); - return cpythonCheckFunction(metaType->typeEntry(), genericNumberType); + return cpythonCheckFunction(metaType.typeEntry(), genericNumberType); } - auto typeEntry = metaType->typeEntry(); + auto typeEntry = metaType.typeEntry(); if (typeEntry->isContainer()) { QString typeCheck = QLatin1String("Shiboken::Conversions::"); ContainerTypeEntry::ContainerKind type = @@ -1193,7 +1194,7 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType *metaType || type == ContainerTypeEntry::StackContainer || type == ContainerTypeEntry::SetContainer || type == ContainerTypeEntry::QueueContainer) { - const AbstractMetaType *type = metaType->instantiations().constFirst(); + const AbstractMetaType &type = metaType.instantiations().constFirst(); if (isPointerToWrapperType(type)) { typeCheck += QString::fromLatin1("checkSequenceTypes(%1, ").arg(cpythonTypeNameExt(type)); } else if (isWrapperType(type)) { @@ -1209,8 +1210,8 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType *metaType || type == ContainerTypeEntry::MultiHashContainer || type == ContainerTypeEntry::PairContainer) { QString pyType = (type == ContainerTypeEntry::PairContainer) ? QLatin1String("Pair") : QLatin1String("Dict"); - const AbstractMetaType *firstType = metaType->instantiations().constFirst(); - const AbstractMetaType *secondType = metaType->instantiations().constLast(); + const AbstractMetaType &firstType = metaType.instantiations().constFirst(); + const AbstractMetaType &secondType = metaType.instantiations().constLast(); if (isPointerToWrapperType(firstType) && isPointerToWrapperType(secondType)) { typeCheck += QString::fromLatin1("check%1Types(%2, %3, ") .arg(pyType, cpythonTypeNameExt(firstType), cpythonTypeNameExt(secondType)); @@ -1231,10 +1232,12 @@ QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry *type, bool gene { QString customCheck; if (type->isCustom()) { - AbstractMetaType *metaType; + AbstractMetaType metaType; customCheck = guessCPythonCheckFunction(type->name(), &metaType); - if (metaType) - return cpythonCheckFunction(metaType, genericNumberType); + if (metaType) { + const QString result = cpythonCheckFunction(metaType, genericNumberType); + return result; + } return customCheck; } @@ -1254,9 +1257,9 @@ QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry *type, bool gene return typeCheck; } -QString ShibokenGenerator::guessCPythonCheckFunction(const QString &type, AbstractMetaType **metaType) +QString ShibokenGenerator::guessCPythonCheckFunction(const QString &type, AbstractMetaType *metaType) { - *metaType = nullptr; + *metaType = {}; // PYSIDE-795: We abuse PySequence for iterables. // This part handles the overrides in the XML files. if (type == QLatin1String("PySequence")) @@ -1272,7 +1275,7 @@ QString ShibokenGenerator::guessCPythonCheckFunction(const QString &type, Abstra return QLatin1String("Shiboken::String::check"); *metaType = buildAbstractMetaTypeFromString(type); - if (*metaType && !(*metaType)->typeEntry()->isCustom()) + if (*metaType && !metaType->typeEntry()->isCustom()) return QString(); return type + QLatin1String("_Check"); @@ -1294,13 +1297,13 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntry *type, return QString::fromLatin1("Shiboken::Conversions::isPythonToCppConvertible(%1, ") .arg(converterObject(type)); } -QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType *metaType, +QString ShibokenGenerator::cpythonIsConvertibleFunction(AbstractMetaType metaType, bool /* genericNumberType */) { QString customCheck; - if (metaType->typeEntry()->isCustom()) { - AbstractMetaType *type; - customCheck = guessCPythonCheckFunction(metaType->typeEntry()->name(), &type); + if (metaType.typeEntry()->isCustom()) { + AbstractMetaType type; + customCheck = guessCPythonCheckFunction(metaType.typeEntry()->name(), &type); if (type) metaType = type; if (!customCheck.isEmpty()) @@ -1311,7 +1314,7 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType * if (isWrapperType(metaType)) { if (isPointer(metaType) || isValueTypeWithCopyConstructorOnly(metaType)) result += QLatin1String("isPythonToCppPointerConvertible"); - else if (metaType->referenceType() == LValueReference) + else if (metaType.referenceType() == LValueReference) result += QLatin1String("isPythonToCppReferenceConvertible"); else result += QLatin1String("isPythonToCppValueConvertible"); @@ -1321,11 +1324,11 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType * } result += QLatin1String("isPythonToCppConvertible(") + converterObject(metaType); // Write out array sizes if known - const AbstractMetaTypeCList nestedArrayTypes = metaType->nestedArrayTypes(); - if (!nestedArrayTypes.isEmpty() && nestedArrayTypes.constLast()->isCppPrimitive()) { - const int dim1 = metaType->arrayElementCount(); - const int dim2 = nestedArrayTypes.constFirst()->isArray() - ? nestedArrayTypes.constFirst()->arrayElementCount() : -1; + const AbstractMetaTypeList nestedArrayTypes = metaType.nestedArrayTypes(); + if (!nestedArrayTypes.isEmpty() && nestedArrayTypes.constLast().isCppPrimitive()) { + const int dim1 = metaType.arrayElementCount(); + const int dim2 = nestedArrayTypes.constFirst().isArray() + ? nestedArrayTypes.constFirst().arrayElementCount() : -1; result += QLatin1String(", ") + QString::number(dim1) + QLatin1String(", ") + QString::number(dim2); } @@ -1344,7 +1347,7 @@ QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaClas + cpythonTypeNameExt(metaClass->typeEntry()) + QLatin1String("), "); } -QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaType *type, +QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaType &type, const AbstractMetaClass * /* context */) { if (isWrapperType(type)) { @@ -1357,14 +1360,14 @@ QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaType .arg(converterObject(type)); } -QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaType *type, +QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaType &type, const AbstractMetaClass * /* context */) { if (isWrapperType(type)) { QString conversion; - if (type->referenceType() == LValueReference && !(type->isValue() && type->isConstant()) && !isPointer(type)) + if (type.referenceType() == LValueReference && !(type.isValue() && type.isConstant()) && !isPointer(type)) conversion = QLatin1String("reference"); - else if (type->isValue() || type->isSmartPointer()) + else if (type.isValue() || type.isSmartPointer()) conversion = QLatin1String("copy"); else conversion = QLatin1String("pointer"); @@ -1608,7 +1611,7 @@ ShibokenGenerator::ExtendedConverterData ShibokenGenerator::getExtendedConverter for (AbstractMetaFunction *convOp : overloads) { // Get only the conversion operators that return a type from another module, // that are value-types and were not removed in the type system. - const TypeEntry *convType = convOp->type()->typeEntry(); + const TypeEntry *convType = convOp->type().typeEntry(); if (convType->generateCode() || !convType->isValue() || convOp->isModifiedRemoved()) continue; @@ -1728,14 +1731,14 @@ ShibokenGenerator::ArgumentVarReplacementList ShibokenGenerator::getArgumentRepl argValue = QLatin1String(CPP_ARG_REMOVED) + QString::number(i); if (!argRemoved && argValue.isEmpty()) { int argPos = i - removed; - const AbstractMetaType *type = arg->type(); + AbstractMetaType type = arg->type(); QString typeReplaced = func->typeReplaced(arg->argumentIndex() + 1); if (!typeReplaced.isEmpty()) { - AbstractMetaType *builtType = buildAbstractMetaTypeFromString(typeReplaced); + AbstractMetaType builtType = buildAbstractMetaTypeFromString(typeReplaced); if (builtType) type = builtType; } - if (type->typeEntry()->isCustom()) { + if (type.typeEntry()->isCustom()) { argValue = usePyArgs ? pythonArgsAt(argPos) : QLatin1String(PYTHON_ARG); } else { @@ -1743,7 +1746,7 @@ ShibokenGenerator::ArgumentVarReplacementList ShibokenGenerator::getArgumentRepl ? arg->name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX) : QLatin1String(CPP_ARG) + QString::number(argPos); if (isWrapperType(type)) { - if (type->referenceType() == LValueReference && !isPointer(type)) + if (type.referenceType() == LValueReference && !isPointer(type)) argValue.prepend(QLatin1Char('*')); } } @@ -1845,7 +1848,7 @@ void ShibokenGenerator::writeCodeSnips(QTextStream &s, const AbstractMetaArgumentList &arguments = func->arguments(); for (const AbstractMetaArgument *arg : arguments) { QString argTypeVar = QStringLiteral("%ARG%1_TYPE").arg(arg->argumentIndex() + 1); - QString argTypeVal = arg->type()->cppSignature(); + QString argTypeVal = arg->type().cppSignature(); code.replace(argTypeVar, argTypeVal); } @@ -1950,18 +1953,18 @@ void ShibokenGenerator::writeCodeSnips(QTextStream &s, for (const ArgumentVarReplacementPair &pair : argReplacements) { const AbstractMetaArgument *arg = pair.first; int idx = arg->argumentIndex() + 1; - AbstractMetaType *type = arg->type(); + AbstractMetaType type = arg->type(); QString typeReplaced = func->typeReplaced(arg->argumentIndex() + 1); if (!typeReplaced.isEmpty()) { - AbstractMetaType *builtType = buildAbstractMetaTypeFromString(typeReplaced); + AbstractMetaType builtType = buildAbstractMetaTypeFromString(typeReplaced); if (builtType) type = builtType; } if (isWrapperType(type)) { QString replacement = pair.second; - if (type->referenceType() == LValueReference && !isPointer(type)) + if (type.referenceType() == LValueReference && !isPointer(type)) replacement.remove(0, 1); - if (type->referenceType() == LValueReference || isPointer(type)) + if (type.referenceType() == LValueReference || isPointer(type)) code.replace(QString::fromLatin1("%%1.").arg(idx), replacement + QLatin1String("->")); } code.replace(placeHolderRegex(idx), pair.second); @@ -2079,7 +2082,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa QString conversionString = list.constFirst(); const QString &conversionTypeName = list.constLast(); QString message; - const AbstractMetaType *conversionType = buildAbstractMetaTypeFromString(conversionTypeName, &message); + const AbstractMetaType conversionType = buildAbstractMetaTypeFromString(conversionTypeName, &message); if (!conversionType) { qFatal("%s", qPrintable(msgCannotFindType(conversionTypeName, m_typeSystemConvName[converterVariable], @@ -2100,7 +2103,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa varType = miniNormalizer(varType); QString varName = list.at(1).trimmed(); if (!varType.isEmpty()) { - const QString conversionSignature = conversionType->cppSignature(); + const QString conversionSignature = conversionType.cppSignature(); if (varType != QLatin1String("auto") && varType != conversionSignature) qFatal("%s", qPrintable(msgConversionTypesDiffer(varType, conversionSignature))); c << getFullTypeName(conversionType) << ' ' << varName; @@ -2124,8 +2127,8 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa } case TypeSystemCheckFunction: conversion = cpythonCheckFunction(conversionType); - if (conversionType->typeEntry()->isPrimitive() - && (conversionType->typeEntry()->name() == QLatin1String("PyObject") + if (conversionType.typeEntry()->isPrimitive() + && (conversionType.typeEntry()->name() == QLatin1String("PyObject") || !conversion.endsWith(QLatin1Char(' ')))) { c << '('; break; @@ -2378,8 +2381,8 @@ bool ShibokenGenerator::isCopyable(const AbstractMetaClass *metaClass) return metaClass->typeEntry()->copyable() == ComplexTypeEntry::CopyableSet; } -AbstractMetaType *ShibokenGenerator::buildAbstractMetaTypeFromString(QString typeSignature, - QString *errorMessage) +AbstractMetaType ShibokenGenerator::buildAbstractMetaTypeFromString(QString typeSignature, + QString *errorMessage) { typeSignature = typeSignature.trimmed(); if (typeSignature.startsWith(QLatin1String("::"))) @@ -2387,34 +2390,34 @@ AbstractMetaType *ShibokenGenerator::buildAbstractMetaTypeFromString(QString typ auto it = m_metaTypeFromStringCache.find(typeSignature); if (it == m_metaTypeFromStringCache.end()) { - AbstractMetaType *metaType = + AbstractMetaType metaType = AbstractMetaBuilder::translateType(typeSignature, nullptr, {}, errorMessage); if (Q_UNLIKELY(!metaType)) { if (errorMessage) errorMessage->prepend(msgCannotBuildMetaType(typeSignature)); - return nullptr; + return {}; } it = m_metaTypeFromStringCache.insert(typeSignature, metaType); } return it.value(); } -AbstractMetaType *ShibokenGenerator::buildAbstractMetaTypeFromTypeEntry(const TypeEntry *typeEntry) +AbstractMetaType ShibokenGenerator::buildAbstractMetaTypeFromTypeEntry(const TypeEntry *typeEntry) { QString typeName = typeEntry->qualifiedCppName(); if (typeName.startsWith(QLatin1String("::"))) typeName.remove(0, 2); if (m_metaTypeFromStringCache.contains(typeName)) return m_metaTypeFromStringCache.value(typeName); - auto *metaType = new AbstractMetaType(typeEntry); - metaType->clearIndirections(); - metaType->setReferenceType(NoReference); - metaType->setConstant(false); - metaType->decideUsagePattern(); + AbstractMetaType metaType(typeEntry); + metaType.clearIndirections(); + metaType.setReferenceType(NoReference); + metaType.setConstant(false); + metaType.decideUsagePattern(); m_metaTypeFromStringCache.insert(typeName, metaType); return metaType; } -AbstractMetaType *ShibokenGenerator::buildAbstractMetaTypeFromAbstractMetaClass(const AbstractMetaClass *metaClass) +AbstractMetaType ShibokenGenerator::buildAbstractMetaTypeFromAbstractMetaClass(const AbstractMetaClass *metaClass) { return ShibokenGenerator::buildAbstractMetaTypeFromTypeEntry(metaClass->typeEntry()); } @@ -2669,9 +2672,9 @@ void ShibokenGenerator::collectContainerTypesFromConverterMacros(const QString & start += offset; if (code.at(start) != QLatin1Char('%')) { QString typeString = code.mid(start, end - start); - if (AbstractMetaType *type = + if (AbstractMetaType type = buildAbstractMetaTypeFromString(typeString, &errorMessage)) { - addInstantiatedContainersAndSmartPointers(type, type->originalTypeDescription()); + addInstantiatedContainersAndSmartPointers(type, type.originalTypeDescription()); } else { qFatal("%s: Cannot translate type \"%s\": %s", __FUNCTION__, qPrintable(typeString), qPrintable(errorMessage)); @@ -2733,13 +2736,13 @@ QString ShibokenGenerator::convertersVariableName(const QString &moduleName) con return result; } -static QString processInstantiationsVariableName(const AbstractMetaType *type) +static QString processInstantiationsVariableName(const AbstractMetaType &type) { - QString res = QLatin1Char('_') + _fixedCppTypeName(type->typeEntry()->qualifiedCppName()).toUpper(); - for (const auto *instantiation : type->instantiations()) { - res += instantiation->isContainer() + QString res = QLatin1Char('_') + _fixedCppTypeName(type.typeEntry()->qualifiedCppName()).toUpper(); + for (const auto &instantiation : type.instantiations()) { + res += instantiation.isContainer() ? processInstantiationsVariableName(instantiation) - : QLatin1Char('_') + _fixedCppTypeName(instantiation->cppSignature()).toUpper(); + : QLatin1Char('_') + _fixedCppTypeName(instantiation.cppSignature()).toUpper(); } return res; } @@ -2760,7 +2763,7 @@ QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaClass *met return QString(); QString result = QLatin1String("SBK_") + _fixedCppTypeName(templateBaseClass->typeEntry()->qualifiedCppName()).toUpper(); - for (const auto *instantiation : metaClass->templateBaseClassInstantiations()) + for (const auto &instantiation : metaClass->templateBaseClassInstantiations()) result += processInstantiationsVariableName(instantiation); appendIndexSuffix(&result); return result; @@ -2785,10 +2788,10 @@ QString ShibokenGenerator::getTypeIndexVariableName(const TypeEntry *type) const appendIndexSuffix(&result); return result; } -QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaType *type) const +QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaType &type) const { QString result = QLatin1String("SBK"); - if (type->typeEntry()->isContainer()) + if (type.typeEntry()->isContainer()) result += QLatin1Char('_') + moduleName().toUpper(); result += processInstantiationsVariableName(type); appendIndexSuffix(&result); @@ -2814,19 +2817,21 @@ bool ShibokenGenerator::pythonFunctionWrapperUsesListOfArguments(const OverloadD || overloadData.hasArgumentWithDefaultValue(); } -void ShibokenGenerator::writeMinimalConstructorExpression(QTextStream &s, const AbstractMetaType *type, const QString &defaultCtor) +void ShibokenGenerator::writeMinimalConstructorExpression(QTextStream &s, + const AbstractMetaType &type, + const QString &defaultCtor) { if (!defaultCtor.isEmpty()) { s << " = " << defaultCtor; return; } - if (isCppPrimitive(type) || type->isSmartPointer()) + if (isCppPrimitive(type) || type.isSmartPointer()) return; const auto ctor = minimalConstructor(type); if (ctor.isValid()) { s << ctor.initialization(); } else { - const QString message = msgCouldNotFindMinimalConstructor(QLatin1String(__FUNCTION__), type->cppSignature()); + const QString message = msgCouldNotFindMinimalConstructor(QLatin1String(__FUNCTION__), type.cppSignature()); qCWarning(lcShiboken()).noquote() << message; s << ";\n#error " << message << '\n'; } @@ -2862,9 +2867,9 @@ bool ShibokenGenerator::isCppIntegralPrimitive(const TypeEntry *type) && !typeName.contains(QLatin1String("float")) && !typeName.contains(QLatin1String("wchar")); } -bool ShibokenGenerator::isCppIntegralPrimitive(const AbstractMetaType *type) +bool ShibokenGenerator::isCppIntegralPrimitive(const AbstractMetaType &type) { - return isCppIntegralPrimitive(type->typeEntry()); + return isCppIntegralPrimitive(type.typeEntry()); } QString ShibokenGenerator::pythonArgsAt(int i) diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h index 6d36026cd..7b2f0cb39 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h @@ -217,9 +217,10 @@ protected: /// Returns a list of parent classes for a given class. AbstractMetaClassList getBaseClasses(const AbstractMetaClass *metaClass) const; - void writeToPythonConversion(QTextStream &s, const AbstractMetaType *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); + void writeToCppConversion(QTextStream &s, const AbstractMetaType &type, const AbstractMetaClass *context, + const QString &inArgName, const QString &outArgName); void writeToCppConversion(QTextStream &s, const AbstractMetaClass *metaClass, const QString &inArgName, const QString &outArgName); /// Returns true if the argument is a pointer that rejects nullptr values. @@ -251,14 +252,14 @@ protected: static QString pythonRichCompareOperatorId(const AbstractMetaFunction *func); static QString fixedCppTypeName(const CustomConversion::TargetToNativeConversion *toNative); - static QString fixedCppTypeName(const AbstractMetaType *type); + static QString fixedCppTypeName(const AbstractMetaType &type); static QString fixedCppTypeName(const TypeEntry *type, QString typeName = QString()); static bool isNumber(const QString &cpythonApiName); static bool isNumber(const TypeEntry *type); - static bool isNumber(const AbstractMetaType *type); + static bool isNumber(const AbstractMetaType &type); static bool isPyInt(const TypeEntry *type); - static bool isPyInt(const AbstractMetaType *type); + static bool isPyInt(const AbstractMetaType &type); /** * Returns true if the type passed has a Python wrapper for it. @@ -266,56 +267,56 @@ protected: */ static bool isWrapperType(const TypeEntry *type); static bool isWrapperType(const ComplexTypeEntry *type); - static bool isWrapperType(const AbstractMetaType *metaType); + static bool isWrapperType(const AbstractMetaType &metaType); /** * Checks if the type is an Object/QObject or pointer to Value Type. * In other words, tells if the type is "T*" and T has a Python wrapper. */ - static bool isPointerToWrapperType(const AbstractMetaType *type); + static bool isPointerToWrapperType(const AbstractMetaType &type); /** * Returns true if \p type is an Object Type used as a value. */ - static bool isObjectTypeUsedAsValueType(const AbstractMetaType *type); + static bool isObjectTypeUsedAsValueType(const AbstractMetaType &type); static bool isValueTypeWithCopyConstructorOnly(const AbstractMetaClass *metaClass); bool isValueTypeWithCopyConstructorOnly(const TypeEntry *type) const; - bool isValueTypeWithCopyConstructorOnly(const AbstractMetaType *type) const; + bool isValueTypeWithCopyConstructorOnly(const AbstractMetaType &type) const; /// Returns true if the type is a primitive but not a C++ primitive. static bool isUserPrimitive(const TypeEntry *type); - static bool isUserPrimitive(const AbstractMetaType *type); + static bool isUserPrimitive(const AbstractMetaType &type); /// Returns true if the type is a C++ primitive, a void*, a const char*, or a std::string. static bool isCppPrimitive(const TypeEntry *type); - static bool isCppPrimitive(const AbstractMetaType *type); + static bool isCppPrimitive(const AbstractMetaType &type); /// Returns true if the type is a C++ integral primitive, i.e. bool, char, int, long, and their unsigned counterparts. static bool isCppIntegralPrimitive(const TypeEntry *type); - static bool isCppIntegralPrimitive(const AbstractMetaType *type); + static bool isCppIntegralPrimitive(const AbstractMetaType &type); /// Checks if an argument type should be dereferenced by the Python method wrapper before calling the C++ method. static bool shouldDereferenceArgumentPointer(const AbstractMetaArgument *arg); /// Checks if a meta type should be dereferenced by the Python method wrapper passing it to C++. - static bool shouldDereferenceAbstractMetaTypePointer(const AbstractMetaType *metaType); + static bool shouldDereferenceAbstractMetaTypePointer(const AbstractMetaType &metaType); static bool visibilityModifiedToPrivate(const AbstractMetaFunction *func); static bool isNullPtr(const QString &value); - QString converterObject(const AbstractMetaType *type); + QString converterObject(const AbstractMetaType &type); QString converterObject(const TypeEntry *type); static QString cpythonBaseName(const AbstractMetaClass *metaClass); static QString cpythonBaseName(const TypeEntry *type); - static QString cpythonBaseName(const AbstractMetaType *type); + static QString cpythonBaseName(const AbstractMetaType &type); static QString cpythonTypeName(const AbstractMetaClass *metaClass); static QString cpythonTypeName(const TypeEntry *type); QString cpythonTypeNameExt(const TypeEntry *type) const; - QString cpythonTypeNameExt(const AbstractMetaType *type) const; + QString cpythonTypeNameExt(const AbstractMetaType &type) const; QString cpythonCheckFunction(const TypeEntry *type, bool genericNumberType = false); - QString cpythonCheckFunction(const AbstractMetaType *metaType, bool genericNumberType = false); + QString cpythonCheckFunction(AbstractMetaType metaType, bool genericNumberType = false); /** * Receives the argument \p type and tries to find the appropriate AbstractMetaType for it * or a custom type check. @@ -326,14 +327,14 @@ 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); + QString guessCPythonCheckFunction(const QString &type, AbstractMetaType *metaType); QString cpythonIsConvertibleFunction(const TypeEntry *type, bool genericNumberType = false, bool checkExact = false); - QString cpythonIsConvertibleFunction(const AbstractMetaType *metaType, bool genericNumberType = false); + QString cpythonIsConvertibleFunction(AbstractMetaType metaType, bool genericNumberType = false); QString cpythonIsConvertibleFunction(const AbstractMetaArgument *metaArg, bool genericNumberType = false); QString cpythonToCppConversionFunction(const AbstractMetaClass *metaClass); - QString cpythonToCppConversionFunction(const AbstractMetaType *type, const AbstractMetaClass *context = nullptr); - QString cpythonToPythonConversionFunction(const AbstractMetaType *type, const AbstractMetaClass *context = nullptr); + QString cpythonToCppConversionFunction(const AbstractMetaType &type, const AbstractMetaClass *context = nullptr); + QString cpythonToPythonConversionFunction(const AbstractMetaType &type, const AbstractMetaClass *context = nullptr); QString cpythonToPythonConversionFunction(const AbstractMetaClass *metaClass); QString cpythonToPythonConversionFunction(const TypeEntry *type); @@ -350,7 +351,7 @@ protected: const AbstractMetaClass *metaClass); QString cpythonWrapperCPtr(const AbstractMetaClass *metaClass, const QString &argName = QLatin1String("self")) const; - QString cpythonWrapperCPtr(const AbstractMetaType *metaType, const QString &argName) const; + QString cpythonWrapperCPtr(const AbstractMetaType &metaType, const QString &argName) const; QString cpythonWrapperCPtr(const TypeEntry *type, const QString &argName) const; /// Guesses the scope to where belongs an argument's default value. @@ -395,7 +396,7 @@ protected: */ QString getTypeIndexVariableName(const AbstractMetaClass *metaClass, bool alternativeTemplateName = false) const; QString getTypeIndexVariableName(const TypeEntry *type) const; - QString getTypeIndexVariableName(const AbstractMetaType *type) const; + QString getTypeIndexVariableName(const AbstractMetaType &type) const; /// Returns true if the user don't want verbose error messages on the generated bindings. bool verboseErrorMessagesDisabled() const; @@ -407,15 +408,16 @@ 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); + AbstractMetaType buildAbstractMetaTypeFromString(QString typeSignature, + QString *errorMessage = nullptr); /// Creates an AbstractMetaType object from a TypeEntry. - AbstractMetaType *buildAbstractMetaTypeFromTypeEntry(const TypeEntry *typeEntry); + AbstractMetaType buildAbstractMetaTypeFromTypeEntry(const TypeEntry *typeEntry); /// Creates an AbstractMetaType object from an AbstractMetaClass. - AbstractMetaType *buildAbstractMetaTypeFromAbstractMetaClass(const AbstractMetaClass *metaClass); + AbstractMetaType buildAbstractMetaTypeFromAbstractMetaClass(const AbstractMetaClass *metaClass); - void writeMinimalConstructorExpression(QTextStream &s, const AbstractMetaType *type, const QString &defaultCtor = QString()); + void writeMinimalConstructorExpression(QTextStream &s, const AbstractMetaType &type, + const QString &defaultCtor = QString()); void writeMinimalConstructorExpression(QTextStream &s, const TypeEntry *type, const QString &defaultCtor = QString()); void collectContainerTypesFromConverterMacros(const QString &code, bool toPythonMacro); @@ -473,7 +475,7 @@ private: static FunctionGroups getFunctionGroupsImpl(const AbstractMetaClass *scope); static bool classNeedsGetattroFunctionImpl(const AbstractMetaClass *metaClass); - QString translateTypeForWrapperMethod(const AbstractMetaType *cType, + QString translateTypeForWrapperMethod(const AbstractMetaType &cType, const AbstractMetaClass *context, Options opt = NoOption) const; @@ -570,7 +572,7 @@ private: bool m_avoidProtectedHack = false; bool m_wrapperDiagnostics = false; - using AbstractMetaTypeCache = QHash; + using AbstractMetaTypeCache = QHash; AbstractMetaTypeCache m_metaTypeFromStringCache; /// Type system converter variable replacement names and regular expressions. -- cgit v1.2.3