diff options
Diffstat (limited to 'lldb/test/API/lang/cpp')
| -rw-r--r-- | lldb/test/API/lang/cpp/libcxx-internals-recognizer/Makefile (renamed from lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile) | 2 | ||||
| -rw-r--r-- | lldb/test/API/lang/cpp/libcxx-internals-recognizer/TestLibcxxInternalsRecognizer.py | 67 | ||||
| -rw-r--r-- | lldb/test/API/lang/cpp/libcxx-internals-recognizer/main.cpp | 86 | ||||
| -rw-r--r-- | lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py | 44 | ||||
| -rw-r--r-- | lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp | 30 |
5 files changed, 154 insertions, 75 deletions
diff --git a/lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile b/lldb/test/API/lang/cpp/libcxx-internals-recognizer/Makefile index 69014eb9c0f2..bb5712996649 100644 --- a/lldb/test/API/lang/cpp/std-invoke-recognizer/Makefile +++ b/lldb/test/API/lang/cpp/libcxx-internals-recognizer/Makefile @@ -1,5 +1,5 @@ CXX_SOURCES := main.cpp USE_LIBCPP := 1 -CXXFLAGS_EXTRAS := -std=c++17 +CXXFLAGS_EXTRAS := -std=c++20 include Makefile.rules diff --git a/lldb/test/API/lang/cpp/libcxx-internals-recognizer/TestLibcxxInternalsRecognizer.py b/lldb/test/API/lang/cpp/libcxx-internals-recognizer/TestLibcxxInternalsRecognizer.py new file mode 100644 index 000000000000..ad48208f21e5 --- /dev/null +++ b/lldb/test/API/lang/cpp/libcxx-internals-recognizer/TestLibcxxInternalsRecognizer.py @@ -0,0 +1,67 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class LibCxxInternalsRecognizerTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + @add_test_categories(["libc++"]) + def test_frame_recognizer(self): + """Test that implementation details of libc++ are hidden""" + self.build() + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, "break here", lldb.SBFileSpec("main.cpp") + ) + + expected_parents = { + "sort_less(int, int)": ["::sort", "test_algorithms"], + # `std::ranges::sort` is implemented as an object of types `__sort`. + # We never hide the frame of the entry-point into the standard library, even + # if the name starts with `__` which usually indicates an internal function. + "ranges_sort_less(int, int)": [ + "ranges::__sort::operator()", + "test_algorithms", + ], + # `ranges::views::transform` internally uses `std::invoke`, and that + # call also shows up in the stack trace + "view_transform(int)": [ + "::invoke", + "ranges::transform_view", + "test_algorithms", + ], + # Various types of `invoke` calls + "consume_number(int)": ["::invoke", "test_invoke"], + "invoke_add(int, int)": ["::invoke", "test_invoke"], + "Callable::member_function(int) const": ["::invoke", "test_invoke"], + "Callable::operator()(int) const": ["::invoke", "test_invoke"], + # Containers + "MyKey::operator<(MyKey const&) const": [ + "less", + "::emplace", + "test_containers", + ], + } + stop_set = set() + while process.GetState() != lldb.eStateExited: + fn = thread.GetFrameAtIndex(0).GetFunctionName() + stop_set.add(fn) + self.assertIn(fn, expected_parents.keys()) + frame_id = 1 + for expected_parent in expected_parents[fn]: + # Skip all hidden frames + while ( + frame_id < thread.GetNumFrames() + and thread.GetFrameAtIndex(frame_id).IsHidden() + ): + frame_id = frame_id + 1 + # Expect the correct parent frame + self.assertIn( + expected_parent, thread.GetFrameAtIndex(frame_id).GetFunctionName() + ) + frame_id = frame_id + 1 + process.Continue() + + # Make sure that we actually verified all intended scenarios + self.assertEqual(len(stop_set), len(expected_parents)) diff --git a/lldb/test/API/lang/cpp/libcxx-internals-recognizer/main.cpp b/lldb/test/API/lang/cpp/libcxx-internals-recognizer/main.cpp new file mode 100644 index 000000000000..870301b09704 --- /dev/null +++ b/lldb/test/API/lang/cpp/libcxx-internals-recognizer/main.cpp @@ -0,0 +1,86 @@ +#include <algorithm> +#include <functional> +#include <map> +#include <ranges> +#include <vector> + +bool sort_less(int a, int b) { + __builtin_printf("break here"); + return a < b; +} + +bool ranges_sort_less(int a, int b) { + __builtin_printf("break here"); + return a < b; +} + +int view_transform(int a) { + __builtin_printf("break here"); + return a * a; +} + +void test_algorithms() { + std::vector<int> vec{8, 1, 3, 2}; + + // The internal frames for `std::sort` should be hidden + std::sort(vec.begin(), vec.end(), sort_less); + + // The internal frames for `ranges::sort` should be hidden + std::ranges::sort(vec.begin(), vec.end(), ranges_sort_less); + + // Same for views + for (auto x : vec | std::ranges::views::transform(view_transform)) { + // no-op + } +} + +void consume_number(int i) { __builtin_printf("break here"); } + +int invoke_add(int i, int j) { + __builtin_printf("break here"); + return i + j; +} + +struct Callable { + Callable(int num) : num_(num) {} + void operator()(int i) const { __builtin_printf("break here"); } + void member_function(int i) const { __builtin_printf("break here"); } + int num_; +}; + +void test_invoke() { + // Invoke a void-returning function + std::invoke(consume_number, -9); + + // Invoke a non-void-returning function + std::invoke(invoke_add, 1, 10); + + // Invoke a member function + const Callable foo(314159); + std::invoke(&Callable::member_function, foo, 1); + + // Invoke a function object + std::invoke(Callable(12), 18); +} + +struct MyKey { + int x; + bool operator==(const MyKey &) const = default; + bool operator<(const MyKey &other) const { + __builtin_printf("break here"); + return x < other.x; + } +}; + +void test_containers() { + std::map<MyKey, int> map; + map.emplace(MyKey{1}, 2); + map.emplace(MyKey{2}, 3); +} + +int main() { + test_algorithms(); + test_invoke(); + test_containers(); + return 0; +} diff --git a/lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py b/lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py deleted file mode 100644 index dbe29610bf79..000000000000 --- a/lldb/test/API/lang/cpp/std-invoke-recognizer/TestStdInvokeRecognizer.py +++ /dev/null @@ -1,44 +0,0 @@ -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil - - -class LibCxxStdFunctionRecognizerTestCase(TestBase): - NO_DEBUG_INFO_TESTCASE = True - - @add_test_categories(["libc++"]) - def test_frame_recognizer(self): - """Test that implementation details of `std::invoke` are hidden""" - self.build() - (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( - self, "break here", lldb.SBFileSpec("main.cpp") - ) - - stop_cnt = 0 - while process.GetState() != lldb.eStateExited: - stop_cnt += 1 - self.assertTrue( - any( - f in thread.GetFrameAtIndex(0).GetFunctionName() - for f in ["consume_number", "add", "Callable"] - ) - ) - # Skip all hidden frames - frame_id = 1 - while ( - frame_id < thread.GetNumFrames() - and thread.GetFrameAtIndex(frame_id).IsHidden() - ): - frame_id = frame_id + 1 - # Expect `std::invoke` to be the direct parent - self.assertIn( - "::invoke", thread.GetFrameAtIndex(frame_id).GetFunctionName() - ) - # And right above that, there should be the `main` frame - self.assertIn( - "main", thread.GetFrameAtIndex(frame_id + 1).GetFunctionName() - ) - process.Continue() - - self.assertEqual(stop_cnt, 4) diff --git a/lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp b/lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp deleted file mode 100644 index bafbbd28386e..000000000000 --- a/lldb/test/API/lang/cpp/std-invoke-recognizer/main.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include <functional> - -void consume_number(int i) { __builtin_printf("break here"); } - -int add(int i, int j) { - // break here - return i + j; -} - -struct Callable { - Callable(int num) : num_(num) {} - void operator()(int i) const { __builtin_printf("break here"); } - void member_function(int i) const { __builtin_printf("break here"); } - int num_; -}; - -int main() { - // Invoke a void-returning function - std::invoke(consume_number, -9); - - // Invoke a non-void-returning function - std::invoke(add, 1, 10); - - // Invoke a member function - const Callable foo(314159); - std::invoke(&Callable::member_function, foo, 1); - - // Invoke a function object - std::invoke(Callable(12), 18); -} |
