https://github.com/YakoYakoYokuYoku updated https://github.com/llvm/llvm-project/pull/175534
>From b0f17422af7ffd9bd9ba61ebfb767b6415cee0d0 Mon Sep 17 00:00:00 2001 From: Martin Rodriguez Reboredo <[email protected]> Date: Mon, 12 Jan 2026 01:04:05 -0300 Subject: [PATCH 1/2] [libclang] Query atomic unqualified in cindex This is purpoted to be exposed in Python. Signed-off-by: Martin Rodriguez Reboredo <[email protected]> --- clang/include/clang-c/Index.h | 17 ++++++++++++++++- clang/tools/libclang/CXType.cpp | 4 ++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 8427236e0b444..59055b6cd6ab6 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -3390,7 +3390,9 @@ CINDEX_LINKAGE CXType clang_getPointeeType(CXType T); * Retrieve the unqualified variant of the given type, removing as * little sugar as possible. * - * For example, given the following series of typedefs: + * This routine looks through various kinds of sugar to find the + * least-desugared type that is unqualified. For example, given the + * following series of typedefs: * * \code * typedef int Integer; @@ -3420,9 +3422,22 @@ CINDEX_LINKAGE CXType clang_getPointeeType(CXType T); * * A type that resulted from a call to \c clang_getUnqualifiedType * will return \c false for all of the above calls. + * + * Note: In C, the _Atomic qualifier is special (see C23 6.2.5p32 for + * details), and it is not stripped by this function. Use + * clang_getAtomicUnqualifiedType() to strip qualifiers including + * _Atomic. */ CINDEX_LINKAGE CXType clang_getUnqualifiedType(CXType CT); +/** + * Remove all qualifiers including _Atomic. + * + * Like \c clang_getUnqualifiedType(), the type may still be + * qualified if it is a sugared array type. + */ +CINDEX_LINKAGE CXType clang_getAtomicUnqualifiedType(CXType CT); + /** * For reference types (e.g., "const int&"), returns the type that the * reference refers to (e.g "const int"). diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp index 0063939dec423..e3cb5ef3c0f37 100644 --- a/clang/tools/libclang/CXType.cpp +++ b/clang/tools/libclang/CXType.cpp @@ -518,6 +518,10 @@ CXType clang_getUnqualifiedType(CXType CT) { return MakeCXType(GetQualType(CT).getUnqualifiedType(), GetTU(CT)); } +CXType clang_getAtomicUnqualifiedType(CXType CT) { + return MakeCXType(GetQualType(CT).getAtomicUnqualifiedType(), GetTU(CT)); +} + CXType clang_getNonReferenceType(CXType CT) { return MakeCXType(GetQualType(CT).getNonReferenceType(), GetTU(CT)); } >From 633701c89f89500516dc50212775eb530b29b40f Mon Sep 17 00:00:00 2001 From: Martin Rodriguez Reboredo <[email protected]> Date: Mon, 12 Jan 2026 01:04:05 -0300 Subject: [PATCH 2/2] [libclang/python] Add non ref and unqualified getters for types These methods were missing in the bindings API. Signed-off-by: Martin Rodriguez Reboredo <[email protected]> --- clang/bindings/python/clang/cindex.py | 34 +++++++++++++ .../bindings/python/tests/cindex/test_type.py | 51 +++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index 24b737139dba8..9fc1350121f09 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -2812,6 +2812,37 @@ def get_canonical(self) -> Type: """ return Type.from_result(conf.lib.clang_getCanonicalType(self), self) + def get_non_reference(self) -> Type: + """ + Return the type stripped of references from a Type. + + If a type is either an l-value or an r-value reference then those + are going to be removed. It returns the type unchanged otherwise. + """ + return Type.from_result(conf.lib.clang_getNonReferenceType(self), self) + + def get_unqualified(self) -> Type: + """ + Return the type without any qualifiers from a Type. + + A type can be qualified with const, volatile, restrict or a + combination of these. This method removes the qualifier of a type. In + the absence of any of these, the type is returned unchanged. + + Arrays and the _Atomic qualifier are not stripped by this function. + See ``get_atomic_unqualified()`` for atomics. + """ + return Type.from_result(conf.lib.clang_getUnqualifiedType(self), self) + + def get_atomic_unqualified(self) -> Type: + """ + Remove all qualifiers including _Atomic. + + Like ``get_unqualified_type()``, the type may still be qualified if it + is a sugared array type. + """ + return Type.from_result(conf.lib.clang_getAtomicUnqualifiedType(self), self) + def get_fully_qualified_name( self, policy: PrintingPolicy, with_global_ns_prefix: bool = False ) -> str: @@ -4339,6 +4370,7 @@ def set_property(self, property, value): ("clang_getArgType", [Type, c_uint], Type), ("clang_getArrayElementType", [Type], Type), ("clang_getArraySize", [Type], c_longlong), + ("clang_getAtomicUnqualifiedType", [Type], Type), ("clang_getFieldDeclBitWidth", [Cursor], c_int), ("clang_getCanonicalCursor", [Cursor], Cursor), ("clang_getCanonicalType", [Type], Type), @@ -4417,6 +4449,7 @@ def set_property(self, property, value): ), ("clang_getLocation", [TranslationUnit, File, c_uint, c_uint], SourceLocation), ("clang_getLocationForOffset", [TranslationUnit, File, c_uint], SourceLocation), + ("clang_getNonReferenceType", [Type], Type), ("clang_getNullCursor", None, Cursor), ("clang_getNumArgTypes", [Type], c_uint), ("clang_getNumCompletionChunks", [c_void_p], c_int), @@ -4446,6 +4479,7 @@ def set_property(self, property, value): ("clang_getTypeKindSpelling", [c_uint], _CXString), ("clang_getTypePrettyPrinted", [Type, PrintingPolicy], _CXString), ("clang_getTypeSpelling", [Type], _CXString), + ("clang_getUnqualifiedType", [Type], Type), ("clang_hashCursor", [Cursor], c_uint), ("clang_isAttribute", [CursorKind], c_uint), ("clang_getFullyQualifiedName", [Type, PrintingPolicy, c_uint], _CXString), diff --git a/clang/bindings/python/tests/cindex/test_type.py b/clang/bindings/python/tests/cindex/test_type.py index 562ac74e98b6e..b2a8b97182fd5 100644 --- a/clang/bindings/python/tests/cindex/test_type.py +++ b/clang/bindings/python/tests/cindex/test_type.py @@ -530,6 +530,57 @@ def test_pretty(self): pp.set_property(PrintingPolicyProperty.SuppressTagKeyword, False) self.assertEqual(f.type.get_canonical().pretty_printed(pp), "struct X") + def test_non_reference(self): + source = """ + int &reference; + """ + tu = get_tu(source, lang="cpp") + reference = get_cursor(tu, "reference") + self.assertEqual( + reference.type.get_non_reference().get_ref_qualifier(), + RefQualifierKind.NONE, + ) + + def test_unqualified(self): + source = """ + bool b; + const long c; + volatile long v; + const volatile int cv; + _Atomic int a; + void f(int *__restrict l, const int *__restrict r, long s); + const bool &ref; + """ + tu = get_tu(source, lang="cpp") + b = get_cursor(tu, "b") + c = get_cursor(tu, "c") + v = get_cursor(tu, "v") + cv = get_cursor(tu, "cv") + a = get_cursor(tu, "a") + l = get_cursor(tu, "l") + r = get_cursor(tu, "r") + ref = get_cursor(tu, "ref") + self.assertEqual(b.type.get_unqualified().spelling, "bool") + self.assertEqual(c.type.get_unqualified().spelling, "long") + self.assertEqual(v.type.get_unqualified().spelling, "long") + self.assertEqual(cv.type.get_unqualified().spelling, "int") + self.assertEqual(a.type.get_unqualified().spelling, "_Atomic(int)") + self.assertEqual(l.type.get_unqualified().spelling, "int *") + self.assertEqual(r.type.get_unqualified().spelling, "const int *") + self.assertEqual(ref.type.get_unqualified().spelling, "const bool &") + self.assertEqual( + ref.type.get_non_reference().get_unqualified().spelling, "bool" + ) + + def test_atomic_unqualified(self): + source = """ + _Atomic int a; + """ + tu = get_tu(source, lang="c") + a = get_cursor(tu, "a") + self.assertEqual(a.type.get_unqualified().spelling, "_Atomic(int)") + self.assertEqual(a.type.get_atomic_unqualified().spelling, "int") + def test_fully_qualified_name(self): source = """ namespace home { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
