diff options
Diffstat (limited to 'lldb/source/DataFormatters/ValueObjectPrinter.cpp')
| -rw-r--r-- | lldb/source/DataFormatters/ValueObjectPrinter.cpp | 143 |
1 files changed, 119 insertions, 24 deletions
diff --git a/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/lldb/source/DataFormatters/ValueObjectPrinter.cpp index ec7862eb8a1..4bc33fdaa91 100644 --- a/lldb/source/DataFormatters/ValueObjectPrinter.cpp +++ b/lldb/source/DataFormatters/ValueObjectPrinter.cpp @@ -29,12 +29,12 @@ ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, if (valobj) { DumpValueObjectOptions options(*valobj); - Init (valobj,s,options,m_options.m_max_ptr_depth,0); + Init (valobj,s,options,m_options.m_max_ptr_depth,0, nullptr); } else { DumpValueObjectOptions options; - Init (valobj,s,options,m_options.m_max_ptr_depth,0); + Init (valobj,s,options,m_options.m_max_ptr_depth,0, nullptr); } } @@ -42,16 +42,17 @@ ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, Stream* s, const DumpValueObjectOptions& options) { - Init(valobj,s,options,m_options.m_max_ptr_depth,0); + Init(valobj,s,options,m_options.m_max_ptr_depth,0, nullptr); } ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, Stream* s, const DumpValueObjectOptions& options, const DumpValueObjectOptions::PointerDepth& ptr_depth, - uint32_t curr_depth) + uint32_t curr_depth, + InstancePointersSetSP printed_instance_pointers) { - Init(valobj,s,options,ptr_depth,curr_depth); + Init(valobj,s,options,ptr_depth,curr_depth, printed_instance_pointers); } void @@ -59,7 +60,8 @@ ValueObjectPrinter::Init (ValueObject* valobj, Stream* s, const DumpValueObjectOptions& options, const DumpValueObjectOptions::PointerDepth& ptr_depth, - uint32_t curr_depth) + uint32_t curr_depth, + InstancePointersSetSP printed_instance_pointers) { m_orig_valobj = valobj; m_valobj = nullptr; @@ -74,10 +76,13 @@ ValueObjectPrinter::Init (ValueObject* valobj, m_is_ptr = eLazyBoolCalculate; m_is_ref = eLazyBoolCalculate; m_is_aggregate = eLazyBoolCalculate; + m_is_instance_ptr = eLazyBoolCalculate; m_summary_formatter = {nullptr,false}; m_value.assign(""); m_summary.assign(""); m_error.assign(""); + m_val_summary_ok = false; + m_printed_instance_pointers = printed_instance_pointers ? printed_instance_pointers : InstancePointersSetSP(new InstancePointersSet()); } bool @@ -95,13 +100,13 @@ ValueObjectPrinter::PrintValueObject () PrintDecl(); } - + bool value_printed = false; bool summary_printed = false; - bool val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed); - - if (val_summary_ok) + m_val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed); + + if (m_val_summary_ok) PrintChildrenIfNeeded (value_printed, summary_printed); else m_stream->EOL(); @@ -189,8 +194,8 @@ const char* ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail) { const char *root_valobj_name = m_options.m_root_valobj_name.empty() ? - m_valobj->GetName().AsCString() : - m_options.m_root_valobj_name.c_str(); + m_valobj->GetName().AsCString() : + m_options.m_root_valobj_name.c_str(); return root_valobj_name ? root_valobj_name : if_fail; } @@ -235,6 +240,17 @@ ValueObjectPrinter::IsAggregate () } bool +ValueObjectPrinter::IsInstancePointer () +{ + // you need to do this check on the value's clang type + if (m_is_instance_ptr == eLazyBoolCalculate) + m_is_instance_ptr = (m_valobj->GetValue().GetCompilerType().GetTypeInfo() & eTypeInstanceIsPointer) != 0 ? eLazyBoolYes : eLazyBoolNo; + if ((eLazyBoolYes == m_is_instance_ptr) && m_valobj->IsBaseClass()) + m_is_instance_ptr = eLazyBoolNo; + return m_is_instance_ptr == eLazyBoolYes; +} + +bool ValueObjectPrinter::PrintLocationIfNeeded () { if (m_options.m_show_location) @@ -361,7 +377,7 @@ ValueObjectPrinter::CheckScopeIfNeeded () } TypeSummaryImpl* -ValueObjectPrinter::GetSummaryFormatter () +ValueObjectPrinter::GetSummaryFormatter (bool null_if_omitted) { if (m_summary_formatter.second == false) { @@ -372,6 +388,8 @@ ValueObjectPrinter::GetSummaryFormatter () m_summary_formatter.first = entry; m_summary_formatter.second = true; } + if (m_options.m_omit_summary_depth > 0 && null_if_omitted) + return nullptr; return m_summary_formatter.first; } @@ -379,7 +397,7 @@ static bool IsPointerValue (const CompilerType &type) { Flags type_flags(type.GetTypeInfo()); - if (type_flags.AnySet(eTypeIsPointer)) + if (type_flags.AnySet(eTypeInstanceIsPointer | eTypeIsPointer)) return type_flags.AllClear(eTypeIsBuiltIn); return false; } @@ -438,6 +456,16 @@ ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed, } if (m_error.size()) { + // we need to support scenarios in which it is actually fine for a value to have no type + // but - on the other hand - if we get an error *AND* have no type, we try to get out + // gracefully, since most often that combination means "could not resolve a type" + // and the default failure mode is quite ugly + if (!m_compiler_type.IsValid()) + { + m_stream->Printf(" <could not resolve type>"); + return false; + } + error_printed = true; m_stream->Printf (" <%s>\n", m_error.c_str()); } @@ -543,9 +571,12 @@ ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description, { const bool is_ref = IsRef (); const bool is_ptr = IsPtr (); - + TypeSummaryImpl* entry = GetSummaryFormatter(); - + + if (m_options.m_use_objc) + return false; + if (is_failed_description || m_curr_depth < m_options.m_max_depth) { // We will show children for all concrete types. We won't show @@ -588,10 +619,10 @@ bool ValueObjectPrinter::ShouldExpandEmptyAggregates () { TypeSummaryImpl* entry = GetSummaryFormatter(); - + if (!entry) return true; - + return entry->DoesPrintEmptyAggregates(); } @@ -625,13 +656,15 @@ ValueObjectPrinter::PrintChild (ValueObjectSP child_sp, 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); + m_curr_depth + 1, + m_printed_instance_pointers); child_printer.PrintValueObject(); } } @@ -671,6 +704,30 @@ ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot) } } +bool +ValueObjectPrinter::ShouldPrintEmptyBrackets (bool value_printed, + bool summary_printed) +{ + ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); + + if (!IsAggregate()) + return false; + + if (m_options.m_reveal_empty_aggregates == false) + { + if (value_printed || summary_printed) + return false; + } + + if (synth_m_valobj->MightHaveChildren()) + return true; + + if (m_val_summary_ok) + return false; + + return true; +} + void ValueObjectPrinter::PrintChildren (bool value_printed, bool summary_printed, @@ -682,17 +739,38 @@ ValueObjectPrinter::PrintChildren (bool value_printed, size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); if (num_children) { - PrintChildrenPreamble (); + bool any_children_printed = false; for (size_t idx=0; idx<num_children; ++idx) { ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); - PrintChild (child_sp, curr_ptr_depth); + if (child_sp) + { + if (!any_children_printed) + { + PrintChildrenPreamble (); + any_children_printed = true; + } + PrintChild (child_sp, curr_ptr_depth); + } } - PrintChildrenPostamble (print_dotdotdot); + if (any_children_printed) + PrintChildrenPostamble (print_dotdotdot); + else + { + if (ShouldPrintEmptyBrackets(value_printed, summary_printed)) + { + if (ShouldPrintValueObject()) + m_stream->PutCString(" {}\n"); + else + m_stream->EOL(); + } + else + m_stream->EOL(); + } } - else if (IsAggregate()) + else if (ShouldPrintEmptyBrackets(value_printed, summary_printed)) { // Aggregate, no children... if (ShouldPrintValueObject()) @@ -774,6 +852,23 @@ ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed, !m_options.m_allow_oneliner_mode || m_options.m_flat_output || m_options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj); + bool is_instance_ptr = IsInstancePointer(); + uint64_t instance_ptr_value = LLDB_INVALID_ADDRESS; + + if (print_children && is_instance_ptr) + { + instance_ptr_value = m_valobj->GetValueAsUnsigned(0); + if (m_printed_instance_pointers->count(instance_ptr_value)) + { + // we already printed this instance-is-pointer thing, so don't expand it + m_stream->PutCString(" {...}\n"); + + // we're done here - get out fast + return; + } + else + m_printed_instance_pointers->emplace(instance_ptr_value); // remember this guy for future reference + } if (print_children) { @@ -788,7 +883,7 @@ ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed, } else if (m_curr_depth >= m_options.m_max_depth && IsAggregate() && ShouldPrintValueObject()) { - m_stream->PutCString("{...}\n"); + m_stream->PutCString("{...}\n"); } else m_stream->EOL(); |

