Skip to content

Commit

Permalink
[lldb/Dataformatters] Adapt C++ std::string dataformatter for D128285
Browse files Browse the repository at this point in the history
This patch changes the C++ `std::string` dataformatter to reflect
internal layout changes following D128285.

Now, in short-mode strings, in order to access the `__size_` and
`__is_long_` attributes, we need to access a packed anonymous struct,
which introduces another indirection.

We need to do the same in order to access the `__cap_` field for
long-mode strings.

This should fix the various test failures that are happening on
GreenDragon:

https://green.lab.llvm.org/green/job/lldb-cmake/44918/

rdar://96010248

Differential Revision: https://reviews.llvm.org/D128694

Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
  • Loading branch information
medismailben committed Jun 28, 2022
1 parent 73e5d7b commit 44a114f
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,8 +583,18 @@ ExtractLibcxxStringInfo(ValueObject &valobj) {
: eLibcxxStringLayoutModeCSD;
uint64_t size_mode_value = 0;

if (ValueObjectSP is_long = dataval_sp->GetChildAtNamePath(
{ConstString("__s"), ConstString("__is_long_")})) {
ValueObjectSP short_sp(dataval_sp->GetChildAtIndex(1, true));
if (!short_sp)
return {};

// After D128285, we need to access the `__is_long_` and `__size_` fields from
// a packed anonymous struct
ValueObjectSP packed_fields_sp = short_sp->GetChildAtIndex(0, true);
if (!packed_fields_sp)
return {};

if (ValueObjectSP is_long = packed_fields_sp->GetChildMemberWithName(
ConstString("__is_long_"), true)) {
using_bitmasks = false;
short_mode = !is_long->GetValueAsUnsigned(/*fail_value=*/0);
if (ValueObjectSP size_member =
Expand Down Expand Up @@ -621,14 +631,11 @@ ExtractLibcxxStringInfo(ValueObject &valobj) {
}

if (short_mode) {
ValueObjectSP short_sp(dataval_sp->GetChildAtIndex(1, true));
if (!short_sp)
return {};
ValueObjectSP location_sp = short_sp->GetChildAtIndex(
ValueObjectSP location_sp = packed_fields_sp->GetChildAtIndex(
(layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true);
// After D125496, there is a flat layout.
if (location_sp->GetName() == g_size_name)
location_sp = short_sp->GetChildAtIndex(3, true);
location_sp = short_sp->GetChildMemberWithName(g_data_name, true);
if (using_bitmasks)
size = (layout == eLibcxxStringLayoutModeDSC)
? size_mode_value
Expand All @@ -650,13 +657,19 @@ ExtractLibcxxStringInfo(ValueObject &valobj) {
ValueObjectSP l(dataval_sp->GetChildAtIndex(0, true));
if (!l)
return {};

// After D128285, we need to access the `__cap_` field from a packed anonymous
// struct
packed_fields_sp = l->GetChildAtIndex(0, true);
if (!packed_fields_sp)
return {};
// we can use the layout_decider object as the data pointer
ValueObjectSP location_sp =
l->GetChildMemberWithName(ConstString("__data_"), /*can_create=*/true);
ValueObjectSP size_vo =
l->GetChildMemberWithName(ConstString("__size_"), /*can_create=*/true);
ValueObjectSP capacity_vo =
l->GetChildMemberWithName(ConstString("__cap_"), /*can_create=*/true);
ValueObjectSP capacity_vo = packed_fields_sp->GetChildMemberWithName(
ConstString("__cap_"), /*can_create=*/true);
if (!size_vo || !location_sp || !capacity_vo)
return {};
size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
Expand Down

0 comments on commit 44a114f

Please sign in to comment.