diff options
author | Luca Di Sera <disera.luca@gmail.com> | 2022-11-14 15:17:22 +0100 |
---|---|---|
committer | Luca Di Sera <disera.luca@gmail.com> | 2022-11-14 15:21:36 +0100 |
commit | 5c67cf0a7fdc00c9b9c55578b770e768f5618bed (patch) | |
tree | 1c2e01bb61e88c8fdee0ca303017ee3354e4b3e1 /clang/bindings | |
parent | 47eddbbf33fe3b020e1fc4ef272461b8533238f8 (diff) | |
download | llvm-5c67cf0a7fdc00c9b9c55578b770e768f5618bed.zip llvm-5c67cf0a7fdc00c9b9c55578b770e768f5618bed.tar.gz llvm-5c67cf0a7fdc00c9b9c55578b770e768f5618bed.tar.bz2 |
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.py | 29 | ||||
-rw-r--r-- | clang/bindings/python/tests/cindex/test_cursor.py | 58 |
2 files changed, 87 insertions, 0 deletions
diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index 99dcbb3..2e32ce2 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 ef875e9..1983520 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_; };' |