[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-01-19 Thread Trevor Laughlin via cfe-commits

https://github.com/trelau created 
https://github.com/llvm/llvm-project/pull/123539

Inspired by https://github.com/llvm/llvm-project/pull/120300, add a new API 
`clang_visitCXXMethods` to libclang (and the Python bindings) which allows 
iterating over the class methods of a type.

>From bb0542e8f2ad50892ee9d2c1f76ec1def85c3e56 Mon Sep 17 00:00:00 2001
From: Trevor Laughlin 
Date: Sun, 19 Jan 2025 19:21:10 -0500
Subject: [PATCH] [cindex] Add API to query the class methods of a type

---
 clang/bindings/python/clang/cindex.py | 16 +++
 .../bindings/python/tests/cindex/test_type.py | 18 +
 clang/docs/ReleaseNotes.rst   |  4 +++
 clang/include/clang-c/Index.h | 23 
 clang/tools/libclang/CIndexCXX.cpp| 27 +++
 clang/tools/libclang/libclang.map |  1 +
 6 files changed, 89 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 806e1b40f3c9e1..9e65ea2942d163 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2710,6 +2710,21 @@ def visitor(base, children):
 conf.lib.clang_visitCXXBaseClasses(self, 
fields_visit_callback(visitor), bases)
 return iter(bases)
 
+def get_methods(self):
+"""Return an iterator for accessing the methods of this type."""
+
+def visitor(method, children):
+assert method != conf.lib.clang_getNullCursor()
+
+# Create reference to TU so it isn't GC'd before Cursor.
+method._tu = self._tu
+methods.append(method)
+return 1  # continue
+
+methods: list[Cursor] = []
+conf.lib.clang_visitCXXMethods(self, fields_visit_callback(visitor), 
methods)
+return iter(methods)
+
 def get_exception_specification_kind(self):
 """
 Return the kind of the exception specification; a value from
@@ -4017,6 +4032,7 @@ def set_property(self, property, value):
 ),
 ("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], 
c_uint),
 ("clang_visitCXXBaseClasses", [Type, fields_visit_callback, py_object], 
c_uint),
+("clang_visitCXXMethods", [Type, fields_visit_callback, py_object], 
c_uint),
 ("clang_Cursor_getNumArguments", [Cursor], c_int),
 ("clang_Cursor_getArgument", [Cursor, c_uint], Cursor),
 ("clang_Cursor_getNumTemplateArguments", [Cursor], c_int),
diff --git a/clang/bindings/python/tests/cindex/test_type.py 
b/clang/bindings/python/tests/cindex/test_type.py
index 9bac33f3041f40..bc893d509524e0 100644
--- a/clang/bindings/python/tests/cindex/test_type.py
+++ b/clang/bindings/python/tests/cindex/test_type.py
@@ -559,3 +559,21 @@ class Template : public A, public B, virtual C {
 self.assertEqual(bases[1].get_base_offsetof(cursor_type_decl), 96)
 self.assertTrue(bases[2].is_virtual_base())
 self.assertEqual(bases[2].get_base_offsetof(cursor_type_decl), 128)
+
+def test_class_methods(self):
+source = """
+template 
+class Template { void Foo(); };
+typedef Template instance;
+instance bar;
+"""
+tu = get_tu(source, lang="cpp", flags=["--target=x86_64-linux-gnu"])
+cursor = get_cursor(tu, "instance")
+cursor_type = cursor.underlying_typedef_type
+self.assertEqual(cursor.kind, CursorKind.TYPEDEF_DECL)
+methods = list(cursor_type.get_methods())
+self.assertEqual(len(methods), 4)
+self.assertEqual(methods[0].kind, CursorKind.CXX_METHOD)
+self.assertEqual(methods[1].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[2].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[3].kind, CursorKind.CONSTRUCTOR)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b02ac467cd3a22..dd9f722a6a08cb 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1241,6 +1241,8 @@ libclang
   of a class.
 - Added ``clang_getOffsetOfBase``, which allows computing the offset of a base
   class in a class's layout.
+- Added ``clang_visitCXXMethods``, which allows visiting the methods
+  of a class.
 
 Static Analyzer
 ---
@@ -1394,6 +1396,8 @@ Python Binding Changes
   allows visiting the base classes of a class.
 - Added ``Cursor.get_base_offsetof``, a binding for ``clang_getOffsetOfBase``,
   which allows computing the offset of a base class in a class's layout.
+- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
+  allows visiting the methods of a class.
 
 OpenMP Support
 --
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index aac5d1fa8aa2e0..5d961ca0cdd7fc 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -6680,6 +6680,29 @@ CINDEX_LINKAGE unsigned clang_visitCXXBaseClasses(CXType 
T,
  

[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-01-26 Thread Trevor Laughlin via cfe-commits

https://github.com/trelau updated 
https://github.com/llvm/llvm-project/pull/123539

>From bb0542e8f2ad50892ee9d2c1f76ec1def85c3e56 Mon Sep 17 00:00:00 2001
From: Trevor Laughlin 
Date: Sun, 19 Jan 2025 19:21:10 -0500
Subject: [PATCH] [cindex] Add API to query the class methods of a type

---
 clang/bindings/python/clang/cindex.py | 16 +++
 .../bindings/python/tests/cindex/test_type.py | 18 +
 clang/docs/ReleaseNotes.rst   |  4 +++
 clang/include/clang-c/Index.h | 23 
 clang/tools/libclang/CIndexCXX.cpp| 27 +++
 clang/tools/libclang/libclang.map |  1 +
 6 files changed, 89 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 806e1b40f3c9e1..9e65ea2942d163 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2710,6 +2710,21 @@ def visitor(base, children):
 conf.lib.clang_visitCXXBaseClasses(self, 
fields_visit_callback(visitor), bases)
 return iter(bases)
 
+def get_methods(self):
+"""Return an iterator for accessing the methods of this type."""
+
+def visitor(method, children):
+assert method != conf.lib.clang_getNullCursor()
+
+# Create reference to TU so it isn't GC'd before Cursor.
+method._tu = self._tu
+methods.append(method)
+return 1  # continue
+
+methods: list[Cursor] = []
+conf.lib.clang_visitCXXMethods(self, fields_visit_callback(visitor), 
methods)
+return iter(methods)
+
 def get_exception_specification_kind(self):
 """
 Return the kind of the exception specification; a value from
@@ -4017,6 +4032,7 @@ def set_property(self, property, value):
 ),
 ("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], 
c_uint),
 ("clang_visitCXXBaseClasses", [Type, fields_visit_callback, py_object], 
c_uint),
+("clang_visitCXXMethods", [Type, fields_visit_callback, py_object], 
c_uint),
 ("clang_Cursor_getNumArguments", [Cursor], c_int),
 ("clang_Cursor_getArgument", [Cursor, c_uint], Cursor),
 ("clang_Cursor_getNumTemplateArguments", [Cursor], c_int),
