Skip to content

Commit 98b6ce9

Browse files
author
git apple-llvm automerger
committed
Merge commit '84f765b899f6' from swift/release/6.2 into stable/20240723
2 parents 4d4fa8e + 84f765b commit 98b6ce9

File tree

12 files changed

+201
-122
lines changed

12 files changed

+201
-122
lines changed

lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h

Lines changed: 76 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44
#include <type_traits>
55
#include <utility> // for std::forward
66

7+
// COMPRESSED_PAIR_REV versions:
8+
// 0 -> Post-c88580c layout
9+
// 1 -> Post-27c83382d83dc layout
10+
// 2 -> Post-769c42f4a552a layout
11+
// 3 -> Post-f5e687d7bf49c layout
12+
// 4 -> padding-less no_unique_address-based layout (introduced in
13+
// 27c83382d83dc)
14+
715
namespace std {
816
namespace __lldb {
917

@@ -13,7 +21,50 @@ namespace __lldb {
1321
#define _LLDB_NO_UNIQUE_ADDRESS [[__no_unique_address__]]
1422
#endif
1523

16-
#if COMPRESSED_PAIR_REV == 0 // Post-c88580c layout
24+
// From libc++ datasizeof.h
25+
template <class _Tp> struct _FirstPaddingByte {
26+
_LLDB_NO_UNIQUE_ADDRESS _Tp __v_;
27+
char __first_padding_byte_;
28+
};
29+
30+
template <class _Tp>
31+
inline const size_t __datasizeof_v =
32+
__builtin_offsetof(_FirstPaddingByte<_Tp>, __first_padding_byte_);
33+
34+
template <class _Tp>
35+
struct __lldb_is_final : public integral_constant<bool, __is_final(_Tp)> {};
36+
37+
// The legacy layout has been patched, see
38+
// https://github.com/llvm/llvm-project/pull/142516.
39+
#if COMPRESSED_PAIR_REV == 1
40+
template <class _ToPad> class __compressed_pair_padding {
41+
char __padding_[((is_empty<_ToPad>::value &&
42+
!__lldb_is_final<_ToPad>::value) ||
43+
is_reference<_ToPad>::value)
44+
? 0
45+
: sizeof(_ToPad) - __datasizeof_v<_ToPad>];
46+
};
47+
#elif COMPRESSED_PAIR_REV > 1 && COMPRESSED_PAIR_REV < 4
48+
template <class _ToPad>
49+
inline const bool __is_reference_or_unpadded_object =
50+
(std::is_empty<_ToPad>::value && !__lldb_is_final<_ToPad>::value) ||
51+
sizeof(_ToPad) == __datasizeof_v<_ToPad>;
52+
53+
template <class _Tp>
54+
inline const bool __is_reference_or_unpadded_object<_Tp &> = true;
55+
56+
template <class _Tp>
57+
inline const bool __is_reference_or_unpadded_object<_Tp &&> = true;
58+
59+
template <class _ToPad, bool _Empty = __is_reference_or_unpadded_object<_ToPad>>
60+
class __compressed_pair_padding {
61+
char __padding_[sizeof(_ToPad) - __datasizeof_v<_ToPad>] = {};
62+
};
63+
64+
template <class _ToPad> class __compressed_pair_padding<_ToPad, true> {};
65+
#endif // COMPRESSED_PAIR_REV == 1
66+
67+
#if COMPRESSED_PAIR_REV == 0
1768
struct __value_init_tag {};
1869
struct __default_init_tag {};
1970

@@ -58,28 +109,7 @@ class __compressed_pair : private __compressed_pair_elem<_T1, 0>,
58109

59110
_T1 &first() { return static_cast<_Base1 &>(*this).__get(); }
60111
};
61-
#elif COMPRESSED_PAIR_REV == 1
62-
// From libc++ datasizeof.h
63-
template <class _Tp> struct _FirstPaddingByte {
64-
_LLDB_NO_UNIQUE_ADDRESS _Tp __v_;
65-
char __first_padding_byte_;
66-
};
67-
68-
template <class _Tp>
69-
inline const size_t __datasizeof_v =
70-
__builtin_offsetof(_FirstPaddingByte<_Tp>, __first_padding_byte_);
71-
72-
template <class _Tp>
73-
struct __lldb_is_final : public integral_constant<bool, __is_final(_Tp)> {};
74-
75-
template <class _ToPad> class __compressed_pair_padding {
76-
char __padding_[((is_empty<_ToPad>::value &&
77-
!__lldb_is_final<_ToPad>::value) ||
78-
is_reference<_ToPad>::value)
79-
? 0
80-
: sizeof(_ToPad) - __datasizeof_v<_ToPad>];
81-
};
82-
112+
#elif COMPRESSED_PAIR_REV == 1 || COMPRESSED_PAIR_REV == 2
83113
#define _LLDB_COMPRESSED_PAIR(T1, Initializer1, T2, Initializer2) \
84114
[[__gnu__::__aligned__( \
85115
alignof(T2))]] _LLDB_NO_UNIQUE_ADDRESS T1 Initializer1; \
@@ -96,7 +126,28 @@ template <class _ToPad> class __compressed_pair_padding {
96126
_LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T2> __padding2_; \
97127
_LLDB_NO_UNIQUE_ADDRESS T3 Initializer3; \
98128
_LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T3> __padding3_;
99-
#elif COMPRESSED_PAIR_REV == 2
129+
#elif COMPRESSED_PAIR_REV == 3
130+
#define _LLDB_COMPRESSED_PAIR(T1, Initializer1, T2, Initializer2) \
131+
struct { \
132+
[[__gnu__::__aligned__( \
133+
alignof(T2))]] _LLDB_NO_UNIQUE_ADDRESS T1 Initializer1; \
134+
_LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T1> __padding1_; \
135+
_LLDB_NO_UNIQUE_ADDRESS T2 Initializer2; \
136+
_LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T2> __padding2_; \
137+
}
138+
139+
#define _LLDB_COMPRESSED_TRIPLE(T1, Initializer1, T2, Initializer2, T3, \
140+
Initializer3) \
141+
struct { \
142+
[[using __gnu__: __aligned__(alignof(T2)), \
143+
__aligned__(alignof(T3))]] _LLDB_NO_UNIQUE_ADDRESS T1 Initializer1; \
144+
_LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T1> __padding1_; \
145+
_LLDB_NO_UNIQUE_ADDRESS T2 Initializer2; \
146+
_LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T2> __padding2_; \
147+
_LLDB_NO_UNIQUE_ADDRESS T3 Initializer3; \
148+
_LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T3> __padding3_; \
149+
}
150+
#elif COMPRESSED_PAIR_REV == 4
100151
#define _LLDB_COMPRESSED_PAIR(T1, Name1, T2, Name2) \
101152
_LLDB_NO_UNIQUE_ADDRESS T1 Name1; \
102153
_LLDB_NO_UNIQUE_ADDRESS T2 Name2
@@ -105,7 +156,7 @@ template <class _ToPad> class __compressed_pair_padding {
105156
_LLDB_NO_UNIQUE_ADDRESS T1 Name1; \
106157
_LLDB_NO_UNIQUE_ADDRESS T2 Name2; \
107158
_LLDB_NO_UNIQUE_ADDRESS T3 Name3
108-
#endif
159+
#endif // COMPRESSED_PAIR_REV == 3
109160
} // namespace __lldb
110161
} // namespace std
111162

lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,6 @@ static void consumeInlineNamespace(llvm::StringRef &name) {
4949
}
5050
}
5151

