diff --git a/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h b/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h index c6d9db36f3fb..0a91aca00c0e 100644 --- a/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h +++ b/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h @@ -26,13 +26,42 @@ namespace lldb_private { struct DumpValueObjectOptions { - uint32_t m_max_ptr_depth = 0; + struct PointerDepth + { + enum class Mode + { + Always, + Formatters, + Default, + Never + } m_mode; + uint32_t m_count; + + PointerDepth + operator --() const + { + if (m_count > 0) + return PointerDepth {m_mode,m_count-1}; + return PointerDepth {m_mode,m_count}; + } + + bool + CanAllowExpansion () const; + + bool + CanAllowExpansion (bool is_root, + TypeSummaryImpl* entry, + ValueObject *valobj, + const std::string& summary); + }; + uint32_t m_max_depth = UINT32_MAX; lldb::DynamicValueType m_use_dynamic = lldb::eNoDynamicValues; uint32_t m_omit_summary_depth = 0; lldb::Format m_format = lldb::eFormatDefault; lldb::TypeSummaryImplSP m_summary_sp; std::string m_root_valobj_name; + PointerDepth m_max_ptr_depth; bool m_use_synthetic : 1; bool m_scope_already_checked : 1; bool m_flat_output : 1; @@ -50,6 +79,7 @@ struct DumpValueObjectOptions DumpValueObjectOptions() : m_summary_sp(), m_root_valobj_name(), + m_max_ptr_depth{PointerDepth::Mode::Default,0}, m_use_synthetic(true), m_scope_already_checked(false), m_flat_output(false), @@ -78,7 +108,7 @@ struct DumpValueObjectOptions DumpValueObjectOptions (ValueObject& valobj); DumpValueObjectOptions& - SetMaximumPointerDepth(uint32_t depth = 0) + SetMaximumPointerDepth(PointerDepth depth = {PointerDepth::Mode::Never,0}) { m_max_ptr_depth = depth; return *this; @@ -268,7 +298,7 @@ protected: ValueObjectPrinter (ValueObject* valobj, Stream* s, const DumpValueObjectOptions& options, - uint32_t ptr_depth, + const DumpValueObjectOptions::PointerDepth& ptr_depth, uint32_t curr_depth); // we should actually be using delegating constructors here @@ -277,7 +307,7 @@ protected: Init (ValueObject* valobj, Stream* s, const DumpValueObjectOptions& options, - uint32_t ptr_depth, + const DumpValueObjectOptions::PointerDepth& ptr_depth, uint32_t curr_depth); bool @@ -343,7 +373,7 @@ protected: bool ShouldPrintChildren (bool is_failed_description, - uint32_t& curr_ptr_depth); + DumpValueObjectOptions::PointerDepth& curr_ptr_depth); bool ShouldExpandEmptyAggregates (); @@ -359,13 +389,15 @@ protected: void PrintChild (lldb::ValueObjectSP child_sp, - uint32_t curr_ptr_depth); + const DumpValueObjectOptions::PointerDepth& curr_ptr_depth); uint32_t GetMaxNumChildrenToPrint (bool& print_dotdotdot); void - PrintChildren (uint32_t curr_ptr_depth); + PrintChildren (bool value_printed, + bool summary_printed, + const DumpValueObjectOptions::PointerDepth& curr_ptr_depth); void PrintChildrenIfNeeded (bool value_printed, @@ -382,7 +414,7 @@ private: DumpValueObjectOptions options; Flags m_type_flags; ClangASTType m_clang_type; - uint32_t m_ptr_depth; + DumpValueObjectOptions::PointerDepth m_ptr_depth; uint32_t m_curr_depth; LazyBool m_should_print; LazyBool m_is_nil; diff --git a/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/lldb/source/DataFormatters/ValueObjectPrinter.cpp index 7fca7a3f0af4..0e02821d451f 100644 --- a/lldb/source/DataFormatters/ValueObjectPrinter.cpp +++ b/lldb/source/DataFormatters/ValueObjectPrinter.cpp @@ -53,7 +53,7 @@ ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, Stream* s, const DumpValueObjectOptions& options, - uint32_t ptr_depth, + const DumpValueObjectOptions::PointerDepth& ptr_depth, uint32_t curr_depth) { Init(valobj,s,options,ptr_depth,curr_depth); @@ -63,7 +63,7 @@ void ValueObjectPrinter::Init (ValueObject* valobj, Stream* s, const DumpValueObjectOptions& options, - uint32_t ptr_depth, + const DumpValueObjectOptions::PointerDepth& ptr_depth, uint32_t curr_depth) { m_orig_valobj = valobj; @@ -436,13 +436,52 @@ ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed, return true; } +bool +DumpValueObjectOptions::PointerDepth::CanAllowExpansion (bool is_root, + TypeSummaryImpl* entry, + ValueObject *valobj, + const std::string& summary) +{ + switch (m_mode) + { + case Mode::Always: + return (m_count > 0); + case Mode::Never: + return false; + case Mode::Default: + if (is_root) + m_count = std::min(m_count,1); + return m_count > 0; + case Mode::Formatters: + if (!entry || entry->DoesPrintChildren(valobj) || summary.empty()) + return m_count > 0; + return false; + } +} + +bool +DumpValueObjectOptions::PointerDepth::CanAllowExpansion () const +{ + switch (m_mode) + { + case Mode::Always: + case Mode::Default: + case Mode::Formatters: + return (m_count > 0); + case Mode::Never: + return false; + } +} + bool ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description, - uint32_t& curr_ptr_depth) + DumpValueObjectOptions::PointerDepth& curr_ptr_depth) { const bool is_ref = IsRef (); const bool is_ptr = IsPtr (); + TypeSummaryImpl* entry = GetSummaryFormatter(); + if (is_failed_description || m_curr_depth < options.m_max_depth) { // We will show children for all concrete types. We won't show @@ -461,20 +500,21 @@ ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description, if (m_valobj->GetPointerValue (&ptr_address_type) == 0) return false; - else if (is_ref && m_curr_depth == 0 && curr_ptr_depth == 0) + const bool is_root_level = m_curr_depth == 0; + + if (is_ref && + is_root_level) { // If this is the root object (depth is zero) that we are showing // and it is a reference, and no pointer depth has been supplied // print out what it references. Don't do this at deeper depths // otherwise we can end up with infinite recursion... - curr_ptr_depth = 1; + return true; } - return (curr_ptr_depth > 0); + return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, m_summary); } - TypeSummaryImpl* entry = GetSummaryFormatter(); - return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty()); } return false; @@ -515,7 +555,7 @@ ValueObjectPrinter::PrintChildrenPreamble () void ValueObjectPrinter::PrintChild (ValueObjectSP child_sp, - uint32_t curr_ptr_depth) + const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) { DumpValueObjectOptions child_options(options); child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName(); @@ -526,11 +566,10 @@ ValueObjectPrinter::PrintChild (ValueObjectSP child_sp, ValueObjectPrinter child_printer(child_sp.get(), m_stream, child_options, - (IsPtr() || IsRef()) && curr_ptr_depth >= 1 ? curr_ptr_depth - 1 : curr_ptr_depth, + (IsPtr() || IsRef()) ? --curr_ptr_depth : curr_ptr_depth, m_curr_depth + 1); child_printer.PrintValueObject(); } - } uint32_t @@ -569,7 +608,9 @@ ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot) } void -ValueObjectPrinter::PrintChildren (uint32_t curr_ptr_depth) +ValueObjectPrinter::PrintChildren (bool value_printed, + bool summary_printed, + const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) { ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); @@ -662,9 +703,9 @@ ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed, // if that happens, we want to display the children, if any bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed); - uint32_t curr_ptr_depth = m_ptr_depth; + auto curr_ptr_depth = m_ptr_depth; bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth); - bool print_oneline = (curr_ptr_depth > 0 || + bool print_oneline = (curr_ptr_depth.CanAllowExpansion() || options.m_show_types || !options.m_allow_oneliner_mode || options.m_flat_output || @@ -679,7 +720,7 @@ ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed, m_stream->EOL(); } else - PrintChildren (curr_ptr_depth); + PrintChildren (value_printed, summary_printed, curr_ptr_depth); } else if (m_curr_depth >= options.m_max_depth && IsAggregate() && ShouldPrintValueObject()) { diff --git a/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp index e5a5c004b2da..bbd966859c34 100644 --- a/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp +++ b/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp @@ -162,7 +162,7 @@ OptionGroupValueObjectDisplay::GetAsDumpOptions (LanguageRuntimeDescriptionDispl lldb::TypeSummaryImplSP summary_sp) { DumpValueObjectOptions options; - options.SetMaximumPointerDepth(ptr_depth); + options.SetMaximumPointerDepth( {DumpValueObjectOptions::PointerDepth::Mode::Always,ptr_depth} ); if (use_objc) options.SetShowSummary(false); else