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
  • [clang] [libclang/python] Add no... Martin Rodriguez Reboredo via cfe-commits

Reply via email to