Upstream changes to the ValueObjectPrinter; nfc

llvm-svn: 252638
This commit is contained in:
Enrico Granata 2015-11-10 19:07:58 +00:00
parent 795128fc5d
commit 8cf44d9684
4 changed files with 466 additions and 338 deletions

View File

@ -24,157 +24,162 @@
namespace lldb_private {
class DumpValueObjectOptions
{
public:
struct PointerDepth
class DumpValueObjectOptions
{
enum class Mode
public:
struct PointerDepth
{
Always,
Formatters,
Default,
Never
} m_mode;
uint32_t m_count;
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);
};
PointerDepth
operator --() const
typedef std::function<bool(ConstString,
ConstString,
const DumpValueObjectOptions &,
Stream&)> DeclPrintingHelper;
static const DumpValueObjectOptions
DefaultOptions()
{
if (m_count > 0)
return PointerDepth {m_mode,m_count-1};
return PointerDepth {m_mode,m_count};
static DumpValueObjectOptions g_default_options;
return g_default_options;
}
bool
CanAllowExpansion () const;
DumpValueObjectOptions();
bool
CanAllowExpansion (bool is_root,
TypeSummaryImpl* entry,
ValueObject *valobj,
const std::string& summary);
DumpValueObjectOptions (const DumpValueObjectOptions& rhs) = default;
DumpValueObjectOptions (ValueObject& valobj);
DumpValueObjectOptions&
SetMaximumPointerDepth(PointerDepth depth = {PointerDepth::Mode::Never,0});
DumpValueObjectOptions&
SetMaximumDepth(uint32_t depth = 0);
DumpValueObjectOptions&
SetDeclPrintingHelper(DeclPrintingHelper helper);
DumpValueObjectOptions&
SetShowTypes(bool show = false);
DumpValueObjectOptions&
SetShowLocation(bool show = false);
DumpValueObjectOptions&
SetUseObjectiveC(bool use = false);
DumpValueObjectOptions&
SetShowSummary(bool show = true);
DumpValueObjectOptions&
SetUseDynamicType(lldb::DynamicValueType dyn = lldb::eNoDynamicValues);
DumpValueObjectOptions&
SetUseSyntheticValue(bool use_synthetic = true);
DumpValueObjectOptions&
SetScopeChecked(bool check = true);
DumpValueObjectOptions&
SetFlatOutput(bool flat = false);
DumpValueObjectOptions&
SetOmitSummaryDepth(uint32_t depth = 0);
DumpValueObjectOptions&
SetIgnoreCap(bool ignore = false);
DumpValueObjectOptions&
SetRawDisplay();
DumpValueObjectOptions&
SetFormat (lldb::Format format = lldb::eFormatDefault);
DumpValueObjectOptions&
SetSummary (lldb::TypeSummaryImplSP summary = lldb::TypeSummaryImplSP());
DumpValueObjectOptions&
SetRootValueObjectName(const char* name = nullptr);
DumpValueObjectOptions&
SetHideRootType (bool hide_root_type = false);
DumpValueObjectOptions&
SetHideName (bool hide_name = false);
DumpValueObjectOptions&
SetHideValue (bool hide_value = false);
DumpValueObjectOptions&
SetHidePointerValue (bool hide = false);
DumpValueObjectOptions&
SetVariableFormatDisplayLanguage (lldb::LanguageType lang = lldb::eLanguageTypeUnknown);
DumpValueObjectOptions&
SetRunValidator (bool run = true);
DumpValueObjectOptions&
SetUseTypeDisplayName (bool dis = false);
DumpValueObjectOptions&
SetAllowOnelinerMode (bool oneliner = false);
DumpValueObjectOptions&
SetRevealEmptyAggregates (bool reveal = true);
public:
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;
lldb::LanguageType m_varformat_language = lldb::eLanguageTypeUnknown;
PointerDepth m_max_ptr_depth;
DeclPrintingHelper m_decl_printing_helper;
bool m_use_synthetic : 1;
bool m_scope_already_checked : 1;
bool m_flat_output : 1;
bool m_ignore_cap : 1;
bool m_show_types : 1;
bool m_show_location : 1;
bool m_use_objc : 1;
bool m_hide_root_type : 1;
bool m_hide_name : 1;
bool m_hide_value : 1;
bool m_run_validator : 1;
bool m_use_type_display_name : 1;
bool m_allow_oneliner_mode : 1;
bool m_hide_pointer_value : 1;
bool m_reveal_empty_aggregates : 1;
};
typedef std::function<bool(ConstString,
ConstString,
const DumpValueObjectOptions &,
Stream&)> DeclPrintingHelper;
static const DumpValueObjectOptions
DefaultOptions()
{
static DumpValueObjectOptions g_default_options;
return g_default_options;
}
DumpValueObjectOptions();
DumpValueObjectOptions (const DumpValueObjectOptions& rhs) = default;
DumpValueObjectOptions (ValueObject& valobj);
DumpValueObjectOptions&
SetMaximumPointerDepth(PointerDepth depth = {PointerDepth::Mode::Never,0});
DumpValueObjectOptions&
SetMaximumDepth(uint32_t depth = 0);
DumpValueObjectOptions&
SetDeclPrintingHelper(DeclPrintingHelper helper);
DumpValueObjectOptions&
SetShowTypes(bool show = false);
DumpValueObjectOptions&
SetShowLocation(bool show = false);
DumpValueObjectOptions&
SetUseObjectiveC(bool use = false);
DumpValueObjectOptions&
SetShowSummary(bool show = true);
DumpValueObjectOptions&
SetUseDynamicType(lldb::DynamicValueType dyn = lldb::eNoDynamicValues);
DumpValueObjectOptions&
SetUseSyntheticValue(bool use_synthetic = true);
DumpValueObjectOptions&
SetScopeChecked(bool check = true);
DumpValueObjectOptions&
SetFlatOutput(bool flat = false);
DumpValueObjectOptions&
SetOmitSummaryDepth(uint32_t depth = 0);
DumpValueObjectOptions&
SetIgnoreCap(bool ignore = false);
DumpValueObjectOptions&
SetRawDisplay();
DumpValueObjectOptions&
SetFormat (lldb::Format format = lldb::eFormatDefault);
DumpValueObjectOptions&
SetSummary (lldb::TypeSummaryImplSP summary = lldb::TypeSummaryImplSP());
DumpValueObjectOptions&
SetRootValueObjectName(const char* name = nullptr);
DumpValueObjectOptions&
SetHideRootType (bool hide_root_type = false);
DumpValueObjectOptions&
SetHideName (bool hide_name = false);
DumpValueObjectOptions&
SetHideValue (bool hide_value = false);
DumpValueObjectOptions&
SetHidePointerValue (bool hide = false);
DumpValueObjectOptions&
SetVariableFormatDisplayLanguage (lldb::LanguageType lang = lldb::eLanguageTypeUnknown);
DumpValueObjectOptions&
SetRunValidator (bool run = true);
DumpValueObjectOptions&
SetUseTypeDisplayName (bool dis = false);
DumpValueObjectOptions&
SetAllowOnelinerMode (bool oneliner = false);
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;
lldb::LanguageType m_varformat_language = lldb::eLanguageTypeUnknown;
PointerDepth m_max_ptr_depth;
DeclPrintingHelper m_decl_printing_helper;
bool m_use_synthetic : 1;
bool m_scope_already_checked : 1;
bool m_flat_output : 1;
bool m_ignore_cap : 1;
bool m_show_types : 1;
bool m_show_location : 1;
bool m_use_objc : 1;
bool m_hide_root_type : 1;
bool m_hide_name : 1;
bool m_hide_value : 1;
bool m_run_validator : 1;
bool m_use_type_display_name : 1;
bool m_allow_oneliner_mode : 1;
bool m_hide_pointer_value : 1;
};
} // namespace lldb_private
#endif // lldb_DumpValueObjectOptions_h_

