[Lldb-commits] [lldb] [WIP][lldb][test] Add a layout simulator test for std::unique_ptr (PR #98330)

Michael Buch via lldb-commits lldb-commits at lists.llvm.org
Thu Jul 11 08:58:43 PDT 2024


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 <michaelbuch12 at gmail.com>
Date: Wed, 10 Jul 2024 15:37:45 +0100
Subject: [PATCH 1/3] [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 <michaelbuch12 at gmail.com>
Date: Wed, 10 Jul 2024 17:07:42 +0100
Subject: [PATCH 2/3] 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(

>From 1575ca227d3e55ca7fab54a769bad8efc39d5ff2 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Thu, 11 Jul 2024 16:57:39 +0100
Subject: [PATCH 3/3] fixup! remove dependency on internal libc++ headers; move
 common header

---
 .../compressed_pair.h                         | 22 +++++++++----------
 ...stDataFormatterLibcxxUniquePtrSimulator.py |  3 +--
 .../libcxx-simulators/unique_ptr/main.cpp     |  6 ++---
 3 files changed, 14 insertions(+), 17 deletions(-)
 rename lldb/{test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators => packages/Python/lldbsuite/test/make/libcxx-simulators-common}/compressed_pair.h (79%)

diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/compressed_pair.h b/lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h
similarity index 79%
rename from lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/compressed_pair.h
rename to lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h
index ec978b8053646..858ef3c4500db 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/compressed_pair.h
+++ b/lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h
@@ -1,7 +1,6 @@
 #ifndef STD_LLDB_COMPRESSED_PAIR_H
 #define STD_LLDB_COMPRESSED_PAIR_H
 
-#include <__memory/compressed_pair.h>
 #include <type_traits>
 
 namespace std {
@@ -53,26 +52,27 @@ class __compressed_pair : private __compressed_pair_elem<_T1, 0>,
   _T1 &first() { return static_cast<_Base1 &>(*this).__get(); }
 };
 #elif COMPRESSED_PAIR_REV == 1
+template <class _ToPad> class __compressed_pair_padding {
+  char __padding_[(is_empty<_ToPad>::value && !__libcpp_is_final<_ToPad>::value)
+                      ? 0
+                      : sizeof(_ToPad) - __datasizeof(_ToPad)];
+};
+
 #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]] __compressed_pair_padding<T1> __padding1_;             \
   [[no_unique_address]] T2 Initializer2;                                       \
-  [[no_unique_address]] __compressed_pair_padding<T2> _LIBCPP_CONCAT3(         \
-      __padding2_, __LINE__, _)
+  [[no_unique_address]] __compressed_pair_padding<T2> __padding2_;
 
 #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]] __compressed_pair_padding<T1> __padding1_;             \
   [[no_unique_address]] T2 Initializer2;                                       \
-  [[no_unique_address]] __compressed_pair_padding<T2> _LIBCPP_CONCAT3(         \
-      __padding2_, __LINE__, _);                                               \
+  [[no_unique_address]] __compressed_pair_padding<T2> __padding2_;             \
   [[no_unique_address]] T3 Initializer3;                                       \
-  [[no_unique_address]] __compressed_pair_padding<T3> _LIBCPP_CONCAT3(         \
-      __padding3_, __LINE__, _)
+  [[no_unique_address]] __compressed_pair_padding<T3> __padding3_;
 #elif COMPRESSED_PAIR_REV == 2
 #define _LLDB_COMPRESSED_PAIR(T1, Name1, T2, Name2)                            \
   [[no_unique_address]] T1 Name1;                                              \
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 e63de67dfb759..b870afaa67467 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
@@ -26,8 +26,7 @@ def _run_test(self, defines):
         )
 
 
-# for r in range(3):
-for r in [0, 2]:
+for r in range(3):
     name = "test_r%d" % r
     defines = ["COMPRESSED_PAIR_REV=%d" % r]
     f = functools.partialmethod(
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
index 33066febc7623..9c47c2914de6a 100644
--- 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
@@ -1,6 +1,4 @@
-#include "../compressed_pair.h"
-
-#include <__memory/allocator_traits.h>
+#include <libcxx-simulators-common/compressed_pair.h>
 
 namespace std {
 namespace __lldb {
@@ -14,7 +12,7 @@ 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;
+  typedef _Tp *pointer;
 
 #if COMPRESSED_PAIR_REV == 0
   std::__lldb::__compressed_pair<pointer, deleter_type> __ptr_;



More information about the lldb-commits mailing list