void ValueObjectPrinter::PrintChild( ValueObjectSP child_sp, const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) { const uint32_t consumed_depth = (!m_options.m_pointer_as_array) ? 1 : 0; const bool does_consume_ptr_depth = ((IsPtr() && !m_options.m_pointer_as_array) || IsRef()); DumpValueObjectOptions child_options(m_options); child_options.SetFormat(m_options.m_format) .SetSummary() .SetRootValueObjectName(); child_options.SetScopeChecked(true) .SetHideName(m_options.m_hide_name) .SetHideValue(m_options.m_hide_value) .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - consumed_depth : 0) .SetElementCount(0); if (child_sp.get()) { ValueObjectPrinter child_printer( child_sp.get(), m_stream, child_options, does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth, m_curr_depth + consumed_depth, m_printed_instance_pointers); child_printer.PrintValueObject(); } }
// 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) { ValueObjectSP D(valobj.GetChildAtIndexPath({0,0,0,0})); if (!D) return false; ValueObjectSP layout_decider(D->GetChildAtIndexPath({0,0})); // this child should exist if (!layout_decider) return false; ConstString g_data_name("__data_"); ConstString g_size_name("__size_"); bool short_mode = false; // this means the string is in short-mode and the data is stored inline LibcxxStringLayoutMode layout = (layout_decider->GetName() == g_data_name) ? eLibcxxStringLayoutModeDSC : eLibcxxStringLayoutModeCSD; uint64_t size_mode_value = 0; if (layout == eLibcxxStringLayoutModeDSC) { ValueObjectSP size_mode(D->GetChildAtIndexPath({1,1,0})); if (!size_mode) return false; 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; } size_mode_value = (size_mode->GetValueAsUnsigned(0)); short_mode = ((size_mode_value & 0x80) == 0); } else { ValueObjectSP size_mode(D->GetChildAtIndexPath({1,0,0})); if (!size_mode) return false; size_mode_value = (size_mode->GetValueAsUnsigned(0)); short_mode = ((size_mode_value & 1) == 0); } if (short_mode) { ValueObjectSP s(D->GetChildAtIndex(1, true)); if (!s) return false; location_sp = s->GetChildAtIndex((layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true); size = (layout == eLibcxxStringLayoutModeDSC) ? size_mode_value : ((size_mode_value >> 1) % 256); return (location_sp.get() != nullptr); } else {
void ValueObjectPrinter::PrintChild (ValueObjectSP child_sp, const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) { DumpValueObjectOptions child_options(m_options); child_options.SetFormat(m_options.m_format).SetSummary().SetRootValueObjectName(); child_options.SetScopeChecked(true).SetHideName(m_options.m_hide_name).SetHideValue(m_options.m_hide_value) .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0); if (child_sp.get()) { ValueObjectPrinter child_printer(child_sp.get(), m_stream, child_options, (IsPtr() || IsRef()) ? --curr_ptr_depth : curr_ptr_depth, m_curr_depth + 1); child_printer.PrintValueObject(); } }