View File

@ -22,161 +22,180 @@
#include "lldb/DataFormatters/DumpValueObjectOptions.h"
#include "lldb/Symbol/CompilerType.h"
//#include <functional>
//#include <memory>
//#include <set>
namespace lldb_private {
class ValueObjectPrinter
{
public:
ValueObjectPrinter (ValueObject* valobj,
Stream* s);
ValueObjectPrinter (ValueObject* valobj,
Stream* s,
const DumpValueObjectOptions& options);
~ValueObjectPrinter () {}
bool
PrintValueObject ();
protected:
// only this class (and subclasses, if any) should ever be concerned with
// the depth mechanism
ValueObjectPrinter (ValueObject* valobj,
Stream* s,
const DumpValueObjectOptions& options,
const DumpValueObjectOptions::PointerDepth& ptr_depth,
uint32_t curr_depth);
// we should actually be using delegating constructors here
// but some versions of GCC still have trouble with those
void
Init (ValueObject* valobj,
Stream* s,
const DumpValueObjectOptions& options,
const DumpValueObjectOptions::PointerDepth& ptr_depth,
uint32_t curr_depth);
bool
GetMostSpecializedValue ();
const char*
GetDescriptionForDisplay ();
const char*
GetRootNameForDisplay (const char* if_fail = nullptr);
bool
ShouldPrintValueObject ();
bool
ShouldPrintValidation ();
bool
IsNil ();
bool
IsPtr ();
bool
IsRef ();
bool
IsAggregate ();
bool
PrintValidationMarkerIfNeeded ();
bool
PrintValidationErrorIfNeeded ();
bool
PrintLocationIfNeeded ();
void
PrintDecl ();
bool
CheckScopeIfNeeded ();
TypeSummaryImpl*
GetSummaryFormatter ();
void
GetValueSummaryError (std::string& value,
std::string& summary,
std::string& error);
bool
PrintValueAndSummaryIfNeeded (bool& value_printed,
bool& summary_printed);
bool
PrintObjectDescriptionIfNeeded (bool value_printed,
bool summary_printed);
bool
ShouldPrintChildren (bool is_failed_description,
DumpValueObjectOptions::PointerDepth& curr_ptr_depth);
bool
ShouldExpandEmptyAggregates ();
ValueObject*
GetValueObjectForChildrenGeneration ();
void
PrintChildrenPreamble ();
void
PrintChildrenPostamble (bool print_dotdotdot);
void
PrintChild (lldb::ValueObjectSP child_sp,
const DumpValueObjectOptions::PointerDepth& curr_ptr_depth);
uint32_t
GetMaxNumChildrenToPrint (bool& print_dotdotdot);
void
PrintChildren (bool value_printed,
bool summary_printed,
const DumpValueObjectOptions::PointerDepth& curr_ptr_depth);
void
PrintChildrenIfNeeded (bool value_printed,
bool summary_printed);
bool
PrintChildrenOneLiner (bool hide_names);
private:
ValueObject *m_orig_valobj;
ValueObject *m_valobj;
Stream *m_stream;
DumpValueObjectOptions m_options;
Flags m_type_flags;
CompilerType m_compiler_type;
DumpValueObjectOptions::PointerDepth m_ptr_depth;
uint32_t m_curr_depth;
LazyBool m_should_print;
LazyBool m_is_nil;
LazyBool m_is_ptr;
LazyBool m_is_ref;
LazyBool m_is_aggregate;
std::pair<TypeSummaryImpl*,bool> m_summary_formatter;
std::string m_value;
std::string m_summary;
std::string m_error;
std::pair<TypeValidatorResult,std::string> m_validation;
friend struct StringSummaryFormat;
DISALLOW_COPY_AND_ASSIGN(ValueObjectPrinter);
};
class ValueObjectPrinter
{
public:
ValueObjectPrinter (ValueObject* valobj,
Stream* s);
ValueObjectPrinter (ValueObject* valobj,
Stream* s,
const DumpValueObjectOptions& options);
~ValueObjectPrinter () {}
bool
PrintValueObject ();
protected:
typedef std::set<uint64_t> InstancePointersSet;
typedef std::shared_ptr<InstancePointersSet> InstancePointersSetSP;
InstancePointersSetSP m_printed_instance_pointers;
// only this class (and subclasses, if any) should ever be concerned with
// the depth mechanism
ValueObjectPrinter (ValueObject* valobj,
Stream* s,
const DumpValueObjectOptions& options,
const DumpValueObjectOptions::PointerDepth& ptr_depth,
uint32_t curr_depth,
InstancePointersSetSP printed_instance_pointers);
// we should actually be using delegating constructors here
// but some versions of GCC still have trouble with those
void
Init (ValueObject* valobj,
Stream* s,
const DumpValueObjectOptions& options,
const DumpValueObjectOptions::PointerDepth& ptr_depth,
uint32_t curr_depth,
InstancePointersSetSP printed_instance_pointers);
bool
GetMostSpecializedValue ();
const char*
GetDescriptionForDisplay ();
const char*
GetRootNameForDisplay (const char* if_fail = nullptr);
bool
ShouldPrintValueObject ();
bool
ShouldPrintValidation ();
bool
IsNil ();
bool
IsPtr ();
bool
IsRef ();
bool
IsInstancePointer ();
bool
IsAggregate ();
bool
PrintValidationMarkerIfNeeded ();
bool
PrintValidationErrorIfNeeded ();
bool
PrintLocationIfNeeded ();
void
PrintDecl ();
bool
CheckScopeIfNeeded ();
bool
ShouldPrintEmptyBrackets (bool value_printed,
bool summary_printed);
TypeSummaryImpl*
GetSummaryFormatter (bool null_if_omitted = true);
void
GetValueSummaryError (std::string& value,
std::string& summary,
std::string& error);
bool
PrintValueAndSummaryIfNeeded (bool& value_printed,
bool& summary_printed);
bool
PrintObjectDescriptionIfNeeded (bool value_printed,
bool summary_printed);
bool
ShouldPrintChildren (bool is_failed_description,
DumpValueObjectOptions::PointerDepth& curr_ptr_depth);
bool
ShouldExpandEmptyAggregates ();
ValueObject*
GetValueObjectForChildrenGeneration ();
void
PrintChildrenPreamble ();
void
PrintChildrenPostamble (bool print_dotdotdot);
void
PrintChild (lldb::ValueObjectSP child_sp,
const DumpValueObjectOptions::PointerDepth& curr_ptr_depth);
uint32_t
GetMaxNumChildrenToPrint (bool& print_dotdotdot);
void
PrintChildren (bool value_printed,
bool summary_printed,
const DumpValueObjectOptions::PointerDepth& curr_ptr_depth);
void
PrintChildrenIfNeeded (bool value_printed,
bool summary_printed);
bool
PrintChildrenOneLiner (bool hide_names);
private:
ValueObject *m_orig_valobj;
ValueObject *m_valobj;
Stream *m_stream;
DumpValueObjectOptions m_options;
Flags m_type_flags;
CompilerType m_compiler_type;
DumpValueObjectOptions::PointerDepth m_ptr_depth;
uint32_t m_curr_depth;
LazyBool m_should_print;
LazyBool m_is_nil;
LazyBool m_is_ptr;
LazyBool m_is_ref;
LazyBool m_is_aggregate;
LazyBool m_is_instance_ptr;
std::pair<TypeSummaryImpl*,bool> m_summary_formatter;
std::string m_value;
std::string m_summary;
std::string m_error;
bool m_val_summary_ok;
std::pair<TypeValidatorResult,std::string> m_validation;
friend struct StringSummaryFormat;
DISALLOW_COPY_AND_ASSIGN(ValueObjectPrinter);
};
} // namespace lldb_private