diff --git a/clang/bindings/python/tests/cindex/test_type.py 
b/clang/bindings/python/tests/cindex/test_type.py
index 9bac33f3041f40..bc893d509524e0 100644
--- a/clang/bindings/python/tests/cindex/test_type.py
+++ b/clang/bindings/python/tests/cindex/test_type.py
@@ -559,3 +559,21 @@ class Template : public A, public B, virtual C {
 self.assertEqual(bases[1].get_base_offsetof(cursor_type_decl), 96)
 self.assertTrue(bases[2].is_virtual_base())
 self.assertEqual(bases[2].get_base_offsetof(cursor_type_decl), 128)
+
+def test_class_methods(self):
+source = """
+template 
+class Template { void Foo(); };
+typedef Template instance;
+instance bar;
+"""
+tu = get_tu(source, lang="cpp", flags=["--target=x86_64-linux-gnu"])
+cursor = get_cursor(tu, "instance")
+cursor_type = cursor.underlying_typedef_type
+self.assertEqual(cursor.kind, CursorKind.TYPEDEF_DECL)
+methods = list(cursor_type.get_methods())
+self.assertEqual(len(methods), 4)
+self.assertEqual(methods[0].kind, CursorKind.CXX_METHOD)
+self.assertEqual(methods[1].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[2].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[3].kind, CursorKind.CONSTRUCTOR)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b02ac467cd3a22..dd9f722a6a08cb 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1241,6 +1241,8 @@ libclang
   of a class.
 - Added ``clang_getOffsetOfBase``, which allows computing the offset of a base
   class in a class's layout.
+- Added ``clang_visitCXXMethods``, which allows visiting the methods
+  of a class.
 
 Static Analyzer
 ---
@@ -1394,6 +1396,8 @@ Python Binding Changes
   allows visiting the base classes of a class.
 - Added ``Cursor.get_base_offsetof``, a binding for ``clang_getOffsetOfBase``,
   which allows computing the offset of a base class in a class's layout.
+- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
+  allows visiting the methods of a class.
 
 OpenMP Support
 --
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index aac5d1fa8aa2e0..5d961ca0cdd7fc 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -6680,6 +6680,29 @@ CINDEX_LINKAGE unsigned clang_visitCXXBaseClasses(CXType 
T,
   CXFieldVisitor visitor,
   CXClientData client_data);
 
+/**
+ * Visit the class methods of a type.
+ *
+ * This function visits all the methods 

[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-01-26 Thread Trevor Laughlin via cfe-commits


@@ -2052,6 +2052,19 @@ def referenced(self):
 
 return self._referenced
 
+@property
+def specialized(self):
+"""
+For a cursor that is instantiated from a template, returns a cursor
+representing the template that it was instantiated from.
+"""
+if not hasattr(self, "_specialized"):
+self._specialized = Cursor.from_result(
+conf.lib.clang_getSpecializedCursorTemplate(self), self
+)
+
+return self._specialized
+

trelau wrote:

removed this and will put into a different PR (with tests)

https://github.com/llvm/llvm-project/pull/123539
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-01-25 Thread Trevor Laughlin via cfe-commits

https://github.com/trelau updated 
https://github.com/llvm/llvm-project/pull/123539

>From bb0542e8f2ad50892ee9d2c1f76ec1def85c3e56 Mon Sep 17 00:00:00 2001
From: Trevor Laughlin 
Date: Sun, 19 Jan 2025 19:21:10 -0500
Subject: [PATCH 1/2] [cindex] Add API to query the class methods of a type

---
 clang/bindings/python/clang/cindex.py | 16 +++
 .../bindings/python/tests/cindex/test_type.py | 18 +
 clang/docs/ReleaseNotes.rst   |  4 +++
 clang/include/clang-c/Index.h | 23 
 clang/tools/libclang/CIndexCXX.cpp| 27 +++
 clang/tools/libclang/libclang.map |  1 +
 6 files changed, 89 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 806e1b40f3c9e1..9e65ea2942d163 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2710,6 +2710,21 @@ def visitor(base, children):
 conf.lib.clang_visitCXXBaseClasses(self, 
fields_visit_callback(visitor), bases)
 return iter(bases)
 
+def get_methods(self):
+"""Return an iterator for accessing the methods of this type."""
+
+def visitor(method, children):
+assert method != conf.lib.clang_getNullCursor()
+
+# Create reference to TU so it isn't GC'd before Cursor.
+method._tu = self._tu
+methods.append(method)
+return 1  # continue
+
+methods: list[Cursor] = []
+conf.lib.clang_visitCXXMethods(self, fields_visit_callback(visitor), 
methods)
+return iter(methods)
+
 def get_exception_specification_kind(self):
 """
 Return the kind of the exception specification; a value from
@@ -4017,6 +4032,7 @@ def set_property(self, property, value):
 ),
 ("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], 
c_uint),
 ("clang_visitCXXBaseClasses", [Type, fields_visit_callback, py_object], 
c_uint),
+("clang_visitCXXMethods", [Type, fields_visit_callback, py_object], 
c_uint),
 ("clang_Cursor_getNumArguments", [Cursor], c_int),
 ("clang_Cursor_getArgument", [Cursor, c_uint], Cursor),
 ("clang_Cursor_getNumTemplateArguments", [Cursor], c_int),
diff --git a/clang/bindings/python/tests/cindex/test_type.py 
b/clang/bindings/python/tests/cindex/test_type.py
index 9bac33f3041f40..bc893d509524e0 100644
--- a/clang/bindings/python/tests/cindex/test_type.py
+++ b/clang/bindings/python/tests/cindex/test_type.py
@@ -559,3 +559,21 @@ class Template : public A, public B, virtual C {
 self.assertEqual(bases[1].get_base_offsetof(cursor_type_decl), 96)
 self.assertTrue(bases[2].is_virtual_base())
 self.assertEqual(bases[2].get_base_offsetof(cursor_type_decl), 128)
+
+def test_class_methods(self):
+source = """
+template 
+class Template { void Foo(); };
+typedef Template instance;
+instance bar;
+"""
+tu = get_tu(source, lang="cpp", flags=["--target=x86_64-linux-gnu"])
+cursor = get_cursor(tu, "instance")
+cursor_type = cursor.underlying_typedef_type
+self.assertEqual(cursor.kind, CursorKind.TYPEDEF_DECL)
+methods = list(cursor_type.get_methods())
+self.assertEqual(len(methods), 4)
+self.assertEqual(methods[0].kind, CursorKind.CXX_METHOD)
+self.assertEqual(methods[1].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[2].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[3].kind, CursorKind.CONSTRUCTOR)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b02ac467cd3a22..dd9f722a6a08cb 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1241,6 +1241,8 @@ libclang
   of a class.
 - Added ``clang_getOffsetOfBase``, which allows computing the offset of a base
   class in a class's layout.
+- Added ``clang_visitCXXMethods``, which allows visiting the methods
+  of a class.
 
 Static Analyzer
 ---
@@ -1394,6 +1396,8 @@ Python Binding Changes
   allows visiting the base classes of a class.
 - Added ``Cursor.get_base_offsetof``, a binding for ``clang_getOffsetOfBase``,
   which allows computing the offset of a base class in a class's layout.
+- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
+  allows visiting the methods of a class.
 
 OpenMP Support
 --
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index aac5d1fa8aa2e0..5d961ca0cdd7fc 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -6680,6 +6680,29 @@ CINDEX_LINKAGE unsigned clang_visitCXXBaseClasses(CXType 
T,
   CXFieldVisitor visitor,
   CXClientData client_data);
 
+/**
+ * Visit the class methods of a type.
+ *
+ * This function visits all the meth

[clang] [libclang] Add API to query more information about base classes. (PR #120300)

2025-01-04 Thread Trevor Laughlin via cfe-commits

trelau wrote:

For what it's worth, to get around my issue in 
https://github.com/llvm/llvm-project/issues/121502 I followed your same pattern 
here and added a ```get_methods()``` function to Python (and a new libclang 
function ```clang_visitCXXMethods```) to access the class methods.

Looking at 
[CXXRecordDecl](https://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html),
 perhaps the following might all be useful to add to the libclang API 
(including Python):
- methods()
- fields()
- ctors()?
- friends()?

For my purposes of parsing C++ headers and generating Python bindings via 
pybind11, this bases PR plus adding the ```get_methods()``` function would make 
things much easier (ctors and friends seem like more "nice to have" and ctors 
seem to come through in "methods" anyway and can be determined by the cursor 
kind property).

Adding ```get_methods``` was basically copy/pasting your work (see libclang 
function 
[here](https://github.com/llvm/llvm-project/issues/121502#issuecomment-2571512174)).

I'll open a PR for the ```get_methods()``` addition (and maybe I'll try the 
others if they work as I imagine them to).

https://github.com/llvm/llvm-project/pull/120300
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclang] Add API to query more information about base classes. (PR #120300)

2025-01-02 Thread Trevor Laughlin via cfe-commits

trelau wrote:

Just referencing https://github.com/llvm/llvm-project/issues/121502 since this 
PR seem somewhat related (making it easier to iterate over things and pointed 
out it doesn't work for template instantiations, which might be the underlying 
problem I encountered).

I'd like to keep using libclang (and its Python bindings), so if there is a new 
API that could be added to libclang or a modification somewhere that is 
obvious, let me know and I'll see if I can make an attempt at it.

https://github.com/llvm/llvm-project/pull/120300
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-02-15 Thread Trevor Laughlin via cfe-commits

https://github.com/trelau updated 
https://github.com/llvm/llvm-project/pull/123539

>From bb0542e8f2ad50892ee9d2c1f76ec1def85c3e56 Mon Sep 17 00:00:00 2001
From: Trevor Laughlin 
Date: Sun, 19 Jan 2025 19:21:10 -0500
Subject: [PATCH] [cindex] Add API to query the class methods of a type

---
 clang/bindings/python/clang/cindex.py | 16 +++
 .../bindings/python/tests/cindex/test_type.py | 18 +
 clang/docs/ReleaseNotes.rst   |  4 +++
 clang/include/clang-c/Index.h | 23 
 clang/tools/libclang/CIndexCXX.cpp| 27 +++
 clang/tools/libclang/libclang.map |  1 +
 6 files changed, 89 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 806e1b40f3c9e..9e65ea2942d16 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2710,6 +2710,21 @@ def visitor(base, children):
 conf.lib.clang_visitCXXBaseClasses(self, 
fields_visit_callback(visitor), bases)
 return iter(bases)
 
+def get_methods(self):
+"""Return an iterator for accessing the methods of this type."""
+
+def visitor(method, children):
+assert method != conf.lib.clang_getNullCursor()
+
+# Create reference to TU so it isn't GC'd before Cursor.
+method._tu = self._tu
+methods.append(method)
+return 1  # continue
+
+methods: list[Cursor] = []
+conf.lib.clang_visitCXXMethods(self, fields_visit_callback(visitor), 
methods)
+return iter(methods)
+
 def get_exception_specification_kind(self):
 """
 Return the kind of the exception specification; a value from
@@ -4017,6 +4032,7 @@ def set_property(self, property, value):
 ),
 ("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], 
c_uint),
 ("clang_visitCXXBaseClasses", [Type, fields_visit_callback, py_object], 
c_uint),
+("clang_visitCXXMethods", [Type, fields_visit_callback, py_object], 
c_uint),
 ("clang_Cursor_getNumArguments", [Cursor], c_int),
 ("clang_Cursor_getArgument", [Cursor, c_uint], Cursor),
 ("clang_Cursor_getNumTemplateArguments", [Cursor], c_int),
diff --git a/clang/bindings/python/tests/cindex/test_type.py 
b/clang/bindings/python/tests/cindex/test_type.py
index 9bac33f3041f4..bc893d509524e 100644
--- a/clang/bindings/python/tests/cindex/test_type.py
+++ b/clang/bindings/python/tests/cindex/test_type.py
@@ -559,3 +559,21 @@ class Template : public A, public B, virtual C {
 self.assertEqual(bases[1].get_base_offsetof(cursor_type_decl), 96)
 self.assertTrue(bases[2].is_virtual_base())
 self.assertEqual(bases[2].get_base_offsetof(cursor_type_decl), 128)
+
+def test_class_methods(self):
+source = """
+template 
+class Template { void Foo(); };
+typedef Template instance;
+instance bar;
+"""
+tu = get_tu(source, lang="cpp", flags=["--target=x86_64-linux-gnu"])
+cursor = get_cursor(tu, "instance")
+cursor_type = cursor.underlying_typedef_type
+self.assertEqual(cursor.kind, CursorKind.TYPEDEF_DECL)
+methods = list(cursor_type.get_methods())
+self.assertEqual(len(methods), 4)
+self.assertEqual(methods[0].kind, CursorKind.CXX_METHOD)
+self.assertEqual(methods[1].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[2].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[3].kind, CursorKind.CONSTRUCTOR)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b02ac467cd3a2..dd9f722a6a08c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1241,6 +1241,8 @@ libclang
   of a class.
 - Added ``clang_getOffsetOfBase``, which allows computing the offset of a base
   class in a class's layout.
+- Added ``clang_visitCXXMethods``, which allows visiting the methods
+  of a class.
 
 Static Analyzer
 ---
@@ -1394,6 +1396,8 @@ Python Binding Changes
   allows visiting the base classes of a class.
 - Added ``Cursor.get_base_offsetof``, a binding for ``clang_getOffsetOfBase``,
   which allows computing the offset of a base class in a class's layout.
+- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
+  allows visiting the methods of a class.
 
 OpenMP Support
 --
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index aac5d1fa8aa2e..5d961ca0cdd7f 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -6680,6 +6680,29 @@ CINDEX_LINKAGE unsigned clang_visitCXXBaseClasses(CXType 
T,
   CXFieldVisitor visitor,
   CXClientData client_data);
 
+/**
+ * Visit the class methods of a type.
+ *
+ * This function visits all the methods of the g

[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-02-15 Thread Trevor Laughlin via cfe-commits

trelau wrote:

Not sure what happen, but there was a merge conflict with ReleaseNotes.rst 
where it looked like previous enhancements to liblang and Python bindings had 
been removed. To resolve the conflict I only left changes relevant to this PR.

https://github.com/llvm/llvm-project/pull/123539
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-02-15 Thread Trevor Laughlin via cfe-commits

trelau wrote:

Ping

https://github.com/llvm/llvm-project/pull/123539
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-02-15 Thread Trevor Laughlin via cfe-commits

https://github.com/trelau updated 
https://github.com/llvm/llvm-project/pull/123539

>From bb0542e8f2ad50892ee9d2c1f76ec1def85c3e56 Mon Sep 17 00:00:00 2001
From: Trevor Laughlin 
Date: Sun, 19 Jan 2025 19:21:10 -0500
Subject: [PATCH 1/2] [cindex] Add API to query the class methods of a type

---
 clang/bindings/python/clang/cindex.py | 16 +++
 .../bindings/python/tests/cindex/test_type.py | 18 +
 clang/docs/ReleaseNotes.rst   |  4 +++
 clang/include/clang-c/Index.h | 23 
 clang/tools/libclang/CIndexCXX.cpp| 27 +++
 clang/tools/libclang/libclang.map |  1 +
 6 files changed, 89 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 806e1b40f3c9e..9e65ea2942d16 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2710,6 +2710,21 @@ def visitor(base, children):
 conf.lib.clang_visitCXXBaseClasses(self, 
fields_visit_callback(visitor), bases)
 return iter(bases)
 
+def get_methods(self):
+"""Return an iterator for accessing the methods of this type."""
+
+def visitor(method, children):
+assert method != conf.lib.clang_getNullCursor()
+
+# Create reference to TU so it isn't GC'd before Cursor.
+method._tu = self._tu
+methods.append(method)
+return 1  # continue
+
+methods: list[Cursor] = []
+conf.lib.clang_visitCXXMethods(self, fields_visit_callback(visitor), 
methods)
+return iter(methods)
+
 def get_exception_specification_kind(self):
 """
 Return the kind of the exception specification; a value from
@@ -4017,6 +4032,7 @@ def set_property(self, property, value):
 ),
 ("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], 
c_uint),
 ("clang_visitCXXBaseClasses", [Type, fields_visit_callback, py_object], 
c_uint),
+("clang_visitCXXMethods", [Type, fields_visit_callback, py_object], 
c_uint),
 ("clang_Cursor_getNumArguments", [Cursor], c_int),
 ("clang_Cursor_getArgument", [Cursor, c_uint], Cursor),
 ("clang_Cursor_getNumTemplateArguments", [Cursor], c_int),
diff --git a/clang/bindings/python/tests/cindex/test_type.py 
b/clang/bindings/python/tests/cindex/test_type.py
index 9bac33f3041f4..bc893d509524e 100644
--- a/clang/bindings/python/tests/cindex/test_type.py
+++ b/clang/bindings/python/tests/cindex/test_type.py
@@ -559,3 +559,21 @@ class Template : public A, public B, virtual C {
 self.assertEqual(bases[1].get_base_offsetof(cursor_type_decl), 96)
 self.assertTrue(bases[2].is_virtual_base())
 self.assertEqual(bases[2].get_base_offsetof(cursor_type_decl), 128)
+
+def test_class_methods(self):
+source = """
+template 
+class Template { void Foo(); };
+typedef Template instance;
+instance bar;
+"""
+tu = get_tu(source, lang="cpp", flags=["--target=x86_64-linux-gnu"])
+cursor = get_cursor(tu, "instance")
+cursor_type = cursor.underlying_typedef_type
+self.assertEqual(cursor.kind, CursorKind.TYPEDEF_DECL)
+methods = list(cursor_type.get_methods())
+self.assertEqual(len(methods), 4)
+self.assertEqual(methods[0].kind, CursorKind.CXX_METHOD)
+self.assertEqual(methods[1].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[2].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[3].kind, CursorKind.CONSTRUCTOR)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b02ac467cd3a2..dd9f722a6a08c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1241,6 +1241,8 @@ libclang
   of a class.
 - Added ``clang_getOffsetOfBase``, which allows computing the offset of a base
   class in a class's layout.
+- Added ``clang_visitCXXMethods``, which allows visiting the methods
+  of a class.
 
 Static Analyzer
 ---
@@ -1394,6 +1396,8 @@ Python Binding Changes
   allows visiting the base classes of a class.
 - Added ``Cursor.get_base_offsetof``, a binding for ``clang_getOffsetOfBase``,
   which allows computing the offset of a base class in a class's layout.
+- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
+  allows visiting the methods of a class.
 
 OpenMP Support
 --
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index aac5d1fa8aa2e..5d961ca0cdd7f 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -6680,6 +6680,29 @@ CINDEX_LINKAGE unsigned clang_visitCXXBaseClasses(CXType 
T,
   CXFieldVisitor visitor,
   CXClientData client_data);
 
+/**
+ * Visit the class methods of a type.
+ *
+ * This function visits all the methods of t

[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-02-21 Thread Trevor Laughlin via cfe-commits

https://github.com/trelau updated 
https://github.com/llvm/llvm-project/pull/123539

>From bb0542e8f2ad50892ee9d2c1f76ec1def85c3e56 Mon Sep 17 00:00:00 2001
From: Trevor Laughlin 
Date: Sun, 19 Jan 2025 19:21:10 -0500
Subject: [PATCH 1/3] [cindex] Add API to query the class methods of a type

---
 clang/bindings/python/clang/cindex.py | 16 +++
 .../bindings/python/tests/cindex/test_type.py | 18 +
 clang/docs/ReleaseNotes.rst   |  4 +++
 clang/include/clang-c/Index.h | 23 
 clang/tools/libclang/CIndexCXX.cpp| 27 +++
 clang/tools/libclang/libclang.map |  1 +
 6 files changed, 89 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 806e1b40f3c9e..9e65ea2942d16 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2710,6 +2710,21 @@ def visitor(base, children):
 conf.lib.clang_visitCXXBaseClasses(self, 
fields_visit_callback(visitor), bases)
 return iter(bases)
 
+def get_methods(self):
+"""Return an iterator for accessing the methods of this type."""
+
+def visitor(method, children):
+assert method != conf.lib.clang_getNullCursor()
+
+# Create reference to TU so it isn't GC'd before Cursor.
+method._tu = self._tu
+methods.append(method)
+return 1  # continue
+
+methods: list[Cursor] = []
+conf.lib.clang_visitCXXMethods(self, fields_visit_callback(visitor), 
methods)
+return iter(methods)
+
 def get_exception_specification_kind(self):
 """
 Return the kind of the exception specification; a value from
@@ -4017,6 +4032,7 @@ def set_property(self, property, value):
 ),
 ("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], 
c_uint),
 ("clang_visitCXXBaseClasses", [Type, fields_visit_callback, py_object], 
c_uint),
+("clang_visitCXXMethods", [Type, fields_visit_callback, py_object], 
c_uint),
 ("clang_Cursor_getNumArguments", [Cursor], c_int),
 ("clang_Cursor_getArgument", [Cursor, c_uint], Cursor),
 ("clang_Cursor_getNumTemplateArguments", [Cursor], c_int),
diff --git a/clang/bindings/python/tests/cindex/test_type.py 
b/clang/bindings/python/tests/cindex/test_type.py
index 9bac33f3041f4..bc893d509524e 100644
--- a/clang/bindings/python/tests/cindex/test_type.py
+++ b/clang/bindings/python/tests/cindex/test_type.py
@@ -559,3 +559,21 @@ class Template : public A, public B, virtual C {
 self.assertEqual(bases[1].get_base_offsetof(cursor_type_decl), 96)
 self.assertTrue(bases[2].is_virtual_base())
 self.assertEqual(bases[2].get_base_offsetof(cursor_type_decl), 128)
+
+def test_class_methods(self):
+source = """
+template 
+class Template { void Foo(); };
+typedef Template instance;
+instance bar;
+"""
+tu = get_tu(source, lang="cpp", flags=["--target=x86_64-linux-gnu"])
+cursor = get_cursor(tu, "instance")
+cursor_type = cursor.underlying_typedef_type
+self.assertEqual(cursor.kind, CursorKind.TYPEDEF_DECL)
+methods = list(cursor_type.get_methods())
+self.assertEqual(len(methods), 4)
+self.assertEqual(methods[0].kind, CursorKind.CXX_METHOD)
+self.assertEqual(methods[1].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[2].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[3].kind, CursorKind.CONSTRUCTOR)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b02ac467cd3a2..dd9f722a6a08c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1241,6 +1241,8 @@ libclang
   of a class.
 - Added ``clang_getOffsetOfBase``, which allows computing the offset of a base
   class in a class's layout.
+- Added ``clang_visitCXXMethods``, which allows visiting the methods
+  of a class.
 
 Static Analyzer
 ---
@@ -1394,6 +1396,8 @@ Python Binding Changes
   allows visiting the base classes of a class.
 - Added ``Cursor.get_base_offsetof``, a binding for ``clang_getOffsetOfBase``,
   which allows computing the offset of a base class in a class's layout.
+- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
+  allows visiting the methods of a class.
 
 OpenMP Support
 --
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index aac5d1fa8aa2e..5d961ca0cdd7f 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -6680,6 +6680,29 @@ CINDEX_LINKAGE unsigned clang_visitCXXBaseClasses(CXType 
T,
   CXFieldVisitor visitor,
   CXClientData client_data);
 
+/**
+ * Visit the class methods of a type.
+ *
+ * This function visits all the methods of t

[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-02-21 Thread Trevor Laughlin via cfe-commits

https://github.com/trelau updated 
https://github.com/llvm/llvm-project/pull/123539

>From bb0542e8f2ad50892ee9d2c1f76ec1def85c3e56 Mon Sep 17 00:00:00 2001
From: Trevor Laughlin 
Date: Sun, 19 Jan 2025 19:21:10 -0500
Subject: [PATCH 1/4] [cindex] Add API to query the class methods of a type

---
 clang/bindings/python/clang/cindex.py | 16 +++
 .../bindings/python/tests/cindex/test_type.py | 18 +
 clang/docs/ReleaseNotes.rst   |  4 +++
 clang/include/clang-c/Index.h | 23 
 clang/tools/libclang/CIndexCXX.cpp| 27 +++
 clang/tools/libclang/libclang.map |  1 +
 6 files changed, 89 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 806e1b40f3c9e..9e65ea2942d16 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2710,6 +2710,21 @@ def visitor(base, children):
 conf.lib.clang_visitCXXBaseClasses(self, 
fields_visit_callback(visitor), bases)
 return iter(bases)
 
+def get_methods(self):
+"""Return an iterator for accessing the methods of this type."""
+
+def visitor(method, children):
+assert method != conf.lib.clang_getNullCursor()
+
+# Create reference to TU so it isn't GC'd before Cursor.
+method._tu = self._tu
+methods.append(method)
+return 1  # continue
+
+methods: list[Cursor] = []
+conf.lib.clang_visitCXXMethods(self, fields_visit_callback(visitor), 
methods)
+return iter(methods)
+
 def get_exception_specification_kind(self):
 """
 Return the kind of the exception specification; a value from
@@ -4017,6 +4032,7 @@ def set_property(self, property, value):
 ),
 ("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], 
c_uint),
 ("clang_visitCXXBaseClasses", [Type, fields_visit_callback, py_object], 
c_uint),
+("clang_visitCXXMethods", [Type, fields_visit_callback, py_object], 
c_uint),
 ("clang_Cursor_getNumArguments", [Cursor], c_int),
 ("clang_Cursor_getArgument", [Cursor, c_uint], Cursor),
 ("clang_Cursor_getNumTemplateArguments", [Cursor], c_int),
diff --git a/clang/bindings/python/tests/cindex/test_type.py 
b/clang/bindings/python/tests/cindex/test_type.py
index 9bac33f3041f4..bc893d509524e 100644
--- a/clang/bindings/python/tests/cindex/test_type.py
+++ b/clang/bindings/python/tests/cindex/test_type.py
@@ -559,3 +559,21 @@ class Template : public A, public B, virtual C {
 self.assertEqual(bases[1].get_base_offsetof(cursor_type_decl), 96)
 self.assertTrue(bases[2].is_virtual_base())
 self.assertEqual(bases[2].get_base_offsetof(cursor_type_decl), 128)
+
+def test_class_methods(self):
+source = """
+template 
+class Template { void Foo(); };
+typedef Template instance;
+instance bar;
+"""
+tu = get_tu(source, lang="cpp", flags=["--target=x86_64-linux-gnu"])
+cursor = get_cursor(tu, "instance")
+cursor_type = cursor.underlying_typedef_type
+self.assertEqual(cursor.kind, CursorKind.TYPEDEF_DECL)
+methods = list(cursor_type.get_methods())
+self.assertEqual(len(methods), 4)
+self.assertEqual(methods[0].kind, CursorKind.CXX_METHOD)
+self.assertEqual(methods[1].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[2].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[3].kind, CursorKind.CONSTRUCTOR)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b02ac467cd3a2..dd9f722a6a08c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1241,6 +1241,8 @@ libclang
   of a class.
 - Added ``clang_getOffsetOfBase``, which allows computing the offset of a base
   class in a class's layout.
+- Added ``clang_visitCXXMethods``, which allows visiting the methods
+  of a class.
 
 Static Analyzer
 ---
@@ -1394,6 +1396,8 @@ Python Binding Changes
   allows visiting the base classes of a class.
 - Added ``Cursor.get_base_offsetof``, a binding for ``clang_getOffsetOfBase``,
   which allows computing the offset of a base class in a class's layout.
+- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
+  allows visiting the methods of a class.
 
 OpenMP Support
 --
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index aac5d1fa8aa2e..5d961ca0cdd7f 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -6680,6 +6680,29 @@ CINDEX_LINKAGE unsigned clang_visitCXXBaseClasses(CXType 
T,
   CXFieldVisitor visitor,
   CXClientData client_data);
 
+/**
+ * Visit the class methods of a type.
+ *
+ * This function visits all the methods of t

[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-02-21 Thread Trevor Laughlin via cfe-commits

https://github.com/trelau updated 
https://github.com/llvm/llvm-project/pull/123539

>From bb0542e8f2ad50892ee9d2c1f76ec1def85c3e56 Mon Sep 17 00:00:00 2001
From: Trevor Laughlin 
Date: Sun, 19 Jan 2025 19:21:10 -0500
Subject: [PATCH 1/4] [cindex] Add API to query the class methods of a type

---
 clang/bindings/python/clang/cindex.py | 16 +++
 .../bindings/python/tests/cindex/test_type.py | 18 +
 clang/docs/ReleaseNotes.rst   |  4 +++
 clang/include/clang-c/Index.h | 23 
 clang/tools/libclang/CIndexCXX.cpp| 27 +++
 clang/tools/libclang/libclang.map |  1 +
 6 files changed, 89 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 806e1b40f3c9e..9e65ea2942d16 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2710,6 +2710,21 @@ def visitor(base, children):
 conf.lib.clang_visitCXXBaseClasses(self, 
fields_visit_callback(visitor), bases)
 return iter(bases)
 
+def get_methods(self):
+"""Return an iterator for accessing the methods of this type."""
+
+def visitor(method, children):
+assert method != conf.lib.clang_getNullCursor()
+
+# Create reference to TU so it isn't GC'd before Cursor.
+method._tu = self._tu
+methods.append(method)
+return 1  # continue
+
+methods: list[Cursor] = []
+conf.lib.clang_visitCXXMethods(self, fields_visit_callback(visitor), 
methods)
+return iter(methods)
+
 def get_exception_specification_kind(self):
 """
 Return the kind of the exception specification; a value from
@@ -4017,6 +4032,7 @@ def set_property(self, property, value):
 ),
 ("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], 
c_uint),
 ("clang_visitCXXBaseClasses", [Type, fields_visit_callback, py_object], 
c_uint),
+("clang_visitCXXMethods", [Type, fields_visit_callback, py_object], 
c_uint),
 ("clang_Cursor_getNumArguments", [Cursor], c_int),
 ("clang_Cursor_getArgument", [Cursor, c_uint], Cursor),
 ("clang_Cursor_getNumTemplateArguments", [Cursor], c_int),
diff --git a/clang/bindings/python/tests/cindex/test_type.py 
b/clang/bindings/python/tests/cindex/test_type.py
index 9bac33f3041f4..bc893d509524e 100644
--- a/clang/bindings/python/tests/cindex/test_type.py
+++ b/clang/bindings/python/tests/cindex/test_type.py
@@ -559,3 +559,21 @@ class Template : public A, public B, virtual C {
 self.assertEqual(bases[1].get_base_offsetof(cursor_type_decl), 96)
 self.assertTrue(bases[2].is_virtual_base())
 self.assertEqual(bases[2].get_base_offsetof(cursor_type_decl), 128)
+
+def test_class_methods(self):
+source = """
+template 
+class Template { void Foo(); };
+typedef Template instance;
+instance bar;
+"""
+tu = get_tu(source, lang="cpp", flags=["--target=x86_64-linux-gnu"])
+cursor = get_cursor(tu, "instance")
+cursor_type = cursor.underlying_typedef_type
+self.assertEqual(cursor.kind, CursorKind.TYPEDEF_DECL)
+methods = list(cursor_type.get_methods())
+self.assertEqual(len(methods), 4)
+self.assertEqual(methods[0].kind, CursorKind.CXX_METHOD)
+self.assertEqual(methods[1].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[2].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[3].kind, CursorKind.CONSTRUCTOR)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b02ac467cd3a2..dd9f722a6a08c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1241,6 +1241,8 @@ libclang
   of a class.
 - Added ``clang_getOffsetOfBase``, which allows computing the offset of a base
   class in a class's layout.
+- Added ``clang_visitCXXMethods``, which allows visiting the methods
+  of a class.
 
 Static Analyzer
 ---
@@ -1394,6 +1396,8 @@ Python Binding Changes
   allows visiting the base classes of a class.
 - Added ``Cursor.get_base_offsetof``, a binding for ``clang_getOffsetOfBase``,
   which allows computing the offset of a base class in a class's layout.
+- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
+  allows visiting the methods of a class.
 
 OpenMP Support
 --
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index aac5d1fa8aa2e..5d961ca0cdd7f 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -6680,6 +6680,29 @@ CINDEX_LINKAGE unsigned clang_visitCXXBaseClasses(CXType 
T,
   CXFieldVisitor visitor,
   CXClientData client_data);
 
+/**
+ * Visit the class methods of a type.
+ *
+ * This function visits all the methods of t

[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-03-01 Thread Trevor Laughlin via cfe-commits

https://github.com/trelau updated 
https://github.com/llvm/llvm-project/pull/123539

>From bb0542e8f2ad50892ee9d2c1f76ec1def85c3e56 Mon Sep 17 00:00:00 2001
From: Trevor Laughlin 
Date: Sun, 19 Jan 2025 19:21:10 -0500
Subject: [PATCH 1/6] [cindex] Add API to query the class methods of a type

---
 clang/bindings/python/clang/cindex.py | 16 +++
 .../bindings/python/tests/cindex/test_type.py | 18 +
 clang/docs/ReleaseNotes.rst   |  4 +++
 clang/include/clang-c/Index.h | 23 
 clang/tools/libclang/CIndexCXX.cpp| 27 +++
 clang/tools/libclang/libclang.map |  1 +
 6 files changed, 89 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 806e1b40f3c9e..9e65ea2942d16 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2710,6 +2710,21 @@ def visitor(base, children):
 conf.lib.clang_visitCXXBaseClasses(self, 
fields_visit_callback(visitor), bases)
 return iter(bases)
 
+def get_methods(self):
+"""Return an iterator for accessing the methods of this type."""
+
+def visitor(method, children):
+assert method != conf.lib.clang_getNullCursor()
+
+# Create reference to TU so it isn't GC'd before Cursor.
+method._tu = self._tu
+methods.append(method)
+return 1  # continue
+
+methods: list[Cursor] = []
+conf.lib.clang_visitCXXMethods(self, fields_visit_callback(visitor), 
methods)
+return iter(methods)
+
 def get_exception_specification_kind(self):
 """
 Return the kind of the exception specification; a value from
@@ -4017,6 +4032,7 @@ def set_property(self, property, value):
 ),
 ("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], 
c_uint),
 ("clang_visitCXXBaseClasses", [Type, fields_visit_callback, py_object], 
c_uint),
+("clang_visitCXXMethods", [Type, fields_visit_callback, py_object], 
c_uint),
 ("clang_Cursor_getNumArguments", [Cursor], c_int),
 ("clang_Cursor_getArgument", [Cursor, c_uint], Cursor),
 ("clang_Cursor_getNumTemplateArguments", [Cursor], c_int),
diff --git a/clang/bindings/python/tests/cindex/test_type.py 
b/clang/bindings/python/tests/cindex/test_type.py
index 9bac33f3041f4..bc893d509524e 100644
--- a/clang/bindings/python/tests/cindex/test_type.py
+++ b/clang/bindings/python/tests/cindex/test_type.py
@@ -559,3 +559,21 @@ class Template : public A, public B, virtual C {
 self.assertEqual(bases[1].get_base_offsetof(cursor_type_decl), 96)
 self.assertTrue(bases[2].is_virtual_base())
 self.assertEqual(bases[2].get_base_offsetof(cursor_type_decl), 128)
+
+def test_class_methods(self):
+source = """
+template 
+class Template { void Foo(); };
+typedef Template instance;
+instance bar;
+"""
+tu = get_tu(source, lang="cpp", flags=["--target=x86_64-linux-gnu"])
+cursor = get_cursor(tu, "instance")
+cursor_type = cursor.underlying_typedef_type
+self.assertEqual(cursor.kind, CursorKind.TYPEDEF_DECL)
+methods = list(cursor_type.get_methods())
+self.assertEqual(len(methods), 4)
+self.assertEqual(methods[0].kind, CursorKind.CXX_METHOD)
+self.assertEqual(methods[1].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[2].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[3].kind, CursorKind.CONSTRUCTOR)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b02ac467cd3a2..dd9f722a6a08c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1241,6 +1241,8 @@ libclang
   of a class.
 - Added ``clang_getOffsetOfBase``, which allows computing the offset of a base
   class in a class's layout.
+- Added ``clang_visitCXXMethods``, which allows visiting the methods
+  of a class.
 
 Static Analyzer
 ---
@@ -1394,6 +1396,8 @@ Python Binding Changes
   allows visiting the base classes of a class.
 - Added ``Cursor.get_base_offsetof``, a binding for ``clang_getOffsetOfBase``,
   which allows computing the offset of a base class in a class's layout.
+- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
+  allows visiting the methods of a class.
 
 OpenMP Support
 --
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index aac5d1fa8aa2e..5d961ca0cdd7f 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -6680,6 +6680,29 @@ CINDEX_LINKAGE unsigned clang_visitCXXBaseClasses(CXType 
T,
   CXFieldVisitor visitor,
   CXClientData client_data);
 
+/**
+ * Visit the class methods of a type.
+ *
+ * This function visits all the methods of t

[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-03-01 Thread Trevor Laughlin via cfe-commits

https://github.com/trelau updated 
https://github.com/llvm/llvm-project/pull/123539

>From bb0542e8f2ad50892ee9d2c1f76ec1def85c3e56 Mon Sep 17 00:00:00 2001
From: Trevor Laughlin 
Date: Sun, 19 Jan 2025 19:21:10 -0500
Subject: [PATCH 1/4] [cindex] Add API to query the class methods of a type

---
 clang/bindings/python/clang/cindex.py | 16 +++
 .../bindings/python/tests/cindex/test_type.py | 18 +
 clang/docs/ReleaseNotes.rst   |  4 +++
 clang/include/clang-c/Index.h | 23 
 clang/tools/libclang/CIndexCXX.cpp| 27 +++
 clang/tools/libclang/libclang.map |  1 +
 6 files changed, 89 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 806e1b40f3c9e..9e65ea2942d16 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2710,6 +2710,21 @@ def visitor(base, children):
 conf.lib.clang_visitCXXBaseClasses(self, 
fields_visit_callback(visitor), bases)
 return iter(bases)
 
+def get_methods(self):
+"""Return an iterator for accessing the methods of this type."""
+
+def visitor(method, children):
+assert method != conf.lib.clang_getNullCursor()
+
+# Create reference to TU so it isn't GC'd before Cursor.
+method._tu = self._tu
+methods.append(method)
+return 1  # continue
+
+methods: list[Cursor] = []
+conf.lib.clang_visitCXXMethods(self, fields_visit_callback(visitor), 
methods)
+return iter(methods)
+
 def get_exception_specification_kind(self):
 """
 Return the kind of the exception specification; a value from
@@ -4017,6 +4032,7 @@ def set_property(self, property, value):
 ),
 ("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], 
c_uint),
 ("clang_visitCXXBaseClasses", [Type, fields_visit_callback, py_object], 
c_uint),
+("clang_visitCXXMethods", [Type, fields_visit_callback, py_object], 
c_uint),
 ("clang_Cursor_getNumArguments", [Cursor], c_int),
 ("clang_Cursor_getArgument", [Cursor, c_uint], Cursor),
 ("clang_Cursor_getNumTemplateArguments", [Cursor], c_int),
diff --git a/clang/bindings/python/tests/cindex/test_type.py 
b/clang/bindings/python/tests/cindex/test_type.py
index 9bac33f3041f4..bc893d509524e 100644
--- a/clang/bindings/python/tests/cindex/test_type.py
+++ b/clang/bindings/python/tests/cindex/test_type.py
@@ -559,3 +559,21 @@ class Template : public A, public B, virtual C {
 self.assertEqual(bases[1].get_base_offsetof(cursor_type_decl), 96)
 self.assertTrue(bases[2].is_virtual_base())
 self.assertEqual(bases[2].get_base_offsetof(cursor_type_decl), 128)
+
+def test_class_methods(self):
+source = """
+template 
+class Template { void Foo(); };
+typedef Template instance;
+instance bar;
+"""
+tu = get_tu(source, lang="cpp", flags=["--target=x86_64-linux-gnu"])
+cursor = get_cursor(tu, "instance")
+cursor_type = cursor.underlying_typedef_type
+self.assertEqual(cursor.kind, CursorKind.TYPEDEF_DECL)
+methods = list(cursor_type.get_methods())
+self.assertEqual(len(methods), 4)
+self.assertEqual(methods[0].kind, CursorKind.CXX_METHOD)
+self.assertEqual(methods[1].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[2].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[3].kind, CursorKind.CONSTRUCTOR)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b02ac467cd3a2..dd9f722a6a08c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1241,6 +1241,8 @@ libclang
   of a class.
 - Added ``clang_getOffsetOfBase``, which allows computing the offset of a base
   class in a class's layout.
+- Added ``clang_visitCXXMethods``, which allows visiting the methods
+  of a class.
 
 Static Analyzer
 ---
@@ -1394,6 +1396,8 @@ Python Binding Changes
   allows visiting the base classes of a class.
 - Added ``Cursor.get_base_offsetof``, a binding for ``clang_getOffsetOfBase``,
   which allows computing the offset of a base class in a class's layout.
+- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
+  allows visiting the methods of a class.
 
 OpenMP Support
 --
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index aac5d1fa8aa2e..5d961ca0cdd7f 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -6680,6 +6680,29 @@ CINDEX_LINKAGE unsigned clang_visitCXXBaseClasses(CXType 
T,
   CXFieldVisitor visitor,
   CXClientData client_data);
 
+/**
+ * Visit the class methods of a type.
+ *
+ * This function visits all the methods of t

[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-03-01 Thread Trevor Laughlin via cfe-commits

https://github.com/trelau updated 
https://github.com/llvm/llvm-project/pull/123539

>From bb0542e8f2ad50892ee9d2c1f76ec1def85c3e56 Mon Sep 17 00:00:00 2001
From: Trevor Laughlin 
Date: Sun, 19 Jan 2025 19:21:10 -0500
Subject: [PATCH 1/5] [cindex] Add API to query the class methods of a type

---
 clang/bindings/python/clang/cindex.py | 16 +++
 .../bindings/python/tests/cindex/test_type.py | 18 +
 clang/docs/ReleaseNotes.rst   |  4 +++
 clang/include/clang-c/Index.h | 23 
 clang/tools/libclang/CIndexCXX.cpp| 27 +++
 clang/tools/libclang/libclang.map |  1 +
 6 files changed, 89 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 806e1b40f3c9e..9e65ea2942d16 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -2710,6 +2710,21 @@ def visitor(base, children):
 conf.lib.clang_visitCXXBaseClasses(self, 
fields_visit_callback(visitor), bases)
 return iter(bases)
 
+def get_methods(self):
+"""Return an iterator for accessing the methods of this type."""
+
+def visitor(method, children):
+assert method != conf.lib.clang_getNullCursor()
+
+# Create reference to TU so it isn't GC'd before Cursor.
+method._tu = self._tu
+methods.append(method)
+return 1  # continue
+
+methods: list[Cursor] = []
+conf.lib.clang_visitCXXMethods(self, fields_visit_callback(visitor), 
methods)
+return iter(methods)
+
 def get_exception_specification_kind(self):
 """
 Return the kind of the exception specification; a value from
@@ -4017,6 +4032,7 @@ def set_property(self, property, value):
 ),
 ("clang_visitChildren", [Cursor, cursor_visit_callback, py_object], 
c_uint),
 ("clang_visitCXXBaseClasses", [Type, fields_visit_callback, py_object], 
c_uint),
+("clang_visitCXXMethods", [Type, fields_visit_callback, py_object], 
c_uint),
 ("clang_Cursor_getNumArguments", [Cursor], c_int),
 ("clang_Cursor_getArgument", [Cursor, c_uint], Cursor),
 ("clang_Cursor_getNumTemplateArguments", [Cursor], c_int),
diff --git a/clang/bindings/python/tests/cindex/test_type.py 
b/clang/bindings/python/tests/cindex/test_type.py
index 9bac33f3041f4..bc893d509524e 100644
--- a/clang/bindings/python/tests/cindex/test_type.py
+++ b/clang/bindings/python/tests/cindex/test_type.py
@@ -559,3 +559,21 @@ class Template : public A, public B, virtual C {
 self.assertEqual(bases[1].get_base_offsetof(cursor_type_decl), 96)
 self.assertTrue(bases[2].is_virtual_base())
 self.assertEqual(bases[2].get_base_offsetof(cursor_type_decl), 128)
+
+def test_class_methods(self):
+source = """
+template 
+class Template { void Foo(); };
+typedef Template instance;
+instance bar;
+"""
+tu = get_tu(source, lang="cpp", flags=["--target=x86_64-linux-gnu"])
+cursor = get_cursor(tu, "instance")
+cursor_type = cursor.underlying_typedef_type
+self.assertEqual(cursor.kind, CursorKind.TYPEDEF_DECL)
+methods = list(cursor_type.get_methods())
+self.assertEqual(len(methods), 4)
+self.assertEqual(methods[0].kind, CursorKind.CXX_METHOD)
+self.assertEqual(methods[1].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[2].kind, CursorKind.CONSTRUCTOR)
+self.assertEqual(methods[3].kind, CursorKind.CONSTRUCTOR)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b02ac467cd3a2..dd9f722a6a08c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1241,6 +1241,8 @@ libclang
   of a class.
 - Added ``clang_getOffsetOfBase``, which allows computing the offset of a base
   class in a class's layout.
+- Added ``clang_visitCXXMethods``, which allows visiting the methods
+  of a class.
 
 Static Analyzer
 ---
@@ -1394,6 +1396,8 @@ Python Binding Changes
   allows visiting the base classes of a class.
 - Added ``Cursor.get_base_offsetof``, a binding for ``clang_getOffsetOfBase``,
   which allows computing the offset of a base class in a class's layout.
+- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
+  allows visiting the methods of a class.
 
 OpenMP Support
 --
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index aac5d1fa8aa2e..5d961ca0cdd7f 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -6680,6 +6680,29 @@ CINDEX_LINKAGE unsigned clang_visitCXXBaseClasses(CXType 
T,
   CXFieldVisitor visitor,
   CXClientData client_data);
 
+/**
+ * Visit the class methods of a type.
+ *
+ * This function visits all the methods of t

[clang] [cindex] Add API to query the class methods of a type (PR #123539)

2025-03-01 Thread Trevor Laughlin via cfe-commits

trelau wrote:

@DeinAlptraum ok now i think it's ready

https://github.com/llvm/llvm-project/pull/123539
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits