diff options
| author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-05-15 10:23:11 +0200 |
|---|---|---|
| committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2020-05-18 17:07:23 +0200 |
| commit | 8d65e9c3e451d9ad3a715dacdb2b415bc2dca8a3 (patch) | |
| tree | a3fa7246457fc7577ee47978e883aa5126ba6ba6 /sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp | |
| parent | dc9c6f502e82105dd4c4cc5f3aca5915ed163910 (diff) | |
Add support for template type aliases
In Qt 6 as of May 2020, this is used to alias QList to QVector:
template<typename T> using QList = QVector<T>
which shiboken needs to handle. Introduce a new code model
item for this and add it to the resolver.
Task-number: PYSIDE-904
Change-Id: I9e558635e843b60d44c0ceaaaa68b09b50c25c9f
Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp')
| -rw-r--r-- | sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp | 67 |
1 files changed, 58 insertions, 9 deletions
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp index ebec8770e..63de317c3 100644 --- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp +++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp @@ -191,6 +191,8 @@ public: bool addTemplateInstantiationsRecursion(const CXType &type, TypeInfo *t) const; void addTypeDef(const CXCursor &cursor, const CXType &cxType); + void startTemplateTypeAlias(const CXCursor &cursor); + void endTemplateTypeAlias(const CXCursor &typeAliasCursor); TemplateParameterModelItem createTemplateParameter(const CXCursor &cursor) const; TemplateParameterModelItem createNonTypeTemplateParameter(const CXCursor &cursor) const; @@ -216,12 +218,14 @@ public: CursorTypedefHash m_cursorTypedefHash; mutable TypeInfoHash m_typeInfoHash; // Cache type information + mutable QHash<QString, TemplateTypeAliasModelItem> m_templateTypeAliases; ClassModelItem m_currentClass; EnumModelItem m_currentEnum; FunctionModelItem m_currentFunction; ArgumentModelItem m_currentArgument; VariableModelItem m_currentField; + TemplateTypeAliasModelItem m_currentTemplateTypeAlias; QByteArrayList m_systemIncludes; // files, like "memory" QByteArrayList m_systemIncludePaths; // paths, like "/usr/include/Qt/" @@ -552,6 +556,26 @@ void BuilderPrivate::addTypeDef(const CXCursor &cursor, const CXType &cxType) m_cursorTypedefHash.insert(cursor, item); } +void BuilderPrivate::startTemplateTypeAlias(const CXCursor &cursor) +{ + const QString target = getCursorSpelling(cursor); + m_currentTemplateTypeAlias.reset(new _TemplateTypeAliasModelItem(m_model, target)); + setFileName(cursor, m_currentTemplateTypeAlias.data()); + m_currentTemplateTypeAlias->setScope(m_scope); +} + +void BuilderPrivate::endTemplateTypeAlias(const CXCursor &typeAliasCursor) +{ + CXType type = clang_getTypedefDeclUnderlyingType(typeAliasCursor); + // Usually "<elaborated>std::list<T>" or "<unexposed>Container1<T>", + // as obtained with parser of PYSIDE-323 + if (type.kind == CXType_Unexposed || type.kind == CXType_Elaborated) { + m_currentTemplateTypeAlias->setType(createTypeInfo(type)); + m_scopeStack.back()->addTemplateTypeAlias(m_currentTemplateTypeAlias); + } + m_currentTemplateTypeAlias.reset(); +} + // extract an expression from the cursor via source // CXCursor_EnumConstantDecl, ParmDecl (a = Flag1 | Flag2) QString BuilderPrivate::cursorValueExpression(BaseVisitor *bv, const CXCursor &cursor) const @@ -597,8 +621,22 @@ long clang_EnumDecl_isScoped4(BaseVisitor *bv, const CXCursor &cursor) // Add a base class to the current class from CXCursor_CXXBaseSpecifier void BuilderPrivate::addBaseClass(const CXCursor &cursor) { - const CXType inheritedType = clang_getCursorType(cursor); // Note spelling has "struct baseClass", - QString baseClassName = getTypeName(inheritedType); // use type. + // Note: spelling has "struct baseClass", use type + QString baseClassName; + const CXType inheritedType = clang_getCursorType(cursor); + if (inheritedType.kind == CXType_Unexposed) { + // The type is unexposed when the base class is a template type alias: + // "class QItemSelection : public QList<X>" where QList is aliased to QVector. + // Try to resolve via code model. + TypeInfo info = createTypeInfo(inheritedType); + auto parentScope = m_scopeStack.at(m_scopeStack.size() - 2); // Current is class. + auto resolved = TypeInfo::resolveType(info, parentScope); + if (resolved != info) + baseClassName = resolved.toString(); + } + if (baseClassName.isEmpty()) + baseClassName = getTypeName(inheritedType); + const CXCursor declCursor = clang_getTypeDeclaration(inheritedType); const CursorClassHash::const_iterator it = m_cursorClassHash.constFind(declCursor); const CodeModel::AccessPolicy access = accessPolicy(clang_getCXXAccessSpecifier(cursor)); @@ -990,6 +1028,8 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor) // Apply to function/member template? if (!d->m_currentFunction.isNull()) { d->m_currentFunction->setTemplateParameters(d->m_currentFunction->templateParameters() << tItem); + } else if (!d->m_currentTemplateTypeAlias.isNull()) { + d->m_currentTemplateTypeAlias->addTemplateParameter(tItem); } else if (!d->m_currentClass.isNull()) { // Apply to class const QString &tplParmName = tItem->name(); if (Q_UNLIKELY(!insertTemplateParameterIntoClassName(tplParmName, d->m_currentClass) @@ -1005,13 +1045,19 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor) } } break; - case CXCursor_TypeAliasDecl: - case CXCursor_TypeAliasTemplateDecl: { // May contain nested CXCursor_TemplateTypeParameter - const CXType type = clang_getCanonicalType(clang_getCursorType(cursor)); - if (type.kind > CXType_Unexposed) - d->addTypeDef(cursor, type); - } - return Skip; + case CXCursor_TypeAliasTemplateDecl: + d->startTemplateTypeAlias(cursor); + break; + case CXCursor_TypeAliasDecl: // May contain nested CXCursor_TemplateTypeParameter + if (d->m_currentTemplateTypeAlias.isNull()) { + const CXType type = clang_getCanonicalType(clang_getCursorType(cursor)); + if (type.kind > CXType_Unexposed) + d->addTypeDef(cursor, type); + return Skip; + } else { + d->endTemplateTypeAlias(cursor); + } + break; case CXCursor_TypedefDecl: { auto underlyingType = clang_getTypedefDeclUnderlyingType(cursor); d->addTypeDef(cursor, underlyingType); @@ -1090,6 +1136,9 @@ bool Builder::endToken(const CXCursor &cursor) case CXCursor_ParmDecl: d->m_currentArgument.clear(); break; + case CXCursor_TypeAliasTemplateDecl: + d->m_currentTemplateTypeAlias.reset(); + break; default: break; } |