View File

@ -19,29 +19,30 @@ using namespace lldb;
using namespace lldb_private;
DumpValueObjectOptions::DumpValueObjectOptions() :
m_summary_sp(),
m_root_valobj_name(),
m_max_ptr_depth(PointerDepth{PointerDepth::Mode::Default,0}),
m_decl_printing_helper(),
m_use_synthetic(true),
m_scope_already_checked(false),
m_flat_output(false),
m_ignore_cap(false),
m_show_types(false),
m_show_location(false),
m_use_objc(false),
m_hide_root_type(false),
m_hide_name(false),
m_hide_value(false),
m_run_validator(false),
m_use_type_display_name(true),
m_allow_oneliner_mode(true),
m_hide_pointer_value(false)
m_summary_sp(),
m_root_valobj_name(),
m_max_ptr_depth(PointerDepth{PointerDepth::Mode::Default,0}),
m_decl_printing_helper(),
m_use_synthetic(true),
m_scope_already_checked(false),
m_flat_output(false),
m_ignore_cap(false),
m_show_types(false),
m_show_location(false),
m_use_objc(false),
m_hide_root_type(false),
m_hide_name(false),
m_hide_value(false),
m_run_validator(false),
m_use_type_display_name(true),
m_allow_oneliner_mode(true),
m_hide_pointer_value(false),
m_reveal_empty_aggregates(true)
{}
DumpValueObjectOptions::DumpValueObjectOptions (ValueObject& valobj) :
DumpValueObjectOptions()
DumpValueObjectOptions()
{
m_use_dynamic = valobj.GetDynamicValueType();
m_use_synthetic = valobj.IsSynthetic();
@ -234,3 +235,11 @@ DumpValueObjectOptions::SetAllowOnelinerMode (bool oneliner)
m_allow_oneliner_mode = oneliner;
return *this;
}
DumpValueObjectOptions&
DumpValueObjectOptions::SetRevealEmptyAggregates (bool reveal)
{
m_reveal_empty_aggregates = reveal;
return *this;
}

View File

@ -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;
}
@ -234,6 +239,17 @@ ValueObjectPrinter::IsAggregate ()
return m_is_aggregate == eLazyBoolYes;
}
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 ()
{
@ -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();