diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-10-14 20:34:46 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-10-14 20:34:46 +0200 |
commit | 68ec9c643abf30cf22b9932ec82098cdebc08b98 (patch) | |
tree | 18e6db70e971b3e437145183d07ed017933ab64d /sources/shiboken2/ApiExtractor | |
parent | 30724622333ffc8bce61f7e19217977eebbf9564 (diff) | |
parent | b0da5a06e147b02af0bf2d69364e3bfcc04327d5 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: I46f5d2dc758d0e1f23377c91ba7496793461771e
Diffstat (limited to 'sources/shiboken2/ApiExtractor')
5 files changed, 104 insertions, 89 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 70cccebcd..af10f1831 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -1258,9 +1258,7 @@ void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaF if (!retType) return; - auto *metaType = new AbstractMetaType; - metaType->setTypeEntry(retType); - metaFunction->replaceType(metaType); + metaFunction->replaceType(new AbstractMetaType(retType)); } AbstractMetaFunctionList AbstractMetaBuilderPrivate::classFunctionList(const ScopeModelItem &scopeItem, @@ -1300,7 +1298,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem, QPropertySpec *read = nullptr; if (!metaFunction->isSignal() && (read = metaClass->propertySpecForRead(metaFunction->name()))) { // Property reader must be in the form "<type> name()" - if (metaFunction->type() && (read->typeEntry() == metaFunction->type()->typeEntry()) + if (read->typeEntry() == metaFunction->type()->typeEntry() && metaFunction->arguments().isEmpty()) { *metaFunction += AbstractMetaAttributes::PropertyReader; metaFunction->setPropertySpec(read); @@ -1309,14 +1307,14 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem, // Property setter must be in the form "void name(<type>)" // 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->type()) && (metaFunction->arguments().size() == 1) + if (metaFunction->isVoid() && metaFunction->arguments().size() == 1 && (write->typeEntry() == metaFunction->arguments().at(0)->type()->typeEntry())) { *metaFunction += AbstractMetaAttributes::PropertyWriter; metaFunction->setPropertySpec(write); } } else if (QPropertySpec *reset = metaClass->propertySpecForReset(metaFunction->name())) { // Property resetter must be in the form "void name()" - if ((!metaFunction->type()) && metaFunction->arguments().isEmpty()) { + if (metaFunction->isVoid() && metaFunction->arguments().isEmpty()) { *metaFunction += AbstractMetaAttributes::PropertyResetter; metaFunction->setPropertySpec(reset); } @@ -1516,16 +1514,13 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu { QString errorMessage; - AbstractMetaType *returnType = nullptr; - if (addedFunc->returnType().name != QLatin1String("void")) { - returnType = translateType(addedFunc->returnType(), &errorMessage); - if (!returnType) { - qCWarning(lcShiboken, "%s", - qPrintable(msgAddedFunctionInvalidReturnType(addedFunc->name(), - addedFunc->returnType().name, - errorMessage))); - return nullptr; - } + AbstractMetaType *returnType = translateType(addedFunc->returnType(), &errorMessage); + if (!returnType) { + qCWarning(lcShiboken, "%s", + qPrintable(msgAddedFunctionInvalidReturnType(addedFunc->name(), + addedFunc->returnType().name, + errorMessage))); + return nullptr; } auto metaFunction = new AbstractMetaFunction(addedFunc); @@ -1806,10 +1801,12 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio QString errorMessage; switch (metaFunction->functionType()) { case AbstractMetaFunction::DestructorFunction: + metaFunction->setType(AbstractMetaType::createVoid()); break; case AbstractMetaFunction::ConstructorFunction: metaFunction->setExplicit(functionItem->isExplicit()); metaFunction->setName(currentClass->name()); + metaFunction->setType(AbstractMetaType::createVoid()); break; default: { TypeInfo returnType = functionItem->type(); @@ -1820,17 +1817,14 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio return nullptr; } - AbstractMetaType *type = nullptr; - if (!returnType.isVoid()) { - type = translateType(returnType, currentClass, {}, &errorMessage); - if (!type) { - const QString reason = msgUnmatchedReturnType(functionItem, errorMessage); - qCWarning(lcShiboken, "%s", - qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason))); - m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn, AbstractMetaBuilder::UnmatchedReturnType); - delete metaFunction; - return nullptr; - } + AbstractMetaType *type = translateType(returnType, currentClass, {}, &errorMessage); + if (!type) { + const QString reason = msgUnmatchedReturnType(functionItem, errorMessage); + qCWarning(lcShiboken, "%s", + qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason))); + m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn, AbstractMetaBuilder::UnmatchedReturnType); + delete metaFunction; + return nullptr; } metaFunction->setType(type); @@ -1979,7 +1973,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: QString typeName = typeInfo.name; if (typeName == QLatin1String("void")) - return nullptr; + return AbstractMetaType::createVoid(); type = typeDb->findType(typeName); if (!type) @@ -1989,13 +1983,21 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: bool isTemplate = false; QStringList templateArgs; if (!type && typeInfo.name.contains(QLatin1Char('<'))) { - const QStringList& parsedType = parseTemplateType(typeInfo.name); + QStringList parsedType = parseTemplateType(typeInfo.name); if (parsedType.isEmpty()) { *errorMessage = QStringLiteral("Template type parsing failed for '%1'").arg(typeInfo.name); return nullptr; } - templateArgs = parsedType.mid(1); - isTemplate = (type = typeDb->findContainerType(parsedType[0])); + const QString name = parsedType.takeFirst(); + templateArgs = parsedType; + type = typeDb->findContainerType(name); + if (!type) { // A template typedef? + if (auto candidate = typeDb->findType(name)) { + if (candidate->type() == TypeEntry::ObjectType || candidate->type() == TypeEntry::BasicValueType) + type = candidate; + } + } + isTemplate = type != nullptr; } if (!type) { @@ -2021,20 +2023,16 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction: } // These are only implicit and should not appear in code... - auto *metaType = new AbstractMetaType; - metaType->setTypeEntry(type); + auto *metaType = new AbstractMetaType(type); metaType->setIndirections(typeInfo.indirections); if (typeInfo.isReference) metaType->setReferenceType(LValueReference); metaType->setConstant(typeInfo.isConstant); if (isTemplate) { for (const QString& templateArg : qAsConst(templateArgs)) { - AbstractMetaType *metaArgType = nullptr; - if (templateArg != QLatin1String("void")) { - metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg), errorMessage); - if (!metaArgType) - return nullptr; - } + AbstractMetaType *metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg), errorMessage); + if (!metaArgType) + return nullptr; metaType->addInstantiation(metaArgType); } metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern); @@ -2120,6 +2118,9 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo TranslateTypeFlags flags, QString *errorMessageIn) { + if (_typei.isVoid()) + return AbstractMetaType::createVoid(); + // 1. Test the type info without resolving typedefs in case this is present in the // type system const bool resolveType = !flags.testFlag(AbstractMetaBuilder::DontResolveType); @@ -2622,7 +2623,7 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, const TypeInfo &info) { QVector<TypeInfo> targs = info.instantiations(); - QVector<AbstractMetaType *> templateTypes; + AbstractMetaTypeList templateTypes; QString errorMessage; if (subclass->isTypeDef()) { @@ -2665,8 +2666,7 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, } if (t) { - auto *temporaryType = new AbstractMetaType; - temporaryType->setTypeEntry(t); + auto *temporaryType = new AbstractMetaType(t); temporaryType->setConstant(i.isConstant()); temporaryType->setReferenceType(i.referenceType()); temporaryType->setIndirectionsV(i.indirectionsV()); @@ -2692,7 +2692,7 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, QScopedPointer<AbstractMetaFunction> f(function->copy()); f->setArguments(AbstractMetaArgumentList()); - if (function->type()) { // Non-void + if (!function->isVoid()) { AbstractMetaType *returnType = inheritTemplateType(templateTypes, function->type()); if (!returnType) continue; diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index f705994f2..2f68dd743 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -186,7 +186,8 @@ void AbstractMetaAttributes::assignMetaAttributes(const AbstractMetaAttributes & * AbstractMetaType */ -AbstractMetaType::AbstractMetaType() : +AbstractMetaType::AbstractMetaType(const TypeEntry *t) : + m_typeEntry(t), m_constant(false), m_volatile(false), m_cppInstantiation(true), @@ -220,7 +221,7 @@ QString AbstractMetaType::fullName() const AbstractMetaType *AbstractMetaType::copy() const { - auto *cpy = new AbstractMetaType; + auto *cpy = new AbstractMetaType(typeEntry()); cpy->setTypeUsagePattern(typeUsagePattern()); cpy->setConstant(isConstant()); @@ -234,8 +235,6 @@ AbstractMetaType *AbstractMetaType::copy() const cpy->setArrayElementType(arrayElementType() ? arrayElementType()->copy() : nullptr); - cpy->setTypeEntry(typeEntry()); - return cpy; } @@ -322,8 +321,11 @@ AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() con if (m_typeEntry->isPrimitive() && (actualIndirections() == 0 || passByConstRef())) return PrimitivePattern; - if (m_typeEntry->isVoid()) - return NativePointerPattern; + 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; @@ -413,6 +415,15 @@ bool AbstractMetaType::compare(const AbstractMetaType &rhs, ComparisonFlags flag 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) { @@ -647,8 +658,7 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const cpy->setImplementingClass(implementingClass()); cpy->setFunctionType(functionType()); cpy->setDeclaringClass(declaringClass()); - if (type()) - cpy->setType(type()->copy()); + cpy->setType(type()->copy()); cpy->setConstant(isConstant()); cpy->setExceptionSpecification(m_exceptionSpecification); cpy->setAllowThreadModification(m_allowThreadModification); @@ -658,8 +668,7 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const for (AbstractMetaArgument *arg : m_arguments) cpy->addArgument(arg->copy()); - Q_ASSERT((!type() && !cpy->type()) - || (type()->instantiations() == cpy->type()->instantiations())); + Q_ASSERT(type()->instantiations() == cpy->type()->instantiations()); return cpy; } @@ -668,7 +677,7 @@ bool AbstractMetaFunction::usesRValueReferences() const { if (m_functionType == MoveConstructorFunction || m_functionType == MoveAssignmentOperatorFunction) return true; - if (m_type && m_type->referenceType() == RValueReference) + if (m_type->referenceType() == RValueReference) return true; for (const AbstractMetaArgument *a : m_arguments) { if (a->type()->referenceType() == RValueReference) @@ -833,8 +842,7 @@ bool AbstractMetaFunction::isDeprecated() const bool AbstractMetaFunction::autoDetectAllowThread() const { // Disallow for simple getter functions. - const bool maybeGetter = m_constant != 0 && m_type != nullptr - && m_arguments.isEmpty(); + const bool maybeGetter = m_constant != 0 && !isVoid() && m_arguments.isEmpty(); return !maybeGetter; } @@ -1409,8 +1417,7 @@ AbstractMetaClass::~AbstractMetaClass() qDeleteAll(m_fields); qDeleteAll(m_enums); qDeleteAll(m_propertySpecs); - if (hasTemplateBaseClassInstantiations()) - qDeleteAll(templateBaseClassInstantiations()); + qDeleteAll(m_baseTemplateInstantiations); } /******************************************************************************* @@ -1736,28 +1743,20 @@ QPropertySpec *AbstractMetaClass::propertySpecForReset(const QString &name) cons return nullptr; } -using AbstractMetaClassBaseTemplateInstantiationsMap = QHash<const AbstractMetaClass *, AbstractMetaTypeList>; -Q_GLOBAL_STATIC(AbstractMetaClassBaseTemplateInstantiationsMap, metaClassBaseTemplateInstantiations); - bool AbstractMetaClass::hasTemplateBaseClassInstantiations() const { - if (!templateBaseClass()) - return false; - return metaClassBaseTemplateInstantiations()->contains(this); + return m_templateBaseClass != nullptr && !m_baseTemplateInstantiations.isEmpty(); } -AbstractMetaTypeList AbstractMetaClass::templateBaseClassInstantiations() const +const AbstractMetaTypeList &AbstractMetaClass::templateBaseClassInstantiations() const { - if (!templateBaseClass()) - return AbstractMetaTypeList(); - return metaClassBaseTemplateInstantiations()->value(this); + return m_baseTemplateInstantiations; } -void AbstractMetaClass::setTemplateBaseClassInstantiations(AbstractMetaTypeList &instantiations) +void AbstractMetaClass::setTemplateBaseClassInstantiations(const AbstractMetaTypeList &instantiations) { - if (!templateBaseClass()) - return; - metaClassBaseTemplateInstantiations()->insert(this, instantiations); + Q_ASSERT(m_templateBaseClass != nullptr); + m_baseTemplateInstantiations = instantiations; } // Does any of the base classes require deletion in the main thread? @@ -1930,6 +1929,7 @@ bool AbstractMetaClass::hasPrivateCopyConstructor() const void AbstractMetaClass::addDefaultConstructor() { auto *f = new AbstractMetaFunction; + f->setType(AbstractMetaType::createVoid()); f->setOriginalName(name()); f->setName(name()); f->setOwnerClass(this); @@ -1948,14 +1948,14 @@ void AbstractMetaClass::addDefaultConstructor() void AbstractMetaClass::addDefaultCopyConstructor(bool isPrivate) { auto f = new AbstractMetaFunction; + f->setType(AbstractMetaType::createVoid()); f->setOriginalName(name()); f->setName(name()); f->setOwnerClass(this); f->setFunctionType(AbstractMetaFunction::CopyConstructorFunction); f->setDeclaringClass(this); - auto argType = new AbstractMetaType; - argType->setTypeEntry(typeEntry()); + auto argType = new AbstractMetaType(typeEntry()); argType->setReferenceType(LValueReference); argType->setConstant(true); argType->setTypeUsagePattern(AbstractMetaType::ValuePattern); @@ -2184,8 +2184,7 @@ static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractM } if (type->hasInstantiations()) { - const AbstractMetaTypeList &instantiations = type->instantiations(); - for (const AbstractMetaType *instantiation : instantiations) + for (const AbstractMetaType *instantiation : type->instantiations()) addExtraIncludeForType(metaClass, instantiation); } } @@ -2630,7 +2629,7 @@ void AbstractMetaClass::format(QDebug &d) const d << " \"" << b->name() << '"'; } if (auto templateBase = templateBaseClass()) { - const auto instantiatedTypes = templateBaseClassInstantiations(); + const auto &instantiatedTypes = templateBaseClassInstantiations(); d << ", instantiates \"" << templateBase->name(); for (int i = 0, count = instantiatedTypes.size(); i < count; ++i) d << (i ? ',' : '<') << instantiatedTypes.at(i)->name(); diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index df9790a3d..154314d69 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -293,7 +293,8 @@ public: ContainerPattern, SmartPointerPattern, VarargsPattern, - ArrayPattern + ArrayPattern, + VoidPattern // Plain "void", no "void *" or similar. }; Q_ENUM(TypeUsagePattern) @@ -302,7 +303,7 @@ public: }; Q_DECLARE_FLAGS(ComparisonFlags, ComparisonFlag); - AbstractMetaType(); + explicit AbstractMetaType(const TypeEntry *t = nullptr); AbstractMetaType(const AbstractMetaType &); ~AbstractMetaType(); @@ -341,7 +342,7 @@ public: } } - AbstractMetaTypeList instantiations() const + const AbstractMetaTypeList &instantiations() const { return m_instantiations; } @@ -417,6 +418,8 @@ public: return m_pattern == FlagsPattern; } + bool isVoid() const { return m_pattern == VoidPattern; } + bool isConstant() const { return m_constant; @@ -510,7 +513,7 @@ public: AbstractMetaType *getSmartPointerInnerType() const { Q_ASSERT(isSmartPointer()); - AbstractMetaTypeList instantiations = this->instantiations(); + const AbstractMetaTypeList &instantiations = this->instantiations(); Q_ASSERT(!instantiations.isEmpty()); AbstractMetaType *innerType = instantiations.at(0); return innerType; @@ -537,12 +540,14 @@ public: 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 = nullptr; + const TypeEntry *m_typeEntry; AbstractMetaTypeList m_instantiations; QString m_package; mutable QString m_cachedCppSignature; @@ -887,6 +892,7 @@ public: bool isModifiedRemoved(int types = TypeSystem::All) const; + bool isVoid() const { return m_type->isVoid(); } AbstractMetaType *type() const { return m_type; @@ -1640,8 +1646,8 @@ public: } bool hasTemplateBaseClassInstantiations() const; - AbstractMetaTypeList templateBaseClassInstantiations() const; - void setTemplateBaseClassInstantiations(AbstractMetaTypeList& instantiations); + const AbstractMetaTypeList &templateBaseClassInstantiations() const; + void setTemplateBaseClassInstantiations(const AbstractMetaTypeList& instantiations); void setTypeDef(bool typeDef) { m_isTypeDef = typeDef; } bool isTypeDef() const { return m_isTypeDef; } @@ -1712,6 +1718,7 @@ private: const AbstractMetaClass *m_enclosingClass = nullptr; AbstractMetaClassList m_baseClasses; // Real base classes after setting up inheritance + AbstractMetaTypeList m_baseTemplateInstantiations; AbstractMetaClass *m_extendedNamespace = nullptr; const AbstractMetaClass *m_templateBaseClass = nullptr; diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp index ca4af9a10..a131e7fe2 100644 --- a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp @@ -145,7 +145,7 @@ void TestAddFunction::testAddFunctionConstructor() QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::ConstructorFunction); QCOMPARE(addedFunc->arguments().size(), 1); QVERIFY(addedFunc->isUserAdded()); - QVERIFY(!addedFunc->type()); + QVERIFY(addedFunc->isVoid()); } void TestAddFunction::testAddFunctionTagDefaultValues() @@ -167,7 +167,7 @@ void TestAddFunction::testAddFunctionTagDefaultValues() QCOMPARE(addedFunc->visibility(), AbstractMetaFunction::Public); QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction); QVERIFY(addedFunc->isUserAdded()); - QVERIFY(!addedFunc->type()); + QVERIFY(addedFunc->isVoid()); } void TestAddFunction::testAddFunctionCodeSnippets() diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp index 0d5a8cba7..6b56d362e 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp @@ -887,9 +887,8 @@ void TypeEntry::formatDebug(QDebug &d) const d << '"' << m_name << '"'; if (m_name != cppName) d << "\", cppName=\"" << cppName << '"'; - d << ", type=" << m_type << ", codeGeneration=0x" - << Qt::hex << m_codeGeneration << Qt::dec - << ", target=\"" << targetLangName() << '"'; + d << ", type=" << m_type << ", codeGeneration=" + << m_codeGeneration << ", target=\"" << targetLangName() << '"'; FORMAT_NONEMPTY_STRING("package", m_targetLangPackage) FORMAT_BOOL("stream", m_stream) FORMAT_LIST_SIZE("codeSnips", m_codeSnips) @@ -1002,6 +1001,16 @@ void TypeDatabase::formatDebug(QDebug &d) const << "entries[" << m_entries.size() << "]="; for (auto it = m_entries.cbegin(), end = m_entries.cend(); it != end; ++it) d << " " << it.value() << '\n'; + if (!m_typedefEntries.isEmpty()) { + d << "typedefs[" << m_typedefEntries.size() << "]=("; + const auto begin = m_typedefEntries.cbegin(); + for (auto it = begin, end = m_typedefEntries.cend(); it != end; ++it) { + if (it != begin) + d << ", "; + d << " " << it.value() << '\n'; + } + d << ")\n"; + } if (!m_templates.isEmpty()) { d << "templates[" << m_templates.size() << "]=("; const auto begin = m_templates.cbegin(); |