[clang] [cindex] Add support for calling getFullyQualifiedName to the Python binding. (PR #135420)

Brian Cody via cfe-commits cfe-commits at lists.llvm.org
Sun Apr 13 05:52:10 PDT 2025


https://github.com/epistax updated https://github.com/llvm/llvm-project/pull/135420

>From 6fe4155fad0cdbc6ca04e37df143f22f537d5514 Mon Sep 17 00:00:00 2001
From: Brian Cody <brian.j.cody at gmail.com>
Date: Fri, 11 Apr 2025 14:27:22 -0400
Subject: [PATCH 1/7] [cindex] Add support for calling getFullyQualifiedName to
 the Python binding.

---
 clang/bindings/python/clang/cindex.py         | 12 ++++++++++
 .../bindings/python/tests/cindex/test_type.py | 22 +++++++++++++++++++
 clang/docs/ReleaseNotes.rst                   |  4 ++++
 clang/include/clang-c/Index.h                 | 12 ++++++++++
 clang/tools/libclang/CXType.cpp               | 17 ++++++++++++++
 clang/tools/libclang/libclang.map             |  1 +
 6 files changed, 68 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index 2319534a6f121..5830dc2149348 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2593,6 +2593,17 @@ def get_canonical(self):
         """
         return Type.from_result(conf.lib.clang_getCanonicalType(self), (self,))
 
+    def get_fully_qualified_name(self, policy, with_global_ns_prefix = False):
+        """
+        Get the fully qualified name for a type.
+
+        This includes full qualification of all template parameters.
+
+        policy - This PrintingPolicy can further refine the type formatting
+        with_global_ns_prefix - If true, function will prepend a '::' to qualified names
+        """
+        return _CXString.from_result(conf.lib.clang_getFullyQualifiedName(self, policy, with_global_ns_prefix))
+
     def is_const_qualified(self):
         """Determine whether a Type has the "const" qualifier set.
 
@@ -4022,6 +4033,7 @@ def set_property(self, property, value):
     ("clang_getTypeSpelling", [Type], _CXString),
     ("clang_hashCursor", [Cursor], c_uint),
     ("clang_isAttribute", [CursorKind], bool),
+    ("clang_getFullyQualifiedName", [Type, PrintingPolicy, c_uint], _CXString),
     ("clang_isConstQualifiedType", [Type], bool),
     ("clang_isCursorDefinition", [Cursor], bool),
     ("clang_isDeclaration", [CursorKind], bool),
diff --git a/clang/bindings/python/tests/cindex/test_type.py b/clang/bindings/python/tests/cindex/test_type.py
index a9473e1dc2458..b2a82a00b4f40 100644
--- a/clang/bindings/python/tests/cindex/test_type.py
+++ b/clang/bindings/python/tests/cindex/test_type.py
@@ -535,6 +535,28 @@ def test_pretty(self):
         pp.set_property(PrintingPolicyProperty.SuppressTagKeyword, False)
         self.assertEqual(f.type.get_canonical().pretty_printed(pp), "struct X")
 
+    def test_fully_qualified_name(self):
+        source = """
+        namespace home {
+          class Bar {
+          };
+          class Foo {
+            public:
+              void setIt(Bar*);
+          };
+        }
+        class A : public home::Foo {
+        };
+        """
+        tu = get_tu(source, lang="cpp")
+        c = get_cursor(tu, "A")
+        pp = PrintingPolicy.create(c)
+        base = list(c.get_children())[0].type.get_declaration()
+        set_it = list(base.get_children())[1]
+        arg = list(set_it.get_arguments())[0]
+        self.assertEqual(arg.type.get_fully_qualified_name(pp), "home::Bar *")
+        self.assertEqual(arg.type.get_fully_qualified_name(pp, True), "::home::Bar *")
+
     def test_base_classes(self):
         source = """
         class A { int a; };
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9c45965dc4d82..f228a32acd51d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -589,6 +589,8 @@ libclang
 --------
 - Added ``clang_visitCXXMethods``, which allows visiting the methods
   of a class.
+- Added ``clang_getFullyQualifiedName``, which provides fully qualified type names as
+  instructed by a PrintingPolicy.
 
 - Fixed a buffer overflow in ``CXString`` implementation. The fix may result in
   increased memory allocation.
@@ -643,6 +645,8 @@ Python Binding Changes
   the cursor is a specialization of.
 - Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
   allows visiting the methods of a class.
+- Added ``Type.getFullyQualifiedName``, which provides fully qualified type names as
+  instructed by a PrintingPolicy.
 
 OpenMP Support
 --------------
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 38e2417dcd181..25700a48c928c 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -4223,6 +4223,18 @@ CINDEX_LINKAGE CXString clang_getCursorPrettyPrinted(CXCursor Cursor,
 CINDEX_LINKAGE CXString clang_getTypePrettyPrinted(CXType CT,
                                                    CXPrintingPolicy cxPolicy);
 
+/**
+ * Get the fully qualified name for a type.
+ *
+ * This includes full qualification of all template parameters.
+ *
+ * Policy - Further refine the type formatting
+ * WithGlobalNsPrefix - If non-zero, function will prepend a '::' to qualified
+ * names
+ */
+CINDEX_LINKAGE CXString clang_getFullyQualifiedName(
+    CXType CT, CXPrintingPolicy Policy, unsigned WithGlobalNsPrefix);
+
 /**
  * Retrieve the display name for the entity referenced by this cursor.
  *
diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp
index 2c9ef282b8abc..ffa942d10669c 100644
--- a/clang/tools/libclang/CXType.cpp
+++ b/clang/tools/libclang/CXType.cpp
@@ -19,6 +19,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/QualTypeNames.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/AddressSpaces.h"
@@ -328,6 +329,22 @@ CXString clang_getTypePrettyPrinted(CXType CT, CXPrintingPolicy cxPolicy) {
   return cxstring::createDup(OS.str());
 }
 
+CXString clang_getFullyQualifiedName(CXType CT, CXPrintingPolicy cxPolicy,
+                                     unsigned int WithGlobalNsPrefix) {
+  const QualType T = GetQualType(CT);
+  if (T.isNull())
+    return cxstring::createEmpty();
+  const CXTranslationUnit TU = GetTU(CT);
+  const ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
+  const PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
+  const bool WithGlobalNs = (WithGlobalNsPrefix != 0);
+
+  const std::string Str =
+      TypeName::getFullyQualifiedName(T, Ctx, *UserPolicy, WithGlobalNs);
+
+  return cxstring::createDup(Str);
+}
+
 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
   using namespace cxcursor;
   CXTranslationUnit TU = cxcursor::getCursorTU(C);
diff --git a/clang/tools/libclang/libclang.map b/clang/tools/libclang/libclang.map
index 07471ca42c97e..9a5e381113d37 100644
--- a/clang/tools/libclang/libclang.map
+++ b/clang/tools/libclang/libclang.map
@@ -431,6 +431,7 @@ LLVM_19 {
 
 LLVM_20 {
   global:
+    clang_getFullyQualifiedName;
     clang_getOffsetOfBase;
     clang_getTypePrettyPrinted;
     clang_isBeforeInTranslationUnit;

>From 7ffb50aac00dad31dac4d5c1abf3609bb90efd77 Mon Sep 17 00:00:00 2001
From: Brian Cody <brian.j.cody at gmail.com>
Date: Fri, 11 Apr 2025 14:55:35 -0400
Subject: [PATCH 2/7] Fix a Python formatting issue.

---
 clang/bindings/python/clang/cindex.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index 5830dc2149348..9916939acb24b 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2602,7 +2602,9 @@ def get_fully_qualified_name(self, policy, with_global_ns_prefix = False):
         policy - This PrintingPolicy can further refine the type formatting
         with_global_ns_prefix - If true, function will prepend a '::' to qualified names
         """
-        return _CXString.from_result(conf.lib.clang_getFullyQualifiedName(self, policy, with_global_ns_prefix))
+        return _CXString.from_result(
+            conf.lib.clang_getFullyQualifiedName(self, policy, with_global_ns_prefix)
+        )
 
     def is_const_qualified(self):
         """Determine whether a Type has the "const" qualifier set.

>From c603ed235805db94f0e9c7ec32d987080a698c6c Mon Sep 17 00:00:00 2001
From: Brian Cody <brian.j.cody at gmail.com>
Date: Fri, 11 Apr 2025 21:24:00 -0400
Subject: [PATCH 3/7] Fix a Python formatting issue.

---
 clang/bindings/python/clang/cindex.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index 9916939acb24b..d1510cb0a0c4c 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2593,7 +2593,7 @@ def get_canonical(self):
         """
         return Type.from_result(conf.lib.clang_getCanonicalType(self), (self,))
 
-    def get_fully_qualified_name(self, policy, with_global_ns_prefix = False):
+    def get_fully_qualified_name(self, policy, with_global_ns_prefix=False):
         """
         Get the fully qualified name for a type.
 

>From 427c071c273d24a16a35ffafc444ddd8bf373c25 Mon Sep 17 00:00:00 2001
From: Brian Cody <brian.j.cody at gmail.com>
Date: Sun, 13 Apr 2025 08:31:04 -0400
Subject: [PATCH 4/7] Doc string update

Co-authored-by: Jannick Kremer <jannick.kremer at mailbox.org>
---
 clang/bindings/python/clang/cindex.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index d1510cb0a0c4c..8dc79f28a090a 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2600,7 +2600,7 @@ def get_fully_qualified_name(self, policy, with_global_ns_prefix=False):
         This includes full qualification of all template parameters.
 
         policy - This PrintingPolicy can further refine the type formatting
-        with_global_ns_prefix - If true, function will prepend a '::' to qualified names
+        with_global_ns_prefix - If true, prepend '::' to qualified names
         """
         return _CXString.from_result(
             conf.lib.clang_getFullyQualifiedName(self, policy, with_global_ns_prefix)

>From ec6ef3d0684aad3e8953bb9191d56da8e6c9fa81 Mon Sep 17 00:00:00 2001
From: Brian Cody <brian.j.cody at gmail.com>
Date: Sun, 13 Apr 2025 08:31:24 -0400
Subject: [PATCH 5/7] Unit test simplification

Co-authored-by: Jannick Kremer <jannick.kremer at mailbox.org>
---
 clang/bindings/python/tests/cindex/test_type.py | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/clang/bindings/python/tests/cindex/test_type.py b/clang/bindings/python/tests/cindex/test_type.py
index b2a82a00b4f40..34081bb88f3dd 100644
--- a/clang/bindings/python/tests/cindex/test_type.py
+++ b/clang/bindings/python/tests/cindex/test_type.py
@@ -549,11 +549,8 @@ class A : public home::Foo {
         };
         """
         tu = get_tu(source, lang="cpp")
-        c = get_cursor(tu, "A")
-        pp = PrintingPolicy.create(c)
-        base = list(c.get_children())[0].type.get_declaration()
-        set_it = list(base.get_children())[1]
-        arg = list(set_it.get_arguments())[0]
+        arg = next(get_cursor(tu, "setIt").get_arguments())
+        pp = PrintingPolicy.create(arg)
         self.assertEqual(arg.type.get_fully_qualified_name(pp), "home::Bar *")
         self.assertEqual(arg.type.get_fully_qualified_name(pp, True), "::home::Bar *")
 

>From 926400d4060e3d07845bb79e3e38c9a613907332 Mon Sep 17 00:00:00 2001
From: Brian Cody <brian.j.cody at gmail.com>
Date: Sun, 13 Apr 2025 08:31:36 -0400
Subject: [PATCH 6/7] Doc string fix

Co-authored-by: Jannick Kremer <jannick.kremer at mailbox.org>
---
 clang/docs/ReleaseNotes.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f228a32acd51d..bf3a7c082944d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -645,7 +645,7 @@ Python Binding Changes
   the cursor is a specialization of.
 - Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
   allows visiting the methods of a class.
-- Added ``Type.getFullyQualifiedName``, which provides fully qualified type names as
+- Added ``Type.get_fully_qualified_name``, which provides fully qualified type names as
   instructed by a PrintingPolicy.
 
 OpenMP Support

>From 1b313ae0e72e4c28229bdd130e9d6531e8b7d69a Mon Sep 17 00:00:00 2001
From: Brian Cody <brian.j.cody at gmail.com>
Date: Sun, 13 Apr 2025 08:33:50 -0400
Subject: [PATCH 7/7] Moved release note addition to a new LLVM_21 section.

---
 clang/tools/libclang/libclang.map | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/clang/tools/libclang/libclang.map b/clang/tools/libclang/libclang.map
index 9a5e381113d37..f08d13c3da9e1 100644
--- a/clang/tools/libclang/libclang.map
+++ b/clang/tools/libclang/libclang.map
@@ -431,7 +431,6 @@ LLVM_19 {
 
 LLVM_20 {
   global:
-    clang_getFullyQualifiedName;
     clang_getOffsetOfBase;
     clang_getTypePrettyPrinted;
     clang_isBeforeInTranslationUnit;
@@ -439,6 +438,11 @@ LLVM_20 {
     clang_visitCXXMethods;
 };
 
+LLVM_21 {
+  global:
+    clang_getFullyQualifiedName;
+};
+
 # Example of how to add a new symbol version entry.  If you do add a new symbol
 # version, please update the example to depend on the version you added.
 # LLVM_X {



More information about the cfe-commits mailing list