[Lldb-commits] [lldb] [lldb][test] Add a new __compressed_pair layout to libcxx simulator tests (PR #99012)

Michael Buch via lldb-commits lldb-commits at lists.llvm.org
Mon Sep 16 04:56:33 PDT 2024


https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/99012

>From 8d0245dfccc607a4237fc94bbbfea646fa1a6887 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/5] [WIP][lldb][test] Add a new __compressed_pair layout to
 libcxx simulator tests

---
 .../compressed_pair.h                         | 34 ++++++++++++++++++-
 .../TestDataFormatterLibcxxStringSimulator.py | 19 ++++++-----
 .../libcxx-simulators/string/main.cpp         | 33 +++++++++++-------
 ...stDataFormatterLibcxxUniquePtrSimulator.py | 14 ++++++--
 .../libcxx-simulators/unique_ptr/main.cpp     |  5 +++
 5 files changed, 81 insertions(+), 24 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h b/lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h
index 026e7183ab27a0..f2c1b626bd46f7 100644
--- a/lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h
+++ b/lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h
@@ -7,7 +7,7 @@
 namespace std {
 namespace __lldb {
 
-// Post-c88580c layout
+#if COMPRESSED_PAIR_REV == 0 // Post-c88580c layout
 struct __value_init_tag {};
 struct __default_init_tag {};
 
@@ -52,6 +52,38 @@ 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> __padding1_;             \
+  [[no_unique_address]] T2 Initializer2;                                       \
+  [[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> __padding1_;             \
+  [[no_unique_address]] T2 Initializer2;                                       \
+  [[no_unique_address]] __compressed_pair_padding<T2> __padding2_;             \
+  [[no_unique_address]] T3 Initializer3;                                       \
+  [[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;                                              \
+  [[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
 
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/TestDataFormatterLibcxxStringSimulator.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/TestDataFormatterLibcxxStringSimulator.py
index 98d2c7320003e4..afe6374e55a355 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/TestDataFormatterLibcxxStringSimulator.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/TestDataFormatterLibcxxStringSimulator.py
@@ -28,12 +28,13 @@ def _run_test(self, defines):
 
 for v in [None, "ALTERNATE_LAYOUT"]:
     for r in range(5):
-        name = "test_r%d" % r
-        defines = ["REVISION=%d" % r]
-        if v:
-            name += "_" + v
-            defines += [v]
-        f = functools.partialmethod(
-            LibcxxStringDataFormatterSimulatorTestCase._run_test, defines
-        )
-        setattr(LibcxxStringDataFormatterSimulatorTestCase, name, f)
+        for c in range(3):
+            name = "test_r%d_c%d" % (r, c)
+            defines = ["REVISION=%d" % r, "COMPRESSED_PAIR_REV=%d" % c]
+            if v:
+                name += "_" + v
+                defines += [v]
+            f = functools.partialmethod(
+                LibcxxStringDataFormatterSimulatorTestCase._run_test, defines
+            )
+            setattr(LibcxxStringDataFormatterSimulatorTestCase, name, f)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp
index b010dc25f8f804..b19443136fbb2e 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp
@@ -184,31 +184,40 @@ template <class _CharT, class _Traits, class _Allocator> class basic_string {
     };
   };
 
+#if COMPRESSED_PAIR_REV == 0
   std::__lldb::__compressed_pair<__rep, allocator_type> __r_;
+#define __R_ __r_
+#define __R_L __r_.first().__l
+#define __R_S __r_.first().__s
+#elif COMPRESSED_PAIR_REV <= 2
+  _LLDB_COMPRESSED_PAIR(__rep, __rep_, allocator_type, __alloc_);
+#define __R_ __rep_
+#define __R_L __rep_.__l
+#define __R_S __rep_.__s
+#endif
 
 public:
   template <size_t __N>
-  basic_string(unsigned char __size, const value_type (&__data)[__N])
-      : __r_({}, {}) {
+  basic_string(unsigned char __size, const value_type (&__data)[__N]) {
     static_assert(__N < __min_cap, "");
 #ifdef BITMASKS
-    __r_.first().__s.__size_ = __size << __short_shift;
+    __R_S.__size_ = __size << __short_shift;
 #else
-    __r_.first().__s.__size_ = __size;
-    __r_.first().__s.__is_long_ = false;
+    __R_S.__size_ = __size;
+    __R_S.__is_long_ = false;
 #endif
     for (size_t __i = 0; __i < __N; ++__i)
-      __r_.first().__s.__data_[__i] = __data[__i];
+      __R_S.__data_[__i] = __data[__i];
   }
-  basic_string(size_t __cap, size_type __size, pointer __data) : __r_({}, {}) {
+  basic_string(size_t __cap, size_type __size, pointer __data) {
 #ifdef BITMASKS
-    __r_.first().__l.__cap_ = __cap | __long_mask;
+    __R_L.__cap_ = __cap | __long_mask;
 #else
-    __r_.first().__l.__cap_ = __cap / __endian_factor;
-    __r_.first().__l.__is_long_ = true;
+    __R_L.__cap_ = __cap / __endian_factor;
+    __R_L.__is_long_ = true;
 #endif
-    __r_.first().__l.__size_ = __size;
-    __r_.first().__l.__data_ = __data;
+    __R_L.__size_ = __size;
+    __R_L.__data_ = __data;
   }
 };
 
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 da780f54bfd374..116400c4fd36a5 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
@@ -7,13 +7,15 @@
 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 test(self):
-        self.build()
+    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")
         )
@@ -22,3 +24,11 @@ def test(self):
         self.expect(
             "frame variable var_with_deleter_up", substrs=["pointer =", "deleter ="]
         )
+
+for r in range(3):
+    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
index a6bfaa3febebb9..91a019566affbc 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
@@ -16,9 +16,14 @@ template <class _Tp, class _Dp = default_delete<_Tp>> class unique_ptr {
   typedef _Dp deleter_type;
   typedef _Tp *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

>From 1a87168ed39b0286e8b39cdde1c2a9124a97c245 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Tue, 16 Jul 2024 13:00:40 +0100
Subject: [PATCH 2/5] fixup! use getters for string internals

---
 .../libcxx-simulators/string/main.cpp         | 40 ++++++++++++-------
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp
index b19443136fbb2e..89bcc75dc21868 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp
@@ -184,16 +184,26 @@ template <class _CharT, class _Traits, class _Allocator> class basic_string {
     };
   };
 
+  __long &getLongRep() {
+#if COMPRESSED_PAIR_REV == 0
+    return __r_.first().__l
+#elif COMPRESSED_PAIR_REV <= 2
+    return __rep_.__l;
+#endif
+  }
+
+  __short &getShortRep() {
+#if COMPRESSED_PAIR_REV == 0
+    return __r_.first().__s
+#elif COMPRESSED_PAIR_REV <= 2
+    return __rep_.__s;
+#endif
+  }
+
 #if COMPRESSED_PAIR_REV == 0
   std::__lldb::__compressed_pair<__rep, allocator_type> __r_;
-#define __R_ __r_
-#define __R_L __r_.first().__l
-#define __R_S __r_.first().__s
 #elif COMPRESSED_PAIR_REV <= 2
   _LLDB_COMPRESSED_PAIR(__rep, __rep_, allocator_type, __alloc_);
-#define __R_ __rep_
-#define __R_L __rep_.__l
-#define __R_S __rep_.__s
 #endif
 
 public:
@@ -201,23 +211,23 @@ template <class _CharT, class _Traits, class _Allocator> class basic_string {
   basic_string(unsigned char __size, const value_type (&__data)[__N]) {
     static_assert(__N < __min_cap, "");
 #ifdef BITMASKS
-    __R_S.__size_ = __size << __short_shift;
+    getShortRep().__size_ = __size << __short_shift;
 #else
-    __R_S.__size_ = __size;
-    __R_S.__is_long_ = false;
+    getShortRep().__size_ = __size;
+    getShortRep().__is_long_ = false;
 #endif
     for (size_t __i = 0; __i < __N; ++__i)
-      __R_S.__data_[__i] = __data[__i];
+      getShortRep().__data_[__i] = __data[__i];
   }
   basic_string(size_t __cap, size_type __size, pointer __data) {
 #ifdef BITMASKS
-    __R_L.__cap_ = __cap | __long_mask;
+    getLongRep().__cap_ = __cap | __long_mask;
 #else
-    __R_L.__cap_ = __cap / __endian_factor;
-    __R_L.__is_long_ = true;
+    getLongRep().__cap_ = __cap / __endian_factor;
+    getLongRep().__is_long_ = true;
 #endif
-    __R_L.__size_ = __size;
-    __R_L.__data_ = __data;
+    getLongRep().__size_ = __size;
+    getLongRep().__data_ = __data;
   }
 };
 

>From 8b71129300643276c0e6d5da22a5cf60119027e1 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Tue, 16 Jul 2024 13:14:57 +0100
Subject: [PATCH 3/5] fixup! python format

---
 .../unique_ptr/TestDataFormatterLibcxxUniquePtrSimulator.py      | 1 +
 1 file changed, 1 insertion(+)

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 116400c4fd36a5..0026eca8eebeae 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
@@ -25,6 +25,7 @@ def _run_test(self, defines):
             "frame variable var_with_deleter_up", substrs=["pointer =", "deleter ="]
         )
 
+
 for r in range(3):
     name = "test_r%d" % r
     defines = ["COMPRESSED_PAIR_REV=%d" % r]

>From d4af03ec48ec85ac54c43a5fd56b61729b23957a Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Sun, 28 Jul 2024 14:03:38 +0100
Subject: [PATCH 4/5] fixup! fix string test compilation

---
 .../data-formatter-stl/libcxx-simulators/string/main.cpp      | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp
index 89bcc75dc21868..f8fc13c10c4372 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp
@@ -186,7 +186,7 @@ template <class _CharT, class _Traits, class _Allocator> class basic_string {
 
   __long &getLongRep() {
 #if COMPRESSED_PAIR_REV == 0
-    return __r_.first().__l
+    return __r_.first().__l;
 #elif COMPRESSED_PAIR_REV <= 2
     return __rep_.__l;
 #endif
@@ -194,7 +194,7 @@ template <class _CharT, class _Traits, class _Allocator> class basic_string {
 
   __short &getShortRep() {
 #if COMPRESSED_PAIR_REV == 0
-    return __r_.first().__s
+    return __r_.first().__s;
 #elif COMPRESSED_PAIR_REV <= 2
     return __rep_.__s;
 #endif

>From 0537cd1dcb96c59f2898b03e11dca9848cf94856 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 16 Sep 2024 12:56:15 +0100
Subject: [PATCH 5/5] fixup! don't include libc++ internals (Linux CI doesn't
 build against libc++)

---
 .../compressed_pair.h                         | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h b/lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h
index f2c1b626bd46f7..89eafcec0ea962 100644
--- a/lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h
+++ b/lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h
@@ -53,10 +53,25 @@ class __compressed_pair : private __compressed_pair_elem<_T1, 0>,
   _T1 &first() { return static_cast<_Base1 &>(*this).__get(); }
 };
 #elif COMPRESSED_PAIR_REV == 1
+// From libc++ datasizeof.h
+template <class _Tp> struct _FirstPaddingByte {
+  [[no_unique_address]] _Tp __v_;
+  char __first_padding_byte_;
+};
+
+template <class _Tp>
+inline const size_t __datasizeof_v =
+    __builtin_offsetof(_FirstPaddingByte<_Tp>, __first_padding_byte_);
+
+template <class _Tp>
+struct __lldb_is_final : public integral_constant<bool, __is_final(_Tp)> {};
+
 template <class _ToPad> class __compressed_pair_padding {
-  char __padding_[(is_empty<_ToPad>::value && !__libcpp_is_final<_ToPad>::value)
+  char __padding_[((is_empty<_ToPad>::value &&
+                    !__lldb_is_final<_ToPad>::value) ||
+                   is_reference<_ToPad>::value)
                       ? 0
-                      : sizeof(_ToPad) - __datasizeof(_ToPad)];
+                      : sizeof(_ToPad) - __datasizeof_v<_ToPad>];
 };
 
 #define _LLDB_COMPRESSED_PAIR(T1, Initializer1, T2, Initializer2)              \



More information about the lldb-commits mailing list