52-
bool lldb_private::formatters::isOldCompressedPairLayout(
53-
ValueObject &pair_obj) {
54-
return isStdTemplate(pair_obj.GetTypeName(), "__compressed_pair");
55-
}
56-
5752
bool lldb_private::formatters::isStdTemplate(ConstString type_name,
5853
llvm::StringRef type) {
5954
llvm::StringRef name = type_name.GetStringRef();
@@ -105,6 +100,44 @@ lldb_private::formatters::GetSecondValueOfLibCXXCompressedPair(
105100
return value;
106101
}
107102

103+
std::pair<lldb::ValueObjectSP, bool>
104+
lldb_private::formatters::GetValueOrOldCompressedPair(
105+
ValueObject &obj, size_t anon_struct_idx, llvm::StringRef child_name,
106+
llvm::StringRef compressed_pair_name) {
107+
auto is_old_compressed_pair = [](ValueObject &pair_obj) -> bool {
108+
return isStdTemplate(pair_obj.GetTypeName(), "__compressed_pair");
109+
};
110+
111+
// Try searching the child member in an anonymous structure first.
112+
if (auto unwrapped = obj.GetChildAtIndex(anon_struct_idx)) {
113+
ValueObjectSP node_sp(obj.GetChildMemberWithName(child_name));
114+
if (node_sp)
115+
return {node_sp, is_old_compressed_pair(*node_sp)};
116+
}
117+
118+
// Older versions of libc++ don't wrap the children in anonymous structures.
119+
// Try that instead.
120+
ValueObjectSP node_sp(obj.GetChildMemberWithName(child_name));
121+
if (node_sp)
122+
return {node_sp, is_old_compressed_pair(*node_sp)};
123+
124+
// Try the even older __compressed_pair layout.
125+
126+
assert(!compressed_pair_name.empty());
127+
128+
node_sp = obj.GetChildMemberWithName(compressed_pair_name);
129+
130+
// Unrecognized layout (possibly older than LLDB supports).
131+
if (!node_sp)
132+
return {nullptr, false};
133+
134+
// Expected old compressed_pair layout, but got something else.
135+
if (!is_old_compressed_pair(*node_sp))
136+
return {nullptr, false};
137+
138+
return {node_sp, true};
139+
}
140+
108141
bool lldb_private::formatters::LibcxxFunctionSummaryProvider(
109142
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
110143

@@ -205,11 +238,12 @@ bool lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
205238
if (!valobj_sp)
206239
return false;
207240

208-
ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName("__ptr_"));
241+
auto [ptr_sp, is_compressed_pair] = GetValueOrOldCompressedPair(
242+
*valobj_sp, /*anon_struct_idx=*/0, "__ptr_", "__ptr_");
209243
if (!ptr_sp)
210244
return false;
211245

212-
if (isOldCompressedPairLayout(*ptr_sp))
246+
if (is_compressed_pair)
213247
ptr_sp = GetFirstValueOfLibCXXCompressedPair(*ptr_sp);
214248

215249
if (!ptr_sp)
@@ -382,13 +416,14 @@ lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() {
382416
if (!valobj_sp)
383417
return lldb::ChildCacheState::eRefetch;
384418

385-
ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName("__ptr_"));
419+
auto [ptr_sp, is_compressed_pair] = GetValueOrOldCompressedPair(
420+
*valobj_sp, /*anon_struct_idx=*/0, "__ptr_", "__ptr_");
386421
if (!ptr_sp)
387422
return lldb::ChildCacheState::eRefetch;
388423

389424
// Retrieve the actual pointer and the deleter, and clone them to give them
390425
// user-friendly names.
391-
if (isOldCompressedPairLayout(*ptr_sp)) {
426+
if (is_compressed_pair) {
392427
if (ValueObjectSP value_pointer_sp =
393428
GetFirstValueOfLibCXXCompressedPair(*ptr_sp))
394429
m_value_ptr_sp = value_pointer_sp->Clone(ConstString("pointer"));
@@ -442,17 +477,15 @@ enum class StringLayout { CSD, DSC };
442477
}
443478

444479
static ValueObjectSP ExtractLibCxxStringData(ValueObject &valobj) {
445-
if (auto rep_sp = valobj.GetChildMemberWithName("__rep_"))
446-
return rep_sp;
447-
448-
ValueObjectSP valobj_r_sp = valobj.GetChildMemberWithName("__r_");
449-
if (!valobj_r_sp || !valobj_r_sp->GetError().Success())
480+
auto [valobj_r_sp, is_compressed_pair] = GetValueOrOldCompressedPair(
481+
valobj, /*anon_struct_idx=*/0, "__rep_", "__r_");
482+
if (!valobj_r_sp)
450483
return nullptr;
451484

452-
if (!isOldCompressedPairLayout(*valobj_r_sp))
453-
return nullptr;
485+
if (is_compressed_pair)
486+
return GetFirstValueOfLibCXXCompressedPair(*valobj_r_sp);
454487

455-
return GetFirstValueOfLibCXXCompressedPair(*valobj_r_sp);
488+
return valobj_r_sp;
456489
}
457490

458491
/// Determine the size in bytes of \p valobj (a libc++ std::string object) and

lldb/source/Plugins/Language/CPlusPlus/LibCxx.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,22 @@ GetChildMemberWithName(ValueObject &obj,
2525

2626
lldb::ValueObjectSP GetFirstValueOfLibCXXCompressedPair(ValueObject &pair);
2727
lldb::ValueObjectSP GetSecondValueOfLibCXXCompressedPair(ValueObject &pair);
28-
bool isOldCompressedPairLayout(ValueObject &pair_obj);
28+
29+
/// Returns the ValueObjectSP of the child of \c obj. If \c obj has no
30+
/// child named \c child_name, returns the __compressed_pair child instead
31+
/// with \c compressed_pair_name, if one exists.
32+
///
33+
/// Latest libc++ wrap the compressed children in an anonymous structure.
34+
/// The \c anon_struct_idx indicates the location of this struct.
35+
///
36+
/// The returned boolean is \c true if the returned child was has an old-style
37+
/// libc++ __compressed_pair layout.
38+
///
39+
/// If no child was found returns a nullptr.
40+
std::pair<lldb::ValueObjectSP, bool>
41+
GetValueOrOldCompressedPair(ValueObject &obj, size_t anon_struct_idx,
42+
llvm::StringRef child_name,
43+
llvm::StringRef compressed_pair_name);
2944
bool isStdTemplate(ConstString type_name, llvm::StringRef type);
3045

3146
bool LibcxxStringSummaryProviderASCII(

lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -293,11 +293,18 @@ lldb::ChildCacheState ForwardListFrontEnd::Update() {
293293
if (err.Fail() || !backend_addr)
294294
return lldb::ChildCacheState::eRefetch;
295295

296-
ValueObjectSP impl_sp(m_backend.GetChildMemberWithName("__before_begin_"));
296+
auto list_base_sp = m_backend.GetChildAtIndex(0);
297+
if (!list_base_sp)
298+
return lldb::ChildCacheState::eRefetch;
299+
300+
// Anonymous strucutre index is in base class at index 0.
301+
auto [impl_sp, is_compressed_pair] =
302+
GetValueOrOldCompressedPair(*list_base_sp, /*anon_struct_idx=*/0,
303+
"__before_begin_", "__before_begin_");
297304
if (!impl_sp)
298305
return ChildCacheState::eRefetch;
299306

300-
if (isOldCompressedPairLayout(*impl_sp))
307+
if (is_compressed_pair)
301308
impl_sp = GetFirstValueOfLibCXXCompressedPair(*impl_sp);
302309

303310
if (!impl_sp)
@@ -320,17 +327,10 @@ llvm::Expected<uint32_t> ListFrontEnd::CalculateNumChildren() {
320327
if (!m_head || !m_tail || m_node_address == 0)
321328
return 0;
322329

323-
ValueObjectSP size_node_sp(m_backend.GetChildMemberWithName("__size_"));
324-
if (!size_node_sp) {
325-
size_node_sp = m_backend.GetChildMemberWithName(
326-
"__size_alloc_"); // pre-compressed_pair rework
327-
328-
if (!isOldCompressedPairLayout(*size_node_sp))
329-
return llvm::createStringError("Unexpected std::list layout: expected "
330-
"old __compressed_pair layout.");
331-
330+
auto [size_node_sp, is_compressed_pair] = GetValueOrOldCompressedPair(
331+
m_backend, /*anon_struct_idx=*/1, "__size_", "__size_alloc_");
332+
if (is_compressed_pair)
332333
size_node_sp = GetFirstValueOfLibCXXCompressedPair(*size_node_sp);
333-
}
334334

335335
if (size_node_sp)
336336
m_count = size_node_sp->GetValueAsUnsigned(UINT32_MAX);

lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
202202
size_t GetIndexOfChildWithName(ConstString name) override;
203203

204204
private:
205-
llvm::Expected<uint32_t> CalculateNumChildrenForOldCompressedPairLayout();
205+
llvm::Expected<uint32_t>
206+
CalculateNumChildrenForOldCompressedPairLayout(ValueObject &pair);
206207

207208
/// Returns the ValueObject for the __tree_node type that
208209
/// holds the key/value pair of the node at index \ref idx.
@@ -258,16 +259,8 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::
258259

259260
llvm::Expected<uint32_t>
260261
lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::
261-
CalculateNumChildrenForOldCompressedPairLayout() {
262-
ValueObjectSP node_sp(m_tree->GetChildMemberWithName("__pair3_"));
263-
if (!node_sp)
264-
return 0;
265-
266-
if (!isOldCompressedPairLayout(*node_sp))
267-
return llvm::createStringError("Unexpected std::map layout: expected "
268-
"old __compressed_pair layout.");
269-
270-
node_sp = GetFirstValueOfLibCXXCompressedPair(*node_sp);
262+
CalculateNumChildrenForOldCompressedPairLayout(ValueObject &pair) {
263+
auto node_sp = GetFirstValueOfLibCXXCompressedPair(pair);
271264

272265
if (!node_sp)
273266
return 0;
@@ -285,12 +278,16 @@ llvm::Expected<uint32_t> lldb_private::formatters::
285278
if (m_tree == nullptr)
286279
return 0;
287280

288-
if (auto node_sp = m_tree->GetChildMemberWithName("__size_")) {
289-
m_count = node_sp->GetValueAsUnsigned(0);
290-
return m_count;
291-
}
281+
auto [size_sp, is_compressed_pair] = GetValueOrOldCompressedPair(
282+
*m_tree, /*anon_struct_idx=*/2, "__size_", "__pair3_");
283+
if (!size_sp)
284+
return llvm::createStringError("Unexpected std::map layout");
292285

293-
return CalculateNumChildrenForOldCompressedPairLayout();
286+
if (is_compressed_pair)
287+
return CalculateNumChildrenForOldCompressedPairLayout(*size_sp);
288+
289+
m_count = size_sp->GetValueAsUnsigned(0);
290+
return m_count;
294291
}
295292

296293
ValueObjectSP

0 commit comments

Comments
 (0)