https://github.com/DeinAlptraum updated https://github.com/llvm/llvm-project/pull/132377
>From c433f194600d72a3902c4eed304439d6e3f2f62b Mon Sep 17 00:00:00 2001 From: Mathias Stearn <redbeard0...@gmail.com> Date: Thu, 19 Dec 2024 16:22:04 +0100 Subject: [PATCH 1/3] [libclang/python] Add some bindings to the Cursor interface Make Cursor hashable Add Cursor.has_attr() Add Cursor.specialized_template --- clang/bindings/python/clang/cindex.py | 17 ++++++++ .../python/tests/cindex/test_cursor.py | 40 +++++++++++++++++++ clang/docs/ReleaseNotes.rst | 6 +++ 3 files changed, 63 insertions(+) diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index 879a0a3c5c58c..090ee899ad60e 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -1561,6 +1561,9 @@ def __eq__(self, other): def __ne__(self, other): return not self.__eq__(other) + def __hash__(self) -> int: + return self.hash + def is_definition(self): """ Returns true if the declaration pointed at by the cursor is also a @@ -2035,6 +2038,13 @@ def lexical_parent(self): return self._lexical_parent + @property + def specialized_template(self) -> Cursor | None: + """Return the primary template that this cursor is a specialization of, if any.""" + return Cursor.from_cursor_result( + conf.lib.clang_getSpecializedCursorTemplate(self), self + ) + @property def translation_unit(self): """Returns the TranslationUnit to which this Cursor belongs.""" @@ -2178,6 +2188,12 @@ def get_bitfield_width(self): """ return conf.lib.clang_getFieldDeclBitWidth(self) # type: ignore [no-any-return] + def has_attrs(self) -> bool: + """ + Determine whether the given cursor has any attributes. + """ + return bool(conf.lib.clang_Cursor_hasAttrs(self)) + @staticmethod def from_result(res, arg): assert isinstance(res, Cursor) @@ -3932,6 +3948,7 @@ def set_property(self, property, value): ("clang_getCursorType", [Cursor], Type), ("clang_getCursorUSR", [Cursor], _CXString), ("clang_Cursor_getMangling", [Cursor], _CXString), + ("clang_Cursor_hasAttrs", [Cursor], c_uint), # ("clang_getCXTUResourceUsage", # [TranslationUnit], # CXTUResourceUsage), diff --git a/clang/bindings/python/tests/cindex/test_cursor.py b/clang/bindings/python/tests/cindex/test_cursor.py index c6aa65ce3c29f..9947f551cc2f8 100644 --- a/clang/bindings/python/tests/cindex/test_cursor.py +++ b/clang/bindings/python/tests/cindex/test_cursor.py @@ -4,6 +4,7 @@ AvailabilityKind, BinaryOperator, Config, + Cursor, CursorKind, PrintingPolicy, PrintingPolicyProperty, @@ -995,3 +996,42 @@ def test_pretty_print(self): pp.set_property(PrintingPolicyProperty.Bool, False) self.assertEqual(pp.get_property(PrintingPolicyProperty.Bool), False) self.assertEqual(f.pretty_printed(pp), "void f(_Bool x) {\n}\n") + + def test_has_attrs(self): + tu = get_tu( + """ +struct A; +struct A final {}; + +struct B; +struct B {}; +""", + lang="cpp", + ) + A = get_cursor(tu, "A") + B = get_cursor(tu, "B") + self.assertTrue(A.get_definition().has_attrs()) + self.assertFalse(B.get_definition().has_attrs()) + + def test_hash(self): + def accumulate_cursors(cursor: Cursor, all_cursors: list[Cursor]): + all_cursors.append(cursor) + for child in cursor.get_children(): + all_cursors = accumulate_cursors(child, all_cursors) + return all_cursors + + tu = get_tu(kInput) + all_cursors = accumulate_cursors(tu.cursor, []) + cursor_hashes = set() + for cursor in all_cursors: + self.assertNotIn(hash(cursor), cursor_hashes) + cursor_hashes.add(hash(cursor)) + + def test_specialized_template(self): + tu = get_tu(kTemplateArgTest, lang="cpp") + foos = get_cursors(tu, "foo") + prime_foo = foos[1].specialized_template + + self.assertNotEqual(foos[0], foos[1]) + self.assertEqual(foos[0], prime_foo) + self.assertIsNone(tu.cursor.specialized_template) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index a25808e36bd51..ab68be3702840 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -442,6 +442,12 @@ Sanitizers Python Binding Changes ---------------------- +- Made ``Cursor`` hashable. +- Added ``Cursor.has_attrs``, a binding for ``clang_Cursor_hasAttrs``, to check + whether a cursor has any attributes. +- Added ``Cursor.specialized_template``, a binding for + ``clang_getSpecializedCursorTemplate``, to retrieve the primary template that + the cursor is a specialization of. - Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which allows visiting the methods of a class. >From 1160d18e60f92dfe0f05493150849af1bc5b8d48 Mon Sep 17 00:00:00 2001 From: Jannick Kremer <jannick.kre...@mailbox.org> Date: Fri, 21 Mar 2025 20:53:33 +0900 Subject: [PATCH 2/3] Reorder new tests --- .../python/tests/cindex/test_cursor.py | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/clang/bindings/python/tests/cindex/test_cursor.py b/clang/bindings/python/tests/cindex/test_cursor.py index 9947f551cc2f8..7b791380526e6 100644 --- a/clang/bindings/python/tests/cindex/test_cursor.py +++ b/clang/bindings/python/tests/cindex/test_cursor.py @@ -997,6 +997,20 @@ def test_pretty_print(self): self.assertEqual(pp.get_property(PrintingPolicyProperty.Bool), False) self.assertEqual(f.pretty_printed(pp), "void f(_Bool x) {\n}\n") + def test_hash(self): + def accumulate_cursors(cursor: Cursor, all_cursors: list[Cursor]): + all_cursors.append(cursor) + for child in cursor.get_children(): + all_cursors = accumulate_cursors(child, all_cursors) + return all_cursors + + tu = get_tu(kInput) + all_cursors = accumulate_cursors(tu.cursor, []) + cursor_hashes = set() + for cursor in all_cursors: + self.assertNotIn(hash(cursor), cursor_hashes) + cursor_hashes.add(hash(cursor)) + def test_has_attrs(self): tu = get_tu( """ @@ -1013,20 +1027,6 @@ def test_has_attrs(self): self.assertTrue(A.get_definition().has_attrs()) self.assertFalse(B.get_definition().has_attrs()) - def test_hash(self): - def accumulate_cursors(cursor: Cursor, all_cursors: list[Cursor]): - all_cursors.append(cursor) - for child in cursor.get_children(): - all_cursors = accumulate_cursors(child, all_cursors) - return all_cursors - - tu = get_tu(kInput) - all_cursors = accumulate_cursors(tu.cursor, []) - cursor_hashes = set() - for cursor in all_cursors: - self.assertNotIn(hash(cursor), cursor_hashes) - cursor_hashes.add(hash(cursor)) - def test_specialized_template(self): tu = get_tu(kTemplateArgTest, lang="cpp") foos = get_cursors(tu, "foo") >From 22edb94303a7358425906ca577d7f65e19cef072 Mon Sep 17 00:00:00 2001 From: Jannick Kremer <jannick.kre...@mailbox.org> Date: Sat, 22 Mar 2025 18:34:03 +0900 Subject: [PATCH 3/3] Fix formatting Adapt global variable names --- clang/bindings/python/tests/cindex/test_cursor.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/bindings/python/tests/cindex/test_cursor.py b/clang/bindings/python/tests/cindex/test_cursor.py index df363c392b097..db3c408439eb5 100644 --- a/clang/bindings/python/tests/cindex/test_cursor.py +++ b/clang/bindings/python/tests/cindex/test_cursor.py @@ -998,13 +998,14 @@ def test_pretty_print(self): self.assertEqual(f.pretty_printed(pp), "void f(_Bool x) {\n}\n") def test_hash(self): - def accumulate_cursors(cursor: Cursor, all_cursors: list[Cursor]): + + def accumulate_cursors(cursor: Cursor, all_cursors: list): all_cursors.append(cursor) for child in cursor.get_children(): all_cursors = accumulate_cursors(child, all_cursors) return all_cursors - tu = get_tu(kInput) + tu = get_tu(children_test) all_cursors = accumulate_cursors(tu.cursor, []) cursor_hashes = set() for cursor in all_cursors: @@ -1028,7 +1029,7 @@ def test_has_attrs(self): self.assertFalse(B.get_definition().has_attrs()) def test_specialized_template(self): - tu = get_tu(kTemplateArgTest, lang="cpp") + tu = get_tu(template_arg_test, lang="cpp") foos = get_cursors(tu, "foo") prime_foo = foos[1].specialized_template _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits