@@ -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-
5752bool 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+
108141bool 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)
@@ -379,13 +413,14 @@ lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() {
379413 if (!valobj_sp)
380414 return lldb::ChildCacheState::eRefetch;
381415
382- ValueObjectSP ptr_sp (valobj_sp->GetChildMemberWithName (" __ptr_" ));
416+ auto [ptr_sp, is_compressed_pair] = GetValueOrOldCompressedPair (
417+ *valobj_sp, /* anon_struct_idx=*/ 0 , " __ptr_" , " __ptr_" );
383418 if (!ptr_sp)
384419 return lldb::ChildCacheState::eRefetch;
385420
386421 // Retrieve the actual pointer and the deleter, and clone them to give them
387422 // user-friendly names.
388- if (isOldCompressedPairLayout (*ptr_sp) ) {
423+ if (is_compressed_pair ) {
389424 if (ValueObjectSP value_pointer_sp =
390425 GetFirstValueOfLibCXXCompressedPair (*ptr_sp))
391426 m_value_ptr_sp = value_pointer_sp->Clone (ConstString (" pointer" ));
@@ -424,17 +459,15 @@ enum class StringLayout { CSD, DSC };
424459}
425460
426461static ValueObjectSP ExtractLibCxxStringData (ValueObject &valobj) {
427- if (auto rep_sp = valobj.GetChildMemberWithName (" __rep_" ))
428- return rep_sp;
429-
430- ValueObjectSP valobj_r_sp = valobj.GetChildMemberWithName (" __r_" );
431- if (!valobj_r_sp || !valobj_r_sp->GetError ().Success ())
462+ auto [valobj_r_sp, is_compressed_pair] = GetValueOrOldCompressedPair (
463+ valobj, /* anon_struct_idx=*/ 0 , " __rep_" , " __r_" );
464+ if (!valobj_r_sp)
432465 return nullptr ;
433466
434- if (! isOldCompressedPairLayout (*valobj_r_sp) )
435- return nullptr ;
467+ if (is_compressed_pair )
468+ return GetFirstValueOfLibCXXCompressedPair (*valobj_r_sp) ;
436469
437- return GetFirstValueOfLibCXXCompressedPair (* valobj_r_sp) ;
470+ return valobj_r_sp;
438471}
439472
440473// / Determine the size in bytes of \p valobj (a libc++ std::string object) and
0 commit comments