diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-05-19 14:35:49 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-05-19 16:46:25 +0200 |
commit | eb3313989a5a93f66067042dd5a8ed516e5febe7 (patch) | |
tree | 0b317970d16405698c544cb2d39993ab53a47d28 | |
parent | 843b9c3c2ed76af346984de7be65dc1666eb49d7 (diff) |
shiboken: Support non-type template parameters in functions
Create dummy constant value type entries on the fly as is done
for classes.
Fixes: PYSIDE-1296
Change-Id: I7990a44d5bf32dbf4bf801e06eb1af655ab8f488
Reviewed-by: Christian Tismer <tismer@stackless.com>
6 files changed, 62 insertions, 6 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 02450f1c7..b54dc70ef 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -2108,6 +2108,12 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ return translateTypeStatic(_typei, currentClass, this, flags, errorMessage); } +static bool isNumber(const QString &s) +{ + return std::all_of(s.cbegin(), s.cend(), + [](QChar c) { return c.isDigit(); }); +} + AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei, AbstractMetaClass *currentClass, AbstractMetaBuilderPrivate *d, @@ -2255,6 +2261,15 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo for (int t = 0, size = templateArguments.size(); t < size; ++t) { const TypeInfo &ti = templateArguments.at(t); 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) { + const QString value = ti.qualifiedName().join(colonColon()); + if (isNumber(value)) { + TypeDatabase::instance()->addConstantValueTypeEntry(value, type->typeSystemTypeEntry()); + targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage); + } + } if (!targType) { if (errorMessageIn) *errorMessageIn = msgCannotTranslateTemplateArgument(t, ti, errorMessage); @@ -2628,14 +2643,11 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, // "template <int R, int C> Matrix<R, C>" and subclass // "typedef Matrix<2,3> Matrix2x3;". If so, create dummy entries of // EnumValueTypeEntry for the integer values encountered on the fly. - const bool isNumber = std::all_of(typeName.cbegin(), typeName.cend(), - [](QChar c) { return c.isDigit(); }); - if (isNumber) { + if (isNumber(typeName)) { t = typeDb->findType(typeName); if (!t) { - t = new ConstantValueTypeEntry(typeName, subclass->typeEntry()->typeSystemTypeEntry()); - t->setCodeGeneration(0); - typeDb->addType(t); + auto parent = subclass->typeEntry()->typeSystemTypeEntry(); + t = TypeDatabase::instance()->addConstantValueTypeEntry(typeName, parent); } } else { QStringList possibleNames; diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp index 926b0bc59..f0f60f316 100644 --- a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp @@ -443,6 +443,35 @@ typedef Vector<int> IntVector; QCOMPARE(otherMethod->type()->cppSignature(), QLatin1String("Vector<int >")); } +void TestTemplates::testNonTypeTemplates() +{ + // PYSIDe-1296, functions with non type templates parameters. + const char cppCode[] = R"CPP( +template <class T, int Size> +class Array { + T array[Size]; +}; + +Array<int, 2> foo(); + +)CPP"; + + const char xmlCode[] = R"XML( +<typesystem package='Foo'> + <primitive-type name='int'/> + <container-type name='Array' type='vector'/> + <function signature="foo()"/> +</typesystem>)XML"; + + QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true)); + QVERIFY(!builder.isNull()); + auto functions = builder->globalFunctions(); + QCOMPARE(functions.count(), 1); + auto foo = functions.constFirst(); + QCOMPARE(foo->name(), QLatin1String("foo")); + QCOMPARE(foo->type()->name(), QLatin1String("Array")); +} + // Perform checks on template inheritance; a typedef of a template class // should result in rewritten types. void TestTemplates::testTemplateTypeDefs_data() diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.h b/sources/shiboken2/ApiExtractor/tests/testtemplates.h index 80d97512e..c96e7fe4a 100644 --- a/sources/shiboken2/ApiExtractor/tests/testtemplates.h +++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.h @@ -46,6 +46,7 @@ private slots: void testTemplateInheritanceMixedWithNamespaceAndForwardDeclaration(); void testTypedefOfInstantiationOfTemplateClass(); void testContainerTypeIncompleteArgument(); + void testNonTypeTemplates(); void testTemplateTypeDefs_data(); void testTemplateTypeDefs(); void testTemplateTypeAliases(); diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp index ddf43b54a..43d05fb78 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp @@ -426,6 +426,17 @@ bool TypeDatabase::addType(TypeEntry *e, QString *errorMessage) return true; } +// Add a dummy value entry for non-type template parameters +ConstantValueTypeEntry * + TypeDatabase::addConstantValueTypeEntry(const QString &value, + const TypeEntry *parent) +{ + auto result = new ConstantValueTypeEntry(value, parent); + result->setCodeGeneration(0); + addType(result); + return result; +} + bool TypeDatabase::isFunctionRejected(const QString& className, const QString& functionName, QString *reason) const { diff --git a/sources/shiboken2/ApiExtractor/typedatabase.h b/sources/shiboken2/ApiExtractor/typedatabase.h index 0a0a4eed5..7651d6b7b 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.h +++ b/sources/shiboken2/ApiExtractor/typedatabase.h @@ -137,6 +137,8 @@ public: QString *reason = nullptr) const; bool addType(TypeEntry *e, QString *errorMessage = nullptr); + ConstantValueTypeEntry *addConstantValueTypeEntry(const QString &value, + const TypeEntry *parent); void addTypeSystemType(const TypeSystemTypeEntry *e); FlagsTypeEntry *findFlagsType(const QString &name) const; diff --git a/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h b/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h index 0bb5cde1d..f9e6c669e 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h +++ b/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h @@ -33,6 +33,7 @@ #include <QtCore/QString> #include <QtCore/QVector> +class ConstantValueTypeEntry; class ContainerTypeEntry; class NamespaceTypeEntry; class PrimitiveTypeEntry; |