diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-10-26 14:16:11 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-10-27 06:24:15 +0000 |
commit | 636b9a4bd5624d8ddb00da53b16add546e3944c4 (patch) | |
tree | 34d65abff69395ca6ae03b2e0930a2d4bdeb7dd6 /sources | |
parent | 80ab9a3b6e8ba704e14a6ffa04d8f78870b56b59 (diff) |
shiboken2: Handle typedefs of template parameters within templates
Typedefs of template parameters like
template <class T> class QList
{
using reference = T&;
are reported as "type-parameter-0-0" by clang. Resolve that to the
proper name of the template parameter in the clang builder. Also,
these typeinfo results must not be cached since the same CXType is
used for parameters of unrelated templates. Rename the
createTypeInfoHelper() function to createTypeInfoUncached() for
clarity and introduce a cacheable parameter.
Change-Id: I2b21a4dfdd8d86cf36497832837c21f37cb86518
Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources')
-rw-r--r-- | sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp | 58 |
1 files changed, 47 insertions, 11 deletions
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp index 944445579..dd0aca407 100644 --- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp +++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp @@ -176,7 +176,8 @@ public: FunctionModelItem createMemberFunction(const CXCursor &cursor, bool isTemplateCode = false); void qualifyConstructor(const CXCursor &cursor); - TypeInfo createTypeInfoHelper(const CXType &type) const; // uncashed + TypeInfo createTypeInfoUncached(const CXType &type, + bool *cacheable = nullptr) const; TypeInfo createTypeInfo(const CXType &type) const; TypeInfo createTypeInfo(const CXCursor &cursor) const { return createTypeInfo(clang_getCursorType(cursor)); } @@ -186,6 +187,7 @@ public: bool addTemplateInstantiationsRecursion(const CXType &type, TypeInfo *t) const; void addTypeDef(const CXCursor &cursor, const CXType &cxType); + ClassModelItem currentTemplateClass() const; void startTemplateTypeAlias(const CXCursor &cursor); void endTemplateTypeAlias(const CXCursor &typeAliasCursor); @@ -333,7 +335,7 @@ FunctionModelItem BuilderPrivate::createFunction(const CXCursor &cursor, name = fixTypeName(name); FunctionModelItem result(new _FunctionModelItem(m_model, name)); setFileName(cursor, result.data()); - result->setType(createTypeInfoHelper(clang_getCursorResultType(cursor))); + result->setType(createTypeInfo(clang_getCursorResultType(cursor))); result->setFunctionType(t); result->setScope(m_scope); result->setStatic(clang_Cursor_getStorageClass(cursor) == CX_SC_Static); @@ -415,7 +417,7 @@ TemplateParameterModelItem BuilderPrivate::createTemplateParameter(const CXCurso TemplateParameterModelItem BuilderPrivate::createNonTypeTemplateParameter(const CXCursor &cursor) const { TemplateParameterModelItem result = createTemplateParameter(cursor); - result->setType(createTypeInfoHelper(clang_getCursorType(cursor))); + result->setType(createTypeInfo(clang_getCursorType(cursor))); return result; } @@ -477,7 +479,7 @@ bool BuilderPrivate::addTemplateInstantiationsRecursion(const CXType &type, Type // of a non-type template (template <int v>). if (argType.kind == CXType_Invalid) return false; - t->addInstantiation(createTypeInfoHelper(argType)); + t->addInstantiation(createTypeInfoUncached(argType)); } } break; @@ -513,16 +515,19 @@ void BuilderPrivate::addTemplateInstantiations(const CXType &type, typeName->remove(pos.first, pos.second - pos.first); } -TypeInfo BuilderPrivate::createTypeInfoHelper(const CXType &type) const +TypeInfo BuilderPrivate::createTypeInfoUncached(const CXType &type, + bool *cacheable) const { if (type.kind == CXType_Pointer) { // Check for function pointers, first. const CXType pointeeType = clang_getPointeeType(type); const int argCount = clang_getNumArgTypes(pointeeType); if (argCount >= 0) { - TypeInfo result = createTypeInfoHelper(clang_getResultType(pointeeType)); + TypeInfo result = createTypeInfoUncached(clang_getResultType(pointeeType), + cacheable); result.setFunctionPointer(true); for (int a = 0; a < argCount; ++a) - result.addArgument(createTypeInfoHelper(clang_getArgType(pointeeType, unsigned(a)))); + result.addArgument(createTypeInfoUncached(clang_getArgType(pointeeType, unsigned(a)), + cacheable)); return result; } } @@ -562,6 +567,23 @@ TypeInfo BuilderPrivate::createTypeInfoHelper(const CXType &type) const || TypeInfo::stripLeadingVolatile(&typeName)) { } + // For typedefs within templates or nested classes within templates (iterators): + // "template <class T> class QList { using Value=T; .." + // the typedef source is named "type-parameter-0-0". Convert it back to the + // template parameter name. The CXTypes are the same for all templates and + // must not be cached. + if (!m_currentClass.isNull() && typeName.startsWith(QLatin1String("type-parameter-0-"))) { + if (cacheable != nullptr) + *cacheable = false; + bool ok; + const int n = QStringView{typeName}.mid(17).toInt(&ok); + if (ok) { + auto currentTemplate = currentTemplateClass(); + if (!currentTemplate.isNull() && n < currentTemplate->templateParameters().size()) + typeName = currentTemplate->templateParameters().at(n)->name(); + } + } + // Obtain template instantiations if the name has '<' (thus excluding // typedefs like "std::string". if (typeName.contains(QLatin1Char('<'))) @@ -575,10 +597,14 @@ TypeInfo BuilderPrivate::createTypeInfoHelper(const CXType &type) const TypeInfo BuilderPrivate::createTypeInfo(const CXType &type) const { - TypeInfoHash::iterator it = m_typeInfoHash.find(type); - if (it == m_typeInfoHash.end()) - it = m_typeInfoHash.insert(type, createTypeInfoHelper(type)); - return it.value(); + const auto it = m_typeInfoHash.constFind(type); + if (it != m_typeInfoHash.constEnd()) + return it.value(); + bool cacheable = true; + TypeInfo result = createTypeInfoUncached(type, &cacheable); + if (cacheable) + m_typeInfoHash.insert(type, result); + return result; } void BuilderPrivate::addTypeDef(const CXCursor &cursor, const CXType &cxType) @@ -592,6 +618,16 @@ void BuilderPrivate::addTypeDef(const CXCursor &cursor, const CXType &cxType) m_cursorTypedefHash.insert(cursor, item); } +ClassModelItem BuilderPrivate::currentTemplateClass() const +{ + for (int i = m_scopeStack.size() - 1; i >= 0; --i) { + auto klass = qSharedPointerDynamicCast<_ClassModelItem>(m_scopeStack.at(i)); + if (!klass.isNull() && klass->isTemplate()) + return klass; + } + return {}; +} + void BuilderPrivate::startTemplateTypeAlias(const CXCursor &cursor) { const QString target = getCursorSpelling(cursor); |