14d93b8cdSEnrico Granata //===-- ValueObjectPrinter.cpp -------------------------------------*- C++ -*-===// 24d93b8cdSEnrico Granata // 34d93b8cdSEnrico Granata // The LLVM Compiler Infrastructure 44d93b8cdSEnrico Granata // 54d93b8cdSEnrico Granata // This file is distributed under the University of Illinois Open Source 64d93b8cdSEnrico Granata // License. See LICENSE.TXT for details. 74d93b8cdSEnrico Granata // 84d93b8cdSEnrico Granata //===----------------------------------------------------------------------===// 94d93b8cdSEnrico Granata 104d93b8cdSEnrico Granata #include "lldb/DataFormatters/ValueObjectPrinter.h" 114d93b8cdSEnrico Granata 124d93b8cdSEnrico Granata // C Includes 134d93b8cdSEnrico Granata // C++ Includes 144d93b8cdSEnrico Granata // Other libraries and framework includes 154d93b8cdSEnrico Granata // Project includes 164d93b8cdSEnrico Granata #include "lldb/Core/Debugger.h" 17*a29cb0baSEnrico Granata #include "lldb/DataFormatters/DataVisualization.h" 184d93b8cdSEnrico Granata #include "lldb/Interpreter/CommandInterpreter.h" 194d93b8cdSEnrico Granata #include "lldb/Target/Target.h" 204d93b8cdSEnrico Granata 214d93b8cdSEnrico Granata using namespace lldb; 224d93b8cdSEnrico Granata using namespace lldb_private; 234d93b8cdSEnrico Granata 244d93b8cdSEnrico Granata ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, 254d93b8cdSEnrico Granata Stream* s, 264d93b8cdSEnrico Granata const DumpValueObjectOptions& options) : 274d93b8cdSEnrico Granata m_orig_valobj(valobj), 284d93b8cdSEnrico Granata m_valobj(nullptr), 294d93b8cdSEnrico Granata m_stream(s), 304d93b8cdSEnrico Granata options(options), 314d93b8cdSEnrico Granata m_ptr_depth(options.m_max_ptr_depth), 324d93b8cdSEnrico Granata m_curr_depth(0), 334d93b8cdSEnrico Granata m_should_print(eLazyBoolCalculate), 344d93b8cdSEnrico Granata m_is_nil(eLazyBoolCalculate), 354d93b8cdSEnrico Granata m_is_ptr(eLazyBoolCalculate), 364d93b8cdSEnrico Granata m_is_ref(eLazyBoolCalculate), 374d93b8cdSEnrico Granata m_is_aggregate(eLazyBoolCalculate), 384d93b8cdSEnrico Granata m_summary_formatter({nullptr,false}), 394d93b8cdSEnrico Granata m_value(), 404d93b8cdSEnrico Granata m_summary(), 414d93b8cdSEnrico Granata m_error() 424d93b8cdSEnrico Granata { 434d93b8cdSEnrico Granata assert (m_orig_valobj && "cannot print a NULL ValueObject"); 444d93b8cdSEnrico Granata assert (m_stream && "cannot print to a NULL Stream"); 454d93b8cdSEnrico Granata } 464d93b8cdSEnrico Granata 474d93b8cdSEnrico Granata ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, 484d93b8cdSEnrico Granata Stream* s, 494d93b8cdSEnrico Granata const DumpValueObjectOptions& options, 504d93b8cdSEnrico Granata uint32_t ptr_depth, 514d93b8cdSEnrico Granata uint32_t curr_depth) : 5273435afdSDaniel Malea m_orig_valobj(valobj), 5373435afdSDaniel Malea m_valobj(nullptr), 5473435afdSDaniel Malea m_stream(s), 5573435afdSDaniel Malea options(options), 5673435afdSDaniel Malea m_ptr_depth(ptr_depth), 5773435afdSDaniel Malea m_curr_depth(curr_depth), 5873435afdSDaniel Malea m_should_print(eLazyBoolCalculate), 5973435afdSDaniel Malea m_is_nil(eLazyBoolCalculate), 6073435afdSDaniel Malea m_is_ptr(eLazyBoolCalculate), 6173435afdSDaniel Malea m_is_ref(eLazyBoolCalculate), 6273435afdSDaniel Malea m_is_aggregate(eLazyBoolCalculate), 6373435afdSDaniel Malea m_summary_formatter({nullptr,false}), 6473435afdSDaniel Malea m_value(), 6573435afdSDaniel Malea m_summary(), 6673435afdSDaniel Malea m_error() 6773435afdSDaniel Malea { } 684d93b8cdSEnrico Granata 694d93b8cdSEnrico Granata bool 704d93b8cdSEnrico Granata ValueObjectPrinter::PrintValueObject () 714d93b8cdSEnrico Granata { 724d93b8cdSEnrico Granata if (!GetDynamicValueIfNeeded () || m_valobj == nullptr) 734d93b8cdSEnrico Granata return false; 744d93b8cdSEnrico Granata 754d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 764d93b8cdSEnrico Granata { 774d93b8cdSEnrico Granata PrintLocationIfNeeded(); 784d93b8cdSEnrico Granata m_stream->Indent(); 794d93b8cdSEnrico Granata 804d93b8cdSEnrico Granata bool show_type = PrintTypeIfNeeded(); 814d93b8cdSEnrico Granata 824d93b8cdSEnrico Granata PrintNameIfNeeded(show_type); 834d93b8cdSEnrico Granata } 844d93b8cdSEnrico Granata 854d93b8cdSEnrico Granata bool value_printed = false; 864d93b8cdSEnrico Granata bool summary_printed = false; 874d93b8cdSEnrico Granata 884d93b8cdSEnrico Granata bool val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed); 894d93b8cdSEnrico Granata 904d93b8cdSEnrico Granata if (val_summary_ok) 914d93b8cdSEnrico Granata PrintChildrenIfNeeded (value_printed, summary_printed); 9239938938SEnrico Granata else 934d93b8cdSEnrico Granata m_stream->EOL(); 944d93b8cdSEnrico Granata 954d93b8cdSEnrico Granata return true; 964d93b8cdSEnrico Granata } 974d93b8cdSEnrico Granata 984d93b8cdSEnrico Granata bool 994d93b8cdSEnrico Granata ValueObjectPrinter::GetDynamicValueIfNeeded () 1004d93b8cdSEnrico Granata { 101*a29cb0baSEnrico Granata if (m_valobj) 102*a29cb0baSEnrico Granata return true; 1034d93b8cdSEnrico Granata bool update_success = m_orig_valobj->UpdateValueIfNeeded (true); 1044d93b8cdSEnrico Granata if (!update_success) 1054d93b8cdSEnrico Granata return false; 1064d93b8cdSEnrico Granata if (options.m_use_dynamic != eNoDynamicValues) 1074d93b8cdSEnrico Granata { 1084d93b8cdSEnrico Granata ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(options.m_use_dynamic).get(); 1094d93b8cdSEnrico Granata if (dynamic_value) 1104d93b8cdSEnrico Granata m_valobj = dynamic_value; 1114d93b8cdSEnrico Granata else 1124d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 1134d93b8cdSEnrico Granata } 1144d93b8cdSEnrico Granata else 1154d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 1164d93b8cdSEnrico Granata m_clang_type = m_valobj->GetClangType(); 1174d93b8cdSEnrico Granata m_type_flags = m_clang_type.GetTypeInfo (); 1184d93b8cdSEnrico Granata return true; 1194d93b8cdSEnrico Granata } 1204d93b8cdSEnrico Granata 1214d93b8cdSEnrico Granata const char* 1224d93b8cdSEnrico Granata ValueObjectPrinter::GetDescriptionForDisplay () 1234d93b8cdSEnrico Granata { 1244d93b8cdSEnrico Granata const char* str = m_valobj->GetObjectDescription(); 1254d93b8cdSEnrico Granata if (!str) 1264d93b8cdSEnrico Granata str = m_valobj->GetSummaryAsCString(); 1274d93b8cdSEnrico Granata if (!str) 1284d93b8cdSEnrico Granata str = m_valobj->GetValueAsCString(); 1294d93b8cdSEnrico Granata return str; 1304d93b8cdSEnrico Granata } 1314d93b8cdSEnrico Granata 1324d93b8cdSEnrico Granata const char* 1334d93b8cdSEnrico Granata ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail) 1344d93b8cdSEnrico Granata { 1354d93b8cdSEnrico Granata const char *root_valobj_name = options.m_root_valobj_name.empty() ? 1364d93b8cdSEnrico Granata m_valobj->GetName().AsCString() : 1374d93b8cdSEnrico Granata options.m_root_valobj_name.c_str(); 1384d93b8cdSEnrico Granata return root_valobj_name ? root_valobj_name : if_fail; 1394d93b8cdSEnrico Granata } 1404d93b8cdSEnrico Granata 1414d93b8cdSEnrico Granata bool 1424d93b8cdSEnrico Granata ValueObjectPrinter::ShouldPrintValueObject () 1434d93b8cdSEnrico Granata { 1444d93b8cdSEnrico Granata if (m_should_print == eLazyBoolCalculate) 1454d93b8cdSEnrico Granata m_should_print = (options.m_flat_output == false || m_type_flags.Test (ClangASTType::eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo; 1464d93b8cdSEnrico Granata return m_should_print == eLazyBoolYes; 1474d93b8cdSEnrico Granata } 1484d93b8cdSEnrico Granata 1494d93b8cdSEnrico Granata bool 1504d93b8cdSEnrico Granata ValueObjectPrinter::IsNil () 1514d93b8cdSEnrico Granata { 1524d93b8cdSEnrico Granata if (m_is_nil == eLazyBoolCalculate) 1534d93b8cdSEnrico Granata m_is_nil = m_valobj->IsObjCNil() ? eLazyBoolYes : eLazyBoolNo; 1544d93b8cdSEnrico Granata return m_is_nil == eLazyBoolYes; 1554d93b8cdSEnrico Granata } 1564d93b8cdSEnrico Granata 1574d93b8cdSEnrico Granata bool 1584d93b8cdSEnrico Granata ValueObjectPrinter::IsPtr () 1594d93b8cdSEnrico Granata { 1604d93b8cdSEnrico Granata if (m_is_ptr == eLazyBoolCalculate) 1614d93b8cdSEnrico Granata m_is_ptr = m_type_flags.Test (ClangASTType::eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo; 1624d93b8cdSEnrico Granata return m_is_ptr == eLazyBoolYes; 1634d93b8cdSEnrico Granata } 1644d93b8cdSEnrico Granata 1654d93b8cdSEnrico Granata bool 1664d93b8cdSEnrico Granata ValueObjectPrinter::IsRef () 1674d93b8cdSEnrico Granata { 1684d93b8cdSEnrico Granata if (m_is_ref == eLazyBoolCalculate) 1694d93b8cdSEnrico Granata m_is_ref = m_type_flags.Test (ClangASTType::eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo; 1704d93b8cdSEnrico Granata return m_is_ref == eLazyBoolYes; 1714d93b8cdSEnrico Granata } 1724d93b8cdSEnrico Granata 1734d93b8cdSEnrico Granata bool 1744d93b8cdSEnrico Granata ValueObjectPrinter::IsAggregate () 1754d93b8cdSEnrico Granata { 1764d93b8cdSEnrico Granata if (m_is_aggregate == eLazyBoolCalculate) 1774d93b8cdSEnrico Granata m_is_aggregate = m_type_flags.Test (ClangASTType::eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo; 1784d93b8cdSEnrico Granata return m_is_aggregate == eLazyBoolYes; 1794d93b8cdSEnrico Granata } 1804d93b8cdSEnrico Granata 1814d93b8cdSEnrico Granata bool 1824d93b8cdSEnrico Granata ValueObjectPrinter::PrintLocationIfNeeded () 1834d93b8cdSEnrico Granata { 1844d93b8cdSEnrico Granata if (options.m_show_location) 1854d93b8cdSEnrico Granata { 1864d93b8cdSEnrico Granata m_stream->Printf("%s: ", m_valobj->GetLocationAsCString()); 1874d93b8cdSEnrico Granata return true; 1884d93b8cdSEnrico Granata } 1894d93b8cdSEnrico Granata return false; 1904d93b8cdSEnrico Granata } 1914d93b8cdSEnrico Granata 1924d93b8cdSEnrico Granata bool 1934d93b8cdSEnrico Granata ValueObjectPrinter::PrintTypeIfNeeded () 1944d93b8cdSEnrico Granata { 1954d93b8cdSEnrico Granata bool show_type = true; 1964d93b8cdSEnrico Granata // if we are at the root-level and been asked to hide the root's type, then hide it 1974d93b8cdSEnrico Granata if (m_curr_depth == 0 && options.m_hide_root_type) 1984d93b8cdSEnrico Granata show_type = false; 1994d93b8cdSEnrico Granata else 2004d93b8cdSEnrico Granata // otherwise decide according to the usual rules (asked to show types - always at the root level) 2014d93b8cdSEnrico Granata show_type = options.m_show_types || (m_curr_depth == 0 && !options.m_flat_output); 2024d93b8cdSEnrico Granata 2034d93b8cdSEnrico Granata if (show_type) 2044d93b8cdSEnrico Granata { 2054d93b8cdSEnrico Granata // Some ValueObjects don't have types (like registers sets). Only print 2064d93b8cdSEnrico Granata // the type if there is one to print 2074d93b8cdSEnrico Granata ConstString qualified_type_name(m_valobj->GetQualifiedTypeName()); 2084d93b8cdSEnrico Granata if (qualified_type_name) 2094d93b8cdSEnrico Granata m_stream->Printf("(%s) ", qualified_type_name.GetCString()); 2104d93b8cdSEnrico Granata else 2114d93b8cdSEnrico Granata show_type = false; 2124d93b8cdSEnrico Granata } 2134d93b8cdSEnrico Granata return show_type; 2144d93b8cdSEnrico Granata } 2154d93b8cdSEnrico Granata 2164d93b8cdSEnrico Granata bool 2174d93b8cdSEnrico Granata ValueObjectPrinter::PrintNameIfNeeded (bool show_type) 2184d93b8cdSEnrico Granata { 2194d93b8cdSEnrico Granata if (options.m_flat_output) 2204d93b8cdSEnrico Granata { 2214d93b8cdSEnrico Granata // If we are showing types, also qualify the C++ base classes 2224d93b8cdSEnrico Granata const bool qualify_cxx_base_classes = show_type; 2234d93b8cdSEnrico Granata if (!options.m_hide_name) 2244d93b8cdSEnrico Granata { 2254d93b8cdSEnrico Granata m_valobj->GetExpressionPath(*m_stream, qualify_cxx_base_classes); 2264d93b8cdSEnrico Granata m_stream->PutCString(" ="); 2274d93b8cdSEnrico Granata return true; 2284d93b8cdSEnrico Granata } 2294d93b8cdSEnrico Granata } 2304d93b8cdSEnrico Granata else if (!options.m_hide_name) 2314d93b8cdSEnrico Granata { 2324d93b8cdSEnrico Granata const char *name_cstr = GetRootNameForDisplay(""); 2334d93b8cdSEnrico Granata m_stream->Printf ("%s =", name_cstr); 2344d93b8cdSEnrico Granata return true; 2354d93b8cdSEnrico Granata } 2364d93b8cdSEnrico Granata return false; 2374d93b8cdSEnrico Granata } 2384d93b8cdSEnrico Granata 2394d93b8cdSEnrico Granata bool 2404d93b8cdSEnrico Granata ValueObjectPrinter::CheckScopeIfNeeded () 2414d93b8cdSEnrico Granata { 2424d93b8cdSEnrico Granata if (options.m_scope_already_checked) 2434d93b8cdSEnrico Granata return true; 2444d93b8cdSEnrico Granata return m_valobj->IsInScope(); 2454d93b8cdSEnrico Granata } 2464d93b8cdSEnrico Granata 2474d93b8cdSEnrico Granata TypeSummaryImpl* 2484d93b8cdSEnrico Granata ValueObjectPrinter::GetSummaryFormatter () 2494d93b8cdSEnrico Granata { 2504d93b8cdSEnrico Granata if (m_summary_formatter.second == false) 2514d93b8cdSEnrico Granata { 2524d93b8cdSEnrico Granata TypeSummaryImpl* entry = options.m_summary_sp ? options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get(); 2534d93b8cdSEnrico Granata 2544d93b8cdSEnrico Granata if (options.m_omit_summary_depth > 0) 2554d93b8cdSEnrico Granata entry = NULL; 2564d93b8cdSEnrico Granata m_summary_formatter.first = entry; 2574d93b8cdSEnrico Granata m_summary_formatter.second = true; 2584d93b8cdSEnrico Granata } 2594d93b8cdSEnrico Granata return m_summary_formatter.first; 2604d93b8cdSEnrico Granata } 2614d93b8cdSEnrico Granata 2624d93b8cdSEnrico Granata void 2634d93b8cdSEnrico Granata ValueObjectPrinter::GetValueSummaryError (std::string& value, 2644d93b8cdSEnrico Granata std::string& summary, 2654d93b8cdSEnrico Granata std::string& error) 2664d93b8cdSEnrico Granata { 2674d93b8cdSEnrico Granata if (options.m_format != eFormatDefault && options.m_format != m_valobj->GetFormat()) 2684d93b8cdSEnrico Granata { 2694d93b8cdSEnrico Granata m_valobj->GetValueAsCString(options.m_format, 2704d93b8cdSEnrico Granata value); 2714d93b8cdSEnrico Granata } 2724d93b8cdSEnrico Granata else 2734d93b8cdSEnrico Granata { 2744d93b8cdSEnrico Granata const char* val_cstr = m_valobj->GetValueAsCString(); 2754d93b8cdSEnrico Granata if (val_cstr) 2764d93b8cdSEnrico Granata value.assign(val_cstr); 2774d93b8cdSEnrico Granata } 2784d93b8cdSEnrico Granata const char* err_cstr = m_valobj->GetError().AsCString(); 2794d93b8cdSEnrico Granata if (err_cstr) 2804d93b8cdSEnrico Granata error.assign(err_cstr); 2814d93b8cdSEnrico Granata 2824d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 2834d93b8cdSEnrico Granata { 2844d93b8cdSEnrico Granata if (IsNil()) 2854d93b8cdSEnrico Granata summary.assign("nil"); 2864d93b8cdSEnrico Granata else if (options.m_omit_summary_depth == 0) 2874d93b8cdSEnrico Granata { 2884d93b8cdSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 2894d93b8cdSEnrico Granata if (entry) 2904d93b8cdSEnrico Granata m_valobj->GetSummaryAsCString(entry, summary); 2914d93b8cdSEnrico Granata else 2924d93b8cdSEnrico Granata { 2934d93b8cdSEnrico Granata const char* sum_cstr = m_valobj->GetSummaryAsCString(); 2944d93b8cdSEnrico Granata if (sum_cstr) 2954d93b8cdSEnrico Granata summary.assign(sum_cstr); 2964d93b8cdSEnrico Granata } 2974d93b8cdSEnrico Granata } 2984d93b8cdSEnrico Granata } 2994d93b8cdSEnrico Granata } 3004d93b8cdSEnrico Granata 3014d93b8cdSEnrico Granata bool 3024d93b8cdSEnrico Granata ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed, 3034d93b8cdSEnrico Granata bool& summary_printed) 3044d93b8cdSEnrico Granata { 3054d93b8cdSEnrico Granata bool error_printed = false; 3064d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 3074d93b8cdSEnrico Granata { 3084d93b8cdSEnrico Granata if (!CheckScopeIfNeeded()) 3094d93b8cdSEnrico Granata m_error.assign("out of scope"); 3104d93b8cdSEnrico Granata if (m_error.empty()) 3114d93b8cdSEnrico Granata { 3124d93b8cdSEnrico Granata GetValueSummaryError(m_value, m_summary, m_error); 3134d93b8cdSEnrico Granata } 3144d93b8cdSEnrico Granata if (m_error.size()) 3154d93b8cdSEnrico Granata { 3164d93b8cdSEnrico Granata error_printed = true; 3174d93b8cdSEnrico Granata m_stream->Printf (" <%s>\n", m_error.c_str()); 3184d93b8cdSEnrico Granata } 3194d93b8cdSEnrico Granata else 3204d93b8cdSEnrico Granata { 3214d93b8cdSEnrico Granata // Make sure we have a value and make sure the summary didn't 3224d93b8cdSEnrico Granata // specify that the value should not be printed - and do not print 3234d93b8cdSEnrico Granata // the value if this thing is nil 3244d93b8cdSEnrico Granata // (but show the value if the user passes a format explicitly) 3254d93b8cdSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 3264d93b8cdSEnrico Granata if (!IsNil() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue() || options.m_format != eFormatDefault) || m_summary.empty()) && !options.m_hide_value) 3274d93b8cdSEnrico Granata { 3284d93b8cdSEnrico Granata m_stream->Printf(" %s", m_value.c_str()); 3294d93b8cdSEnrico Granata value_printed = true; 3304d93b8cdSEnrico Granata } 3314d93b8cdSEnrico Granata 3324d93b8cdSEnrico Granata if (m_summary.size()) 3334d93b8cdSEnrico Granata { 3344d93b8cdSEnrico Granata m_stream->Printf(" %s", m_summary.c_str()); 3354d93b8cdSEnrico Granata summary_printed = true; 3364d93b8cdSEnrico Granata } 3374d93b8cdSEnrico Granata } 3384d93b8cdSEnrico Granata } 3394d93b8cdSEnrico Granata return !error_printed; 3404d93b8cdSEnrico Granata } 3414d93b8cdSEnrico Granata 3424d93b8cdSEnrico Granata bool 3434d93b8cdSEnrico Granata ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed, 3444d93b8cdSEnrico Granata bool summary_printed) 3454d93b8cdSEnrico Granata { 3464d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 3474d93b8cdSEnrico Granata { 3484d93b8cdSEnrico Granata // let's avoid the overly verbose no description error for a nil thing 3494d93b8cdSEnrico Granata if (options.m_use_objc && !IsNil()) 3504d93b8cdSEnrico Granata { 3514d93b8cdSEnrico Granata if (!options.m_hide_value || !options.m_hide_name) 3524d93b8cdSEnrico Granata m_stream->Printf(" "); 3534d93b8cdSEnrico Granata const char *object_desc = nullptr; 3544d93b8cdSEnrico Granata if (value_printed || summary_printed) 3554d93b8cdSEnrico Granata object_desc = m_valobj->GetObjectDescription(); 3564d93b8cdSEnrico Granata else 3574d93b8cdSEnrico Granata object_desc = GetDescriptionForDisplay(); 3584d93b8cdSEnrico Granata if (object_desc && *object_desc) 3594d93b8cdSEnrico Granata { 3604d93b8cdSEnrico Granata m_stream->Printf("%s\n", object_desc); 3614d93b8cdSEnrico Granata return true; 3624d93b8cdSEnrico Granata } 3634d93b8cdSEnrico Granata else if (value_printed == false && summary_printed == false) 3644d93b8cdSEnrico Granata return true; 3654d93b8cdSEnrico Granata else 3664d93b8cdSEnrico Granata return false; 3674d93b8cdSEnrico Granata } 3684d93b8cdSEnrico Granata } 3694d93b8cdSEnrico Granata return true; 3704d93b8cdSEnrico Granata } 3714d93b8cdSEnrico Granata 3724d93b8cdSEnrico Granata bool 3734d93b8cdSEnrico Granata ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description, 3744d93b8cdSEnrico Granata uint32_t& curr_ptr_depth) 3754d93b8cdSEnrico Granata { 3764d93b8cdSEnrico Granata const bool is_ref = IsRef (); 3774d93b8cdSEnrico Granata const bool is_ptr = IsPtr (); 3784d93b8cdSEnrico Granata 3794d93b8cdSEnrico Granata if (is_failed_description || m_curr_depth < options.m_max_depth) 3804d93b8cdSEnrico Granata { 3814d93b8cdSEnrico Granata // We will show children for all concrete types. We won't show 3824d93b8cdSEnrico Granata // pointer contents unless a pointer depth has been specified. 3834d93b8cdSEnrico Granata // We won't reference contents unless the reference is the 3844d93b8cdSEnrico Granata // root object (depth of zero). 3854d93b8cdSEnrico Granata 3864d93b8cdSEnrico Granata // Use a new temporary pointer depth in case we override the 3874d93b8cdSEnrico Granata // current pointer depth below... 3884d93b8cdSEnrico Granata uint32_t curr_ptr_depth = m_ptr_depth; 3894d93b8cdSEnrico Granata 3904d93b8cdSEnrico Granata if (is_ptr || is_ref) 3914d93b8cdSEnrico Granata { 3924d93b8cdSEnrico Granata // We have a pointer or reference whose value is an address. 3934d93b8cdSEnrico Granata // Make sure that address is not NULL 3944d93b8cdSEnrico Granata AddressType ptr_address_type; 3954d93b8cdSEnrico Granata if (m_valobj->GetPointerValue (&ptr_address_type) == 0) 3964d93b8cdSEnrico Granata return false; 3974d93b8cdSEnrico Granata 3984d93b8cdSEnrico Granata else if (is_ref && m_curr_depth == 0) 3994d93b8cdSEnrico Granata { 4004d93b8cdSEnrico Granata // If this is the root object (depth is zero) that we are showing 4014d93b8cdSEnrico Granata // and it is a reference, and no pointer depth has been supplied 4024d93b8cdSEnrico Granata // print out what it references. Don't do this at deeper depths 4034d93b8cdSEnrico Granata // otherwise we can end up with infinite recursion... 4044d93b8cdSEnrico Granata curr_ptr_depth = 1; 4054d93b8cdSEnrico Granata } 4064d93b8cdSEnrico Granata 4074d93b8cdSEnrico Granata if (curr_ptr_depth == 0) 4084d93b8cdSEnrico Granata return false; 4094d93b8cdSEnrico Granata } 4104d93b8cdSEnrico Granata 4114d93b8cdSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 4124d93b8cdSEnrico Granata 4134d93b8cdSEnrico Granata return (!entry || entry->DoesPrintChildren() || m_summary.empty()); 4144d93b8cdSEnrico Granata } 4154d93b8cdSEnrico Granata return false; 4164d93b8cdSEnrico Granata } 4174d93b8cdSEnrico Granata 4184d93b8cdSEnrico Granata ValueObject* 4194d93b8cdSEnrico Granata ValueObjectPrinter::GetValueObjectForChildrenGeneration () 4204d93b8cdSEnrico Granata { 4214d93b8cdSEnrico Granata ValueObjectSP synth_valobj_sp = m_valobj->GetSyntheticValue (options.m_use_synthetic); 4224d93b8cdSEnrico Granata return (synth_valobj_sp ? synth_valobj_sp.get() : m_valobj); 4234d93b8cdSEnrico Granata } 4244d93b8cdSEnrico Granata 4254d93b8cdSEnrico Granata void 4264d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPreamble () 4274d93b8cdSEnrico Granata { 4284d93b8cdSEnrico Granata if (options.m_flat_output) 4294d93b8cdSEnrico Granata { 4304d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 4314d93b8cdSEnrico Granata m_stream->EOL(); 4324d93b8cdSEnrico Granata } 4334d93b8cdSEnrico Granata else 4344d93b8cdSEnrico Granata { 4354d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 4364d93b8cdSEnrico Granata m_stream->PutCString(IsRef () ? ": {\n" : " {\n"); 4374d93b8cdSEnrico Granata m_stream->IndentMore(); 4384d93b8cdSEnrico Granata } 4394d93b8cdSEnrico Granata } 4404d93b8cdSEnrico Granata 4414d93b8cdSEnrico Granata void 4424d93b8cdSEnrico Granata ValueObjectPrinter::PrintChild (ValueObjectSP child_sp, 4434d93b8cdSEnrico Granata uint32_t curr_ptr_depth) 4444d93b8cdSEnrico Granata { 4454d93b8cdSEnrico Granata DumpValueObjectOptions child_options(options); 4464d93b8cdSEnrico Granata child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName(); 4474d93b8cdSEnrico Granata child_options.SetScopeChecked(true).SetHideName(options.m_hide_name).SetHideValue(options.m_hide_value) 4484d93b8cdSEnrico Granata .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0); 4494d93b8cdSEnrico Granata if (child_sp.get()) 4504d93b8cdSEnrico Granata { 4514d93b8cdSEnrico Granata ValueObjectPrinter child_printer(child_sp.get(), 4524d93b8cdSEnrico Granata m_stream, 4534d93b8cdSEnrico Granata child_options, 4544d93b8cdSEnrico Granata (IsPtr() || IsRef()) ? curr_ptr_depth - 1 : curr_ptr_depth, 4554d93b8cdSEnrico Granata m_curr_depth + 1); 4564d93b8cdSEnrico Granata child_printer.PrintValueObject(); 4574d93b8cdSEnrico Granata } 4584d93b8cdSEnrico Granata 4594d93b8cdSEnrico Granata } 4604d93b8cdSEnrico Granata 4614d93b8cdSEnrico Granata uint32_t 4624d93b8cdSEnrico Granata ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot) 4634d93b8cdSEnrico Granata { 4644d93b8cdSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 4654d93b8cdSEnrico Granata 4664d93b8cdSEnrico Granata size_t num_children = synth_m_valobj->GetNumChildren(); 4674d93b8cdSEnrico Granata print_dotdotdot = false; 4684d93b8cdSEnrico Granata if (num_children) 4694d93b8cdSEnrico Granata { 4704d93b8cdSEnrico Granata const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 4714d93b8cdSEnrico Granata 4724d93b8cdSEnrico Granata if (num_children > max_num_children && !options.m_ignore_cap) 4734d93b8cdSEnrico Granata { 4744d93b8cdSEnrico Granata print_dotdotdot = true; 4754d93b8cdSEnrico Granata return max_num_children; 4764d93b8cdSEnrico Granata } 4774d93b8cdSEnrico Granata } 4784d93b8cdSEnrico Granata return num_children; 4794d93b8cdSEnrico Granata } 4804d93b8cdSEnrico Granata 4814d93b8cdSEnrico Granata void 4824d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot) 4834d93b8cdSEnrico Granata { 4844d93b8cdSEnrico Granata if (!options.m_flat_output) 4854d93b8cdSEnrico Granata { 4864d93b8cdSEnrico Granata if (print_dotdotdot) 4874d93b8cdSEnrico Granata { 4884d93b8cdSEnrico Granata m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated(); 4894d93b8cdSEnrico Granata m_stream->Indent("...\n"); 4904d93b8cdSEnrico Granata } 4914d93b8cdSEnrico Granata m_stream->IndentLess(); 4924d93b8cdSEnrico Granata m_stream->Indent("}\n"); 4934d93b8cdSEnrico Granata } 4944d93b8cdSEnrico Granata } 4954d93b8cdSEnrico Granata 4964d93b8cdSEnrico Granata void 4974d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildren (uint32_t curr_ptr_depth) 4984d93b8cdSEnrico Granata { 4994d93b8cdSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 5004d93b8cdSEnrico Granata 5014d93b8cdSEnrico Granata bool print_dotdotdot = false; 5024d93b8cdSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 5034d93b8cdSEnrico Granata if (num_children) 5044d93b8cdSEnrico Granata { 5054d93b8cdSEnrico Granata PrintChildrenPreamble (); 5064d93b8cdSEnrico Granata 5074d93b8cdSEnrico Granata for (size_t idx=0; idx<num_children; ++idx) 5084d93b8cdSEnrico Granata { 5094d93b8cdSEnrico Granata ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 5104d93b8cdSEnrico Granata PrintChild (child_sp, curr_ptr_depth); 5114d93b8cdSEnrico Granata } 5124d93b8cdSEnrico Granata 5134d93b8cdSEnrico Granata PrintChildrenPostamble (print_dotdotdot); 5144d93b8cdSEnrico Granata } 5154d93b8cdSEnrico Granata else if (IsAggregate()) 5164d93b8cdSEnrico Granata { 5174d93b8cdSEnrico Granata // Aggregate, no children... 5184d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 5194d93b8cdSEnrico Granata m_stream->PutCString(" {}\n"); 5204d93b8cdSEnrico Granata } 5214d93b8cdSEnrico Granata else 5224d93b8cdSEnrico Granata { 5234d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 5244d93b8cdSEnrico Granata m_stream->EOL(); 5254d93b8cdSEnrico Granata } 5264d93b8cdSEnrico Granata } 5274d93b8cdSEnrico Granata 528*a29cb0baSEnrico Granata bool 529*a29cb0baSEnrico Granata ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names) 530*a29cb0baSEnrico Granata { 531*a29cb0baSEnrico Granata if (!GetDynamicValueIfNeeded () || m_valobj == nullptr) 532*a29cb0baSEnrico Granata return false; 533*a29cb0baSEnrico Granata 534*a29cb0baSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 535*a29cb0baSEnrico Granata 536*a29cb0baSEnrico Granata bool print_dotdotdot = false; 537*a29cb0baSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 538*a29cb0baSEnrico Granata 539*a29cb0baSEnrico Granata if (num_children) 540*a29cb0baSEnrico Granata { 541*a29cb0baSEnrico Granata m_stream->PutChar('('); 542*a29cb0baSEnrico Granata 543*a29cb0baSEnrico Granata for (uint32_t idx=0; idx<num_children; ++idx) 544*a29cb0baSEnrico Granata { 545*a29cb0baSEnrico Granata lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 546*a29cb0baSEnrico Granata lldb::ValueObjectSP child_dyn_sp = child_sp.get() ? child_sp->GetDynamicValue(options.m_use_dynamic) : child_sp; 547*a29cb0baSEnrico Granata if (child_dyn_sp) 548*a29cb0baSEnrico Granata child_sp = child_dyn_sp; 549*a29cb0baSEnrico Granata if (child_sp) 550*a29cb0baSEnrico Granata { 551*a29cb0baSEnrico Granata if (idx) 552*a29cb0baSEnrico Granata m_stream->PutCString(", "); 553*a29cb0baSEnrico Granata if (!hide_names) 554*a29cb0baSEnrico Granata { 555*a29cb0baSEnrico Granata const char* name = child_sp.get()->GetName().AsCString(); 556*a29cb0baSEnrico Granata if (name && *name) 557*a29cb0baSEnrico Granata { 558*a29cb0baSEnrico Granata m_stream->PutCString(name); 559*a29cb0baSEnrico Granata m_stream->PutCString(" = "); 560*a29cb0baSEnrico Granata } 561*a29cb0baSEnrico Granata } 562*a29cb0baSEnrico Granata child_sp->DumpPrintableRepresentation(*m_stream, 563*a29cb0baSEnrico Granata ValueObject::eValueObjectRepresentationStyleSummary, 564*a29cb0baSEnrico Granata lldb::eFormatInvalid, 565*a29cb0baSEnrico Granata ValueObject::ePrintableRepresentationSpecialCasesDisable); 566*a29cb0baSEnrico Granata } 567*a29cb0baSEnrico Granata } 568*a29cb0baSEnrico Granata 569*a29cb0baSEnrico Granata if (print_dotdotdot) 570*a29cb0baSEnrico Granata m_stream->PutCString(", ...)"); 571*a29cb0baSEnrico Granata else 572*a29cb0baSEnrico Granata m_stream->PutChar(')'); 573*a29cb0baSEnrico Granata } 574*a29cb0baSEnrico Granata return true; 575*a29cb0baSEnrico Granata } 576*a29cb0baSEnrico Granata 5774d93b8cdSEnrico Granata void 5784d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed, 5794d93b8cdSEnrico Granata bool summary_printed) 5804d93b8cdSEnrico Granata { 5814d93b8cdSEnrico Granata // this flag controls whether we tried to display a description for this object and failed 5824d93b8cdSEnrico Granata // if that happens, we want to display the children, if any 5834d93b8cdSEnrico Granata bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed); 5844d93b8cdSEnrico Granata 5854d93b8cdSEnrico Granata uint32_t curr_ptr_depth = m_ptr_depth; 5864d93b8cdSEnrico Granata bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth); 587*a29cb0baSEnrico Granata bool print_oneline = (curr_ptr_depth > 0 || options.m_show_types) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj); 5884d93b8cdSEnrico Granata 5894d93b8cdSEnrico Granata if (print_children) 5904d93b8cdSEnrico Granata { 591*a29cb0baSEnrico Granata if (print_oneline) 592*a29cb0baSEnrico Granata { 593*a29cb0baSEnrico Granata m_stream->PutChar(' '); 594*a29cb0baSEnrico Granata PrintChildrenOneLiner (false); 595*a29cb0baSEnrico Granata m_stream->EOL(); 596*a29cb0baSEnrico Granata } 597*a29cb0baSEnrico Granata else 5984d93b8cdSEnrico Granata PrintChildren (curr_ptr_depth); 5994d93b8cdSEnrico Granata } 6004d93b8cdSEnrico Granata else if (m_curr_depth >= options.m_max_depth && IsAggregate() && ShouldPrintValueObject()) 6014d93b8cdSEnrico Granata { 6024d93b8cdSEnrico Granata m_stream->PutCString("{...}\n"); 6034d93b8cdSEnrico Granata } 604245b3caaSEnrico Granata else 605245b3caaSEnrico Granata m_stream->EOL(); 6064d93b8cdSEnrico Granata } 607