1 From: Friedemann Kleint <Friedemann.Kleint@qt.io>
2 Date: Tue, 25 Apr 2023 10:00:39 +0200
3 Subject: shiboken2/clang: Fix and simplify resolveType() helper
5 The function had a bug which only manifested with clang 16:
6 "type" should have been assigned the type of the cursor
7 obtained from clang_getTypeDeclaration(). With this, the complicated
8 lookup code in getBaseClass() can be removed.
10 Task-number: PYSIDE-2288
12 Change-Id: I861e30451b3f4af2ec0c2e4ffa4179a429854533
13 Reviewed-by: Christian Tismer <tismer@stackless.com>
14 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
16 .../ApiExtractor/clangparser/clangbuilder.cpp | 39 ++++++++++------------
17 1 file changed, 18 insertions(+), 21 deletions(-)
19 diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
20 index e8e5bcf..1b4c81c 100644
21 --- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
22 +++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
23 @@ -627,6 +627,9 @@ long clang_EnumDecl_isScoped4(BaseVisitor *bv, const CXCursor &cursor)
24 #endif // CLANG_NO_ENUMDECL_ISSCOPED
26 // Resolve declaration and type of a base class
27 +// Note: TypeAliasTemplateDecl ("using QVector<T>=QList<T>") is automatically
28 +// resolved by clang_getTypeDeclaration(), but it stops at
29 +// TypeAliasDecl / TypedefDecl.
31 struct TypeDeclaration
33 @@ -634,19 +637,23 @@ struct TypeDeclaration
37 +static inline bool isTypeAliasDecl(const CXCursor &cursor)
39 + const auto kind = clang_getCursorKind(cursor);
40 + return kind == CXCursor_TypeAliasDecl || kind == CXCursor_TypedefDecl;
43 static TypeDeclaration resolveBaseSpecifier(const CXCursor &cursor)
45 Q_ASSERT(clang_getCursorKind(cursor) == CXCursor_CXXBaseSpecifier);
46 CXType inheritedType = clang_getCursorType(cursor);
47 CXCursor decl = clang_getTypeDeclaration(inheritedType);
48 - if (inheritedType.kind != CXType_Unexposed) {
50 - auto kind = clang_getCursorKind(decl);
51 - if (kind != CXCursor_TypeAliasDecl && kind != CXCursor_TypedefDecl)
53 - inheritedType = clang_getTypedefDeclUnderlyingType(decl);
54 - decl = clang_getTypeDeclaration(inheritedType);
56 + auto resolvedType = clang_getCursorType(decl);
57 + if (resolvedType.kind != CXType_Invalid && resolvedType.kind != inheritedType.kind)
58 + inheritedType = resolvedType;
59 + while (isTypeAliasDecl(decl)) {
60 + inheritedType = clang_getTypedefDeclUnderlyingType(decl);
61 + decl = clang_getTypeDeclaration(inheritedType);
63 return {inheritedType, decl};
65 @@ -656,20 +663,10 @@ void BuilderPrivate::addBaseClass(const CXCursor &cursor)
67 Q_ASSERT(clang_getCursorKind(cursor) == CXCursor_CXXBaseSpecifier);
68 // Note: spelling has "struct baseClass", use type
69 - QString baseClassName;
70 const auto decl = resolveBaseSpecifier(cursor);
71 - if (decl.type.kind == CXType_Unexposed) {
72 - // The type is unexposed when the base class is a template type alias:
73 - // "class QItemSelection : public QList<X>" where QList is aliased to QVector.
74 - // Try to resolve via code model.
75 - TypeInfo info = createTypeInfo(decl.type);
76 - auto parentScope = m_scopeStack.at(m_scopeStack.size() - 2); // Current is class.
77 - auto resolved = TypeInfo::resolveType(info, parentScope);
78 - if (resolved != info)
79 - baseClassName = resolved.toString();
81 - if (baseClassName.isEmpty())
82 - baseClassName = getTypeName(decl.type);
83 + QString baseClassName = getTypeName(decl.type);
84 + if (baseClassName.startsWith(u"std::")) // Simplify "std::" types
85 + baseClassName = createTypeInfo(decl.type).toString();
87 auto it = m_cursorClassHash.constFind(decl.declaration);
88 const CodeModel::AccessPolicy access = accessPolicy(clang_getCXXAccessSpecifier(cursor));