180814287SRaphael Isemann //===-- ValueObjectPrinter.cpp --------------------------------------------===// 24d93b8cdSEnrico Granata // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 64d93b8cdSEnrico Granata // 74d93b8cdSEnrico Granata //===----------------------------------------------------------------------===// 84d93b8cdSEnrico Granata 94d93b8cdSEnrico Granata #include "lldb/DataFormatters/ValueObjectPrinter.h" 104d93b8cdSEnrico Granata 11c8e7649aSEnrico Granata #include "lldb/Core/ValueObject.h" 12a29cb0baSEnrico Granata #include "lldb/DataFormatters/DataVisualization.h" 134d93b8cdSEnrico Granata #include "lldb/Interpreter/CommandInterpreter.h" 14c8e7649aSEnrico Granata #include "lldb/Target/Language.h" 154d93b8cdSEnrico Granata #include "lldb/Target/Target.h" 16bf9a7730SZachary Turner #include "lldb/Utility/Stream.h" 174d93b8cdSEnrico Granata 184d93b8cdSEnrico Granata using namespace lldb; 194d93b8cdSEnrico Granata using namespace lldb_private; 204d93b8cdSEnrico Granata 21b9c1b51eSKate Stone ValueObjectPrinter::ValueObjectPrinter(ValueObject *valobj, Stream *s) { 22b9c1b51eSKate Stone if (valobj) { 23d5957336SEnrico Granata DumpValueObjectOptions options(*valobj); 248cf44d96SEnrico Granata Init(valobj, s, options, m_options.m_max_ptr_depth, 0, nullptr); 25b9c1b51eSKate Stone } else { 26d5957336SEnrico Granata DumpValueObjectOptions options; 278cf44d96SEnrico Granata Init(valobj, s, options, m_options.m_max_ptr_depth, 0, nullptr); 28d5957336SEnrico Granata } 29d5957336SEnrico Granata } 30d5957336SEnrico Granata 31b9c1b51eSKate Stone ValueObjectPrinter::ValueObjectPrinter(ValueObject *valobj, Stream *s, 32b9c1b51eSKate Stone const DumpValueObjectOptions &options) { 338cf44d96SEnrico Granata Init(valobj, s, options, m_options.m_max_ptr_depth, 0, nullptr); 344d93b8cdSEnrico Granata } 354d93b8cdSEnrico Granata 36b9c1b51eSKate Stone ValueObjectPrinter::ValueObjectPrinter( 37b9c1b51eSKate Stone ValueObject *valobj, Stream *s, const DumpValueObjectOptions &options, 38b9c1b51eSKate Stone const DumpValueObjectOptions::PointerDepth &ptr_depth, uint32_t curr_depth, 39b9c1b51eSKate Stone InstancePointersSetSP printed_instance_pointers) { 408cf44d96SEnrico Granata Init(valobj, s, options, ptr_depth, curr_depth, printed_instance_pointers); 41938d1d67SEnrico Granata } 42938d1d67SEnrico Granata 43b9c1b51eSKate Stone void ValueObjectPrinter::Init( 44b9c1b51eSKate Stone ValueObject *valobj, Stream *s, const DumpValueObjectOptions &options, 45b9c1b51eSKate Stone const DumpValueObjectOptions::PointerDepth &ptr_depth, uint32_t curr_depth, 46b9c1b51eSKate Stone InstancePointersSetSP printed_instance_pointers) { 47938d1d67SEnrico Granata m_orig_valobj = valobj; 48938d1d67SEnrico Granata m_valobj = nullptr; 49938d1d67SEnrico Granata m_stream = s; 5026014690SGreg Clayton m_options = options; 51938d1d67SEnrico Granata m_ptr_depth = ptr_depth; 52938d1d67SEnrico Granata m_curr_depth = curr_depth; 53938d1d67SEnrico Granata assert(m_orig_valobj && "cannot print a NULL ValueObject"); 54938d1d67SEnrico Granata assert(m_stream && "cannot print to a NULL Stream"); 55938d1d67SEnrico Granata m_should_print = eLazyBoolCalculate; 56938d1d67SEnrico Granata m_is_nil = eLazyBoolCalculate; 57608d67c1SEnrico Granata m_is_uninit = eLazyBoolCalculate; 58938d1d67SEnrico Granata m_is_ptr = eLazyBoolCalculate; 59938d1d67SEnrico Granata m_is_ref = eLazyBoolCalculate; 60938d1d67SEnrico Granata m_is_aggregate = eLazyBoolCalculate; 618cf44d96SEnrico Granata m_is_instance_ptr = eLazyBoolCalculate; 62938d1d67SEnrico Granata m_summary_formatter = {nullptr, false}; 63938d1d67SEnrico Granata m_value.assign(""); 64938d1d67SEnrico Granata m_summary.assign(""); 65938d1d67SEnrico Granata m_error.assign(""); 668cf44d96SEnrico Granata m_val_summary_ok = false; 67b9c1b51eSKate Stone m_printed_instance_pointers = 68b9c1b51eSKate Stone printed_instance_pointers 69b9c1b51eSKate Stone ? printed_instance_pointers 70b9c1b51eSKate Stone : InstancePointersSetSP(new InstancePointersSet()); 71938d1d67SEnrico Granata } 724d93b8cdSEnrico Granata 73b9c1b51eSKate Stone bool ValueObjectPrinter::PrintValueObject() { 74d07cfd3aSEnrico Granata if (!GetMostSpecializedValue() || m_valobj == nullptr) 754d93b8cdSEnrico Granata return false; 764d93b8cdSEnrico Granata 77b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 784d93b8cdSEnrico Granata PrintLocationIfNeeded(); 794d93b8cdSEnrico Granata m_stream->Indent(); 804d93b8cdSEnrico Granata 81e0ee1e1cSEnrico Granata PrintDecl(); 824d93b8cdSEnrico Granata } 834d93b8cdSEnrico Granata 844d93b8cdSEnrico Granata bool value_printed = false; 854d93b8cdSEnrico Granata bool summary_printed = false; 864d93b8cdSEnrico Granata 87b9c1b51eSKate Stone m_val_summary_ok = 88b9c1b51eSKate Stone PrintValueAndSummaryIfNeeded(value_printed, summary_printed); 894d93b8cdSEnrico Granata 908cf44d96SEnrico Granata if (m_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 98b9c1b51eSKate Stone bool ValueObjectPrinter::GetMostSpecializedValue() { 99a29cb0baSEnrico Granata if (m_valobj) 100a29cb0baSEnrico Granata return true; 1014d93b8cdSEnrico Granata bool update_success = m_orig_valobj->UpdateValueIfNeeded(true); 102b9c1b51eSKate Stone if (!update_success) { 103106260c5SEnrico Granata m_valobj = m_orig_valobj; 104b9c1b51eSKate Stone } else { 105b9c1b51eSKate Stone if (m_orig_valobj->IsDynamic()) { 106b9c1b51eSKate Stone if (m_options.m_use_dynamic == eNoDynamicValues) { 107106260c5SEnrico Granata ValueObject *static_value = m_orig_valobj->GetStaticValue().get(); 108106260c5SEnrico Granata if (static_value) 109106260c5SEnrico Granata m_valobj = static_value; 110106260c5SEnrico Granata else 111106260c5SEnrico Granata m_valobj = m_orig_valobj; 112b9c1b51eSKate Stone } else 113106260c5SEnrico Granata m_valobj = m_orig_valobj; 114b9c1b51eSKate Stone } else { 115b9c1b51eSKate Stone if (m_options.m_use_dynamic != eNoDynamicValues) { 116b9c1b51eSKate Stone ValueObject *dynamic_value = 117b9c1b51eSKate Stone m_orig_valobj->GetDynamicValue(m_options.m_use_dynamic).get(); 1184d93b8cdSEnrico Granata if (dynamic_value) 1194d93b8cdSEnrico Granata m_valobj = dynamic_value; 1204d93b8cdSEnrico Granata else 1214d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 122b9c1b51eSKate Stone } else 1234d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 124106260c5SEnrico Granata } 125d07cfd3aSEnrico Granata 126b9c1b51eSKate Stone if (m_valobj->IsSynthetic()) { 127a6682a41SJonas Devlieghere if (!m_options.m_use_synthetic) { 128d07cfd3aSEnrico Granata ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get(); 129d07cfd3aSEnrico Granata if (non_synthetic) 130d07cfd3aSEnrico Granata m_valobj = non_synthetic; 131d07cfd3aSEnrico Granata } 132b9c1b51eSKate Stone } else { 133a6682a41SJonas Devlieghere if (m_options.m_use_synthetic) { 134d07cfd3aSEnrico Granata ValueObject *synthetic = m_valobj->GetSyntheticValue().get(); 135d07cfd3aSEnrico Granata if (synthetic) 136d07cfd3aSEnrico Granata m_valobj = synthetic; 137d07cfd3aSEnrico Granata } 138d07cfd3aSEnrico Granata } 139106260c5SEnrico Granata } 14059b5a37dSBruce Mitchener m_compiler_type = m_valobj->GetCompilerType(); 14159b5a37dSBruce Mitchener m_type_flags = m_compiler_type.GetTypeInfo(); 1424d93b8cdSEnrico Granata return true; 1434d93b8cdSEnrico Granata } 1444d93b8cdSEnrico Granata 145b9c1b51eSKate Stone const char *ValueObjectPrinter::GetDescriptionForDisplay() { 1464d93b8cdSEnrico Granata const char *str = m_valobj->GetObjectDescription(); 1474d93b8cdSEnrico Granata if (!str) 1484d93b8cdSEnrico Granata str = m_valobj->GetSummaryAsCString(); 1494d93b8cdSEnrico Granata if (!str) 1504d93b8cdSEnrico Granata str = m_valobj->GetValueAsCString(); 1514d93b8cdSEnrico Granata return str; 1524d93b8cdSEnrico Granata } 1534d93b8cdSEnrico Granata 154b9c1b51eSKate Stone const char *ValueObjectPrinter::GetRootNameForDisplay(const char *if_fail) { 155b9c1b51eSKate Stone const char *root_valobj_name = m_options.m_root_valobj_name.empty() 156b9c1b51eSKate Stone ? m_valobj->GetName().AsCString() 157b9c1b51eSKate Stone : m_options.m_root_valobj_name.c_str(); 1584d93b8cdSEnrico Granata return root_valobj_name ? root_valobj_name : if_fail; 1594d93b8cdSEnrico Granata } 1604d93b8cdSEnrico Granata 161b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldPrintValueObject() { 1624d93b8cdSEnrico Granata if (m_should_print == eLazyBoolCalculate) 163b9c1b51eSKate Stone m_should_print = 164a6682a41SJonas Devlieghere (!m_options.m_flat_output || m_type_flags.Test(eTypeHasValue)) 165b9c1b51eSKate Stone ? eLazyBoolYes 166b9c1b51eSKate Stone : eLazyBoolNo; 1674d93b8cdSEnrico Granata return m_should_print == eLazyBoolYes; 1684d93b8cdSEnrico Granata } 1694d93b8cdSEnrico Granata 170b9c1b51eSKate Stone bool ValueObjectPrinter::IsNil() { 1714d93b8cdSEnrico Granata if (m_is_nil == eLazyBoolCalculate) 172608d67c1SEnrico Granata m_is_nil = m_valobj->IsNilReference() ? eLazyBoolYes : eLazyBoolNo; 1734d93b8cdSEnrico Granata return m_is_nil == eLazyBoolYes; 1744d93b8cdSEnrico Granata } 1754d93b8cdSEnrico Granata 176b9c1b51eSKate Stone bool ValueObjectPrinter::IsUninitialized() { 177608d67c1SEnrico Granata if (m_is_uninit == eLazyBoolCalculate) 178b9c1b51eSKate Stone m_is_uninit = 179b9c1b51eSKate Stone m_valobj->IsUninitializedReference() ? eLazyBoolYes : eLazyBoolNo; 180608d67c1SEnrico Granata return m_is_uninit == eLazyBoolYes; 181608d67c1SEnrico Granata } 182608d67c1SEnrico Granata 183b9c1b51eSKate Stone bool ValueObjectPrinter::IsPtr() { 1844d93b8cdSEnrico Granata if (m_is_ptr == eLazyBoolCalculate) 185622be238SEnrico Granata m_is_ptr = m_type_flags.Test(eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo; 1864d93b8cdSEnrico Granata return m_is_ptr == eLazyBoolYes; 1874d93b8cdSEnrico Granata } 1884d93b8cdSEnrico Granata 189b9c1b51eSKate Stone bool ValueObjectPrinter::IsRef() { 1904d93b8cdSEnrico Granata if (m_is_ref == eLazyBoolCalculate) 191622be238SEnrico Granata m_is_ref = m_type_flags.Test(eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo; 1924d93b8cdSEnrico Granata return m_is_ref == eLazyBoolYes; 1934d93b8cdSEnrico Granata } 1944d93b8cdSEnrico Granata 195b9c1b51eSKate Stone bool ValueObjectPrinter::IsAggregate() { 1964d93b8cdSEnrico Granata if (m_is_aggregate == eLazyBoolCalculate) 197b9c1b51eSKate Stone m_is_aggregate = 198b9c1b51eSKate Stone m_type_flags.Test(eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo; 1994d93b8cdSEnrico Granata return m_is_aggregate == eLazyBoolYes; 2004d93b8cdSEnrico Granata } 2014d93b8cdSEnrico Granata 202b9c1b51eSKate Stone bool ValueObjectPrinter::IsInstancePointer() { 2038cf44d96SEnrico Granata // you need to do this check on the value's clang type 2048cf44d96SEnrico Granata if (m_is_instance_ptr == eLazyBoolCalculate) 205b9c1b51eSKate Stone m_is_instance_ptr = (m_valobj->GetValue().GetCompilerType().GetTypeInfo() & 206b9c1b51eSKate Stone eTypeInstanceIsPointer) != 0 207b9c1b51eSKate Stone ? eLazyBoolYes 208b9c1b51eSKate Stone : eLazyBoolNo; 2098cf44d96SEnrico Granata if ((eLazyBoolYes == m_is_instance_ptr) && m_valobj->IsBaseClass()) 2108cf44d96SEnrico Granata m_is_instance_ptr = eLazyBoolNo; 2118cf44d96SEnrico Granata return m_is_instance_ptr == eLazyBoolYes; 2128cf44d96SEnrico Granata } 2138cf44d96SEnrico Granata 214b9c1b51eSKate Stone bool ValueObjectPrinter::PrintLocationIfNeeded() { 215b9c1b51eSKate Stone if (m_options.m_show_location) { 2164d93b8cdSEnrico Granata m_stream->Printf("%s: ", m_valobj->GetLocationAsCString()); 2174d93b8cdSEnrico Granata return true; 2184d93b8cdSEnrico Granata } 2194d93b8cdSEnrico Granata return false; 2204d93b8cdSEnrico Granata } 2214d93b8cdSEnrico Granata 222b9c1b51eSKate Stone void ValueObjectPrinter::PrintDecl() { 2234d93b8cdSEnrico Granata bool show_type = true; 224b9c1b51eSKate Stone // if we are at the root-level and been asked to hide the root's type, then 225b9c1b51eSKate Stone // hide it 22626014690SGreg Clayton if (m_curr_depth == 0 && m_options.m_hide_root_type) 2274d93b8cdSEnrico Granata show_type = false; 2284d93b8cdSEnrico Granata else 229b9c1b51eSKate Stone // otherwise decide according to the usual rules (asked to show types - 230b9c1b51eSKate Stone // always at the root level) 231b9c1b51eSKate Stone show_type = m_options.m_show_types || 232b9c1b51eSKate Stone (m_curr_depth == 0 && !m_options.m_flat_output); 2334d93b8cdSEnrico Granata 234e0ee1e1cSEnrico Granata StreamString typeName; 235e0ee1e1cSEnrico Granata 236e0ee1e1cSEnrico Granata // always show the type at the root level if it is invalid 237b9c1b51eSKate Stone if (show_type) { 23805097246SAdrian Prantl // Some ValueObjects don't have types (like registers sets). Only print the 23905097246SAdrian Prantl // type if there is one to print 240a126e462SEnrico Granata ConstString type_name; 241b9c1b51eSKate Stone if (m_compiler_type.IsValid()) { 24226014690SGreg Clayton if (m_options.m_use_type_display_name) 243a126e462SEnrico Granata type_name = m_valobj->GetDisplayTypeName(); 244e8daa2f8SEnrico Granata else 245a126e462SEnrico Granata type_name = m_valobj->GetQualifiedTypeName(); 246b9c1b51eSKate Stone } else { 247b9c1b51eSKate Stone // only show an invalid type name if the user explicitly triggered 248b9c1b51eSKate Stone // show_type 24926014690SGreg Clayton if (m_options.m_show_types) 250e0ee1e1cSEnrico Granata type_name = ConstString("<invalid type>"); 251e0ee1e1cSEnrico Granata else 252e0ee1e1cSEnrico Granata type_name.Clear(); 2534d93b8cdSEnrico Granata } 2544d93b8cdSEnrico Granata 255b9c1b51eSKate Stone if (type_name) { 256e0ee1e1cSEnrico Granata std::string type_name_str(type_name.GetCString()); 257b9c1b51eSKate Stone if (m_options.m_hide_pointer_value) { 258b9c1b51eSKate Stone for (auto iter = type_name_str.find(" *"); iter != std::string::npos; 259b9c1b51eSKate Stone iter = type_name_str.find(" *")) { 260e0ee1e1cSEnrico Granata type_name_str.erase(iter, 2); 261e0ee1e1cSEnrico Granata } 262e0ee1e1cSEnrico Granata } 263c8e7649aSEnrico Granata typeName.Printf("%s", type_name_str.c_str()); 264e0ee1e1cSEnrico Granata } 265e0ee1e1cSEnrico Granata } 266e0ee1e1cSEnrico Granata 267e0ee1e1cSEnrico Granata StreamString varName; 268e0ee1e1cSEnrico Granata 269b9c1b51eSKate Stone if (!m_options.m_hide_name) { 270*3014efe0SAlex Langford if (m_options.m_flat_output) 271*3014efe0SAlex Langford m_valobj->GetExpressionPath(varName); 272*3014efe0SAlex Langford else { 2734d93b8cdSEnrico Granata const char *name_cstr = GetRootNameForDisplay(""); 274e0ee1e1cSEnrico Granata varName.Printf("%s", name_cstr); 2754d93b8cdSEnrico Granata } 276*3014efe0SAlex Langford } 277e0ee1e1cSEnrico Granata 278e0ee1e1cSEnrico Granata bool decl_printed = false; 279b9c1b51eSKate Stone if (!m_options.m_decl_printing_helper) { 280b9c1b51eSKate Stone // if the user didn't give us a custom helper, pick one based upon the 281b9c1b51eSKate Stone // language, either the one that this printer is bound to, or the preferred 282b9c1b51eSKate Stone // one for the ValueObject 283b9c1b51eSKate Stone lldb::LanguageType lang_type = 284b9c1b51eSKate Stone (m_options.m_varformat_language == lldb::eLanguageTypeUnknown) 285b9c1b51eSKate Stone ? m_valobj->GetPreferredDisplayLanguage() 286b9c1b51eSKate Stone : m_options.m_varformat_language; 287b9c1b51eSKate Stone if (Language *lang_plugin = Language::FindPlugin(lang_type)) { 28826014690SGreg Clayton m_options.m_decl_printing_helper = lang_plugin->GetDeclPrintingHelper(); 289c8e7649aSEnrico Granata } 290c8e7649aSEnrico Granata } 291c8e7649aSEnrico Granata 292b9c1b51eSKate Stone if (m_options.m_decl_printing_helper) { 293c156427dSZachary Turner ConstString type_name_cstr(typeName.GetString()); 294c156427dSZachary Turner ConstString var_name_cstr(varName.GetString()); 295e0ee1e1cSEnrico Granata 296e0ee1e1cSEnrico Granata StreamString dest_stream; 297b9c1b51eSKate Stone if (m_options.m_decl_printing_helper(type_name_cstr, var_name_cstr, 298b9c1b51eSKate Stone m_options, dest_stream)) { 299e0ee1e1cSEnrico Granata decl_printed = true; 300c156427dSZachary Turner m_stream->PutCString(dest_stream.GetString()); 301e0ee1e1cSEnrico Granata } 302e0ee1e1cSEnrico Granata } 303e0ee1e1cSEnrico Granata 304c8e7649aSEnrico Granata // if the helper failed, or there is none, do a default thing 305b9c1b51eSKate Stone if (!decl_printed) { 306c156427dSZachary Turner if (!typeName.Empty()) 307c8e7649aSEnrico Granata m_stream->Printf("(%s) ", typeName.GetData()); 308c156427dSZachary Turner if (!varName.Empty()) 309e0ee1e1cSEnrico Granata m_stream->Printf("%s =", varName.GetData()); 31026014690SGreg Clayton else if (!m_options.m_hide_name) 311e0ee1e1cSEnrico Granata m_stream->Printf(" ="); 312e0ee1e1cSEnrico Granata } 3134d93b8cdSEnrico Granata } 3144d93b8cdSEnrico Granata 315b9c1b51eSKate Stone bool ValueObjectPrinter::CheckScopeIfNeeded() { 31626014690SGreg Clayton if (m_options.m_scope_already_checked) 3174d93b8cdSEnrico Granata return true; 3184d93b8cdSEnrico Granata return m_valobj->IsInScope(); 3194d93b8cdSEnrico Granata } 3204d93b8cdSEnrico Granata 321b9c1b51eSKate Stone TypeSummaryImpl *ValueObjectPrinter::GetSummaryFormatter(bool null_if_omitted) { 322a6682a41SJonas Devlieghere if (!m_summary_formatter.second) { 323b9c1b51eSKate Stone TypeSummaryImpl *entry = m_options.m_summary_sp 324b9c1b51eSKate Stone ? m_options.m_summary_sp.get() 325b9c1b51eSKate Stone : m_valobj->GetSummaryFormat().get(); 3264d93b8cdSEnrico Granata 32726014690SGreg Clayton if (m_options.m_omit_summary_depth > 0) 328248a1305SKonrad Kleine entry = nullptr; 3294d93b8cdSEnrico Granata m_summary_formatter.first = entry; 3304d93b8cdSEnrico Granata m_summary_formatter.second = true; 3314d93b8cdSEnrico Granata } 3328cf44d96SEnrico Granata if (m_options.m_omit_summary_depth > 0 && null_if_omitted) 3338cf44d96SEnrico Granata return nullptr; 3344d93b8cdSEnrico Granata return m_summary_formatter.first; 3354d93b8cdSEnrico Granata } 3364d93b8cdSEnrico Granata 337b9c1b51eSKate Stone static bool IsPointerValue(const CompilerType &type) { 338e0ee1e1cSEnrico Granata Flags type_flags(type.GetTypeInfo()); 3398cf44d96SEnrico Granata if (type_flags.AnySet(eTypeInstanceIsPointer | eTypeIsPointer)) 340e0ee1e1cSEnrico Granata return type_flags.AllClear(eTypeIsBuiltIn); 341e0ee1e1cSEnrico Granata return false; 342e0ee1e1cSEnrico Granata } 343e0ee1e1cSEnrico Granata 344b9c1b51eSKate Stone void ValueObjectPrinter::GetValueSummaryError(std::string &value, 3454d93b8cdSEnrico Granata std::string &summary, 346b9c1b51eSKate Stone std::string &error) { 347520a422bSEnrico Granata lldb::Format format = m_options.m_format; 348b9c1b51eSKate Stone // if I am printing synthetized elements, apply the format to those elements 349b9c1b51eSKate Stone // only 3509ac0dac1SEnrico Granata if (m_options.m_pointer_as_array) 351520a422bSEnrico Granata m_valobj->GetValueAsCString(lldb::eFormatDefault, value); 352520a422bSEnrico Granata else if (format != eFormatDefault && format != m_valobj->GetFormat()) 353520a422bSEnrico Granata m_valobj->GetValueAsCString(format, value); 354b9c1b51eSKate Stone else { 3554d93b8cdSEnrico Granata const char *val_cstr = m_valobj->GetValueAsCString(); 356465f4bc2SEnrico Granata if (val_cstr) 357465f4bc2SEnrico Granata value.assign(val_cstr); 358465f4bc2SEnrico Granata } 3594d93b8cdSEnrico Granata const char *err_cstr = m_valobj->GetError().AsCString(); 3604d93b8cdSEnrico Granata if (err_cstr) 3614d93b8cdSEnrico Granata error.assign(err_cstr); 3624d93b8cdSEnrico Granata 363b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 3644d93b8cdSEnrico Granata if (IsNil()) 3654d93b8cdSEnrico Granata summary.assign("nil"); 366608d67c1SEnrico Granata else if (IsUninitialized()) 367608d67c1SEnrico Granata summary.assign("<uninitialized>"); 368b9c1b51eSKate Stone else if (m_options.m_omit_summary_depth == 0) { 3694d93b8cdSEnrico Granata TypeSummaryImpl *entry = GetSummaryFormatter(); 3704d93b8cdSEnrico Granata if (entry) 371b9c1b51eSKate Stone m_valobj->GetSummaryAsCString(entry, summary, 372b9c1b51eSKate Stone m_options.m_varformat_language); 373b9c1b51eSKate Stone else { 374b9c1b51eSKate Stone const char *sum_cstr = 375b9c1b51eSKate Stone m_valobj->GetSummaryAsCString(m_options.m_varformat_language); 3764d93b8cdSEnrico Granata if (sum_cstr) 3774d93b8cdSEnrico Granata summary.assign(sum_cstr); 3784d93b8cdSEnrico Granata } 3794d93b8cdSEnrico Granata } 3804d93b8cdSEnrico Granata } 3814d93b8cdSEnrico Granata } 3824d93b8cdSEnrico Granata 383b9c1b51eSKate Stone bool ValueObjectPrinter::PrintValueAndSummaryIfNeeded(bool &value_printed, 384b9c1b51eSKate Stone bool &summary_printed) { 3854d93b8cdSEnrico Granata bool error_printed = false; 386b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 3874d93b8cdSEnrico Granata if (!CheckScopeIfNeeded()) 3884d93b8cdSEnrico Granata m_error.assign("out of scope"); 389b9c1b51eSKate Stone if (m_error.empty()) { 3904d93b8cdSEnrico Granata GetValueSummaryError(m_value, m_summary, m_error); 3914d93b8cdSEnrico Granata } 392b9c1b51eSKate Stone if (m_error.size()) { 393b9c1b51eSKate Stone // we need to support scenarios in which it is actually fine for a value 39405097246SAdrian Prantl // to have no type but - on the other hand - if we get an error *AND* 39505097246SAdrian Prantl // have no type, we try to get out gracefully, since most often that 39605097246SAdrian Prantl // combination means "could not resolve a type" and the default failure 39705097246SAdrian Prantl // mode is quite ugly 398b9c1b51eSKate Stone if (!m_compiler_type.IsValid()) { 3998cf44d96SEnrico Granata m_stream->Printf(" <could not resolve type>"); 4008cf44d96SEnrico Granata return false; 4018cf44d96SEnrico Granata } 4028cf44d96SEnrico Granata 4034d93b8cdSEnrico Granata error_printed = true; 4044d93b8cdSEnrico Granata m_stream->Printf(" <%s>\n", m_error.c_str()); 405b9c1b51eSKate Stone } else { 40605097246SAdrian Prantl // Make sure we have a value and make sure the summary didn't specify 40705097246SAdrian Prantl // that the value should not be printed - and do not print the value if 40805097246SAdrian Prantl // this thing is nil (but show the value if the user passes a format 40905097246SAdrian Prantl // explicitly) 4104d93b8cdSEnrico Granata TypeSummaryImpl *entry = GetSummaryFormatter(); 411b9c1b51eSKate Stone if (!IsNil() && !IsUninitialized() && !m_value.empty() && 412248a1305SKonrad Kleine (entry == nullptr || 413248a1305SKonrad Kleine (entry->DoesPrintValue(m_valobj) || 414b9c1b51eSKate Stone m_options.m_format != eFormatDefault) || 415b9c1b51eSKate Stone m_summary.empty()) && 416b9c1b51eSKate Stone !m_options.m_hide_value) { 417b9c1b51eSKate Stone if (m_options.m_hide_pointer_value && 418b9c1b51eSKate Stone IsPointerValue(m_valobj->GetCompilerType())) { 419b9c1b51eSKate Stone } else { 4204d93b8cdSEnrico Granata m_stream->Printf(" %s", m_value.c_str()); 4214d93b8cdSEnrico Granata value_printed = true; 4224d93b8cdSEnrico Granata } 423e0ee1e1cSEnrico Granata } 4244d93b8cdSEnrico Granata 425b9c1b51eSKate Stone if (m_summary.size()) { 4264d93b8cdSEnrico Granata m_stream->Printf(" %s", m_summary.c_str()); 4274d93b8cdSEnrico Granata summary_printed = true; 4284d93b8cdSEnrico Granata } 4294d93b8cdSEnrico Granata } 4304d93b8cdSEnrico Granata } 4314d93b8cdSEnrico Granata return !error_printed; 4324d93b8cdSEnrico Granata } 4334d93b8cdSEnrico Granata 434b9c1b51eSKate Stone bool ValueObjectPrinter::PrintObjectDescriptionIfNeeded(bool value_printed, 435b9c1b51eSKate Stone bool summary_printed) { 436b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 4374d93b8cdSEnrico Granata // let's avoid the overly verbose no description error for a nil thing 438b9c1b51eSKate Stone if (m_options.m_use_objc && !IsNil() && !IsUninitialized() && 4399ac0dac1SEnrico Granata (!m_options.m_pointer_as_array)) { 44026014690SGreg Clayton if (!m_options.m_hide_value || !m_options.m_hide_name) 4414d93b8cdSEnrico Granata m_stream->Printf(" "); 4424d93b8cdSEnrico Granata const char *object_desc = nullptr; 4434d93b8cdSEnrico Granata if (value_printed || summary_printed) 4444d93b8cdSEnrico Granata object_desc = m_valobj->GetObjectDescription(); 4454d93b8cdSEnrico Granata else 4464d93b8cdSEnrico Granata object_desc = GetDescriptionForDisplay(); 447b9c1b51eSKate Stone if (object_desc && *object_desc) { 448b9923589SJim Ingham // If the description already ends with a \n don't add another one. 449b9923589SJim Ingham size_t object_end = strlen(object_desc) - 1; 450b9923589SJim Ingham if (object_desc[object_end] == '\n') 451b9923589SJim Ingham m_stream->Printf("%s", object_desc); 452b9923589SJim Ingham else 4534d93b8cdSEnrico Granata m_stream->Printf("%s\n", object_desc); 4544d93b8cdSEnrico Granata return true; 455a6682a41SJonas Devlieghere } else if (!value_printed && !summary_printed) 4564d93b8cdSEnrico Granata return true; 4574d93b8cdSEnrico Granata else 4584d93b8cdSEnrico Granata return false; 4594d93b8cdSEnrico Granata } 4604d93b8cdSEnrico Granata } 4614d93b8cdSEnrico Granata return true; 4624d93b8cdSEnrico Granata } 4634d93b8cdSEnrico Granata 464b9c1b51eSKate Stone bool DumpValueObjectOptions::PointerDepth::CanAllowExpansion() const { 465b9c1b51eSKate Stone switch (m_mode) { 466c1b7c09aSEnrico Granata case Mode::Always: 467c1b7c09aSEnrico Granata case Mode::Default: 468e4e17b8cSTamas Berghammer return m_count > 0; 469c1b7c09aSEnrico Granata case Mode::Never: 470c1b7c09aSEnrico Granata return false; 471c1b7c09aSEnrico Granata } 47284f5b0dfSZachary Turner return false; 473c1b7c09aSEnrico Granata } 474c1b7c09aSEnrico Granata 475b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldPrintChildren( 476b9c1b51eSKate Stone bool is_failed_description, 477b9c1b51eSKate Stone DumpValueObjectOptions::PointerDepth &curr_ptr_depth) { 4784d93b8cdSEnrico Granata const bool is_ref = IsRef(); 4794d93b8cdSEnrico Granata const bool is_ptr = IsPtr(); 480608d67c1SEnrico Granata const bool is_uninit = IsUninitialized(); 481608d67c1SEnrico Granata 482608d67c1SEnrico Granata if (is_uninit) 483608d67c1SEnrico Granata return false; 4844d93b8cdSEnrico Granata 48505097246SAdrian Prantl // if the user has specified an element count, always print children as it is 48605097246SAdrian Prantl // explicit user demand being honored 4879ac0dac1SEnrico Granata if (m_options.m_pointer_as_array) 488520a422bSEnrico Granata return true; 489520a422bSEnrico Granata 490c1b7c09aSEnrico Granata TypeSummaryImpl *entry = GetSummaryFormatter(); 491c1b7c09aSEnrico Granata 4928cf44d96SEnrico Granata if (m_options.m_use_objc) 4938cf44d96SEnrico Granata return false; 4948cf44d96SEnrico Granata 495b9c1b51eSKate Stone if (is_failed_description || m_curr_depth < m_options.m_max_depth) { 49605097246SAdrian Prantl // We will show children for all concrete types. We won't show pointer 49705097246SAdrian Prantl // contents unless a pointer depth has been specified. We won't reference 49805097246SAdrian Prantl // contents unless the reference is the root object (depth of zero). 4994d93b8cdSEnrico Granata 50005097246SAdrian Prantl // Use a new temporary pointer depth in case we override the current 50105097246SAdrian Prantl // pointer depth below... 5024d93b8cdSEnrico Granata 503b9c1b51eSKate Stone if (is_ptr || is_ref) { 50405097246SAdrian Prantl // We have a pointer or reference whose value is an address. Make sure 50505097246SAdrian Prantl // that address is not NULL 5064d93b8cdSEnrico Granata AddressType ptr_address_type; 5074d93b8cdSEnrico Granata if (m_valobj->GetPointerValue(&ptr_address_type) == 0) 5084d93b8cdSEnrico Granata return false; 5094d93b8cdSEnrico Granata 510c1b7c09aSEnrico Granata const bool is_root_level = m_curr_depth == 0; 511c1b7c09aSEnrico Granata 512b9c1b51eSKate Stone if (is_ref && is_root_level) { 51305097246SAdrian Prantl // If this is the root object (depth is zero) that we are showing and 51405097246SAdrian Prantl // it is a reference, and no pointer depth has been supplied print out 51505097246SAdrian Prantl // what it references. Don't do this at deeper depths otherwise we can 51605097246SAdrian Prantl // end up with infinite recursion... 517c1b7c09aSEnrico Granata return true; 5184d93b8cdSEnrico Granata } 5194d93b8cdSEnrico Granata 520e4e17b8cSTamas Berghammer return curr_ptr_depth.CanAllowExpansion(); 5214d93b8cdSEnrico Granata } 5224d93b8cdSEnrico Granata 5238a068e6cSEnrico Granata return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty()); 5244d93b8cdSEnrico Granata } 5254d93b8cdSEnrico Granata return false; 5264d93b8cdSEnrico Granata } 5274d93b8cdSEnrico Granata 528b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldExpandEmptyAggregates() { 529d26eb907SSiva Chandra TypeSummaryImpl *entry = GetSummaryFormatter(); 530d26eb907SSiva Chandra 531d26eb907SSiva Chandra if (!entry) 532d26eb907SSiva Chandra return true; 533d26eb907SSiva Chandra 534d26eb907SSiva Chandra return entry->DoesPrintEmptyAggregates(); 535d26eb907SSiva Chandra } 536d26eb907SSiva Chandra 537b9c1b51eSKate Stone ValueObject *ValueObjectPrinter::GetValueObjectForChildrenGeneration() { 538d07cfd3aSEnrico Granata return m_valobj; 5394d93b8cdSEnrico Granata } 5404d93b8cdSEnrico Granata 541b9c1b51eSKate Stone void ValueObjectPrinter::PrintChildrenPreamble() { 542b9c1b51eSKate Stone if (m_options.m_flat_output) { 5434d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 5444d93b8cdSEnrico Granata m_stream->EOL(); 545b9c1b51eSKate Stone } else { 5464d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 5474d93b8cdSEnrico Granata m_stream->PutCString(IsRef() ? ": {\n" : " {\n"); 5484d93b8cdSEnrico Granata m_stream->IndentMore(); 5494d93b8cdSEnrico Granata } 5504d93b8cdSEnrico Granata } 5514d93b8cdSEnrico Granata 552b9c1b51eSKate Stone void ValueObjectPrinter::PrintChild( 553b9c1b51eSKate Stone ValueObjectSP child_sp, 554b9c1b51eSKate Stone const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) { 5559ac0dac1SEnrico Granata const uint32_t consumed_depth = (!m_options.m_pointer_as_array) ? 1 : 0; 556b9c1b51eSKate Stone const bool does_consume_ptr_depth = 5579ac0dac1SEnrico Granata ((IsPtr() && !m_options.m_pointer_as_array) || IsRef()); 558520a422bSEnrico Granata 55926014690SGreg Clayton DumpValueObjectOptions child_options(m_options); 560b9c1b51eSKate Stone child_options.SetFormat(m_options.m_format) 561b9c1b51eSKate Stone .SetSummary() 562b9c1b51eSKate Stone .SetRootValueObjectName(); 563b9c1b51eSKate Stone child_options.SetScopeChecked(true) 564b9c1b51eSKate Stone .SetHideName(m_options.m_hide_name) 565b9c1b51eSKate Stone .SetHideValue(m_options.m_hide_value) 566b9c1b51eSKate Stone .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 567b9c1b51eSKate Stone ? child_options.m_omit_summary_depth - 568b9c1b51eSKate Stone consumed_depth 569b9c1b51eSKate Stone : 0) 570520a422bSEnrico Granata .SetElementCount(0); 5718cf44d96SEnrico Granata 572b9c1b51eSKate Stone if (child_sp.get()) { 573b9c1b51eSKate Stone ValueObjectPrinter child_printer( 574b9c1b51eSKate Stone child_sp.get(), m_stream, child_options, 575520a422bSEnrico Granata does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth, 576b9c1b51eSKate Stone m_curr_depth + consumed_depth, m_printed_instance_pointers); 5774d93b8cdSEnrico Granata child_printer.PrintValueObject(); 5784d93b8cdSEnrico Granata } 5794d93b8cdSEnrico Granata } 5804d93b8cdSEnrico Granata 581b9c1b51eSKate Stone uint32_t ValueObjectPrinter::GetMaxNumChildrenToPrint(bool &print_dotdotdot) { 5824d93b8cdSEnrico Granata ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration(); 5834d93b8cdSEnrico Granata 5849ac0dac1SEnrico Granata if (m_options.m_pointer_as_array) 5859ac0dac1SEnrico Granata return m_options.m_pointer_as_array.m_element_count; 586520a422bSEnrico Granata 5874d93b8cdSEnrico Granata size_t num_children = synth_m_valobj->GetNumChildren(); 5884d93b8cdSEnrico Granata print_dotdotdot = false; 589b9c1b51eSKate Stone if (num_children) { 590b9c1b51eSKate Stone const size_t max_num_children = 591b9c1b51eSKate Stone m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 5924d93b8cdSEnrico Granata 593b9c1b51eSKate Stone if (num_children > max_num_children && !m_options.m_ignore_cap) { 5944d93b8cdSEnrico Granata print_dotdotdot = true; 5954d93b8cdSEnrico Granata return max_num_children; 5964d93b8cdSEnrico Granata } 5974d93b8cdSEnrico Granata } 5984d93b8cdSEnrico Granata return num_children; 5994d93b8cdSEnrico Granata } 6004d93b8cdSEnrico Granata 601b9c1b51eSKate Stone void ValueObjectPrinter::PrintChildrenPostamble(bool print_dotdotdot) { 602b9c1b51eSKate Stone if (!m_options.m_flat_output) { 603b9c1b51eSKate Stone if (print_dotdotdot) { 604b9c1b51eSKate Stone m_valobj->GetTargetSP() 605b9c1b51eSKate Stone ->GetDebugger() 606b9c1b51eSKate Stone .GetCommandInterpreter() 607b9c1b51eSKate Stone .ChildrenTruncated(); 6084d93b8cdSEnrico Granata m_stream->Indent("...\n"); 6094d93b8cdSEnrico Granata } 6104d93b8cdSEnrico Granata m_stream->IndentLess(); 6114d93b8cdSEnrico Granata m_stream->Indent("}\n"); 6124d93b8cdSEnrico Granata } 6134d93b8cdSEnrico Granata } 6144d93b8cdSEnrico Granata 615b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldPrintEmptyBrackets(bool value_printed, 616b9c1b51eSKate Stone bool summary_printed) { 6178cf44d96SEnrico Granata ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration(); 6188cf44d96SEnrico Granata 6198cf44d96SEnrico Granata if (!IsAggregate()) 6208cf44d96SEnrico Granata return false; 6218cf44d96SEnrico Granata 622a6682a41SJonas Devlieghere if (!m_options.m_reveal_empty_aggregates) { 6238cf44d96SEnrico Granata if (value_printed || summary_printed) 6248cf44d96SEnrico Granata return false; 6258cf44d96SEnrico Granata } 6268cf44d96SEnrico Granata 6278cf44d96SEnrico Granata if (synth_m_valobj->MightHaveChildren()) 6288cf44d96SEnrico Granata return true; 6298cf44d96SEnrico Granata 6308cf44d96SEnrico Granata if (m_val_summary_ok) 6318cf44d96SEnrico Granata return false; 6328cf44d96SEnrico Granata 6338cf44d96SEnrico Granata return true; 6348cf44d96SEnrico Granata } 6358cf44d96SEnrico Granata 6369ac0dac1SEnrico Granata static constexpr size_t PhysicalIndexForLogicalIndex(size_t base, size_t stride, 6379ac0dac1SEnrico Granata size_t logical) { 6389ac0dac1SEnrico Granata return base + logical * stride; 6399ac0dac1SEnrico Granata } 6409ac0dac1SEnrico Granata 641b9c1b51eSKate Stone ValueObjectSP ValueObjectPrinter::GenerateChild(ValueObject *synth_valobj, 642b9c1b51eSKate Stone size_t idx) { 6439ac0dac1SEnrico Granata if (m_options.m_pointer_as_array) { 644520a422bSEnrico Granata // if generating pointer-as-array children, use GetSyntheticArrayMember 6459ac0dac1SEnrico Granata return synth_valobj->GetSyntheticArrayMember( 6469ac0dac1SEnrico Granata PhysicalIndexForLogicalIndex( 6479ac0dac1SEnrico Granata m_options.m_pointer_as_array.m_base_element, 6489ac0dac1SEnrico Granata m_options.m_pointer_as_array.m_stride, idx), 6499ac0dac1SEnrico Granata true); 650b9c1b51eSKate Stone } else { 651520a422bSEnrico Granata // otherwise, do the usual thing 652520a422bSEnrico Granata return synth_valobj->GetChildAtIndex(idx, true); 653520a422bSEnrico Granata } 654520a422bSEnrico Granata } 655520a422bSEnrico Granata 656b9c1b51eSKate Stone void ValueObjectPrinter::PrintChildren( 657b9c1b51eSKate Stone bool value_printed, bool summary_printed, 658b9c1b51eSKate Stone const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) { 6594d93b8cdSEnrico Granata ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration(); 6604d93b8cdSEnrico Granata 6614d93b8cdSEnrico Granata bool print_dotdotdot = false; 6624d93b8cdSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 663b9c1b51eSKate Stone if (num_children) { 6648cf44d96SEnrico Granata bool any_children_printed = false; 6654d93b8cdSEnrico Granata 666b9c1b51eSKate Stone for (size_t idx = 0; idx < num_children; ++idx) { 667b9c1b51eSKate Stone if (ValueObjectSP child_sp = GenerateChild(synth_m_valobj, idx)) { 668b9c1b51eSKate Stone if (!any_children_printed) { 6698cf44d96SEnrico Granata PrintChildrenPreamble(); 6708cf44d96SEnrico Granata any_children_printed = true; 6718cf44d96SEnrico Granata } 6724d93b8cdSEnrico Granata PrintChild(child_sp, curr_ptr_depth); 6734d93b8cdSEnrico Granata } 6744d93b8cdSEnrico Granata } 6758cf44d96SEnrico Granata 6768cf44d96SEnrico Granata if (any_children_printed) 6778cf44d96SEnrico Granata PrintChildrenPostamble(print_dotdotdot); 678b9c1b51eSKate Stone else { 679b9c1b51eSKate Stone if (ShouldPrintEmptyBrackets(value_printed, summary_printed)) { 6808cf44d96SEnrico Granata if (ShouldPrintValueObject()) 6818cf44d96SEnrico Granata m_stream->PutCString(" {}\n"); 6828cf44d96SEnrico Granata else 6838cf44d96SEnrico Granata m_stream->EOL(); 684b9c1b51eSKate Stone } else 6858cf44d96SEnrico Granata m_stream->EOL(); 6868cf44d96SEnrico Granata } 687b9c1b51eSKate Stone } else if (ShouldPrintEmptyBrackets(value_printed, summary_printed)) { 6884d93b8cdSEnrico Granata // Aggregate, no children... 689b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 690b9c1b51eSKate Stone // if it has a synthetic value, then don't print {}, the synthetic 691b9c1b51eSKate Stone // children are probably only being used to vend a value 692b9c1b51eSKate Stone if (m_valobj->DoesProvideSyntheticValue() || 693b9c1b51eSKate Stone !ShouldExpandEmptyAggregates()) 694d07cfd3aSEnrico Granata m_stream->PutCString("\n"); 695d07cfd3aSEnrico Granata else 6964d93b8cdSEnrico Granata m_stream->PutCString(" {}\n"); 6974d93b8cdSEnrico Granata } 698b9c1b51eSKate Stone } else { 6994d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 7004d93b8cdSEnrico Granata m_stream->EOL(); 7014d93b8cdSEnrico Granata } 7024d93b8cdSEnrico Granata } 7034d93b8cdSEnrico Granata 704b9c1b51eSKate Stone bool ValueObjectPrinter::PrintChildrenOneLiner(bool hide_names) { 705d07cfd3aSEnrico Granata if (!GetMostSpecializedValue() || m_valobj == nullptr) 706a29cb0baSEnrico Granata return false; 707a29cb0baSEnrico Granata 708a29cb0baSEnrico Granata ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration(); 709a29cb0baSEnrico Granata 710a29cb0baSEnrico Granata bool print_dotdotdot = false; 711a29cb0baSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 712a29cb0baSEnrico Granata 713b9c1b51eSKate Stone if (num_children) { 714a29cb0baSEnrico Granata m_stream->PutChar('('); 715a29cb0baSEnrico Granata 716b9c1b51eSKate Stone for (uint32_t idx = 0; idx < num_children; ++idx) { 717a29cb0baSEnrico Granata lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 718ddac7611SEnrico Granata if (child_sp) 719b9c1b51eSKate Stone child_sp = child_sp->GetQualifiedRepresentationIfAvailable( 720b9c1b51eSKate Stone m_options.m_use_dynamic, m_options.m_use_synthetic); 721b9c1b51eSKate Stone if (child_sp) { 722a29cb0baSEnrico Granata if (idx) 723a29cb0baSEnrico Granata m_stream->PutCString(", "); 724b9c1b51eSKate Stone if (!hide_names) { 725a29cb0baSEnrico Granata const char *name = child_sp.get()->GetName().AsCString(); 726b9c1b51eSKate Stone if (name && *name) { 727a29cb0baSEnrico Granata m_stream->PutCString(name); 728a29cb0baSEnrico Granata m_stream->PutCString(" = "); 729a29cb0baSEnrico Granata } 730a29cb0baSEnrico Granata } 731b9c1b51eSKate Stone child_sp->DumpPrintableRepresentation( 732b9c1b51eSKate Stone *m_stream, ValueObject::eValueObjectRepresentationStyleSummary, 7337aafb6a1SEnrico Granata m_options.m_format, 73465d86e4fSEnrico Granata ValueObject::PrintableRepresentationSpecialCases::eDisable); 735a29cb0baSEnrico Granata } 736a29cb0baSEnrico Granata } 737a29cb0baSEnrico Granata 738a29cb0baSEnrico Granata if (print_dotdotdot) 739a29cb0baSEnrico Granata m_stream->PutCString(", ...)"); 740a29cb0baSEnrico Granata else 741a29cb0baSEnrico Granata m_stream->PutChar(')'); 742a29cb0baSEnrico Granata } 743a29cb0baSEnrico Granata return true; 744a29cb0baSEnrico Granata } 745a29cb0baSEnrico Granata 746b9c1b51eSKate Stone void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed, 747b9c1b51eSKate Stone bool summary_printed) { 748dc333e63SJonas Devlieghere // This flag controls whether we tried to display a description for this 749dc333e63SJonas Devlieghere // object and failed if that happens, we want to display the children if any. 750b9c1b51eSKate Stone bool is_failed_description = 751b9c1b51eSKate Stone !PrintObjectDescriptionIfNeeded(value_printed, summary_printed); 7524d93b8cdSEnrico Granata 753dc333e63SJonas Devlieghere DumpValueObjectOptions::PointerDepth curr_ptr_depth = m_ptr_depth; 754dc333e63SJonas Devlieghere const bool print_children = 755b9c1b51eSKate Stone ShouldPrintChildren(is_failed_description, curr_ptr_depth); 756dc333e63SJonas Devlieghere const bool print_oneline = 757b9c1b51eSKate Stone (curr_ptr_depth.CanAllowExpansion() || m_options.m_show_types || 758b9c1b51eSKate Stone !m_options.m_allow_oneliner_mode || m_options.m_flat_output || 7599ac0dac1SEnrico Granata (m_options.m_pointer_as_array) || m_options.m_show_location) 760b9c1b51eSKate Stone ? false 761b9c1b51eSKate Stone : DataVisualization::ShouldPrintAsOneLiner(*m_valobj); 762dc333e63SJonas Devlieghere if (print_children && IsInstancePointer()) { 763dc333e63SJonas Devlieghere uint64_t instance_ptr_value = m_valobj->GetValueAsUnsigned(0); 764b9c1b51eSKate Stone if (m_printed_instance_pointers->count(instance_ptr_value)) { 765dc333e63SJonas Devlieghere // We already printed this instance-is-pointer thing, so don't expand it. 7668cf44d96SEnrico Granata m_stream->PutCString(" {...}\n"); 7678cf44d96SEnrico Granata return; 768dc333e63SJonas Devlieghere } else { 769dc333e63SJonas Devlieghere // Remember this guy for future reference. 770dc333e63SJonas Devlieghere m_printed_instance_pointers->emplace(instance_ptr_value); 771dc333e63SJonas Devlieghere } 7728cf44d96SEnrico Granata } 7734d93b8cdSEnrico Granata 774b9c1b51eSKate Stone if (print_children) { 775b9c1b51eSKate Stone if (print_oneline) { 776a29cb0baSEnrico Granata m_stream->PutChar(' '); 777a29cb0baSEnrico Granata PrintChildrenOneLiner(false); 778a29cb0baSEnrico Granata m_stream->EOL(); 779b9c1b51eSKate Stone } else 780c1b7c09aSEnrico Granata PrintChildren(value_printed, summary_printed, curr_ptr_depth); 781b9c1b51eSKate Stone } else if (m_curr_depth >= m_options.m_max_depth && IsAggregate() && 782b9c1b51eSKate Stone ShouldPrintValueObject()) { 7834d93b8cdSEnrico Granata m_stream->PutCString("{...}\n"); 784b9c1b51eSKate Stone } else 785245b3caaSEnrico Granata m_stream->EOL(); 7864d93b8cdSEnrico Granata } 787