summaryrefslogtreecommitdiff
path: root/clang/bindings
diff options
context:
space:
mode:
authorLuca Di Sera <disera.luca@gmail.com>2022-11-14 15:17:22 +0100
committerLuca Di Sera <disera.luca@gmail.com>2022-11-14 15:21:36 +0100
commit5c67cf0a7fdc00c9b9c55578b770e768f5618bed (patch)
tree1c2e01bb61e88c8fdee0ca303017ee3354e4b3e1 /clang/bindings
parent47eddbbf33fe3b020e1fc4ef272461b8533238f8 (diff)
downloadllvm-5c67cf0a7fdc00c9b9c55578b770e768f5618bed.tar.gz
Add clang_CXXMethod_isMoveAssignmentOperator to libclang
The new method is a wrapper of `CXXMethodDecl::isMoveAssignmentOperator` and can be used to recognized move-assignment operators in libclang. An export for the function, together with its documentation, was added to "clang/include/clang-c/Index.h" with an implementation provided in "clang/tools/libclang/CIndex.cpp". The implementation was based on similar `clang_CXXMethod.*` implementations, following the same structure but calling `CXXMethodDecl::isMoveAssignmentOperator` for its main logic. The new symbol was further added to "clang/tools/libclang/libclang.map" to be exported, under the LLVM16 tag. "clang/tools/c-index-test/c-index-test.c" was modified to print a specific tag, "(move-assignment operator)", for cursors that are recognized by `clang_CXXMethod_isMoveAssignmentOperator`. A new regression test file, "clang/test/Index/move-assignment-operator.cpp", was added to ensure whether the correct constructs were recognized or not by the new function. The "clang/test/Index/get-cursor.cpp" regression test file was updated as it was affected by the new "(move-assignment operator)" tag. A binding for the new function was added to libclang's python's bindings, in "clang/bindings/python/clang/cindex.py", adding a new method for `Cursor`, `is_move_assignment_operator_method`. An accompanying test was added to `clang/bindings/python/tests/cindex/test_cursor.py`, testing the new function with the same methodology as the corresponding libclang test. The current release note, `clang/docs/ReleaseNotes.rst`, was modified to report the new addition under the "libclang" section. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D137246
Diffstat (limited to 'clang/bindings')
-rw-r--r--clang/bindings/python/clang/cindex.py29
-rw-r--r--clang/bindings/python/tests/cindex/test_cursor.py58
2 files changed, 87 insertions, 0 deletions
diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index 99dcbb341dfe..2e32ce2ba6d0 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -1504,6 +1504,31 @@ class Cursor(Structure):
"""
return conf.lib.clang_CXXMethod_isCopyAssignmentOperator(self)
+ def is_move_assignment_operator_method(self):
+ """Returnrs True if the cursor refers to a move-assignment operator.
+
+ A move-assignment operator `X::operator=` is a non-static,
+ non-template member function of _class_ `X` with exactly one
+ parameter of type `X&&`, `const X&&`, `volatile X&&` or `const
+ volatile X&&`.
+
+
+ That is, for example, the `operator=` in:
+
+ class Foo {
+ bool operator=(const volatile Foo&&);
+ };
+
+ Is a move-assignment operator, while the `operator=` in:
+
+ class Bar {
+ bool operator=(const int&&);
+ };
+
+ Is not.
+ """
+ return conf.lib.clang_CXXMethod_isMoveAssignmentOperator(self)
+
def is_mutable_field(self):
"""Returns True if the cursor refers to a C++ field that is declared
'mutable'.
@@ -3465,6 +3490,10 @@ functionList = [
[Cursor],
bool),
+ ("clang_CXXMethod_isMoveAssignmentOperator",
+ [Cursor],
+ bool),
+
("clang_CXXMethod_isPureVirtual",
[Cursor],
bool),
diff --git a/clang/bindings/python/tests/cindex/test_cursor.py b/clang/bindings/python/tests/cindex/test_cursor.py
index ef875e972474..198352080c69 100644
--- a/clang/bindings/python/tests/cindex/test_cursor.py
+++ b/clang/bindings/python/tests/cindex/test_cursor.py
@@ -219,6 +219,64 @@ class TestCursor(unittest.TestCase):
self.assertTrue(xc.is_default_method())
self.assertFalse(yc.is_default_method())
+ def test_is_move_assignment_operator_method(self):
+ """Ensure Cursor.is_move_assignment_operator_method works."""
+ source_with_move_assignment_operators = """
+ struct Foo {
+ // Those are move-assignment operators
+ bool operator=(const Foo&&);
+ bool operator=(Foo&&);
+ bool operator=(volatile Foo&&);
+ bool operator=(const volatile Foo&&);
+
+ // Positive-check that the recognition works for templated classes too
+ template <typename T>
+ class Bar {
+ bool operator=(const Bar&&);
+ bool operator=(Bar<T>&&);
+ bool operator=(volatile Bar&&);
+ bool operator=(const volatile Bar<T>&&);
+ };
+ """
+ source_without_move_assignment_operators = """
+ struct Foo {
+ // Those are not move-assignment operators
+ template<typename T>
+ bool operator=(const T&&);
+ bool operator=(const bool&&);
+ bool operator=(char&&);
+ bool operator=(volatile unsigned int&&);
+ bool operator=(const volatile unsigned char&&);
+ bool operator=(int);
+ bool operator=(Foo);
+ };
+ """
+ tu_with_move_assignment_operators = get_tu(
+ source_with_move_assignment_operators, lang="cpp"
+ )
+ tu_without_move_assignment_operators = get_tu(
+ source_without_move_assignment_operators, lang="cpp"
+ )
+
+ move_assignment_operators_cursors = get_cursors(
+ tu_with_move_assignment_operators, "operator="
+ )
+ non_move_assignment_operators_cursors = get_cursors(
+ tu_without_move_assignment_operators, "operator="
+ )
+
+ self.assertEqual(len(move_assignment_operators_cursors), 8)
+ self.assertTrue(len(non_move_assignment_operators_cursors), 7)
+
+ self.assertTrue(all([
+ cursor.is_move_assignment_operator_method()
+ for cursor in move_assignment_operators_cursors
+ ]))
+ self.assertFalse(any([
+ cursor.is_move_assignment_operator_method()
+ for cursor in non_move_assignment_operators_cursors
+ ]))
+
def test_is_mutable_field(self):
"""Ensure Cursor.is_mutable_field works."""
source = 'class X { int x_; mutable int y_; };'