forked from OSchip/llvm-project
[lldb/LibCxx] Have ExtractLibcxxStringInfo return an Optional result, NFC
Differential Revision: https://reviews.llvm.org/D74018
This commit is contained in:
parent
7aabad1312
commit
90a94c02fb
|
@ -468,22 +468,20 @@ enum LibcxxStringLayoutMode {
|
|||
eLibcxxStringLayoutModeInvalid = 0xffff
|
||||
};
|
||||
|
||||
// this function abstracts away the layout and mode details of a libc++ string
|
||||
// and returns the address of the data and the size ready for callers to
|
||||
// consume
|
||||
static bool ExtractLibcxxStringInfo(ValueObject &valobj,
|
||||
ValueObjectSP &location_sp,
|
||||
uint64_t &size) {
|
||||
/// Determine the size in bytes of \p valobj (a libc++ std::string object) and
|
||||
/// extract its data payload. Return the size + payload pair.
|
||||
static llvm::Optional<std::pair<uint64_t, ValueObjectSP>>
|
||||
ExtractLibcxxStringInfo(ValueObject &valobj) {
|
||||
ValueObjectSP D(valobj.GetChildAtIndexPath({0, 0, 0, 0}));
|
||||
if (!D)
|
||||
return false;
|
||||
return {};
|
||||
|
||||
ValueObjectSP layout_decider(
|
||||
D->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0})));
|
||||
|
||||
// this child should exist
|
||||
if (!layout_decider)
|
||||
return false;
|
||||
return {};
|
||||
|
||||
ConstString g_data_name("__data_");
|
||||
ConstString g_size_name("__size_");
|
||||
|
@ -497,13 +495,13 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj,
|
|||
if (layout == eLibcxxStringLayoutModeDSC) {
|
||||
ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 1, 0}));
|
||||
if (!size_mode)
|
||||
return false;
|
||||
return {};
|
||||
|
||||
if (size_mode->GetName() != g_size_name) {
|
||||
// we are hitting the padding structure, move along
|
||||
size_mode = D->GetChildAtIndexPath({1, 1, 1});
|
||||
if (!size_mode)
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
|
||||
size_mode_value = (size_mode->GetValueAsUnsigned(0));
|
||||
|
@ -511,7 +509,7 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj,
|
|||
} else {
|
||||
ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 0, 0}));
|
||||
if (!size_mode)
|
||||
return false;
|
||||
return {};
|
||||
|
||||
size_mode_value = (size_mode->GetValueAsUnsigned(0));
|
||||
short_mode = ((size_mode_value & 1) == 0);
|
||||
|
@ -520,12 +518,12 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj,
|
|||
if (short_mode) {
|
||||
ValueObjectSP s(D->GetChildAtIndex(1, true));
|
||||
if (!s)
|
||||
return false;
|
||||
location_sp = s->GetChildAtIndex(
|
||||
return {};
|
||||
ValueObjectSP location_sp = s->GetChildAtIndex(
|
||||
(layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true);
|
||||
size = (layout == eLibcxxStringLayoutModeDSC)
|
||||
? size_mode_value
|
||||
: ((size_mode_value >> 1) % 256);
|
||||
const uint64_t size = (layout == eLibcxxStringLayoutModeDSC)
|
||||
? size_mode_value
|
||||
: ((size_mode_value >> 1) % 256);
|
||||
|
||||
// When the small-string optimization takes place, the data must fit in the
|
||||
// inline string buffer (23 bytes on x86_64/Darwin). If it doesn't, it's
|
||||
|
@ -534,39 +532,44 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj,
|
|||
const llvm::Optional<uint64_t> max_bytes =
|
||||
location_sp->GetCompilerType().GetByteSize(
|
||||
exe_ctx.GetBestExecutionContextScope());
|
||||
if (!max_bytes || size > *max_bytes)
|
||||
return false;
|
||||
if (!max_bytes || size > *max_bytes || !location_sp)
|
||||
return {};
|
||||
|
||||
return (location_sp.get() != nullptr);
|
||||
} else {
|
||||
ValueObjectSP l(D->GetChildAtIndex(0, true));
|
||||
if (!l)
|
||||
return false;
|
||||
// we can use the layout_decider object as the data pointer
|
||||
location_sp = (layout == eLibcxxStringLayoutModeDSC)
|
||||
? layout_decider
|
||||
: l->GetChildAtIndex(2, true);
|
||||
ValueObjectSP size_vo(l->GetChildAtIndex(1, true));
|
||||
const unsigned capacity_index =
|
||||
(layout == eLibcxxStringLayoutModeDSC) ? 2 : 0;
|
||||
ValueObjectSP capacity_vo(l->GetChildAtIndex(capacity_index, true));
|
||||
if (!size_vo || !location_sp || !capacity_vo)
|
||||
return false;
|
||||
size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
|
||||
const uint64_t cap = capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
|
||||
if (size == LLDB_INVALID_OFFSET || cap == LLDB_INVALID_OFFSET || cap < size)
|
||||
return false;
|
||||
return true;
|
||||
return std::make_pair(size, location_sp);
|
||||
}
|
||||
|
||||
ValueObjectSP l(D->GetChildAtIndex(0, true));
|
||||
if (!l)
|
||||
return {};
|
||||
// we can use the layout_decider object as the data pointer
|
||||
ValueObjectSP location_sp = (layout == eLibcxxStringLayoutModeDSC)
|
||||
? layout_decider
|
||||
: l->GetChildAtIndex(2, true);
|
||||
ValueObjectSP size_vo(l->GetChildAtIndex(1, true));
|
||||
const unsigned capacity_index =
|
||||
(layout == eLibcxxStringLayoutModeDSC) ? 2 : 0;
|
||||
ValueObjectSP capacity_vo(l->GetChildAtIndex(capacity_index, true));
|
||||
if (!size_vo || !location_sp || !capacity_vo)
|
||||
return {};
|
||||
const uint64_t size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
|
||||
const uint64_t capacity =
|
||||
capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET);
|
||||
if (size == LLDB_INVALID_OFFSET || capacity == LLDB_INVALID_OFFSET ||
|
||||
capacity < size)
|
||||
return {};
|
||||
return std::make_pair(size, location_sp);
|
||||
}
|
||||
|
||||
bool lldb_private::formatters::LibcxxWStringSummaryProvider(
|
||||
ValueObject &valobj, Stream &stream,
|
||||
const TypeSummaryOptions &summary_options) {
|
||||
uint64_t size = 0;
|
||||
ValueObjectSP location_sp;
|
||||
if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
|
||||
auto string_info = ExtractLibcxxStringInfo(valobj);
|
||||
if (!string_info)
|
||||
return false;
|
||||
uint64_t size;
|
||||
ValueObjectSP location_sp;
|
||||
std::tie(size, location_sp) = *string_info;
|
||||
|
||||
if (size == 0) {
|
||||
stream.Printf("L\"\"");
|
||||
return true;
|
||||
|
@ -574,10 +577,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
|
|||
if (!location_sp)
|
||||
return false;
|
||||
|
||||
DataExtractor extractor;
|
||||
|
||||
StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
|
||||
|
||||
if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
|
||||
const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
|
||||
if (size > max_size) {
|
||||
|
@ -585,6 +586,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
|
|||
options.SetIsTruncated(true);
|
||||
}
|
||||
}
|
||||
|
||||
DataExtractor extractor;
|
||||
const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
|
||||
if (bytes_read < size)
|
||||
return false;
|
||||
|
@ -632,10 +635,13 @@ template <StringPrinter::StringElementType element_type>
|
|||
bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
|
||||
const TypeSummaryOptions &summary_options,
|
||||
std::string prefix_token) {
|
||||
uint64_t size = 0;
|
||||
ValueObjectSP location_sp;
|
||||
if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
|
||||
auto string_info = ExtractLibcxxStringInfo(valobj);
|
||||
if (!string_info)
|
||||
return false;
|
||||
uint64_t size;
|
||||
ValueObjectSP location_sp;
|
||||
std::tie(size, location_sp) = *string_info;
|
||||
|
||||
if (size == 0) {
|
||||
stream.Printf("\"\"");
|
||||
return true;
|
||||
|
@ -646,7 +652,6 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
|
|||
|
||||
StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
|
||||
|
||||
DataExtractor extractor;
|
||||
if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) {
|
||||
const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary();
|
||||
if (size > max_size) {
|
||||
|
@ -654,18 +659,18 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
|
|||
options.SetIsTruncated(true);
|
||||
}
|
||||
}
|
||||
|
||||
DataExtractor extractor;
|
||||
const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
|
||||
if (bytes_read < size)
|
||||
return false;
|
||||
|
||||
options.SetData(extractor);
|
||||
options.SetStream(&stream);
|
||||
|
||||
if (prefix_token.empty())
|
||||
options.SetPrefixToken(nullptr);
|
||||
else
|
||||
options.SetPrefixToken(prefix_token);
|
||||
|
||||
options.SetQuote('"');
|
||||
options.SetSourceSize(size);
|
||||
options.SetBinaryZeroIsTerminator(false);
|
||||
|
|
Loading…
Reference in New Issue