https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/98330
>From a25b3c8a6a36326730d00d1060ff84181bece26e Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Wed, 10 Jul 2024 15:37:45 +0100 Subject: [PATCH 1/2] [WIP][lldb][test] Add a layout simulator test for std::unique_ptr --- .../libcxx-simulators/compressed_pair.h | 89 +++++++++++++++++++ .../libcxx-simulators/unique_ptr/Makefile | 3 + ...stDataFormatterLibcxxUniquePtrSimulator.py | 32 +++++++ .../libcxx-simulators/unique_ptr/main.cpp | 43 +++++++++ 4 files changed, 167 insertions(+) create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/compressed_pair.h create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/Makefile create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/TestDataFormatterLibcxxUniquePtrSimulator.py create mode 100644 lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/main.cpp diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/compressed_pair.h b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/compressed_pair.h new file mode 100644 index 0000000000000..ec978b8053646 --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/compressed_pair.h @@ -0,0 +1,89 @@ +#ifndef STD_LLDB_COMPRESSED_PAIR_H +#define STD_LLDB_COMPRESSED_PAIR_H + +#include <__memory/compressed_pair.h> +#include <type_traits> + +namespace std { +namespace __lldb { + +#if COMPRESSED_PAIR_REV == 0 // Post-c88580c layout +struct __value_init_tag {}; +struct __default_init_tag {}; + +template <class _Tp, int _Idx, + bool _CanBeEmptyBase = + std::is_empty<_Tp>::value && !std::is_final<_Tp>::value> +struct __compressed_pair_elem { + explicit __compressed_pair_elem(__default_init_tag) {} + explicit __compressed_pair_elem(__value_init_tag) : __value_() {} + + explicit __compressed_pair_elem(_Tp __t) : __value_(__t) {} + + _Tp &__get() { return __value_; } + +private: + _Tp __value_; +}; + +template <class _Tp, int _Idx> +struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp { + explicit __compressed_pair_elem(_Tp __t) : _Tp(__t) {} + explicit __compressed_pair_elem(__default_init_tag) {} + explicit __compressed_pair_elem(__value_init_tag) : _Tp() {} + + _Tp &__get() { return *this; } +}; + +template <class _T1, class _T2> +class __compressed_pair : private __compressed_pair_elem<_T1, 0>, + private __compressed_pair_elem<_T2, 1> { +public: + using _Base1 = __compressed_pair_elem<_T1, 0>; + using _Base2 = __compressed_pair_elem<_T2, 1>; + + explicit __compressed_pair(_T1 __t1, _T2 __t2) : _Base1(__t1), _Base2(__t2) {} + explicit __compressed_pair() + : _Base1(__value_init_tag()), _Base2(__value_init_tag()) {} + + template <class _U1, class _U2> + explicit __compressed_pair(_U1 &&__t1, _U2 &&__t2) + : _Base1(std::forward<_U1>(__t1)), _Base2(std::forward<_U2>(__t2)) {} + + _T1 &first() { return static_cast<_Base1 &>(*this).__get(); } +}; +#elif COMPRESSED_PAIR_REV == 1 +#define _LLDB_COMPRESSED_PAIR(T1, Initializer1, T2, Initializer2) \ + [[__gnu__::__aligned__(alignof(T2))]] [[no_unique_address]] T1 Initializer1; \ + [[no_unique_address]] __compressed_pair_padding<T1> _LIBCPP_CONCAT3( \ + __padding1_, __LINE__, _); \ + [[no_unique_address]] T2 Initializer2; \ + [[no_unique_address]] __compressed_pair_padding<T2> _LIBCPP_CONCAT3( \ + __padding2_, __LINE__, _) + +#define _LLDB_COMPRESSED_TRIPLE(T1, Initializer1, T2, Initializer2, T3, \ + Initializer3) \ + [[using __gnu__: __aligned__(alignof(T2)), \ + __aligned__(alignof(T3))]] [[no_unique_address]] T1 Initializer1; \ + [[no_unique_address]] __compressed_pair_padding<T1> _LIBCPP_CONCAT3( \ + __padding1_, __LINE__, _); \ + [[no_unique_address]] T2 Initializer2; \ + [[no_unique_address]] __compressed_pair_padding<T2> _LIBCPP_CONCAT3( \ + __padding2_, __LINE__, _); \ + [[no_unique_address]] T3 Initializer3; \ + [[no_unique_address]] __compressed_pair_padding<T3> _LIBCPP_CONCAT3( \ + __padding3_, __LINE__, _) +#elif COMPRESSED_PAIR_REV == 2 +#define _LLDB_COMPRESSED_PAIR(T1, Name1, T2, Name2) \ + [[no_unique_address]] T1 Name1; \ + [[no_unique_address]] T2 Name2 + +#define _LLDB_COMPRESSED_TRIPLE(T1, Name1, T2, Name2, T3, Name3) \ + [[no_unique_address]] T1 Name1; \ + [[no_unique_address]] T2 Name2; \ + [[no_unique_address]] T3 Name3 +#endif +} // namespace __lldb +} // namespace std + +#endif // _H diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/Makefile new file mode 100644 index 0000000000000..38cfa81053488 --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp +override CXXFLAGS_EXTRAS += -std=c++14 +include Makefile.rules diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/TestDataFormatterLibcxxUniquePtrSimulator.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/TestDataFormatterLibcxxUniquePtrSimulator.py new file mode 100644 index 0000000000000..fe3570ff99ae5 --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/TestDataFormatterLibcxxUniquePtrSimulator.py @@ -0,0 +1,32 @@ +""" +Test we can understand various layouts of the libc++'s std::unique_ptr +""" + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import functools + +class LibcxxUniquePtrDataFormatterSimulatorTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + def _run_test(self, defines): + cxxflags_extras = " ".join(["-D%s" % d for d in defines]) + self.build(dictionary=dict(CXXFLAGS_EXTRAS=cxxflags_extras)) + lldbutil.run_to_source_breakpoint( + self, "// Break here", lldb.SBFileSpec("main.cpp") + ) + self.expect("frame variable var_up", substrs=["pointer ="]) + self.expect("frame variable var_up", substrs=["deleter ="], matching=False) + self.expect("frame variable var_with_deleter_up", substrs=["pointer =", "deleter ="]) + +#for r in range(3): +for r in range(1): + name = "test_r%d" % r + defines = ["COMPRESSED_PAIR_REV=%d" % r] + f = functools.partialmethod( + LibcxxUniquePtrDataFormatterSimulatorTestCase._run_test, defines + ) + setattr(LibcxxUniquePtrDataFormatterSimulatorTestCase, name, f) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/main.cpp new file mode 100644 index 0000000000000..33066febc7623 --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/main.cpp @@ -0,0 +1,43 @@ +#include "../compressed_pair.h" + +#include <__memory/allocator_traits.h> + +namespace std { +namespace __lldb { +template <class _Tp> struct default_delete { + default_delete() noexcept = default; + + void operator()(_Tp *__ptr) const noexcept { delete __ptr; } +}; + +template <class _Tp, class _Dp = default_delete<_Tp>> class unique_ptr { +public: + typedef _Tp element_type; + typedef _Dp deleter_type; + typedef typename __pointer<_Tp, deleter_type>::type pointer; + +#if COMPRESSED_PAIR_REV == 0 + std::__lldb::__compressed_pair<pointer, deleter_type> __ptr_; + explicit unique_ptr(pointer __p) noexcept + : __ptr_(__p, std::__lldb::__value_init_tag()) {} +#elif COMPRESSED_PAIR_REV == 1 || COMPRESSED_PAIR_REV == 2 + _LLDB_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_); + explicit unique_ptr(pointer __p) noexcept : __ptr_(__p), __deleter_() {} +#endif +}; +} // namespace __lldb +} // namespace std + +struct StatefulDeleter { + StatefulDeleter() noexcept = default; + + void operator()(int *__ptr) const noexcept { delete __ptr; } + + int m_state = 50; +}; + +int main() { + std::__lldb::unique_ptr<int> var_up(new int(5)); + std::__lldb::unique_ptr<int, StatefulDeleter> var_with_deleter_up(new int(5)); + return 0; // Break here +} >From b25d2ab0ec693fd41e7cbfeafe973e686343eb7a Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Wed, 10 Jul 2024 17:07:42 +0100 Subject: [PATCH 2/2] fixup! format python file --- .../TestDataFormatterLibcxxUniquePtrSimulator.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/TestDataFormatterLibcxxUniquePtrSimulator.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/TestDataFormatterLibcxxUniquePtrSimulator.py index fe3570ff99ae5..e63de67dfb759 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/TestDataFormatterLibcxxUniquePtrSimulator.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/unique_ptr/TestDataFormatterLibcxxUniquePtrSimulator.py @@ -9,6 +9,7 @@ from lldbsuite.test import lldbutil import functools + class LibcxxUniquePtrDataFormatterSimulatorTestCase(TestBase): NO_DEBUG_INFO_TESTCASE = True @@ -20,10 +21,13 @@ def _run_test(self, defines): ) self.expect("frame variable var_up", substrs=["pointer ="]) self.expect("frame variable var_up", substrs=["deleter ="], matching=False) - self.expect("frame variable var_with_deleter_up", substrs=["pointer =", "deleter ="]) + self.expect( + "frame variable var_with_deleter_up", substrs=["pointer =", "deleter ="] + ) + -#for r in range(3): -for r in range(1): +# for r in range(3): +for r in [0, 2]: name = "test_r%d" % r defines = ["COMPRESSED_PAIR_REV=%d" % r] f = functools.partialmethod( _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits