aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-05-19 14:35:49 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-05-19 16:46:25 +0200
commiteb3313989a5a93f66067042dd5a8ed516e5febe7 (patch)
tree0b317970d16405698c544cb2d39993ab53a47d28
parent843b9c3c2ed76af346984de7be65dc1666eb49d7 (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>
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp24
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtemplates.cpp29
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtemplates.h1
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp11
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.h2
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase_typedefs.h1
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;