Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python3-pyside6 for openSUSE:Factory
checked in at 2026-04-18 21:34:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python3-pyside6 (Old)
and /work/SRC/openSUSE:Factory/.python3-pyside6.new.11940 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python3-pyside6"
Sat Apr 18 21:34:12 2026 rev:51 rq:1347333 version:6.11.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python3-pyside6/python3-pyside6.changes
2026-03-28 20:14:00.879066127 +0100
+++
/work/SRC/openSUSE:Factory/.python3-pyside6.new.11940/python3-pyside6.changes
2026-04-18 21:34:24.132739542 +0200
@@ -1,0 +2,18 @@
+Sun Apr 12 16:21:12 UTC 2026 - Aaron Puchert <[email protected]>
+
+- Backport patches for Clang 22 support (boo#1259783):
+ *
0000-shiboken6-Change-class-CodeModel-into-a-non-instantiable-Q_GADGET.patch
+ * 0001-shiboken6-Enable-testing-on-clang-level.patch
+ * 0002-shiboken6-clang-Add-a-define-for-the-LLVM-major-version.patch
+ * 0003-shiboken6-clang-Small-preparatory-refactorings-fixes.patch
+ * 0004-shiboken6-clang-Fix-type-names.patch
+ *
0005-shiboken6-clang-Prepare-for-introducing-error-handling-to-type-parsing.patch
+ *
0006-shiboken6-Add-infrastructure-for-error-handling-to-the-type-parsing.patch
+ * 0007-shiboken6-clang-Refactor-function-proto-type-handling.patch
+ * 0008-shiboken6-Add-some-type-checks.patch
+ * 0009-shiboken6-Add-clang-type-struct.patch
+ *
0010-shiboken6-Fix-retrieving-fully-qualified-type-names-with-clang-22.patch
+- Add 0011-QNativeInterface-QX11Application-display-type.patch to
+ work around an additional issue with Clang 22.
+
+-------------------------------------------------------------------
New:
----
0000-shiboken6-Change-class-CodeModel-into-a-non-instantiable-Q_GADGET.patch
0001-shiboken6-Enable-testing-on-clang-level.patch
0002-shiboken6-clang-Add-a-define-for-the-LLVM-major-version.patch
0003-shiboken6-clang-Small-preparatory-refactorings-fixes.patch
0004-shiboken6-clang-Fix-type-names.patch
0005-shiboken6-clang-Prepare-for-introducing-error-handling-to-type-parsing.patch
0006-shiboken6-Add-infrastructure-for-error-handling-to-the-type-parsing.patch
0007-shiboken6-clang-Refactor-function-proto-type-handling.patch
0008-shiboken6-Add-some-type-checks.patch
0009-shiboken6-Add-clang-type-struct.patch
0010-shiboken6-Fix-retrieving-fully-qualified-type-names-with-clang-22.patch
0011-QNativeInterface-QX11Application-display-type.patch
----------(New B)----------
New:- Backport patches for Clang 22 support (boo#1259783):
* 0000-shiboken6-Change-class-CodeModel-into-a-non-instantiable-Q_GADGET.patch
* 0001-shiboken6-Enable-testing-on-clang-level.patch
New: *
0000-shiboken6-Change-class-CodeModel-into-a-non-instantiable-Q_GADGET.patch
* 0001-shiboken6-Enable-testing-on-clang-level.patch
* 0002-shiboken6-clang-Add-a-define-for-the-LLVM-major-version.patch
New: * 0001-shiboken6-Enable-testing-on-clang-level.patch
* 0002-shiboken6-clang-Add-a-define-for-the-LLVM-major-version.patch
* 0003-shiboken6-clang-Small-preparatory-refactorings-fixes.patch
New: * 0002-shiboken6-clang-Add-a-define-for-the-LLVM-major-version.patch
* 0003-shiboken6-clang-Small-preparatory-refactorings-fixes.patch
* 0004-shiboken6-clang-Fix-type-names.patch
New: * 0003-shiboken6-clang-Small-preparatory-refactorings-fixes.patch
* 0004-shiboken6-clang-Fix-type-names.patch
*
0005-shiboken6-clang-Prepare-for-introducing-error-handling-to-type-parsing.patch
New: * 0004-shiboken6-clang-Fix-type-names.patch
*
0005-shiboken6-clang-Prepare-for-introducing-error-handling-to-type-parsing.patch
*
0006-shiboken6-Add-infrastructure-for-error-handling-to-the-type-parsing.patch
New: *
0005-shiboken6-clang-Prepare-for-introducing-error-handling-to-type-parsing.patch
*
0006-shiboken6-Add-infrastructure-for-error-handling-to-the-type-parsing.patch
* 0007-shiboken6-clang-Refactor-function-proto-type-handling.patch
New: *
0006-shiboken6-Add-infrastructure-for-error-handling-to-the-type-parsing.patch
* 0007-shiboken6-clang-Refactor-function-proto-type-handling.patch
* 0008-shiboken6-Add-some-type-checks.patch
New: * 0007-shiboken6-clang-Refactor-function-proto-type-handling.patch
* 0008-shiboken6-Add-some-type-checks.patch
* 0009-shiboken6-Add-clang-type-struct.patch
New: * 0008-shiboken6-Add-some-type-checks.patch
* 0009-shiboken6-Add-clang-type-struct.patch
* 0010-shiboken6-Fix-retrieving-fully-qualified-type-names-with-clang-22.patch
New: * 0009-shiboken6-Add-clang-type-struct.patch
* 0010-shiboken6-Fix-retrieving-fully-qualified-type-names-with-clang-22.patch
- Add 0011-QNativeInterface-QX11Application-display-type.patch to
New: *
0010-shiboken6-Fix-retrieving-fully-qualified-type-names-with-clang-22.patch
- Add 0011-QNativeInterface-QX11Application-display-type.patch to
work around an additional issue with Clang 22.
----------(New E)----------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python3-pyside6.spec ++++++
--- /var/tmp/diff_new_pack.MB857S/_old 2026-04-18 21:34:25.244784864 +0200
+++ /var/tmp/diff_new_pack.MB857S/_new 2026-04-18 21:34:25.248785028 +0200
@@ -55,6 +55,20 @@
Patch1: 0001-Revert-Modify-headers-installation-for-CMake-builds.patch
# PATCH-FIX-UPSTREAM
Patch2: 0001-Fix-installation.patch
+# PATCH-FIX-UPSTREAM -- clang 22 support
+Patch10:
0000-shiboken6-Change-class-CodeModel-into-a-non-instantiable-Q_GADGET.patch
+Patch11: 0001-shiboken6-Enable-testing-on-clang-level.patch
+Patch12:
0002-shiboken6-clang-Add-a-define-for-the-LLVM-major-version.patch
+Patch13: 0003-shiboken6-clang-Small-preparatory-refactorings-fixes.patch
+Patch14: 0004-shiboken6-clang-Fix-type-names.patch
+Patch15:
0005-shiboken6-clang-Prepare-for-introducing-error-handling-to-type-parsing.patch
+Patch16:
0006-shiboken6-Add-infrastructure-for-error-handling-to-the-type-parsing.patch
+Patch17:
0007-shiboken6-clang-Refactor-function-proto-type-handling.patch
+Patch18: 0008-shiboken6-Add-some-type-checks.patch
+Patch19: 0009-shiboken6-Add-clang-type-struct.patch
+Patch20:
0010-shiboken6-Fix-retrieving-fully-qualified-type-names-with-clang-22.patch
+# PATCH-FIX-OPENSUSE -- add elaborated type for clang 22
+Patch21: 0011-QNativeInterface-QX11Application-display-type.patch
# SECTION common_dependencies
BuildRequires: clang-devel
BuildRequires: %{mypython}-Sphinx
++++++
0000-shiboken6-Change-class-CodeModel-into-a-non-instantiable-Q_GADGET.patch
++++++
++++ 812 lines (skipped)
++++++ 0001-shiboken6-Enable-testing-on-clang-level.patch ++++++
++++ 1237 lines (skipped)
++++++ 0002-shiboken6-clang-Add-a-define-for-the-LLVM-major-version.patch ++++++
>From f1fc6675e5f634df103813d633807fd74db25db2 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <[email protected]>
Date: Tue, 24 Mar 2026 13:41:24 +0100
Subject: shiboken6_generator/clang parser: Add a define for the LLVM major
version
The version macros CINDEX_VERSION_MAJOR, CINDEX_VERSION_MINOR have been
unchanged for quite a while despite behavioral changes being introduced
in clang 22. Add a LLVM_VERSION define for it.
Task-number: PYSIDE-3286
Change-Id: I03a359fb887fa33ad8c17678a8fbb7e963df2a51
Reviewed-by: Cristian Maureira-Fredes <[email protected]>
(cherry picked from commit 2f25d2a3db2ffc4c5e18654138249d285e995d08)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
---
sources/shiboken6_generator/ApiExtractor/clangparser/clangparser.cpp | 3 ++-
sources/shiboken6_generator/cmake/ShibokenGeneratorSetup.cmake | 5 ++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git
a/sources/shiboken6_generator/ApiExtractor/clangparser/clangparser.cpp
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangparser.cpp
index 46d2a26f7..d31d5712d 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangparser.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangparser.cpp
@@ -285,7 +285,8 @@ static void setupTarget(CXTranslationUnit translationUnit)
QString message;
{
QTextStream str(&message);
- str << "CLANG v" << CINDEX_VERSION_MAJOR << '.' << CINDEX_VERSION_MINOR
+ str << "CLANG v" << LLVM_VERSION << '/'
+ << CINDEX_VERSION_MAJOR << '.' << CINDEX_VERSION_MINOR
<< " targeting \"" << targetTriple << "\"/"
<< optionsTriplet().compilerTripletValue()
<< ", " << pointerSize << "bit";
diff --git a/sources/shiboken6_generator/cmake/ShibokenGeneratorSetup.cmake
b/sources/shiboken6_generator/cmake/ShibokenGeneratorSetup.cmake
index 137824d15..7b7c46d6b 100644
--- a/sources/shiboken6_generator/cmake/ShibokenGeneratorSetup.cmake
+++ b/sources/shiboken6_generator/cmake/ShibokenGeneratorSetup.cmake
@@ -36,8 +36,11 @@ compute_config_py_values(shiboken6_VERSION)
shiboken_internal_set_python_site_packages()
+string(REGEX REPLACE "\\.[0-9]+\\.[0-9]+$" "" LLVM_VERSION
"${LLVM_PACKAGE_VERSION}")
+
set_cmake_cxx_flags()
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D QT_NO_CAST_FROM_ASCII -D
QT_NO_CAST_TO_ASCII")
+set(CMAKE_CXX_FLAGS
+ "${CMAKE_CXX_FLAGS} -D QT_NO_CAST_FROM_ASCII -D QT_NO_CAST_TO_ASCII -D
LLVM_VERSION=${LLVM_VERSION}")
# Force usage of the C++17 standard
set(CMAKE_CXX_STANDARD 17)
--
cgit v1.2.3
++++++ 0003-shiboken6-clang-Small-preparatory-refactorings-fixes.patch ++++++
>From a4d4eace908f875379be08d05bddeb69f1f020a4 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <[email protected]>
Date: Tue, 24 Mar 2026 09:38:18 +0100
Subject: shiboken6_generator/clang parser: Small preparatory
refactorings/fixes
Introduce addTemplateParameter() to classes and member model items
and fix function formatting.
Task-number: PYSIDE-3286
Change-Id: If4bc40de421e5f4adbfbc04862a85bf200a30c2a
Reviewed-by: Cristian Maureira-Fredes <[email protected]>
(cherry picked from commit 4522cb44ba5d3deee88c068b7ed4aec07997b15b)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
---
.../ApiExtractor/clangparser/clangbuilder.cpp | 4 ++--
.../shiboken6_generator/ApiExtractor/parser/codemodel.cpp | 12 +++++++++---
sources/shiboken6_generator/ApiExtractor/parser/codemodel.h | 4 ++--
3 files changed, 13 insertions(+), 7 deletions(-)
diff --git
a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
index d26a7efaa..a75cbd4a3 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
@@ -1156,7 +1156,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const
CXCursor &cursor)
? d->createTemplateParameter(cursor) :
d->createNonTypeTemplateParameter(cursor);
// Apply to function/member template?
if (d->m_currentFunction) {
-
d->m_currentFunction->setTemplateParameters(d->m_currentFunction->templateParameters()
<< tItem);
+ d->m_currentFunction->addTemplateParameter(tItem);
} else if (d->m_currentTemplateTypeAlias) {
d->m_currentTemplateTypeAlias->addTemplateParameter(tItem);
} else if (d->m_currentClass) { // Apply to class
@@ -1170,7 +1170,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const
CXCursor &cursor)
appendDiagnostic(d);
return Error;
}
-
d->m_currentClass->setTemplateParameters(d->m_currentClass->templateParameters()
<< tItem);
+ d->m_currentClass->addTemplateParameter(tItem);
}
}
break;
diff --git a/sources/shiboken6_generator/ApiExtractor/parser/codemodel.cpp
b/sources/shiboken6_generator/ApiExtractor/parser/codemodel.cpp
index de3924388..afa28fee5 100644
--- a/sources/shiboken6_generator/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/parser/codemodel.cpp
@@ -279,9 +279,9 @@ TemplateParameterList _ClassModelItem::templateParameters()
const
return m_templateParameters;
}
-void _ClassModelItem::setTemplateParameters(const TemplateParameterList
&templateParameters)
+void _ClassModelItem::addTemplateParameter(const TemplateParameterModelItem
&templateParameter)
{
- m_templateParameters = templateParameters;
+ m_templateParameters.append(templateParameter);
}
bool _ClassModelItem::extendsClass(const QString &name) const
@@ -992,7 +992,8 @@ QString _FunctionModelItem::classQualifiedSignature() const
QTextStream str(&result);
if (m_attributes.testFlag(FunctionAttribute::Virtual))
str << "virtual ";
- str << type().toString() << ' ';
+ if (m_functionType != CodeModel::FunctionType::Constructor)
+ str << type().toString() << ' ';
const auto &scopeList = scope();
for (const auto &scope : scopeList)
str << scope << "::";
@@ -1501,6 +1502,11 @@ void _MemberModelItem::setAccessPolicy(Access
accessPolicy)
m_accessPolicy = accessPolicy;
}
+void _MemberModelItem::addTemplateParameter(const TemplateParameterModelItem
&templateParameter)
+{
+ m_templateParameters.append(templateParameter);
+}
+
bool _MemberModelItem::isStatic() const
{
return m_isStatic;
diff --git a/sources/shiboken6_generator/ApiExtractor/parser/codemodel.h
b/sources/shiboken6_generator/ApiExtractor/parser/codemodel.h
index 45bb85f5f..1641ad8f2 100644
--- a/sources/shiboken6_generator/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken6_generator/ApiExtractor/parser/codemodel.h
@@ -259,7 +259,7 @@ public:
void addBaseClass(const BaseClass &b) { m_baseClasses.append(b); }
TemplateParameterList templateParameters() const;
- void setTemplateParameters(const TemplateParameterList
&templateParameters);
+ void addTemplateParameter(const TemplateParameterModelItem
&templateParameter);
bool extendsClass(const QString &name) const;
@@ -400,7 +400,7 @@ public:
void setAccessPolicy(Access accessPolicy);
TemplateParameterList templateParameters() const { return
m_templateParameters; }
- void setTemplateParameters(const TemplateParameterList
&templateParameters) { m_templateParameters = templateParameters; }
+ void addTemplateParameter(const TemplateParameterModelItem
&templateParameter);
TypeInfo type() const;
void setType(const TypeInfo &type);
--
cgit v1.2.3
++++++ 0004-shiboken6-clang-Fix-type-names.patch ++++++
>From e261816d80b62f14bc6f39910f43ef2d73bf499e Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <[email protected]>
Date: Tue, 24 Mar 2026 13:04:42 +0100
Subject: shiboken6_generator/clang parser: Fix type names
Extract a helper fixTypeName() from createTypeInfoUncached() and rename
the existing fixTypeName() for clarity. fixTypeName() strips
"const"/"volatile" and replaces the "typename" keyword which is reported
for some template parameters.
Task-number: PYSIDE-3286
Change-Id: I1b16c0b42721c32fdcc43cb6069596c6a326ee62
Reviewed-by: Cristian Maureira-Fredes <[email protected]>
(cherry picked from commit 47b52076d2b9f941f439577fa64a849edddd23e1)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
---
.../ApiExtractor/clangparser/clangbuilder.cpp | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git
a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
index a75cbd4a3..897b2f8cb 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
@@ -40,7 +40,7 @@ static inline bool withinClassDeclaration(const CXCursor
&cursor)
return isClassCursor(clang_getCursorLexicalParent(cursor));
}
-static QString fixTypeName(QString t)
+static QString fixOperatorTypeName(QString t)
{
// Fix "Foo &" -> "Foo&", similarly "Bar **" -> "Bar**"
auto pos = t.size() - 1;
@@ -324,7 +324,7 @@ FunctionModelItem BuilderPrivate::createFunction(const
CXCursor &cursor,
QString name = getCursorSpelling(cursor);
// Apply type fixes to "operator X &" -> "operator X&"
if (name.startsWith(u"operator "))
- name = fixTypeName(name);
+ name = fixOperatorTypeName(name);
auto result = std::make_shared<_FunctionModelItem>(name);
setFileName(cursor, result.get());
const auto type = clang_getCursorResultType(cursor);
@@ -541,6 +541,18 @@ static TypeCategory typeCategoryFromClang(CXTypeKind k)
return TypeCategory::Other;
}
+static QString fixTypeName(QString typeName)
+{
+ while (TypeInfo::stripLeadingConst(&typeName) ||
TypeInfo::stripLeadingVolatile(&typeName)) {
+ }
+ static constexpr auto leadingTypename = "typename "_L1;
+ if (typeName.startsWith(leadingTypename))
+ typeName.remove(0, leadingTypename.size());
+ typeName.replace("<typename "_L1, "<"_L1);
+ typeName.replace(", typename "_L1, ", "_L1);
+ return typeName;
+}
+
TypeInfo BuilderPrivate::createTypeInfoUncached(const CXType &type,
bool *cacheable) const
{
@@ -590,10 +602,7 @@ TypeInfo BuilderPrivate::createTypeInfoUncached(const
CXType &type,
typeInfo.setConstant(clang_isConstQualifiedType(nestedType) != 0);
typeInfo.setVolatile(clang_isVolatileQualifiedType(nestedType) != 0);
- QString typeName = getResolvedTypeName(nestedType);
- while (TypeInfo::stripLeadingConst(&typeName)
- || TypeInfo::stripLeadingVolatile(&typeName)) {
- }
+ QString typeName = fixTypeName(getResolvedTypeName(nestedType));
// For typedefs within templates or nested classes within templates
(iterators):
// "template <class T> class QList { using Value=T; .."
--
cgit v1.2.3
++++++
0005-shiboken6-clang-Prepare-for-introducing-error-handling-to-type-parsing.patch
++++++
>From 4768a4a653f0e1986aa8d6f63c018b43dd6e0aab Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <[email protected]>
Date: Mon, 23 Mar 2026 20:41:51 +0100
Subject: shiboken6_generator/clang: Prepare for introducing error handling to
type parsing
Move the adding of the parsed functions to the endToken() function
so that BuilderPrivate::m_currentFunction can be cleared should
errors occur during type parsing.
Task-number: PYSIDE-3286
Change-Id: Id58c84191386ec5c3b8f101fa9f17fd01fac8296
Reviewed-by: Cristian Maureira-Fredes <[email protected]>
(cherry picked from commit 565f8ead9b650b8e2f3e4428d502baaa2248f9bb)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
---
.../ApiExtractor/clangparser/clangbuilder.cpp | 29 ++++++++++++++--------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git
a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
index 897b2f8cb..ecfec292b 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
@@ -1083,7 +1083,6 @@ BaseVisitor::StartTokenResult Builder::startToken(const
CXCursor &cursor)
if (d->m_withinFriendDecl || !withinClassDeclaration(cursor))
return Skip;
d->m_currentFunction = d->createMemberFunction(cursor, false);
- d->m_scopeStack.back()->addFunction(d->m_currentFunction);
break;
// Not fully supported, currently, seen as normal function
// Note: May appear inside class (member template) or outside (free
template).
@@ -1092,7 +1091,6 @@ BaseVisitor::StartTokenResult Builder::startToken(const
CXCursor &cursor)
if (isClassCursor(semParent)) {
if (semParent == clang_getCursorLexicalParent(cursor)) {
d->m_currentFunction = d->createMemberFunction(cursor, true);
- d->m_scopeStack.back()->addFunction(d->m_currentFunction);
break;
}
return Skip; // inline member functions outside class
@@ -1100,22 +1098,14 @@ BaseVisitor::StartTokenResult Builder::startToken(const
CXCursor &cursor)
}
d->m_currentFunction = d->createFunction(cursor, CodeModel::Normal,
true);
d->setFileName(cursor, d->m_currentFunction.get());
- d->m_scopeStack.back()->addFunction(d->m_currentFunction);
break;
case CXCursor_FunctionDecl:
// Free functions or functions completely defined within "friend"
(class
// operators). Note: CXTranslationUnit_SkipFunctionBodies must be off
for
// clang_isCursorDefinition() to work here.
if (!d->m_withinFriendDecl || clang_isCursorDefinition(cursor) != 0) {
- auto scope = d->m_scopeStack.size() - 1; // enclosing class
- if (d->m_withinFriendDecl) {
- // Friend declaration: go back to namespace or file scope.
- for (--scope; d->m_scopeStack.at(scope)->kind() ==
_CodeModelItem::Kind_Class; --scope) {
- }
- }
d->m_currentFunction = d->createFunction(cursor,
CodeModel::Normal, false);
d->m_currentFunction->setHiddenFriend(d->m_withinFriendDecl);
- d->m_scopeStack.at(scope)->addFunction(d->m_currentFunction);
}
break;
case CXCursor_Namespace: {
@@ -1290,9 +1280,10 @@ bool Builder::endToken(const CXCursor &cursor)
d->m_currentField.reset();
break;
case CXCursor_Constructor:
- d->qualifyConstructor(cursor);
if (d->m_currentFunction) {
+ d->qualifyConstructor(cursor);
d->m_currentFunction->_determineType();
+ d->m_scopeStack.back()->addFunction(d->m_currentFunction);
d->m_currentFunction.reset();
}
break;
@@ -1302,12 +1293,28 @@ bool Builder::endToken(const CXCursor &cursor)
case CXCursor_FunctionTemplate:
if (d->m_currentFunction) {
d->m_currentFunction->_determineType();
+ auto scope = d->m_scopeStack.size() - 1; // enclosing class
+ if (cursor.kind == CXCursor_FunctionDecl) {
+ // Free functions or functions completely defined within
"friend" (class
+ // operators).
+ if (!d->m_withinFriendDecl || clang_isCursorDefinition(cursor)
!= 0) {
+ if (d->m_withinFriendDecl) {
+ // Friend declaration: go back to namespace or file
scope.
+ for (--scope;
+ d->m_scopeStack.at(scope)->kind() ==
_CodeModelItem::Kind_Class;
+ --scope) {
+ }
+ }
+ }
+ }
+ d->m_scopeStack.at(scope)->addFunction(d->m_currentFunction);
d->m_currentFunction.reset();
}
break;
case CXCursor_ConversionFunction:
if (d->m_currentFunction) {
d->m_currentFunction->setFunctionType(CodeModel::ConversionOperator);
+ d->m_scopeStack.back()->addFunction(d->m_currentFunction);
d->m_currentFunction.reset();
}
break;
--
cgit v1.2.3
++++++
0006-shiboken6-Add-infrastructure-for-error-handling-to-the-type-parsing.patch
++++++
>From 4326205761b20b3a6be14340ecc29edf338cb47f Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <[email protected]>
Date: Thu, 19 Mar 2026 15:29:20 +0100
Subject: shiboken6_generator: Add infrastructure for error handling to the
type parsing
Change createTypeInfoUncached() to return a std::optional<TypeInfo>
and adapt the call sites. Add logging for rejected types.
Task-number: PYSIDE-3286
Change-Id: I102170ea564cf221daa908e858054c382d37bcee
Reviewed-by: Cristian Maureira-Fredes <[email protected]>
(cherry picked from commit d785072bcf2b730206953cb5cea64cefb0ab3fbc)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
---
.../ApiExtractor/abstractmetabuilder.cpp | 4 +
.../ApiExtractor/clangparser/clangbuilder.cpp | 153 +++++++++++++++------
.../ApiExtractor/clangparser/clangbuilder.h | 2 +
.../shiboken6_generator/ApiExtractor/messages.cpp | 11 ++
.../shiboken6_generator/ApiExtractor/messages.h | 2 +
5 files changed, 132 insertions(+), 40 deletions(-)
diff --git a/sources/shiboken6_generator/ApiExtractor/abstractmetabuilder.cpp
b/sources/shiboken6_generator/ApiExtractor/abstractmetabuilder.cpp
index 21e986221..9ea616eb6 100644
--- a/sources/shiboken6_generator/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/abstractmetabuilder.cpp
@@ -535,6 +535,10 @@ FileModelItem
AbstractMetaBuilderPrivate::buildDom(QByteArrayList arguments,
for (qsizetype i = 0; i < diagnosticsCount; ++i)
d << " " << diagnostics.at(i) << '\n';
}
+
+ if (const auto rejectedTypes = builder.rejectedTypes();
!rejectedTypes.isEmpty())
+ ReportHandler::addGeneralMessage(msgRejectedTypes(rejectedTypes));
+
return result;
}
diff --git
a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
index ecfec292b..9eb7d738e 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
@@ -19,6 +19,10 @@
#include <QtCore/qstack.h>
#include <QtCore/qlist.h>
+#include <algorithm>
+#include <optional>
+#include <set>
+
using namespace Qt::StringLiterals;
namespace clang {
@@ -159,10 +163,10 @@ public:
FunctionModelItem createMemberFunction(const CXCursor &cursor,
bool isTemplateCode = false);
void qualifyConstructor(const CXCursor &cursor);
- TypeInfo createTypeInfoUncached(const CXType &type,
- bool *cacheable = nullptr) const;
- TypeInfo createTypeInfo(const CXType &type) const;
- TypeInfo createTypeInfo(const CXCursor &cursor) const
+ std::optional<TypeInfo> createTypeInfoUncached(const CXType &type,
+ bool *cacheable = nullptr)
const;
+ std::optional<TypeInfo> createTypeInfo(const CXType &type) const;
+ std::optional<TypeInfo> createTypeInfo(const CXCursor &cursor) const
{ return createTypeInfo(clang_getCursorType(cursor)); }
void addTemplateInstantiations(const CXType &type,
QString *typeName,
@@ -176,7 +180,7 @@ public:
TemplateParameterModelItem createTemplateParameter(const CXCursor &cursor)
const;
TemplateParameterModelItem createNonTypeTemplateParameter(const CXCursor
&cursor) const;
- void addField(const CXCursor &cursor);
+ void addField(const CXCursor &cursor, bool staticField = false);
static QString cursorValueExpression(BaseVisitor *bv, const CXCursor
&cursor);
std::pair<QString, ClassModelItem> getBaseClass(CXType type) const;
@@ -215,6 +219,7 @@ public:
CodeModel::FunctionType m_currentFunctionType = CodeModel::Normal;
bool m_withinFriendDecl = false;
mutable QHash<QString, SpecialSystemHeader> m_systemHeaders;
+ mutable std::set<QString> m_rejectedTypes;
};
bool BuilderPrivate::addClass(const CXCursor &cursor, CodeModel::ClassType t)
@@ -328,7 +333,10 @@ FunctionModelItem BuilderPrivate::createFunction(const
CXCursor &cursor,
auto result = std::make_shared<_FunctionModelItem>(name);
setFileName(cursor, result.get());
const auto type = clang_getCursorResultType(cursor);
- result->setType(createTypeInfo(type));
+ auto resultTypeO = createTypeInfo(type);
+ if (!resultTypeO.has_value())
+ return {};
+ result->setType(resultTypeO.value());
result->setScopeResolution(hasScopeResolution(type));
result->setFunctionType(t);
result->setScope(m_scope);
@@ -387,6 +395,8 @@ FunctionModelItem
BuilderPrivate::createMemberFunction(const CXCursor &cursor,
: functionTypeFromCursor(cursor);
isTemplateCode |= m_currentClass->name().endsWith(u'>');
auto result = createFunction(cursor, functionType, isTemplateCode);
+ if (!result)
+ return result;
result->setAccessPolicy(accessPolicy(clang_getCXXAccessSpecifier(cursor)));
result->setConstant(clang_CXXMethod_isConst(cursor) != 0);
result->setAttribute(FunctionAttribute::Static,
clang_CXXMethod_isStatic(cursor) != 0);
@@ -420,19 +430,26 @@ TemplateParameterModelItem
BuilderPrivate::createTemplateParameter(const CXCurso
TemplateParameterModelItem
BuilderPrivate::createNonTypeTemplateParameter(const CXCursor &cursor) const
{
+ auto typeO = createTypeInfo(clang_getCursorType(cursor));
+ if (!typeO.has_value())
+ return {};
TemplateParameterModelItem result = createTemplateParameter(cursor);
- result->setType(createTypeInfo(clang_getCursorType(cursor)));
+ result->setType(typeO.value());
return result;
}
// CXCursor_VarDecl, CXCursor_FieldDecl cursors
-void BuilderPrivate::addField(const CXCursor &cursor)
+void BuilderPrivate::addField(const CXCursor &cursor, bool staticField)
{
+ auto typeO = createTypeInfo(cursor);
+ if (!typeO.has_value())
+ return;
auto field =
std::make_shared<_VariableModelItem>(getCursorSpelling(cursor));
field->setAccessPolicy(accessPolicy(clang_getCXXAccessSpecifier(cursor)));
field->setScope(m_scope);
- field->setType(createTypeInfo(cursor));
+ field->setType(typeO.value());
field->setMutable(clang_CXXField_isMutable(cursor) != 0);
+ field->setStatic(staticField);
setFileName(cursor, field.get());
m_currentField = field;
m_scopeStack.back()->addVariable(field);
@@ -484,7 +501,10 @@ bool
BuilderPrivate::addTemplateInstantiationsRecursion(const CXType &type, Type
// of a non-type template (template <int v>).
if (argType.kind == CXType_Invalid)
return false;
- t->addInstantiation(createTypeInfoUncached(argType));
+ auto typeO = createTypeInfoUncached(argType);
+ if (!typeO.has_value())
+ return false;
+ t->addInstantiation(typeO.value());
}
}
break;
@@ -553,20 +573,26 @@ static QString fixTypeName(QString typeName)
return typeName;
}
-TypeInfo BuilderPrivate::createTypeInfoUncached(const CXType &type,
- bool *cacheable) const
+std::optional<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 =
createTypeInfoUncached(clang_getResultType(pointeeType),
- cacheable);
+ auto resultO =
createTypeInfoUncached(clang_getResultType(pointeeType), cacheable);
+ if (!resultO.has_value())
+ return std::nullopt;
+ auto result = resultO.value();
result.setTypeCategory(TypeCategory::Pointer);
result.setFunctionPointer(true);
- for (int a = 0; a < argCount; ++a)
-
result.addArgument(createTypeInfoUncached(clang_getArgType(pointeeType,
unsigned(a)),
- cacheable));
+ for (int a = 0; a < argCount; ++a) {
+ auto argTypeInfoO =
+ createTypeInfoUncached(clang_getArgType(pointeeType,
unsigned(a)), cacheable);
+ if (!argTypeInfoO.has_value())
+ return std::nullopt;
+ result.addArgument(argTypeInfoO.value());
+ }
return result;
}
}
@@ -632,24 +658,27 @@ TypeInfo BuilderPrivate::createTypeInfoUncached(const
CXType &type,
return typeInfo;
}
-TypeInfo BuilderPrivate::createTypeInfo(const CXType &type) const
+std::optional<TypeInfo> BuilderPrivate::createTypeInfo(const CXType &type)
const
{
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;
+ auto resultO = createTypeInfoUncached(type, &cacheable);
+ if (resultO.has_value() && cacheable)
+ m_typeInfoHash.insert(type, resultO.value());
+ return resultO;
}
void BuilderPrivate::addTypeDef(const CXCursor &cursor, const CXType &cxType)
{
const QString target = getCursorSpelling(cursor);
+ auto typeInfoO = createTypeInfo(cxType);
+ if (!typeInfoO.has_value())
+ return;
auto item = std::make_shared<_TypeDefModelItem>(target);
setFileName(cursor, item.get());
- item->setType(createTypeInfo(cxType));
+ item->setType(typeInfoO.value());
item->setScope(m_scope);
item->setAccessPolicy(accessPolicy(clang_getCXXAccessSpecifier(cursor)));
m_scopeStack.back()->addTypeDef(item);
@@ -679,8 +708,10 @@ void BuilderPrivate::endTemplateTypeAlias(const CXCursor
&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);
+ if (auto typeO = createTypeInfo(type)) {
+ m_currentTemplateTypeAlias->setType(typeO.value());
+
m_scopeStack.back()->addTemplateTypeAlias(m_currentTemplateTypeAlias);
+ }
}
m_currentTemplateTypeAlias.reset();
}
@@ -738,8 +769,10 @@ std::pair<QString, ClassModelItem>
BuilderPrivate::getBaseClass(CXType type) con
const auto decl = resolveBaseClassType(type);
// Note: spelling has "struct baseClass", use type
QString baseClassName = getTypeName(decl.type);
- if (baseClassName.startsWith(u"std::")) // Simplify "std::" types
- baseClassName = createTypeInfo(decl.type).toString();
+ if (baseClassName.startsWith(u"std::")) { // Simplify "std::" types
+ if (auto typeO = createTypeInfo(decl.type))
+ baseClassName = typeO.value().toString();
+ }
auto it = m_cursorClassHash.constFind(decl.declaration);
// Not found: Set unqualified name. This happens in cases like
@@ -921,6 +954,11 @@ FileModelItem Builder::dom() const
return std::dynamic_pointer_cast<_FileModelItem>(rootScope);
}
+QStringList Builder::rejectedTypes() const
+{
+ return {d->m_rejectedTypes.cbegin(), d->m_rejectedTypes.cend()};
+}
+
static QString msgOutOfOrder(const CXCursor &cursor, const char *expectedScope)
{
return getCursorKindName(cursor.kind) + u' '
@@ -1063,10 +1101,8 @@ BaseVisitor::StartTokenResult Builder::startToken(const
CXCursor &cursor)
break;
case CXCursor_VarDecl:
// static class members are seen as CXCursor_VarDecl
- if (isClassOrNamespaceCursor(clang_getCursorSemanticParent(cursor))) {
- d->addField(cursor);
- d->m_currentField->setStatic(true);
- }
+ if (isClassOrNamespaceCursor(clang_getCursorSemanticParent(cursor)))
+ d->addField(cursor, true);
break;
case CXCursor_FieldDecl:
d->addField(cursor);
@@ -1077,12 +1113,16 @@ BaseVisitor::StartTokenResult Builder::startToken(const
CXCursor &cursor)
case CXCursor_Constructor:
case CXCursor_Destructor: // Note: Also use
clang_CXXConstructor_is..Constructor?
case CXCursor_CXXMethod:
- case CXCursor_ConversionFunction:
+ case CXCursor_ConversionFunction: {
// Member functions of other classes can be declared to be friends.
// Skip inline member functions outside class, only go by declarations
inside class
if (d->m_withinFriendDecl || !withinClassDeclaration(cursor))
return Skip;
- d->m_currentFunction = d->createMemberFunction(cursor, false);
+ auto func = d->createMemberFunction(cursor, false);
+ if (!func)
+ return Skip;
+ d->m_currentFunction = func;
+ }
break;
// Not fully supported, currently, seen as normal function
// Note: May appear inside class (member template) or outside (free
template).
@@ -1090,21 +1130,29 @@ BaseVisitor::StartTokenResult Builder::startToken(const
CXCursor &cursor)
const CXCursor semParent = clang_getCursorSemanticParent(cursor);
if (isClassCursor(semParent)) {
if (semParent == clang_getCursorLexicalParent(cursor)) {
- d->m_currentFunction = d->createMemberFunction(cursor, true);
- break;
+ if (auto func = d->createMemberFunction(cursor, true)) {
+ d->m_currentFunction = func;
+ break;
+ }
}
return Skip; // inline member functions outside class
}
- }
- d->m_currentFunction = d->createFunction(cursor, CodeModel::Normal,
true);
+ auto func = d->createFunction(cursor, CodeModel::Normal, true);
+ if (!func)
+ return Skip;
+ d->m_currentFunction = func;
d->setFileName(cursor, d->m_currentFunction.get());
+ }
break;
case CXCursor_FunctionDecl:
// Free functions or functions completely defined within "friend"
(class
// operators). Note: CXTranslationUnit_SkipFunctionBodies must be off
for
// clang_isCursorDefinition() to work here.
if (!d->m_withinFriendDecl || clang_isCursorDefinition(cursor) != 0) {
- d->m_currentFunction = d->createFunction(cursor,
CodeModel::Normal, false);
+ auto func = d->createFunction(cursor, CodeModel::Normal, false);
+ if (!func)
+ return Skip;
+ d->m_currentFunction = func;
d->m_currentFunction->setHiddenFriend(d->m_withinFriendDecl);
}
break;
@@ -1135,10 +1183,15 @@ BaseVisitor::StartTokenResult Builder::startToken(const
CXCursor &cursor)
// and function pointer typedefs.
if (!d->m_currentArgument && d->m_currentFunction) {
const QString name = getCursorSpelling(cursor);
- d->m_currentArgument = std::make_shared<_ArgumentModelItem>(name);
const auto type = clang_getCursorType(cursor);
+ auto typeO = d->createTypeInfo(type);
+ if (!typeO.has_value()) {
+ d->m_currentFunction.reset();
+ return Skip;
+ }
+ d->m_currentArgument = std::make_shared<_ArgumentModelItem>(name);
d->m_currentArgument->setScopeResolution(hasScopeResolution(type));
- d->m_currentArgument->setType(d->createTypeInfo(type));
+ d->m_currentArgument->setType(typeO.value());
d->m_currentFunction->addArgument(d->m_currentArgument);
QString defaultValueExpression =
BuilderPrivate::cursorValueExpression(this, cursor);
if (!defaultValueExpression.isEmpty()) {
@@ -1155,10 +1208,30 @@ BaseVisitor::StartTokenResult Builder::startToken(const
CXCursor &cursor)
? d->createTemplateParameter(cursor) :
d->createNonTypeTemplateParameter(cursor);
// Apply to function/member template?
if (d->m_currentFunction) {
+ if (!tItem) {
+ d->m_currentFunction.reset();
+ return Skip;
+ }
d->m_currentFunction->addTemplateParameter(tItem);
} else if (d->m_currentTemplateTypeAlias) {
+ if (!tItem) {
+ d->m_currentTemplateTypeAlias.reset();
+ return Skip;
+ }
d->m_currentTemplateTypeAlias->addTemplateParameter(tItem);
} else if (d->m_currentClass) { // Apply to class
+ if (!tItem) {
+ // Failure is fatal if the first parameter cannot be
determined, trailing
+ // parameters will be warned about.
+ const bool fatal =
d->m_currentClass->templateParameters().isEmpty();
+ const QString message = "Failed to determine template
parameter of "_L1
+ + d->m_currentClass->name();
+ const Diagnostic d(message, cursor,
+ fatal ? CXDiagnostic_Error :
CXDiagnostic_Warning);
+ qWarning() << d;
+ appendDiagnostic(d);
+ return fatal ? Error : Skip;
+ }
const QString &tplParmName = tItem->name();
if (Q_UNLIKELY(!insertTemplateParameterIntoClassName(tplParmName,
d->m_currentClass)
||
!insertTemplateParameterIntoClassName(tplParmName, &d->m_scope.back()))) {
diff --git
a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.h
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.h
index f60bbe155..4cc58d08d 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.h
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.h
@@ -33,6 +33,8 @@ public:
FileModelItem dom() const;
+ QStringList rejectedTypes() const;
+
private:
BuilderPrivate *d;
};
diff --git a/sources/shiboken6_generator/ApiExtractor/messages.cpp
b/sources/shiboken6_generator/ApiExtractor/messages.cpp
index e619f1e..be11bf9 100644
--- a/sources/shiboken6_generator/ApiExtractor/messages.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/messages.cpp
@@ -1168,3 +1168,14 @@ QString msgSynthesizedFunction(const
AbstractMetaFunctionCPtr &newFunction,
const QString why = "from: \""_L1 + oldFunction->classQualifiedSignature()
+ u'"';
return msgSynthesizedFunction(newFunction, why);
}
+
+QString msgRejectedTypes(const QStringList &rejectedTypes)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "Rejected Types (" << rejectedTypes.size() << "):\n";
+ for (const auto &rejectedType : rejectedTypes)
+ str << " \"" << rejectedType << "\"\n";
+ str << '\n';
+ return result;
+}
diff --git a/sources/shiboken6_generator/ApiExtractor/messages.h
b/sources/shiboken6_generator/ApiExtractor/messages.h
index db32f38..5a81485 100644
--- a/sources/shiboken6_generator/ApiExtractor/messages.h
+++ b/sources/shiboken6_generator/ApiExtractor/messages.h
@@ -297,4 +297,6 @@ QString msgSynthesizedFunction(const
AbstractMetaFunctionCPtr &newFunction,
QString msgSynthesizedFunction(const AbstractMetaFunctionCPtr &newFunction,
const FunctionModelItem &oldFunction);
+QString msgRejectedTypes(const QStringList &rejectedTypes);
+
#endif // MESSAGES_H
--
cgit v1.2.3
++++++ 0007-shiboken6-clang-Refactor-function-proto-type-handling.patch ++++++
>From 10a7218442218b0c47bf56f82f0242e8c27443ed Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <[email protected]>
Date: Tue, 24 Mar 2026 15:50:35 +0100
Subject: shiboken6_generator/clang parser: Refactor function proto type
handling
Add FunctionPointer besides Function (Prototype) to the type categories
and remove the corresponding bit field in TypeInfo. Parse the function
arguments for function prototypes as well.
Task-number: PYSIDE-3286
Change-Id: Ie3a10f18de5c5c43effc8d3e17adc87b888a5d15
Reviewed-by: Cristian Maureira-Fredes <[email protected]>
(cherry picked from commit 40965ebb2f1097d05d57f676765371179c4a86ea)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
---
.../ApiExtractor/abstractmetabuilder.cpp | 2 +-
.../ApiExtractor/clangparser/clangbuilder.cpp | 43 +++++++++++++---------
.../ApiExtractor/parser/codemodel_enums.h | 3 +-
.../ApiExtractor/parser/typeinfo.cpp | 36 ++++++++++--------
.../ApiExtractor/parser/typeinfo.h | 1 -
.../ApiExtractor/tests/testclangparser.cpp | 21 +++++++++++
.../ApiExtractor/tests/testclangparser.h | 1 +
7 files changed, 72 insertions(+), 35 deletions(-)
diff --git a/sources/shiboken6_generator/ApiExtractor/abstractmetabuilder.cpp
b/sources/shiboken6_generator/ApiExtractor/abstractmetabuilder.cpp
index 9ea616eb6..464ff27fe 100644
--- a/sources/shiboken6_generator/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/abstractmetabuilder.cpp
@@ -2879,7 +2879,7 @@ std::optional<AbstractMetaType>
newInfo.setIndirectionsV(typeInfo.indirectionsV());
newInfo.setConstant(typeInfo.isConstant());
newInfo.setVolatile(typeInfo.isVolatile());
- newInfo.setFunctionPointer(typeInfo.isFunctionPointer());
+ newInfo.setTypeCategory(typeInfo.typeCategory());
newInfo.setQualifiedName(typeInfo.qualifiedName());
newInfo.setReferenceType(typeInfo.referenceType());
newInfo.setVolatile(typeInfo.isVolatile());
diff --git
a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
index 9eb7d738e..a31fae778 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
@@ -168,6 +168,8 @@ public:
std::optional<TypeInfo> createTypeInfo(const CXType &type) const;
std::optional<TypeInfo> createTypeInfo(const CXCursor &cursor) const
{ return createTypeInfo(clang_getCursorType(cursor)); }
+ std::optional<TypeInfo> createFunctionTypeInfo(const CXType &type,
TypeCategory cat,
+ bool *cacheable) const;
void addTemplateInstantiations(const CXType &type,
QString *typeName,
TypeInfo *t) const;
@@ -573,28 +575,35 @@ static QString fixTypeName(QString typeName)
return typeName;
}
+std::optional<TypeInfo>
+ BuilderPrivate::createFunctionTypeInfo(const CXType &type, TypeCategory
cat, bool *cacheable) const
+{
+ const int argCount = clang_getNumArgTypes(type);
+ if (argCount < 0)
+ return std::nullopt;
+ auto resultO = createTypeInfoUncached(clang_getResultType(type),
cacheable);
+ if (!resultO.has_value())
+ return std::nullopt;
+ resultO->setTypeCategory(cat);
+ for (int a = 0; a < argCount; ++a) {
+ auto argTypeO = createTypeInfoUncached(clang_getArgType(type,
unsigned(a)), cacheable);
+ if (!argTypeO.has_value())
+ return std::nullopt;
+ resultO->addArgument(argTypeO.value());
+ }
+ return resultO;
+}
+
std::optional<TypeInfo>
BuilderPrivate::createTypeInfoUncached(const CXType &type, bool
*cacheable) const
{
+ if (type.kind == CXType_FunctionProto)
+ return createFunctionTypeInfo(type, TypeCategory::Function, cacheable);
+
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) {
- auto resultO =
createTypeInfoUncached(clang_getResultType(pointeeType), cacheable);
- if (!resultO.has_value())
- return std::nullopt;
- auto result = resultO.value();
- result.setTypeCategory(TypeCategory::Pointer);
- result.setFunctionPointer(true);
- for (int a = 0; a < argCount; ++a) {
- auto argTypeInfoO =
- createTypeInfoUncached(clang_getArgType(pointeeType,
unsigned(a)), cacheable);
- if (!argTypeInfoO.has_value())
- return std::nullopt;
- result.addArgument(argTypeInfoO.value());
- }
- return result;
- }
+ if (pointeeType.kind == CXType_FunctionProto)
+ return createFunctionTypeInfo(pointeeType,
TypeCategory::FunctionPointer, cacheable);
}
TypeInfo typeInfo;
diff --git a/sources/shiboken6_generator/ApiExtractor/parser/codemodel_enums.h
b/sources/shiboken6_generator/ApiExtractor/parser/codemodel_enums.h
index 272140ae3..ae49b0e7c 100644
--- a/sources/shiboken6_generator/ApiExtractor/parser/codemodel_enums.h
+++ b/sources/shiboken6_generator/ApiExtractor/parser/codemodel_enums.h
@@ -59,13 +59,14 @@ enum class FunctionAttribute : std::uint8_t {
Q_DECLARE_FLAGS(FunctionAttributes, FunctionAttribute)
Q_DECLARE_OPERATORS_FOR_FLAGS(FunctionAttributes)
-// C++ type category for TypeInfo, reflecting clang's CXTypeKind
+// C++ type category for TypeInfo, roughly reflecting clang's CXTypeKind
enum class TypeCategory : unsigned char {
Other,
Builtin,
Enum,
Pointer,
Function,
+ FunctionPointer, // not present in clang
Void
};
diff --git a/sources/shiboken6_generator/ApiExtractor/parser/typeinfo.cpp
b/sources/shiboken6_generator/ApiExtractor/parser/typeinfo.cpp
index c530cafea..7bd0223db 100644
--- a/sources/shiboken6_generator/ApiExtractor/parser/typeinfo.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/parser/typeinfo.cpp
@@ -41,8 +41,7 @@ public:
struct {
uint m_constant: 1;
uint m_volatile: 1;
- uint m_functionPointer: 1;
- uint m_padding: 29;
+ uint m_padding: 30;
};
};
@@ -223,13 +222,7 @@ void TypeInfo::addIndirection(Indirection i)
bool TypeInfo::isFunctionPointer() const
{
- return d->m_functionPointer;
-}
-
-void TypeInfo::setFunctionPointer(bool is)
-{
- if (d->m_functionPointer != is)
- d->m_functionPointer = is;
+ return d->m_category == TypeCategory::FunctionPointer;
}
const QStringList &TypeInfo::arrayElements() const
@@ -426,8 +419,11 @@ QString TypeInfo::toString() const
break;
}
- if (isFunctionPointer()) {
- tmp += u" (*)("_s;
+ if (d->m_category == TypeCategory::Function || d->m_category ==
TypeCategory::FunctionPointer) {
+ tmp += u' ';
+ if (d->m_category == TypeCategory::FunctionPointer)
+ tmp += "(*)"_L1;
+ tmp += u'(';
for (qsizetype i = 0; i < d->m_arguments.size(); ++i) {
if (i != 0)
tmp += u", "_s;
@@ -461,7 +457,7 @@ bool TypeInfoData::equals(const TypeInfoData &other) const
return flags == other.flags
&& m_qualifiedName == other.m_qualifiedName
&& m_category == other.m_category
- && (!m_functionPointer || m_arguments == other.m_arguments)
+ && m_arguments == other.m_arguments
&& m_instantiations == other.m_instantiations;
}
@@ -602,8 +598,14 @@ void TypeInfo::formatDebug(QDebug &debug) const
debug << ", [pointer]";
break;
case TypeCategory::Function:
- debug << ", [function";
+ debug << ", [function]";
+ break;
+ case TypeCategory::FunctionPointer:
+ debug << ", [function-ptr]";
break;
+ default:
+ break;
+
}
if (!d->m_indirections.isEmpty()) {
debug << ", indirections=";
@@ -625,8 +627,12 @@ void TypeInfo::formatDebug(QDebug &debug) const
formatSequence(debug, d->m_instantiations.begin(),
d->m_instantiations.end());
debug << '>';
}
- if (d->m_functionPointer) {
- debug << ", function ptr(";
+
+ if (d->m_category == TypeCategory::Function || d->m_category ==
TypeCategory::FunctionPointer) {
+ debug << ", function";
+ if (d->m_category == TypeCategory::FunctionPointer)
+ debug << "_ptr";
+ debug << '(';
formatSequence(debug, d->m_arguments.begin(), d->m_arguments.end());
debug << ')';
}
diff --git a/sources/shiboken6_generator/ApiExtractor/parser/typeinfo.h
b/sources/shiboken6_generator/ApiExtractor/parser/typeinfo.h
index 092fbb724..43c9947d9 100644
--- a/sources/shiboken6_generator/ApiExtractor/parser/typeinfo.h
+++ b/sources/shiboken6_generator/ApiExtractor/parser/typeinfo.h
@@ -71,7 +71,6 @@ public:
void setIndirections(int indirections);
bool isFunctionPointer() const;
- void setFunctionPointer(bool is);
const QStringList &arrayElements() const;
void setArrayElements(const QStringList &arrayElements);
diff --git a/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.cpp
b/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.cpp
index 7345c0501..806b0965c 100644
--- a/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.cpp
@@ -5,6 +5,7 @@
#include <abstractmetabuilder_testutil.h>
#include <clangparser/triplet.h>
+#include <parser/codemodel.h>
#include <QtTest/qtest.h>
@@ -99,4 +100,24 @@ void TestClangParser::testParseTriplet()
}
}
+void TestClangParser::testFunctionPointers()
+{
+ static const char cppCode[] =R"(
+using FunctionType = void(int);
+using FunctionPointerType = void(*)(int);
+)";
+
+ auto dom = TestUtil::buildDom(cppCode);
+ QVERIFY(dom);
+ const auto &typeDefs = dom->typeDefs();
+ QCOMPARE(typeDefs.size(), 2);
+ for (const auto &typeDef : typeDefs) {
+ const auto &type = typeDef->type();
+ const auto expectedCategory = typeDef->name() == "FunctionType"_L1
+ ? TypeCategory::Function :
TypeCategory::FunctionPointer;
+ QCOMPARE(type.arguments().size(), 1);
+ QCOMPARE(type.typeCategory(), expectedCategory);
+ }
+}
+
QTEST_APPLESS_MAIN(TestClangParser)
diff --git a/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.h
b/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.h
index d44e7074c..2b8b285a6 100644
--- a/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.h
+++ b/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.h
@@ -10,6 +10,7 @@ class TestClangParser : public QObject
{
Q_OBJECT
private slots:
+ void testFunctionPointers();
void testParseTriplet_data();
void testParseTriplet();
};
--
cgit v1.2.3
++++++ 0008-shiboken6-Add-some-type-checks.patch ++++++
>From 1ed68f23d4025f935c48e729cf9d39e277ec8e00 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <[email protected]>
Date: Mon, 23 Mar 2026 11:07:43 +0100
Subject: shiboken6_generator: Add some type checks
Reject some types that do not make sense for the generator.
Task-number: PYSIDE-3286
Pick-to: 6.8
Change-Id: I1f097b934f2626b5e69b5d5c81e1f6c8f74f280c
Reviewed-by: Cristian Maureira-Fredes <[email protected]>
(cherry picked from commit d12cf3be34baccf2abe3c32b4931b73431c942bf)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
---
.../ApiExtractor/clangparser/clangbuilder.cpp | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git
a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
index a31fae778..29e9f74c3 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
@@ -563,6 +563,18 @@ static TypeCategory typeCategoryFromClang(CXTypeKind k)
return TypeCategory::Other;
}
+// Reject decltype() expressions, template parameter packs, etc.
+static inline bool checkTypeName(const QString &name)
+{
+ static constexpr QLatin1StringView exclusions[] = {
+ "decltype("_L1, "std::declval"_L1, "::detail::"_L1,
"std::enable_if<"_L1,
+ "template "_L1, "..."_L1
+ };
+
+ auto excludedPred = [&name](QLatin1StringView ex) { return
name.contains(ex); };
+ return std::none_of(std::begin(exclusions), std::end(exclusions),
excludedPred);
+}
+
static QString fixTypeName(QString typeName)
{
while (TypeInfo::stripLeadingConst(&typeName) ||
TypeInfo::stripLeadingVolatile(&typeName)) {
@@ -639,6 +651,11 @@ std::optional<TypeInfo>
QString typeName = fixTypeName(getResolvedTypeName(nestedType));
+ if (!checkTypeName(typeName)) {
+ m_rejectedTypes.insert(typeName);
+ return std::nullopt;
+ }
+
// 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
--
cgit v1.2.3
++++++ 0009-shiboken6-Add-clang-type-struct.patch ++++++
>From ad389a63df0aedf7ef3dc18bedb9d1a1aad56f70 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <[email protected]>
Date: Thu, 19 Mar 2026 08:42:27 +0100
Subject: shiboken6_generator: Add clang type struct
Add a struct, which stores the type name and the template
parameters separately along with a parsing function and tests.
Task-number: PYSIDE-3286
Change-Id: I1c884d14008fcfaa2d76fd7c36f871f4df8842f5
Reviewed-by: Cristian Maureira-Fredes <[email protected]>
(cherry picked from commit f4d0e173e797b70ca89b2373b65de0b49f65b3c2)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
---
.../ApiExtractor/CMakeLists.txt | 1 +
.../ApiExtractor/clangparser/clangbuilder.cpp | 52 +++++---------
.../ApiExtractor/clangparser/clangtype.cpp | 83 ++++++++++++++++++++++
.../ApiExtractor/clangparser/clangtype.h | 28 ++++++++
.../ApiExtractor/tests/testclangparser.cpp | 37 ++++++++++
.../ApiExtractor/tests/testclangparser.h | 2 +
6 files changed, 168 insertions(+), 35 deletions(-)
create mode 100644
sources/shiboken6_generator/ApiExtractor/clangparser/clangtype.cpp
create mode 100644
sources/shiboken6_generator/ApiExtractor/clangparser/clangtype.h
diff --git a/sources/shiboken6_generator/ApiExtractor/CMakeLists.txt
b/sources/shiboken6_generator/ApiExtractor/CMakeLists.txt
index e1c4dcb92..738ae6a88 100644
--- a/sources/shiboken6_generator/ApiExtractor/CMakeLists.txt
+++ b/sources/shiboken6_generator/ApiExtractor/CMakeLists.txt
@@ -78,6 +78,7 @@ xmlutils.cpp xmlutils.h xmlutils_libxslt.h xmlutils_qt.h
clangparser/clangbuilder.cpp clangparser/clangbuilder.h
clangparser/clangdebugutils.cpp clangparser/clangdebugutils.h
clangparser/clangparser.cpp clangparser/clangparser.h
+clangparser/clangtype.cpp clangparser/clangtype.h
clangparser/clangutils.cpp clangparser/clangutils.h
clangparser/compilersupport.cpp clangparser/compilersupport.h
clangparser/triplet.cpp clangparser/triplet.h
diff --git
a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
index 29e9f74c3..11f6580f6 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
@@ -4,6 +4,7 @@
#include "clangbuilder.h"
#include "compilersupport.h"
#include "clangutils.h"
+#include "clangtype.h"
#include "clangdebugutils.h"
#include <codemodel.h>
@@ -171,7 +172,7 @@ public:
std::optional<TypeInfo> createFunctionTypeInfo(const CXType &type,
TypeCategory cat,
bool *cacheable) const;
void addTemplateInstantiations(const CXType &type,
- QString *typeName,
+ const QString &templateParameters,
TypeInfo *t) const;
bool addTemplateInstantiationsRecursion(const CXType &type, TypeInfo *t)
const;
@@ -457,27 +458,6 @@ void BuilderPrivate::addField(const CXCursor &cursor, bool
staticField)
m_scopeStack.back()->addVariable(field);
}
-// Create qualified name "std::list<std::string>" -> ("std",
"list<std::string>")
-static QStringList qualifiedName(const QString &t)
-{
- QStringList result;
- auto end = t.indexOf(u'<');
- if (end == -1)
- end = t.indexOf(u'(');
- if (end == -1)
- end = t.size();
- qsizetype lastPos = 0;
- while (true) {
- const auto nextPos = t.indexOf(u"::"_s, lastPos);
- if (nextPos < 0 || nextPos >= end)
- break;
- result.append(t.mid(lastPos, nextPos - lastPos));
- lastPos = nextPos + 2;
- }
- result.append(t.right(t.size() - lastPos));
- return result;
-}
-
static bool isArrayType(CXTypeKind k)
{
return k == CXType_ConstantArray || k == CXType_IncompleteArray
@@ -516,10 +496,8 @@ bool
BuilderPrivate::addTemplateInstantiationsRecursion(const CXType &type, Type
return true;
}
-static void dummyTemplateArgumentHandler(int, QStringView) {}
-
void BuilderPrivate::addTemplateInstantiations(const CXType &type,
- QString *typeName,
+ const QString
&templateParameters,
TypeInfo *t) const
{
// In most cases, for templates like "Vector<A>", Clang will give us the
@@ -530,16 +508,12 @@ void BuilderPrivate::addTemplateInstantiations(const
CXType &type,
// Vector(const Vector&);
// };
// In that case, have TypeInfo parse the list from the spelling.
- // Finally, remove the list "<>" from the type name.
const bool parsed = addTemplateInstantiationsRecursion(type, t)
&& !t->instantiations().isEmpty();
- if (!parsed)
+ if (!parsed) {
t->setInstantiations({});
- const auto pos = parsed
- ? parseTemplateArgumentList(*typeName, dummyTemplateArgumentHandler)
- : t->parseTemplateArgumentList(*typeName);
- if (pos.first != -1 && pos.second != -1 && pos.second > pos.first)
- typeName->remove(pos.first, pos.second - pos.first);
+ t->parseTemplateArgumentList(templateParameters);
+ }
}
static TypeCategory typeCategoryFromClang(CXTypeKind k)
@@ -675,10 +649,18 @@ std::optional<TypeInfo>
// Obtain template instantiations if the name has '<' (thus excluding
// typedefs like "std::string".
- if (typeName.contains(u'<'))
- addTemplateInstantiations(nestedType, &typeName, &typeInfo);
- typeInfo.setQualifiedName(qualifiedName(typeName));
+ auto clangTypeNameO = clang::parseTypeName(typeName);
+ if (!clangTypeNameO.has_value()) {
+ m_rejectedTypes.insert(typeName);
+ return std::nullopt;
+ }
+
+ const auto &clangTypeName = clangTypeNameO.value();
+ if (!clangTypeName.templateParameters.isEmpty())
+ addTemplateInstantiations(nestedType,
clangTypeName.templateParameters, &typeInfo);
+
+ typeInfo.setQualifiedName(clangTypeName.name.split("::"_L1));
// 3320:CINDEX_LINKAGE int clang_getNumArgTypes(CXType T); function ptr
types?
typeInfo.simplifyStdType();
return typeInfo;
diff --git a/sources/shiboken6_generator/ApiExtractor/clangparser/clangtype.cpp
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangtype.cpp
new file mode 100644
index 000000000..bd455bd53
--- /dev/null
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangtype.cpp
@@ -0,0 +1,83 @@
+// Copyright (C) 2026 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH
Qt-GPL-exception-1.0
+
+#include "clangtype.h"
+
+#include <QtCore/qdebug.h>
+
+using namespace Qt::StringLiterals;
+
+// Up until clang version 21, clang_getTypeSpelling() was used to retrieve
type names,
+// which returned fully qualified names. In clang 22, clang_getTypeSpelling()
was
+// changed to return the actual spelling, that is, no longer return fully
qualified names
+// (from for example inner class contexts) unless they were spelled out.
+// clang_getFullyQualifiedName() was provided as a replacement, but that
returns
+// template parameters of the class as well, that is,
"std::list<int>::value_type"
+// instead of "std::list::value_type". Those they need to be removed for the
+// type entry lookup system to work. This is done by parseTypeName().
+// FIXME: Keep checking whether this can be replaced by a CXPrintingPolicy
setting
+// in a later clang version.
+
+namespace clang {
+
+// Find the start of a template starting from the closing '>'
+static qsizetype findTemplateStart(QStringView sv, qsizetype pos)
+{
+ Q_ASSERT(pos > 0 && pos < sv.size() && sv.at(pos) == u'>');
+ int level = 1;
+ for (--pos; pos >= 0; --pos) {
+ switch (sv.at(pos).unicode()) {
+ case '>':
+ ++level;
+ break;
+ case '<':
+ if (--level == 0)
+ return pos;
+ break;
+ default:
+ break;
+ }
+ }
+ return -1;
+}
+
+std::optional<TypeName> parseTypeName(QString t)
+{
+ TypeName result;
+ // Skip over the trailing template parameters "list<T>::iterator<V>" ->
+ // "list<T>::iterator"
+ if (t.endsWith(u'>')) {
+ const auto pos = findTemplateStart(t, t.size() - 1);
+ if (pos == -1)
+ return std::nullopt;
+ result.templateParameters = t.sliced(pos, t.size() - pos);
+ t.truncate(pos);
+ }
+
+ // Remove class template parameters "list<T>::iterator" -> "list::iterator"
+ while (true) {
+ auto specEnd = t.lastIndexOf(">::"_L1);
+ if (specEnd == -1)
+ break;
+ const auto pos = findTemplateStart(t, specEnd);
+ if (pos == -1)
+ return std::nullopt;
+ t.remove(pos, specEnd + 1 - pos);
+ }
+ result.name = t;
+ return result;
+}
+
+QDebug operator<<(QDebug debug, const TypeName &ct)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug.noquote();
+ debug << "ClangTypeName(name=\"" << ct.name << '"';
+ if (!ct.templateParameters.isEmpty())
+ debug << ", templateParameters=\"" << ct.templateParameters << '"';
+ debug << ')';
+ return debug;
+}
+
+} // namespace clang
diff --git a/sources/shiboken6_generator/ApiExtractor/clangparser/clangtype.h
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangtype.h
new file mode 100644
index 000000000..0ae970648
--- /dev/null
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangtype.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2026 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH
Qt-GPL-exception-1.0
+
+#ifndef CLANGTYPE_H
+#define CLANGTYPE_H
+
+#include <QtCore/qstring.h>
+
+#include <optional>
+
+QT_FORWARD_DECLARE_CLASS(QDebug)
+
+namespace clang {
+
+struct TypeName
+{
+ QString name;
+ QString templateParameters;
+};
+
+// Split a type name "std::list<int>::value_type<T>" into the canonical name
+// "std::list::value_type" and its template parameters "<T>"
+std::optional<TypeName> parseTypeName(QString t);
+
+QDebug operator<<(QDebug, const TypeName &ct);
+} // namespace clang
+
+#endif // CLANGTYPE_H
diff --git a/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.cpp
b/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.cpp
index 806b0965c..947c8c9e3 100644
--- a/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.cpp
@@ -4,13 +4,50 @@
#include "testclangparser.h"
#include <abstractmetabuilder_testutil.h>
+#include <clangparser/clangtype.h>
#include <clangparser/triplet.h>
+
#include <parser/codemodel.h>
#include <QtTest/qtest.h>
using namespace Qt::StringLiterals;
+void TestClangParser::testClangTypeParsing_data()
+{
+ QTest::addColumn<QString>("typeString");
+ QTest::addColumn<bool>("expectedSuccess");
+ QTest::addColumn<QString>("expectedTypeName");
+ QTest::addColumn<QString>("expectedTemplateParameters");
+
+ QTest::newRow("list")
+ << QString(u"std::list<int, std::allocator<int>>::value_type"_s)
+ << true << QString(u"std::list::value_type"_s) << QString{};
+
+ QTest::newRow("mapData")
+ << QString(u"QMapData<std::map<QString, QVariant, std::less<QString>,
std::allocator<std::pair<const QString, QVariant>>>>::const_iterator<U, V>"_s)
+ << true << QString(u"QMapData::const_iterator"_s) << QString(u"<U,
V>"_s);
+
+ QTest::newRow("fail") // unbalanced '>'
+ << QString(u"__optional_relop_t<decltype(std::declval<const _Tp &>() >
std::declval<const _Up &>())>"_s)
+ << false << QString{} << QString{};
+}
+
+void TestClangParser::testClangTypeParsing()
+{
+ QFETCH(QString, typeString);
+ QFETCH(bool, expectedSuccess);
+ QFETCH(QString, expectedTypeName);
+ QFETCH(QString, expectedTemplateParameters);
+
+ auto typeNameO = clang::parseTypeName(typeString);
+ QCOMPARE(typeNameO.has_value(), expectedSuccess);
+ if (typeNameO.has_value()) {
+ QCOMPARE(typeNameO->name, expectedTypeName);
+ QCOMPARE(typeNameO->templateParameters, expectedTemplateParameters);
+ }
+}
+
void TestClangParser::testParseTriplet_data()
{
QTest::addColumn<QString>("tripletString");
diff --git a/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.h
b/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.h
index 2b8b285a6..d2e2fddab 100644
--- a/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.h
+++ b/sources/shiboken6_generator/ApiExtractor/tests/testclangparser.h
@@ -10,6 +10,8 @@ class TestClangParser : public QObject
{
Q_OBJECT
private slots:
+ void testClangTypeParsing_data();
+ void testClangTypeParsing();
void testFunctionPointers();
void testParseTriplet_data();
void testParseTriplet();
--
cgit v1.2.3
++++++
0010-shiboken6-Fix-retrieving-fully-qualified-type-names-with-clang-22.patch
++++++
>From 291ef13ec8352ff2890b1c5d149e44fdd5f49da1 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <[email protected]>
Date: Tue, 10 Mar 2026 09:27:23 +0100
Subject: shiboken6_generator: Fix retrieving fully qualified type names with
clang 22
Change getTypeName() to use clang_getFullyQualifiedName() for version 22
instead of clang_getTypeSpelling() which no longer returns fully
qualified names.
[ChangeLog][shiboken6] Clang version 22 is now supported.
Fixes: PYSIDE-3286
Change-Id: If55932c1ef45d08f20bafdb08f4b68c678988934
Reviewed-by: Cristian Maureira-Fredes <[email protected]>
(cherry picked from commit 27cb9caa4980620cdd055cc82e080056dd22c13c)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
---
.../shiboken6_generator/ApiExtractor/CMakeLists.txt | 2 +-
.../ApiExtractor/clangparser/clang_typedefs.h | 19 +++++++++++++++++++
.../ApiExtractor/clangparser/clangbuilder.cpp | 13 +++++++------
.../ApiExtractor/clangparser/clangparser.cpp | 10 ++++++++++
.../ApiExtractor/clangparser/clangparser.h | 6 +++++-
.../ApiExtractor/clangparser/clangutils.cpp | 15 ++++++++++++---
.../ApiExtractor/clangparser/clangutils.h | 11 ++++-------
7 files changed, 58 insertions(+), 18 deletions(-)
create mode 100644
sources/shiboken6_generator/ApiExtractor/clangparser/clang_typedefs.h
diff --git a/sources/shiboken6_generator/ApiExtractor/CMakeLists.txt
b/sources/shiboken6_generator/ApiExtractor/CMakeLists.txt
index 738ae6a88..d726e73b4 100644
--- a/sources/shiboken6_generator/ApiExtractor/CMakeLists.txt
+++ b/sources/shiboken6_generator/ApiExtractor/CMakeLists.txt
@@ -79,7 +79,7 @@ clangparser/clangbuilder.cpp clangparser/clangbuilder.h
clangparser/clangdebugutils.cpp clangparser/clangdebugutils.h
clangparser/clangparser.cpp clangparser/clangparser.h
clangparser/clangtype.cpp clangparser/clangtype.h
-clangparser/clangutils.cpp clangparser/clangutils.h
+clangparser/clangutils.cpp clangparser/clangutils.h
clangparser/clang_typedefs.h
clangparser/compilersupport.cpp clangparser/compilersupport.h
clangparser/triplet.cpp clangparser/triplet.h
# Old parser
diff --git
a/sources/shiboken6_generator/ApiExtractor/clangparser/clang_typedefs.h
b/sources/shiboken6_generator/ApiExtractor/clangparser/clang_typedefs.h
new file mode 100644
index 000000000..49efc2592
--- /dev/null
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clang_typedefs.h
@@ -0,0 +1,19 @@
+// Copyright (C) 2026 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH
Qt-GPL-exception-1.0
+
+#ifndef CLANG_TYPEDEFS_H
+#define CLANG_TYPEDEFS_H
+
+#include <clang-c/Index.h>
+
+namespace clang {
+
+#if LLVM_VERSION >= 22
+using PrintingPolicy = CXPrintingPolicy;
+#else
+using PrintingPolicy = void *;
+#endif
+
+} // namespace clang
+
+#endif // CLANG_TYPEDEFS_H
diff --git
a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
index 11f6580f6..1bddbc8be 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangbuilder.cpp
@@ -623,7 +623,8 @@ std::optional<TypeInfo>
typeInfo.setConstant(clang_isConstQualifiedType(nestedType) != 0);
typeInfo.setVolatile(clang_isVolatileQualifiedType(nestedType) != 0);
- QString typeName = fixTypeName(getResolvedTypeName(nestedType));
+ QString typeName = fixTypeName(getResolvedTypeName(nestedType,
+
m_baseVisitor->printingPolicy()));
if (!checkTypeName(typeName)) {
m_rejectedTypes.insert(typeName);
@@ -776,7 +777,7 @@ std::pair<QString, ClassModelItem>
BuilderPrivate::getBaseClass(CXType type) con
{
const auto decl = resolveBaseClassType(type);
// Note: spelling has "struct baseClass", use type
- QString baseClassName = getTypeName(decl.type);
+ QString baseClassName = getTypeName(decl.type,
m_baseVisitor->printingPolicy());
if (baseClassName.startsWith(u"std::")) { // Simplify "std::" types
if (auto typeO = createTypeInfo(decl.type))
baseClassName = typeO.value().toString();
@@ -995,7 +996,7 @@ static NamespaceType namespaceType(const CXCursor &cursor)
return NamespaceType::Default;
}
-static QString enumType(const CXCursor &cursor)
+static QString enumType(const CXCursor &cursor, PrintingPolicy p)
{
QString name = getCursorSpelling(cursor); // "enum Foo { v1, v2 };"
if (name.contains(u"unnamed enum")) // Clang 16.0
@@ -1003,7 +1004,7 @@ static QString enumType(const CXCursor &cursor)
if (name.isEmpty()) {
// PYSIDE-1228: For "typedef enum { v1, v2 } Foo;", type will return
// "Foo" as expected. Care must be taken to exclude real anonymous
enums.
- name = getTypeName(clang_getCursorType(cursor));
+ name = getTypeName(clang_getCursorType(cursor), p);
if (name.contains(u"(unnamed") // Clang 12.0.1
|| name.contains(u"(anonymous")) { // earlier
name.clear();
@@ -1061,7 +1062,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const
CXCursor &cursor)
d->m_scope.back() += "<>"_L1;
break;
case CXCursor_EnumDecl: {
- QString name = enumType(cursor);
+ QString name = enumType(cursor, printingPolicy());
EnumKind kind = CEnum;
if (name.isEmpty()) {
kind = AnonymousEnum;
@@ -1081,7 +1082,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const
CXCursor &cursor)
d->m_currentEnum->setDeprecated(true);
const auto enumType =
fullyResolveType(clang_getEnumDeclIntegerType(cursor));
d->m_currentEnum->setSigned(isSigned(enumType.kind));
- d->m_currentEnum->setUnderlyingType(getTypeName(enumType));
+ d->m_currentEnum->setUnderlyingType(getTypeName(enumType,
printingPolicy()));
if (std::dynamic_pointer_cast<_ClassModelItem>(d->m_scopeStack.back()))
d->m_currentEnum->setAccessPolicy(accessPolicy(clang_getCXXAccessSpecifier(cursor)));
}
diff --git
a/sources/shiboken6_generator/ApiExtractor/clangparser/clangparser.cpp
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangparser.cpp
index d31d5712d..ff18e9657 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangparser.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangparser.cpp
@@ -321,9 +321,19 @@ bool parse(const QByteArrayList &clangArgs, bool
addCompilerSupportArguments,
setupTarget(translationUnit);
CXCursor rootCursor = clang_getTranslationUnitCursor(translationUnit);
+#if LLVM_VERSION >= 22
+ CXPrintingPolicy printingPolicy =
clang_getCursorPrintingPolicy(rootCursor);
+ clang_PrintingPolicy_setProperty(printingPolicy,
CXPrintingPolicy_IncludeNewlines, 0);
+ bv.setPrintingPolicy(printingPolicy);
+#endif
clang_visitChildren(rootCursor, visitorCallback,
reinterpret_cast<CXClientData>(&bv));
+#if LLVM_VERSION >= 22
+ bv.setPrintingPolicy(nullptr);
+ clang_PrintingPolicy_dispose(printingPolicy);
+#endif
+
QList<Diagnostic> diagnostics = getDiagnostics(translationUnit);
diagnostics.append(bv.diagnostics());
bv.setDiagnostics(diagnostics);
diff --git a/sources/shiboken6_generator/ApiExtractor/clangparser/clangparser.h
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangparser.h
index 79dc855e2..7cc47e849 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangparser.h
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangparser.h
@@ -4,7 +4,7 @@
#ifndef CLANGPARSER_H
#define CLANGPARSER_H
-#include <clang-c/Index.h>
+#include "clang_typedefs.h"
#include <QtCore/qbytearraylist.h>
#include <QtCore/qhash.h>
@@ -72,10 +72,14 @@ public:
// For usage by the parser
bool _handleVisitLocation( const CXSourceLocation &location);
+ PrintingPolicy printingPolicy() const { return m_printingPolicy; }
+ void setPrintingPolicy(CXPrintingPolicy p) { m_printingPolicy = p; }
+
private:
SourceFileCache m_fileCache;
Diagnostics m_diagnostics;
CXFile m_currentCxFile{};
+ PrintingPolicy m_printingPolicy = nullptr;
bool m_visitCurrent = true;
};
diff --git
a/sources/shiboken6_generator/ApiExtractor/clangparser/clangutils.cpp
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangutils.cpp
index 384fd6815..24646db53 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangutils.cpp
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangutils.cpp
@@ -10,6 +10,8 @@
#include <string_view>
+using namespace Qt::StringLiterals;
+
bool operator==(const CXCursor &c1, const CXCursor &c2) noexcept
{
return c1.kind == c2.kind
@@ -137,11 +139,18 @@ CXType fullyResolveType(const CXType &type)
return resolveTypedef(resolveElaboratedType(type));
}
-QString getTypeName(const CXType &type)
+QString getTypeName(const CXType &type, [[maybe_unused]] PrintingPolicy p)
{
+ // Behavioral change, clang_getTypeSpelling() may no longer return the
qualified name in 22.1
+#if LLVM_VERSION >= 22
+ CXString qualName = clang_getFullyQualifiedName(type, p, 0);
+ QString result = QString::fromUtf8(clang_getCString(qualName));
+ clang_disposeString(qualName);
+#else
CXString typeSpelling = clang_getTypeSpelling(type);
const QString result = QString::fromUtf8(clang_getCString(typeSpelling));
clang_disposeString(typeSpelling);
+#endif
return result;
}
@@ -157,9 +166,9 @@ bool hasScopeResolution(const CXType &type)
}
// Resolve elaborated types occurring with clang 16
-QString getResolvedTypeName(const CXType &type)
+QString getResolvedTypeName(const CXType &type, PrintingPolicy p)
{
- return getTypeName(resolveElaboratedType(type));
+ return getTypeName(resolveElaboratedType(type), p);
}
Diagnostic::Diagnostic(const QString &m, const CXCursor &c,
CXDiagnosticSeverity s)
diff --git a/sources/shiboken6_generator/ApiExtractor/clangparser/clangutils.h
b/sources/shiboken6_generator/ApiExtractor/clangparser/clangutils.h
index bb819e61f..866be9282 100644
--- a/sources/shiboken6_generator/ApiExtractor/clangparser/clangutils.h
+++ b/sources/shiboken6_generator/ApiExtractor/clangparser/clangutils.h
@@ -4,7 +4,8 @@
#ifndef CLANGUTILS_H
#define CLANGUTILS_H
-#include <clang-c/Index.h>
+#include "clang_typedefs.h"
+
#include <QtCore/qstring.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qcompare.h>
@@ -26,14 +27,10 @@ namespace clang {
QString getCursorKindName(CXCursorKind cursorKind);
QString getCursorSpelling(const CXCursor &cursor);
QString getCursorDisplayName(const CXCursor &cursor);
-QString getTypeName(const CXType &type);
+QString getTypeName(const CXType &type, PrintingPolicy p);
bool hasScopeResolution(const CXType &type);
CXType fullyResolveType(const CXType &type);
-QString getResolvedTypeName(const CXType &type);
-inline QString getCursorTypeName(const CXCursor &cursor)
- { return getTypeName(clang_getCursorType(cursor)); }
-inline QString getCursorResultTypeName(const CXCursor &cursor)
- { return getTypeName(clang_getCursorResultType(cursor)); }
+QString getResolvedTypeName(const CXType &type, PrintingPolicy p);
inline bool isCursorValid(const CXCursor &c)
{
--
cgit v1.2.3
++++++ 0011-QNativeInterface-QX11Application-display-type.patch ++++++
Fixes warning with Clang 22:
/usr/include/qt6/QtGui/qguiapplication_platform.h:65: skipping public
abstract function 'Display*
QNativeInterface::QX11Application::display()const',
unmatched return type 'Display*': Unable to translate type "Display*":
Cannot find type entry for "struct _XDisplay".
We leave the original type intact for Clang < 22.
diff --git a/sources/pyside6/PySide6/QtGui/typesystem_gui_x11.xml
b/sources/pyside6/PySide6/QtGui/typesystem_gui_x11.xml
index 70331e29c..8c3978763 100644
--- a/sources/pyside6/PySide6/QtGui/typesystem_gui_x11.xml
+++ b/sources/pyside6/PySide6/QtGui/typesystem_gui_x11.xml
@@ -4,6 +4,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR
GPL-2.0-only OR GPL-3.0-only
-->
<typesystem package="PySide6.QtGui">
<custom-type name="_XDisplay"/>
+ <custom-type name="struct _XDisplay"/>
<custom-type name="xcb_connection_t"/>
</typesystem>