1b9c1b51eSKate Stone //===-- ValueObjectPrinter.cpp -------------------------------------*- C++ 2b9c1b51eSKate Stone //-*-===// 34d93b8cdSEnrico Granata // 44d93b8cdSEnrico Granata // The LLVM Compiler Infrastructure 54d93b8cdSEnrico Granata // 64d93b8cdSEnrico Granata // This file is distributed under the University of Illinois Open Source 74d93b8cdSEnrico Granata // License. See LICENSE.TXT for details. 84d93b8cdSEnrico Granata // 94d93b8cdSEnrico Granata //===----------------------------------------------------------------------===// 104d93b8cdSEnrico Granata 114d93b8cdSEnrico Granata #include "lldb/DataFormatters/ValueObjectPrinter.h" 124d93b8cdSEnrico Granata 134d93b8cdSEnrico Granata // C Includes 144d93b8cdSEnrico Granata // C++ Includes 154d93b8cdSEnrico Granata // Other libraries and framework includes 164d93b8cdSEnrico Granata // Project includes 17c8e7649aSEnrico Granata #include "lldb/Core/Stream.h" 18c8e7649aSEnrico Granata #include "lldb/Core/ValueObject.h" 19a29cb0baSEnrico Granata #include "lldb/DataFormatters/DataVisualization.h" 204d93b8cdSEnrico Granata #include "lldb/Interpreter/CommandInterpreter.h" 21c8e7649aSEnrico Granata #include "lldb/Target/Language.h" 224d93b8cdSEnrico Granata #include "lldb/Target/Target.h" 234d93b8cdSEnrico Granata 244d93b8cdSEnrico Granata using namespace lldb; 254d93b8cdSEnrico Granata using namespace lldb_private; 264d93b8cdSEnrico Granata 27b9c1b51eSKate Stone ValueObjectPrinter::ValueObjectPrinter(ValueObject *valobj, Stream *s) { 28b9c1b51eSKate Stone if (valobj) { 29d5957336SEnrico Granata DumpValueObjectOptions options(*valobj); 308cf44d96SEnrico Granata Init(valobj, s, options, m_options.m_max_ptr_depth, 0, nullptr); 31b9c1b51eSKate Stone } else { 32d5957336SEnrico Granata DumpValueObjectOptions options; 338cf44d96SEnrico Granata Init(valobj, s, options, m_options.m_max_ptr_depth, 0, nullptr); 34d5957336SEnrico Granata } 35d5957336SEnrico Granata } 36d5957336SEnrico Granata 37b9c1b51eSKate Stone ValueObjectPrinter::ValueObjectPrinter(ValueObject *valobj, Stream *s, 38b9c1b51eSKate Stone const DumpValueObjectOptions &options) { 398cf44d96SEnrico Granata Init(valobj, s, options, m_options.m_max_ptr_depth, 0, nullptr); 404d93b8cdSEnrico Granata } 414d93b8cdSEnrico Granata 42b9c1b51eSKate Stone ValueObjectPrinter::ValueObjectPrinter( 43b9c1b51eSKate Stone ValueObject *valobj, Stream *s, const DumpValueObjectOptions &options, 44b9c1b51eSKate Stone const DumpValueObjectOptions::PointerDepth &ptr_depth, uint32_t curr_depth, 45b9c1b51eSKate Stone InstancePointersSetSP printed_instance_pointers) { 468cf44d96SEnrico Granata Init(valobj, s, options, ptr_depth, curr_depth, printed_instance_pointers); 47938d1d67SEnrico Granata } 48938d1d67SEnrico Granata 49b9c1b51eSKate Stone void ValueObjectPrinter::Init( 50b9c1b51eSKate Stone ValueObject *valobj, Stream *s, const DumpValueObjectOptions &options, 51b9c1b51eSKate Stone const DumpValueObjectOptions::PointerDepth &ptr_depth, uint32_t curr_depth, 52b9c1b51eSKate Stone InstancePointersSetSP printed_instance_pointers) { 53938d1d67SEnrico Granata m_orig_valobj = valobj; 54938d1d67SEnrico Granata m_valobj = nullptr; 55938d1d67SEnrico Granata m_stream = s; 5626014690SGreg Clayton m_options = options; 57938d1d67SEnrico Granata m_ptr_depth = ptr_depth; 58938d1d67SEnrico Granata m_curr_depth = curr_depth; 59938d1d67SEnrico Granata assert(m_orig_valobj && "cannot print a NULL ValueObject"); 60938d1d67SEnrico Granata assert(m_stream && "cannot print to a NULL Stream"); 61938d1d67SEnrico Granata m_should_print = eLazyBoolCalculate; 62938d1d67SEnrico Granata m_is_nil = eLazyBoolCalculate; 63608d67c1SEnrico Granata m_is_uninit = eLazyBoolCalculate; 64938d1d67SEnrico Granata m_is_ptr = eLazyBoolCalculate; 65938d1d67SEnrico Granata m_is_ref = eLazyBoolCalculate; 66938d1d67SEnrico Granata m_is_aggregate = eLazyBoolCalculate; 678cf44d96SEnrico Granata m_is_instance_ptr = eLazyBoolCalculate; 68938d1d67SEnrico Granata m_summary_formatter = {nullptr, false}; 69938d1d67SEnrico Granata m_value.assign(""); 70938d1d67SEnrico Granata m_summary.assign(""); 71938d1d67SEnrico Granata m_error.assign(""); 728cf44d96SEnrico Granata m_val_summary_ok = false; 73b9c1b51eSKate Stone m_printed_instance_pointers = 74b9c1b51eSKate Stone printed_instance_pointers 75b9c1b51eSKate Stone ? printed_instance_pointers 76b9c1b51eSKate Stone : InstancePointersSetSP(new InstancePointersSet()); 77938d1d67SEnrico Granata } 784d93b8cdSEnrico Granata 79b9c1b51eSKate Stone bool ValueObjectPrinter::PrintValueObject() { 80d07cfd3aSEnrico Granata if (!GetMostSpecializedValue() || m_valobj == nullptr) 814d93b8cdSEnrico Granata return false; 824d93b8cdSEnrico Granata 83b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 840f883ffbSEnrico Granata PrintValidationMarkerIfNeeded(); 850f883ffbSEnrico Granata 864d93b8cdSEnrico Granata PrintLocationIfNeeded(); 874d93b8cdSEnrico Granata m_stream->Indent(); 884d93b8cdSEnrico Granata 89e0ee1e1cSEnrico Granata PrintDecl(); 904d93b8cdSEnrico Granata } 914d93b8cdSEnrico Granata 924d93b8cdSEnrico Granata bool value_printed = false; 934d93b8cdSEnrico Granata bool summary_printed = false; 944d93b8cdSEnrico Granata 95b9c1b51eSKate Stone m_val_summary_ok = 96b9c1b51eSKate Stone PrintValueAndSummaryIfNeeded(value_printed, summary_printed); 974d93b8cdSEnrico Granata 988cf44d96SEnrico Granata if (m_val_summary_ok) 994d93b8cdSEnrico Granata PrintChildrenIfNeeded(value_printed, summary_printed); 10039938938SEnrico Granata else 1014d93b8cdSEnrico Granata m_stream->EOL(); 1024d93b8cdSEnrico Granata 1030f883ffbSEnrico Granata PrintValidationErrorIfNeeded(); 1040f883ffbSEnrico Granata 1054d93b8cdSEnrico Granata return true; 1064d93b8cdSEnrico Granata } 1074d93b8cdSEnrico Granata 108b9c1b51eSKate Stone bool ValueObjectPrinter::GetMostSpecializedValue() { 109a29cb0baSEnrico Granata if (m_valobj) 110a29cb0baSEnrico Granata return true; 1114d93b8cdSEnrico Granata bool update_success = m_orig_valobj->UpdateValueIfNeeded(true); 112b9c1b51eSKate Stone if (!update_success) { 113106260c5SEnrico Granata m_valobj = m_orig_valobj; 114b9c1b51eSKate Stone } else { 115b9c1b51eSKate Stone if (m_orig_valobj->IsDynamic()) { 116b9c1b51eSKate Stone if (m_options.m_use_dynamic == eNoDynamicValues) { 117106260c5SEnrico Granata ValueObject *static_value = m_orig_valobj->GetStaticValue().get(); 118106260c5SEnrico Granata if (static_value) 119106260c5SEnrico Granata m_valobj = static_value; 120106260c5SEnrico Granata else 121106260c5SEnrico Granata m_valobj = m_orig_valobj; 122b9c1b51eSKate Stone } else 123106260c5SEnrico Granata m_valobj = m_orig_valobj; 124b9c1b51eSKate Stone } else { 125b9c1b51eSKate Stone if (m_options.m_use_dynamic != eNoDynamicValues) { 126b9c1b51eSKate Stone ValueObject *dynamic_value = 127b9c1b51eSKate Stone m_orig_valobj->GetDynamicValue(m_options.m_use_dynamic).get(); 1284d93b8cdSEnrico Granata if (dynamic_value) 1294d93b8cdSEnrico Granata m_valobj = dynamic_value; 1304d93b8cdSEnrico Granata else 1314d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 132b9c1b51eSKate Stone } else 1334d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 134106260c5SEnrico Granata } 135d07cfd3aSEnrico Granata 136b9c1b51eSKate Stone if (m_valobj->IsSynthetic()) { 137b9c1b51eSKate Stone if (m_options.m_use_synthetic == false) { 138d07cfd3aSEnrico Granata ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get(); 139d07cfd3aSEnrico Granata if (non_synthetic) 140d07cfd3aSEnrico Granata m_valobj = non_synthetic; 141d07cfd3aSEnrico Granata } 142b9c1b51eSKate Stone } else { 143b9c1b51eSKate Stone if (m_options.m_use_synthetic == true) { 144d07cfd3aSEnrico Granata ValueObject *synthetic = m_valobj->GetSyntheticValue().get(); 145d07cfd3aSEnrico Granata if (synthetic) 146d07cfd3aSEnrico Granata m_valobj = synthetic; 147d07cfd3aSEnrico Granata } 148d07cfd3aSEnrico Granata } 149106260c5SEnrico Granata } 15059b5a37dSBruce Mitchener m_compiler_type = m_valobj->GetCompilerType(); 15159b5a37dSBruce Mitchener m_type_flags = m_compiler_type.GetTypeInfo(); 1524d93b8cdSEnrico Granata return true; 1534d93b8cdSEnrico Granata } 1544d93b8cdSEnrico Granata 155b9c1b51eSKate Stone const char *ValueObjectPrinter::GetDescriptionForDisplay() { 1564d93b8cdSEnrico Granata const char *str = m_valobj->GetObjectDescription(); 1574d93b8cdSEnrico Granata if (!str) 1584d93b8cdSEnrico Granata str = m_valobj->GetSummaryAsCString(); 1594d93b8cdSEnrico Granata if (!str) 1604d93b8cdSEnrico Granata str = m_valobj->GetValueAsCString(); 1614d93b8cdSEnrico Granata return str; 1624d93b8cdSEnrico Granata } 1634d93b8cdSEnrico Granata 164b9c1b51eSKate Stone const char *ValueObjectPrinter::GetRootNameForDisplay(const char *if_fail) { 165b9c1b51eSKate Stone const char *root_valobj_name = m_options.m_root_valobj_name.empty() 166b9c1b51eSKate Stone ? m_valobj->GetName().AsCString() 167b9c1b51eSKate Stone : m_options.m_root_valobj_name.c_str(); 1684d93b8cdSEnrico Granata return root_valobj_name ? root_valobj_name : if_fail; 1694d93b8cdSEnrico Granata } 1704d93b8cdSEnrico Granata 171b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldPrintValueObject() { 1724d93b8cdSEnrico Granata if (m_should_print == eLazyBoolCalculate) 173b9c1b51eSKate Stone m_should_print = 174b9c1b51eSKate Stone (m_options.m_flat_output == false || m_type_flags.Test(eTypeHasValue)) 175b9c1b51eSKate Stone ? eLazyBoolYes 176b9c1b51eSKate Stone : eLazyBoolNo; 1774d93b8cdSEnrico Granata return m_should_print == eLazyBoolYes; 1784d93b8cdSEnrico Granata } 1794d93b8cdSEnrico Granata 180b9c1b51eSKate Stone bool ValueObjectPrinter::IsNil() { 1814d93b8cdSEnrico Granata if (m_is_nil == eLazyBoolCalculate) 182608d67c1SEnrico Granata m_is_nil = m_valobj->IsNilReference() ? eLazyBoolYes : eLazyBoolNo; 1834d93b8cdSEnrico Granata return m_is_nil == eLazyBoolYes; 1844d93b8cdSEnrico Granata } 1854d93b8cdSEnrico Granata 186b9c1b51eSKate Stone bool ValueObjectPrinter::IsUninitialized() { 187608d67c1SEnrico Granata if (m_is_uninit == eLazyBoolCalculate) 188b9c1b51eSKate Stone m_is_uninit = 189b9c1b51eSKate Stone m_valobj->IsUninitializedReference() ? eLazyBoolYes : eLazyBoolNo; 190608d67c1SEnrico Granata return m_is_uninit == eLazyBoolYes; 191608d67c1SEnrico Granata } 192608d67c1SEnrico Granata 193b9c1b51eSKate Stone bool ValueObjectPrinter::IsPtr() { 1944d93b8cdSEnrico Granata if (m_is_ptr == eLazyBoolCalculate) 195622be238SEnrico Granata m_is_ptr = m_type_flags.Test(eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo; 1964d93b8cdSEnrico Granata return m_is_ptr == eLazyBoolYes; 1974d93b8cdSEnrico Granata } 1984d93b8cdSEnrico Granata 199b9c1b51eSKate Stone bool ValueObjectPrinter::IsRef() { 2004d93b8cdSEnrico Granata if (m_is_ref == eLazyBoolCalculate) 201622be238SEnrico Granata m_is_ref = m_type_flags.Test(eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo; 2024d93b8cdSEnrico Granata return m_is_ref == eLazyBoolYes; 2034d93b8cdSEnrico Granata } 2044d93b8cdSEnrico Granata 205b9c1b51eSKate Stone bool ValueObjectPrinter::IsAggregate() { 2064d93b8cdSEnrico Granata if (m_is_aggregate == eLazyBoolCalculate) 207b9c1b51eSKate Stone m_is_aggregate = 208b9c1b51eSKate Stone m_type_flags.Test(eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo; 2094d93b8cdSEnrico Granata return m_is_aggregate == eLazyBoolYes; 2104d93b8cdSEnrico Granata } 2114d93b8cdSEnrico Granata 212b9c1b51eSKate Stone bool ValueObjectPrinter::IsInstancePointer() { 2138cf44d96SEnrico Granata // you need to do this check on the value's clang type 2148cf44d96SEnrico Granata if (m_is_instance_ptr == eLazyBoolCalculate) 215b9c1b51eSKate Stone m_is_instance_ptr = (m_valobj->GetValue().GetCompilerType().GetTypeInfo() & 216b9c1b51eSKate Stone eTypeInstanceIsPointer) != 0 217b9c1b51eSKate Stone ? eLazyBoolYes 218b9c1b51eSKate Stone : eLazyBoolNo; 2198cf44d96SEnrico Granata if ((eLazyBoolYes == m_is_instance_ptr) && m_valobj->IsBaseClass()) 2208cf44d96SEnrico Granata m_is_instance_ptr = eLazyBoolNo; 2218cf44d96SEnrico Granata return m_is_instance_ptr == eLazyBoolYes; 2228cf44d96SEnrico Granata } 2238cf44d96SEnrico Granata 224b9c1b51eSKate Stone bool ValueObjectPrinter::PrintLocationIfNeeded() { 225b9c1b51eSKate Stone if (m_options.m_show_location) { 2264d93b8cdSEnrico Granata m_stream->Printf("%s: ", m_valobj->GetLocationAsCString()); 2274d93b8cdSEnrico Granata return true; 2284d93b8cdSEnrico Granata } 2294d93b8cdSEnrico Granata return false; 2304d93b8cdSEnrico Granata } 2314d93b8cdSEnrico Granata 232b9c1b51eSKate Stone void ValueObjectPrinter::PrintDecl() { 2334d93b8cdSEnrico Granata bool show_type = true; 234b9c1b51eSKate Stone // if we are at the root-level and been asked to hide the root's type, then 235b9c1b51eSKate Stone // hide it 23626014690SGreg Clayton if (m_curr_depth == 0 && m_options.m_hide_root_type) 2374d93b8cdSEnrico Granata show_type = false; 2384d93b8cdSEnrico Granata else 239b9c1b51eSKate Stone // otherwise decide according to the usual rules (asked to show types - 240b9c1b51eSKate Stone // always at the root level) 241b9c1b51eSKate Stone show_type = m_options.m_show_types || 242b9c1b51eSKate Stone (m_curr_depth == 0 && !m_options.m_flat_output); 2434d93b8cdSEnrico Granata 244e0ee1e1cSEnrico Granata StreamString typeName; 245e0ee1e1cSEnrico Granata 246e0ee1e1cSEnrico Granata // always show the type at the root level if it is invalid 247b9c1b51eSKate Stone if (show_type) { 2484d93b8cdSEnrico Granata // Some ValueObjects don't have types (like registers sets). Only print 2494d93b8cdSEnrico Granata // the type if there is one to print 250a126e462SEnrico Granata ConstString type_name; 251b9c1b51eSKate Stone if (m_compiler_type.IsValid()) { 25226014690SGreg Clayton if (m_options.m_use_type_display_name) 253a126e462SEnrico Granata type_name = m_valobj->GetDisplayTypeName(); 254e8daa2f8SEnrico Granata else 255a126e462SEnrico Granata type_name = m_valobj->GetQualifiedTypeName(); 256b9c1b51eSKate Stone } else { 257b9c1b51eSKate Stone // only show an invalid type name if the user explicitly triggered 258b9c1b51eSKate Stone // show_type 25926014690SGreg Clayton if (m_options.m_show_types) 260e0ee1e1cSEnrico Granata type_name = ConstString("<invalid type>"); 261e0ee1e1cSEnrico Granata else 262e0ee1e1cSEnrico Granata type_name.Clear(); 2634d93b8cdSEnrico Granata } 2644d93b8cdSEnrico Granata 265b9c1b51eSKate Stone if (type_name) { 266e0ee1e1cSEnrico Granata std::string type_name_str(type_name.GetCString()); 267b9c1b51eSKate Stone if (m_options.m_hide_pointer_value) { 268b9c1b51eSKate Stone for (auto iter = type_name_str.find(" *"); iter != std::string::npos; 269b9c1b51eSKate Stone iter = type_name_str.find(" *")) { 270e0ee1e1cSEnrico Granata type_name_str.erase(iter, 2); 271e0ee1e1cSEnrico Granata } 272e0ee1e1cSEnrico Granata } 273c8e7649aSEnrico Granata typeName.Printf("%s", type_name_str.c_str()); 274e0ee1e1cSEnrico Granata } 275e0ee1e1cSEnrico Granata } 276e0ee1e1cSEnrico Granata 277e0ee1e1cSEnrico Granata StreamString varName; 278e0ee1e1cSEnrico Granata 279b9c1b51eSKate Stone if (m_options.m_flat_output) { 2804d93b8cdSEnrico Granata // If we are showing types, also qualify the C++ base classes 2814d93b8cdSEnrico Granata const bool qualify_cxx_base_classes = show_type; 282b9c1b51eSKate Stone if (!m_options.m_hide_name) { 283e0ee1e1cSEnrico Granata m_valobj->GetExpressionPath(varName, qualify_cxx_base_classes); 2844d93b8cdSEnrico Granata } 285b9c1b51eSKate Stone } else if (!m_options.m_hide_name) { 2864d93b8cdSEnrico Granata const char *name_cstr = GetRootNameForDisplay(""); 287e0ee1e1cSEnrico Granata varName.Printf("%s", name_cstr); 2884d93b8cdSEnrico Granata } 289e0ee1e1cSEnrico Granata 290e0ee1e1cSEnrico Granata bool decl_printed = false; 291b9c1b51eSKate Stone if (!m_options.m_decl_printing_helper) { 292b9c1b51eSKate Stone // if the user didn't give us a custom helper, pick one based upon the 293b9c1b51eSKate Stone // language, either the one that this printer is bound to, or the preferred 294b9c1b51eSKate Stone // one for the ValueObject 295b9c1b51eSKate Stone lldb::LanguageType lang_type = 296b9c1b51eSKate Stone (m_options.m_varformat_language == lldb::eLanguageTypeUnknown) 297b9c1b51eSKate Stone ? m_valobj->GetPreferredDisplayLanguage() 298b9c1b51eSKate Stone : m_options.m_varformat_language; 299b9c1b51eSKate Stone if (Language *lang_plugin = Language::FindPlugin(lang_type)) { 30026014690SGreg Clayton m_options.m_decl_printing_helper = lang_plugin->GetDeclPrintingHelper(); 301c8e7649aSEnrico Granata } 302c8e7649aSEnrico Granata } 303c8e7649aSEnrico Granata 304b9c1b51eSKate Stone if (m_options.m_decl_printing_helper) { 305e0ee1e1cSEnrico Granata ConstString type_name_cstr(typeName.GetData()); 306e0ee1e1cSEnrico Granata ConstString var_name_cstr(varName.GetData()); 307e0ee1e1cSEnrico Granata 308e0ee1e1cSEnrico Granata StreamString dest_stream; 309b9c1b51eSKate Stone if (m_options.m_decl_printing_helper(type_name_cstr, var_name_cstr, 310b9c1b51eSKate Stone m_options, dest_stream)) { 311e0ee1e1cSEnrico Granata decl_printed = true; 312e0ee1e1cSEnrico Granata m_stream->Printf("%s", dest_stream.GetData()); 313e0ee1e1cSEnrico Granata } 314e0ee1e1cSEnrico Granata } 315e0ee1e1cSEnrico Granata 316c8e7649aSEnrico Granata // if the helper failed, or there is none, do a default thing 317b9c1b51eSKate Stone if (!decl_printed) { 318e0ee1e1cSEnrico Granata if (typeName.GetSize()) 319c8e7649aSEnrico Granata m_stream->Printf("(%s) ", typeName.GetData()); 320e0ee1e1cSEnrico Granata if (varName.GetSize()) 321e0ee1e1cSEnrico Granata m_stream->Printf("%s =", varName.GetData()); 32226014690SGreg Clayton else if (!m_options.m_hide_name) 323e0ee1e1cSEnrico Granata m_stream->Printf(" ="); 324e0ee1e1cSEnrico Granata } 3254d93b8cdSEnrico Granata } 3264d93b8cdSEnrico Granata 327b9c1b51eSKate Stone bool ValueObjectPrinter::CheckScopeIfNeeded() { 32826014690SGreg Clayton if (m_options.m_scope_already_checked) 3294d93b8cdSEnrico Granata return true; 3304d93b8cdSEnrico Granata return m_valobj->IsInScope(); 3314d93b8cdSEnrico Granata } 3324d93b8cdSEnrico Granata 333b9c1b51eSKate Stone TypeSummaryImpl *ValueObjectPrinter::GetSummaryFormatter(bool null_if_omitted) { 334b9c1b51eSKate Stone if (m_summary_formatter.second == false) { 335b9c1b51eSKate Stone TypeSummaryImpl *entry = m_options.m_summary_sp 336b9c1b51eSKate Stone ? m_options.m_summary_sp.get() 337b9c1b51eSKate Stone : m_valobj->GetSummaryFormat().get(); 3384d93b8cdSEnrico Granata 33926014690SGreg Clayton if (m_options.m_omit_summary_depth > 0) 3404d93b8cdSEnrico Granata entry = NULL; 3414d93b8cdSEnrico Granata m_summary_formatter.first = entry; 3424d93b8cdSEnrico Granata m_summary_formatter.second = true; 3434d93b8cdSEnrico Granata } 3448cf44d96SEnrico Granata if (m_options.m_omit_summary_depth > 0 && null_if_omitted) 3458cf44d96SEnrico Granata return nullptr; 3464d93b8cdSEnrico Granata return m_summary_formatter.first; 3474d93b8cdSEnrico Granata } 3484d93b8cdSEnrico Granata 349b9c1b51eSKate Stone static bool IsPointerValue(const CompilerType &type) { 350e0ee1e1cSEnrico Granata Flags type_flags(type.GetTypeInfo()); 3518cf44d96SEnrico Granata if (type_flags.AnySet(eTypeInstanceIsPointer | eTypeIsPointer)) 352e0ee1e1cSEnrico Granata return type_flags.AllClear(eTypeIsBuiltIn); 353e0ee1e1cSEnrico Granata return false; 354e0ee1e1cSEnrico Granata } 355e0ee1e1cSEnrico Granata 356b9c1b51eSKate Stone void ValueObjectPrinter::GetValueSummaryError(std::string &value, 3574d93b8cdSEnrico Granata std::string &summary, 358b9c1b51eSKate Stone std::string &error) { 359520a422bSEnrico Granata lldb::Format format = m_options.m_format; 360b9c1b51eSKate Stone // if I am printing synthetized elements, apply the format to those elements 361b9c1b51eSKate Stone // only 3629ac0dac1SEnrico Granata if (m_options.m_pointer_as_array) 363520a422bSEnrico Granata m_valobj->GetValueAsCString(lldb::eFormatDefault, value); 364520a422bSEnrico Granata else if (format != eFormatDefault && format != m_valobj->GetFormat()) 365520a422bSEnrico Granata m_valobj->GetValueAsCString(format, value); 366b9c1b51eSKate Stone else { 3674d93b8cdSEnrico Granata const char *val_cstr = m_valobj->GetValueAsCString(); 368465f4bc2SEnrico Granata if (val_cstr) 369465f4bc2SEnrico Granata value.assign(val_cstr); 370465f4bc2SEnrico Granata } 3714d93b8cdSEnrico Granata const char *err_cstr = m_valobj->GetError().AsCString(); 3724d93b8cdSEnrico Granata if (err_cstr) 3734d93b8cdSEnrico Granata error.assign(err_cstr); 3744d93b8cdSEnrico Granata 375b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 3764d93b8cdSEnrico Granata if (IsNil()) 3774d93b8cdSEnrico Granata summary.assign("nil"); 378608d67c1SEnrico Granata else if (IsUninitialized()) 379608d67c1SEnrico Granata summary.assign("<uninitialized>"); 380b9c1b51eSKate Stone else if (m_options.m_omit_summary_depth == 0) { 3814d93b8cdSEnrico Granata TypeSummaryImpl *entry = GetSummaryFormatter(); 3824d93b8cdSEnrico Granata if (entry) 383b9c1b51eSKate Stone m_valobj->GetSummaryAsCString(entry, summary, 384b9c1b51eSKate Stone m_options.m_varformat_language); 385b9c1b51eSKate Stone else { 386b9c1b51eSKate Stone const char *sum_cstr = 387b9c1b51eSKate Stone m_valobj->GetSummaryAsCString(m_options.m_varformat_language); 3884d93b8cdSEnrico Granata if (sum_cstr) 3894d93b8cdSEnrico Granata summary.assign(sum_cstr); 3904d93b8cdSEnrico Granata } 3914d93b8cdSEnrico Granata } 3924d93b8cdSEnrico Granata } 3934d93b8cdSEnrico Granata } 3944d93b8cdSEnrico Granata 395b9c1b51eSKate Stone bool ValueObjectPrinter::PrintValueAndSummaryIfNeeded(bool &value_printed, 396b9c1b51eSKate Stone bool &summary_printed) { 3974d93b8cdSEnrico Granata bool error_printed = false; 398b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 3994d93b8cdSEnrico Granata if (!CheckScopeIfNeeded()) 4004d93b8cdSEnrico Granata m_error.assign("out of scope"); 401b9c1b51eSKate Stone if (m_error.empty()) { 4024d93b8cdSEnrico Granata GetValueSummaryError(m_value, m_summary, m_error); 4034d93b8cdSEnrico Granata } 404b9c1b51eSKate Stone if (m_error.size()) { 405b9c1b51eSKate Stone // we need to support scenarios in which it is actually fine for a value 406b9c1b51eSKate Stone // to have no type 407b9c1b51eSKate Stone // but - on the other hand - if we get an error *AND* have no type, we try 408b9c1b51eSKate Stone // to get out 409b9c1b51eSKate Stone // gracefully, since most often that combination means "could not resolve 410b9c1b51eSKate Stone // a type" 4118cf44d96SEnrico Granata // and the default failure mode is quite ugly 412b9c1b51eSKate Stone if (!m_compiler_type.IsValid()) { 4138cf44d96SEnrico Granata m_stream->Printf(" <could not resolve type>"); 4148cf44d96SEnrico Granata return false; 4158cf44d96SEnrico Granata } 4168cf44d96SEnrico Granata 4174d93b8cdSEnrico Granata error_printed = true; 4184d93b8cdSEnrico Granata m_stream->Printf(" <%s>\n", m_error.c_str()); 419b9c1b51eSKate Stone } else { 4204d93b8cdSEnrico Granata // Make sure we have a value and make sure the summary didn't 4214d93b8cdSEnrico Granata // specify that the value should not be printed - and do not print 4224d93b8cdSEnrico Granata // the value if this thing is nil 4234d93b8cdSEnrico Granata // (but show the value if the user passes a format explicitly) 4244d93b8cdSEnrico Granata TypeSummaryImpl *entry = GetSummaryFormatter(); 425b9c1b51eSKate Stone if (!IsNil() && !IsUninitialized() && !m_value.empty() && 426b9c1b51eSKate Stone (entry == NULL || (entry->DoesPrintValue(m_valobj) || 427b9c1b51eSKate Stone m_options.m_format != eFormatDefault) || 428b9c1b51eSKate Stone m_summary.empty()) && 429b9c1b51eSKate Stone !m_options.m_hide_value) { 430b9c1b51eSKate Stone if (m_options.m_hide_pointer_value && 431b9c1b51eSKate Stone IsPointerValue(m_valobj->GetCompilerType())) { 432b9c1b51eSKate Stone } else { 4334d93b8cdSEnrico Granata m_stream->Printf(" %s", m_value.c_str()); 4344d93b8cdSEnrico Granata value_printed = true; 4354d93b8cdSEnrico Granata } 436e0ee1e1cSEnrico Granata } 4374d93b8cdSEnrico Granata 438b9c1b51eSKate Stone if (m_summary.size()) { 4394d93b8cdSEnrico Granata m_stream->Printf(" %s", m_summary.c_str()); 4404d93b8cdSEnrico Granata summary_printed = true; 4414d93b8cdSEnrico Granata } 4424d93b8cdSEnrico Granata } 4434d93b8cdSEnrico Granata } 4444d93b8cdSEnrico Granata return !error_printed; 4454d93b8cdSEnrico Granata } 4464d93b8cdSEnrico Granata 447b9c1b51eSKate Stone bool ValueObjectPrinter::PrintObjectDescriptionIfNeeded(bool value_printed, 448b9c1b51eSKate Stone bool summary_printed) { 449b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 4504d93b8cdSEnrico Granata // let's avoid the overly verbose no description error for a nil thing 451b9c1b51eSKate Stone if (m_options.m_use_objc && !IsNil() && !IsUninitialized() && 4529ac0dac1SEnrico Granata (!m_options.m_pointer_as_array)) { 45326014690SGreg Clayton if (!m_options.m_hide_value || !m_options.m_hide_name) 4544d93b8cdSEnrico Granata m_stream->Printf(" "); 4554d93b8cdSEnrico Granata const char *object_desc = nullptr; 4564d93b8cdSEnrico Granata if (value_printed || summary_printed) 4574d93b8cdSEnrico Granata object_desc = m_valobj->GetObjectDescription(); 4584d93b8cdSEnrico Granata else 4594d93b8cdSEnrico Granata object_desc = GetDescriptionForDisplay(); 460b9c1b51eSKate Stone if (object_desc && *object_desc) { 4614d93b8cdSEnrico Granata m_stream->Printf("%s\n", object_desc); 4624d93b8cdSEnrico Granata return true; 463b9c1b51eSKate Stone } else if (value_printed == false && summary_printed == false) 4644d93b8cdSEnrico Granata return true; 4654d93b8cdSEnrico Granata else 4664d93b8cdSEnrico Granata return false; 4674d93b8cdSEnrico Granata } 4684d93b8cdSEnrico Granata } 4694d93b8cdSEnrico Granata return true; 4704d93b8cdSEnrico Granata } 4714d93b8cdSEnrico Granata 472b9c1b51eSKate Stone bool DumpValueObjectOptions::PointerDepth::CanAllowExpansion( 473b9c1b51eSKate Stone bool is_root, TypeSummaryImpl *entry, ValueObject *valobj, 474b9c1b51eSKate Stone const std::string &summary) { 475b9c1b51eSKate Stone switch (m_mode) { 476c1b7c09aSEnrico Granata case Mode::Always: 477c1b7c09aSEnrico Granata return (m_count > 0); 478c1b7c09aSEnrico Granata case Mode::Never: 479c1b7c09aSEnrico Granata return false; 480c1b7c09aSEnrico Granata case Mode::Default: 481c1b7c09aSEnrico Granata if (is_root) 482c1b7c09aSEnrico Granata m_count = std::min<decltype(m_count)>(m_count, 1); 483c1b7c09aSEnrico Granata return m_count > 0; 484c1b7c09aSEnrico Granata case Mode::Formatters: 485c1b7c09aSEnrico Granata if (!entry || entry->DoesPrintChildren(valobj) || summary.empty()) 486c1b7c09aSEnrico Granata return m_count > 0; 487c1b7c09aSEnrico Granata return false; 488c1b7c09aSEnrico Granata } 48984f5b0dfSZachary Turner return false; 490c1b7c09aSEnrico Granata } 491c1b7c09aSEnrico Granata 492b9c1b51eSKate Stone bool DumpValueObjectOptions::PointerDepth::CanAllowExpansion() const { 493b9c1b51eSKate Stone switch (m_mode) { 494c1b7c09aSEnrico Granata case Mode::Always: 495c1b7c09aSEnrico Granata case Mode::Default: 496c1b7c09aSEnrico Granata case Mode::Formatters: 497c1b7c09aSEnrico Granata return (m_count > 0); 498c1b7c09aSEnrico Granata case Mode::Never: 499c1b7c09aSEnrico Granata return false; 500c1b7c09aSEnrico Granata } 50184f5b0dfSZachary Turner return false; 502c1b7c09aSEnrico Granata } 503c1b7c09aSEnrico Granata 504b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldPrintChildren( 505b9c1b51eSKate Stone bool is_failed_description, 506b9c1b51eSKate Stone DumpValueObjectOptions::PointerDepth &curr_ptr_depth) { 5074d93b8cdSEnrico Granata const bool is_ref = IsRef(); 5084d93b8cdSEnrico Granata const bool is_ptr = IsPtr(); 509608d67c1SEnrico Granata const bool is_uninit = IsUninitialized(); 510608d67c1SEnrico Granata 511608d67c1SEnrico Granata if (is_uninit) 512608d67c1SEnrico Granata return false; 5134d93b8cdSEnrico Granata 514520a422bSEnrico Granata // if the user has specified an element count, always print children 515520a422bSEnrico Granata // as it is explicit user demand being honored 5169ac0dac1SEnrico Granata if (m_options.m_pointer_as_array) 517520a422bSEnrico Granata return true; 518520a422bSEnrico Granata 519c1b7c09aSEnrico Granata TypeSummaryImpl *entry = GetSummaryFormatter(); 520c1b7c09aSEnrico Granata 5218cf44d96SEnrico Granata if (m_options.m_use_objc) 5228cf44d96SEnrico Granata return false; 5238cf44d96SEnrico Granata 524b9c1b51eSKate Stone if (is_failed_description || m_curr_depth < m_options.m_max_depth) { 5254d93b8cdSEnrico Granata // We will show children for all concrete types. We won't show 5264d93b8cdSEnrico Granata // pointer contents unless a pointer depth has been specified. 5274d93b8cdSEnrico Granata // We won't reference contents unless the reference is the 5284d93b8cdSEnrico Granata // root object (depth of zero). 5294d93b8cdSEnrico Granata 5304d93b8cdSEnrico Granata // Use a new temporary pointer depth in case we override the 5314d93b8cdSEnrico Granata // current pointer depth below... 5324d93b8cdSEnrico Granata 533b9c1b51eSKate Stone if (is_ptr || is_ref) { 5344d93b8cdSEnrico Granata // We have a pointer or reference whose value is an address. 5354d93b8cdSEnrico Granata // Make sure that address is not NULL 5364d93b8cdSEnrico Granata AddressType ptr_address_type; 5374d93b8cdSEnrico Granata if (m_valobj->GetPointerValue(&ptr_address_type) == 0) 5384d93b8cdSEnrico Granata return false; 5394d93b8cdSEnrico Granata 540c1b7c09aSEnrico Granata const bool is_root_level = m_curr_depth == 0; 541c1b7c09aSEnrico Granata 542b9c1b51eSKate Stone if (is_ref && is_root_level) { 5434d93b8cdSEnrico Granata // If this is the root object (depth is zero) that we are showing 5444d93b8cdSEnrico Granata // and it is a reference, and no pointer depth has been supplied 5454d93b8cdSEnrico Granata // print out what it references. Don't do this at deeper depths 5464d93b8cdSEnrico Granata // otherwise we can end up with infinite recursion... 547c1b7c09aSEnrico Granata return true; 5484d93b8cdSEnrico Granata } 5494d93b8cdSEnrico Granata 550b9c1b51eSKate Stone return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, 551b9c1b51eSKate Stone m_summary); 5524d93b8cdSEnrico Granata } 5534d93b8cdSEnrico Granata 5548a068e6cSEnrico Granata return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty()); 5554d93b8cdSEnrico Granata } 5564d93b8cdSEnrico Granata return false; 5574d93b8cdSEnrico Granata } 5584d93b8cdSEnrico Granata 559b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldExpandEmptyAggregates() { 560d26eb907SSiva Chandra TypeSummaryImpl *entry = GetSummaryFormatter(); 561d26eb907SSiva Chandra 562d26eb907SSiva Chandra if (!entry) 563d26eb907SSiva Chandra return true; 564d26eb907SSiva Chandra 565d26eb907SSiva Chandra return entry->DoesPrintEmptyAggregates(); 566d26eb907SSiva Chandra } 567d26eb907SSiva Chandra 568b9c1b51eSKate Stone ValueObject *ValueObjectPrinter::GetValueObjectForChildrenGeneration() { 569d07cfd3aSEnrico Granata return m_valobj; 5704d93b8cdSEnrico Granata } 5714d93b8cdSEnrico Granata 572b9c1b51eSKate Stone void ValueObjectPrinter::PrintChildrenPreamble() { 573b9c1b51eSKate Stone if (m_options.m_flat_output) { 5744d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 5754d93b8cdSEnrico Granata m_stream->EOL(); 576b9c1b51eSKate Stone } else { 5774d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 5784d93b8cdSEnrico Granata m_stream->PutCString(IsRef() ? ": {\n" : " {\n"); 5794d93b8cdSEnrico Granata m_stream->IndentMore(); 5804d93b8cdSEnrico Granata } 5814d93b8cdSEnrico Granata } 5824d93b8cdSEnrico Granata 583b9c1b51eSKate Stone void ValueObjectPrinter::PrintChild( 584b9c1b51eSKate Stone ValueObjectSP child_sp, 585b9c1b51eSKate Stone const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) { 5869ac0dac1SEnrico Granata const uint32_t consumed_depth = (!m_options.m_pointer_as_array) ? 1 : 0; 587b9c1b51eSKate Stone const bool does_consume_ptr_depth = 5889ac0dac1SEnrico Granata ((IsPtr() && !m_options.m_pointer_as_array) || IsRef()); 589520a422bSEnrico Granata 59026014690SGreg Clayton DumpValueObjectOptions child_options(m_options); 591b9c1b51eSKate Stone child_options.SetFormat(m_options.m_format) 592b9c1b51eSKate Stone .SetSummary() 593b9c1b51eSKate Stone .SetRootValueObjectName(); 594b9c1b51eSKate Stone child_options.SetScopeChecked(true) 595b9c1b51eSKate Stone .SetHideName(m_options.m_hide_name) 596b9c1b51eSKate Stone .SetHideValue(m_options.m_hide_value) 597b9c1b51eSKate Stone .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 598b9c1b51eSKate Stone ? child_options.m_omit_summary_depth - 599b9c1b51eSKate Stone consumed_depth 600b9c1b51eSKate Stone : 0) 601520a422bSEnrico Granata .SetElementCount(0); 6028cf44d96SEnrico Granata 603b9c1b51eSKate Stone if (child_sp.get()) { 604b9c1b51eSKate Stone ValueObjectPrinter child_printer( 605b9c1b51eSKate Stone child_sp.get(), m_stream, child_options, 606520a422bSEnrico Granata does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth, 607b9c1b51eSKate Stone m_curr_depth + consumed_depth, m_printed_instance_pointers); 6084d93b8cdSEnrico Granata child_printer.PrintValueObject(); 6094d93b8cdSEnrico Granata } 6104d93b8cdSEnrico Granata } 6114d93b8cdSEnrico Granata 612b9c1b51eSKate Stone uint32_t ValueObjectPrinter::GetMaxNumChildrenToPrint(bool &print_dotdotdot) { 6134d93b8cdSEnrico Granata ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration(); 6144d93b8cdSEnrico Granata 6159ac0dac1SEnrico Granata if (m_options.m_pointer_as_array) 6169ac0dac1SEnrico Granata return m_options.m_pointer_as_array.m_element_count; 617520a422bSEnrico Granata 6184d93b8cdSEnrico Granata size_t num_children = synth_m_valobj->GetNumChildren(); 6194d93b8cdSEnrico Granata print_dotdotdot = false; 620b9c1b51eSKate Stone if (num_children) { 621b9c1b51eSKate Stone const size_t max_num_children = 622b9c1b51eSKate Stone m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 6234d93b8cdSEnrico Granata 624b9c1b51eSKate Stone if (num_children > max_num_children && !m_options.m_ignore_cap) { 6254d93b8cdSEnrico Granata print_dotdotdot = true; 6264d93b8cdSEnrico Granata return max_num_children; 6274d93b8cdSEnrico Granata } 6284d93b8cdSEnrico Granata } 6294d93b8cdSEnrico Granata return num_children; 6304d93b8cdSEnrico Granata } 6314d93b8cdSEnrico Granata 632b9c1b51eSKate Stone void ValueObjectPrinter::PrintChildrenPostamble(bool print_dotdotdot) { 633b9c1b51eSKate Stone if (!m_options.m_flat_output) { 634b9c1b51eSKate Stone if (print_dotdotdot) { 635b9c1b51eSKate Stone m_valobj->GetTargetSP() 636b9c1b51eSKate Stone ->GetDebugger() 637b9c1b51eSKate Stone .GetCommandInterpreter() 638b9c1b51eSKate Stone .ChildrenTruncated(); 6394d93b8cdSEnrico Granata m_stream->Indent("...\n"); 6404d93b8cdSEnrico Granata } 6414d93b8cdSEnrico Granata m_stream->IndentLess(); 6424d93b8cdSEnrico Granata m_stream->Indent("}\n"); 6434d93b8cdSEnrico Granata } 6444d93b8cdSEnrico Granata } 6454d93b8cdSEnrico Granata 646b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldPrintEmptyBrackets(bool value_printed, 647b9c1b51eSKate Stone bool summary_printed) { 6488cf44d96SEnrico Granata ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration(); 6498cf44d96SEnrico Granata 6508cf44d96SEnrico Granata if (!IsAggregate()) 6518cf44d96SEnrico Granata return false; 6528cf44d96SEnrico Granata 653b9c1b51eSKate Stone if (m_options.m_reveal_empty_aggregates == false) { 6548cf44d96SEnrico Granata if (value_printed || summary_printed) 6558cf44d96SEnrico Granata return false; 6568cf44d96SEnrico Granata } 6578cf44d96SEnrico Granata 6588cf44d96SEnrico Granata if (synth_m_valobj->MightHaveChildren()) 6598cf44d96SEnrico Granata return true; 6608cf44d96SEnrico Granata 6618cf44d96SEnrico Granata if (m_val_summary_ok) 6628cf44d96SEnrico Granata return false; 6638cf44d96SEnrico Granata 6648cf44d96SEnrico Granata return true; 6658cf44d96SEnrico Granata } 6668cf44d96SEnrico Granata 6679ac0dac1SEnrico Granata static constexpr size_t PhysicalIndexForLogicalIndex(size_t base, size_t stride, 6689ac0dac1SEnrico Granata size_t logical) { 6699ac0dac1SEnrico Granata return base + logical * stride; 6709ac0dac1SEnrico Granata } 6719ac0dac1SEnrico Granata 672b9c1b51eSKate Stone ValueObjectSP ValueObjectPrinter::GenerateChild(ValueObject *synth_valobj, 673b9c1b51eSKate Stone size_t idx) { 6749ac0dac1SEnrico Granata if (m_options.m_pointer_as_array) { 675520a422bSEnrico Granata // if generating pointer-as-array children, use GetSyntheticArrayMember 6769ac0dac1SEnrico Granata return synth_valobj->GetSyntheticArrayMember( 6779ac0dac1SEnrico Granata PhysicalIndexForLogicalIndex( 6789ac0dac1SEnrico Granata m_options.m_pointer_as_array.m_base_element, 6799ac0dac1SEnrico Granata m_options.m_pointer_as_array.m_stride, idx), 6809ac0dac1SEnrico Granata true); 681b9c1b51eSKate Stone } else { 682520a422bSEnrico Granata // otherwise, do the usual thing 683520a422bSEnrico Granata return synth_valobj->GetChildAtIndex(idx, true); 684520a422bSEnrico Granata } 685520a422bSEnrico Granata } 686520a422bSEnrico Granata 687b9c1b51eSKate Stone void ValueObjectPrinter::PrintChildren( 688b9c1b51eSKate Stone bool value_printed, bool summary_printed, 689b9c1b51eSKate Stone const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) { 6904d93b8cdSEnrico Granata ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration(); 6914d93b8cdSEnrico Granata 6924d93b8cdSEnrico Granata bool print_dotdotdot = false; 6934d93b8cdSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 694b9c1b51eSKate Stone if (num_children) { 6958cf44d96SEnrico Granata bool any_children_printed = false; 6964d93b8cdSEnrico Granata 697b9c1b51eSKate Stone for (size_t idx = 0; idx < num_children; ++idx) { 698b9c1b51eSKate Stone if (ValueObjectSP child_sp = GenerateChild(synth_m_valobj, idx)) { 699b9c1b51eSKate Stone if (!any_children_printed) { 7008cf44d96SEnrico Granata PrintChildrenPreamble(); 7018cf44d96SEnrico Granata any_children_printed = true; 7028cf44d96SEnrico Granata } 7034d93b8cdSEnrico Granata PrintChild(child_sp, curr_ptr_depth); 7044d93b8cdSEnrico Granata } 7054d93b8cdSEnrico Granata } 7068cf44d96SEnrico Granata 7078cf44d96SEnrico Granata if (any_children_printed) 7088cf44d96SEnrico Granata PrintChildrenPostamble(print_dotdotdot); 709b9c1b51eSKate Stone else { 710b9c1b51eSKate Stone if (ShouldPrintEmptyBrackets(value_printed, summary_printed)) { 7118cf44d96SEnrico Granata if (ShouldPrintValueObject()) 7128cf44d96SEnrico Granata m_stream->PutCString(" {}\n"); 7138cf44d96SEnrico Granata else 7148cf44d96SEnrico Granata m_stream->EOL(); 715b9c1b51eSKate Stone } else 7168cf44d96SEnrico Granata m_stream->EOL(); 7178cf44d96SEnrico Granata } 718b9c1b51eSKate Stone } else if (ShouldPrintEmptyBrackets(value_printed, summary_printed)) { 7194d93b8cdSEnrico Granata // Aggregate, no children... 720b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 721b9c1b51eSKate Stone // if it has a synthetic value, then don't print {}, the synthetic 722b9c1b51eSKate Stone // children are probably only being used to vend a value 723b9c1b51eSKate Stone if (m_valobj->DoesProvideSyntheticValue() || 724b9c1b51eSKate Stone !ShouldExpandEmptyAggregates()) 725d07cfd3aSEnrico Granata m_stream->PutCString("\n"); 726d07cfd3aSEnrico Granata else 7274d93b8cdSEnrico Granata m_stream->PutCString(" {}\n"); 7284d93b8cdSEnrico Granata } 729b9c1b51eSKate Stone } else { 7304d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 7314d93b8cdSEnrico Granata m_stream->EOL(); 7324d93b8cdSEnrico Granata } 7334d93b8cdSEnrico Granata } 7344d93b8cdSEnrico Granata 735b9c1b51eSKate Stone bool ValueObjectPrinter::PrintChildrenOneLiner(bool hide_names) { 736d07cfd3aSEnrico Granata if (!GetMostSpecializedValue() || m_valobj == nullptr) 737a29cb0baSEnrico Granata return false; 738a29cb0baSEnrico Granata 739a29cb0baSEnrico Granata ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration(); 740a29cb0baSEnrico Granata 741a29cb0baSEnrico Granata bool print_dotdotdot = false; 742a29cb0baSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 743a29cb0baSEnrico Granata 744b9c1b51eSKate Stone if (num_children) { 745a29cb0baSEnrico Granata m_stream->PutChar('('); 746a29cb0baSEnrico Granata 747b9c1b51eSKate Stone for (uint32_t idx = 0; idx < num_children; ++idx) { 748a29cb0baSEnrico Granata lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 749ddac7611SEnrico Granata if (child_sp) 750b9c1b51eSKate Stone child_sp = child_sp->GetQualifiedRepresentationIfAvailable( 751b9c1b51eSKate Stone m_options.m_use_dynamic, m_options.m_use_synthetic); 752b9c1b51eSKate Stone if (child_sp) { 753a29cb0baSEnrico Granata if (idx) 754a29cb0baSEnrico Granata m_stream->PutCString(", "); 755b9c1b51eSKate Stone if (!hide_names) { 756a29cb0baSEnrico Granata const char *name = child_sp.get()->GetName().AsCString(); 757b9c1b51eSKate Stone if (name && *name) { 758a29cb0baSEnrico Granata m_stream->PutCString(name); 759a29cb0baSEnrico Granata m_stream->PutCString(" = "); 760a29cb0baSEnrico Granata } 761a29cb0baSEnrico Granata } 762b9c1b51eSKate Stone child_sp->DumpPrintableRepresentation( 763b9c1b51eSKate Stone *m_stream, ValueObject::eValueObjectRepresentationStyleSummary, 7647aafb6a1SEnrico Granata m_options.m_format, 765*65d86e4fSEnrico Granata ValueObject::PrintableRepresentationSpecialCases::eDisable); 766a29cb0baSEnrico Granata } 767a29cb0baSEnrico Granata } 768a29cb0baSEnrico Granata 769a29cb0baSEnrico Granata if (print_dotdotdot) 770a29cb0baSEnrico Granata m_stream->PutCString(", ...)"); 771a29cb0baSEnrico Granata else 772a29cb0baSEnrico Granata m_stream->PutChar(')'); 773a29cb0baSEnrico Granata } 774a29cb0baSEnrico Granata return true; 775a29cb0baSEnrico Granata } 776a29cb0baSEnrico Granata 777b9c1b51eSKate Stone void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed, 778b9c1b51eSKate Stone bool summary_printed) { 779b9c1b51eSKate Stone // this flag controls whether we tried to display a description for this 780b9c1b51eSKate Stone // object and failed 7814d93b8cdSEnrico Granata // if that happens, we want to display the children, if any 782b9c1b51eSKate Stone bool is_failed_description = 783b9c1b51eSKate Stone !PrintObjectDescriptionIfNeeded(value_printed, summary_printed); 7844d93b8cdSEnrico Granata 785c1b7c09aSEnrico Granata auto curr_ptr_depth = m_ptr_depth; 786b9c1b51eSKate Stone bool print_children = 787b9c1b51eSKate Stone ShouldPrintChildren(is_failed_description, curr_ptr_depth); 788b9c1b51eSKate Stone bool print_oneline = 789b9c1b51eSKate Stone (curr_ptr_depth.CanAllowExpansion() || m_options.m_show_types || 790b9c1b51eSKate Stone !m_options.m_allow_oneliner_mode || m_options.m_flat_output || 7919ac0dac1SEnrico Granata (m_options.m_pointer_as_array) || m_options.m_show_location) 792b9c1b51eSKate Stone ? false 793b9c1b51eSKate Stone : DataVisualization::ShouldPrintAsOneLiner(*m_valobj); 7948cf44d96SEnrico Granata bool is_instance_ptr = IsInstancePointer(); 7958cf44d96SEnrico Granata uint64_t instance_ptr_value = LLDB_INVALID_ADDRESS; 7968cf44d96SEnrico Granata 797b9c1b51eSKate Stone if (print_children && is_instance_ptr) { 7988cf44d96SEnrico Granata instance_ptr_value = m_valobj->GetValueAsUnsigned(0); 799b9c1b51eSKate Stone if (m_printed_instance_pointers->count(instance_ptr_value)) { 8008cf44d96SEnrico Granata // we already printed this instance-is-pointer thing, so don't expand it 8018cf44d96SEnrico Granata m_stream->PutCString(" {...}\n"); 8028cf44d96SEnrico Granata 8038cf44d96SEnrico Granata // we're done here - get out fast 8048cf44d96SEnrico Granata return; 805b9c1b51eSKate Stone } else 806b9c1b51eSKate Stone m_printed_instance_pointers->emplace( 807b9c1b51eSKate Stone instance_ptr_value); // remember this guy for future reference 8088cf44d96SEnrico Granata } 8094d93b8cdSEnrico Granata 810b9c1b51eSKate Stone if (print_children) { 811b9c1b51eSKate Stone if (print_oneline) { 812a29cb0baSEnrico Granata m_stream->PutChar(' '); 813a29cb0baSEnrico Granata PrintChildrenOneLiner(false); 814a29cb0baSEnrico Granata m_stream->EOL(); 815b9c1b51eSKate Stone } else 816c1b7c09aSEnrico Granata PrintChildren(value_printed, summary_printed, curr_ptr_depth); 817b9c1b51eSKate Stone } else if (m_curr_depth >= m_options.m_max_depth && IsAggregate() && 818b9c1b51eSKate Stone ShouldPrintValueObject()) { 8194d93b8cdSEnrico Granata m_stream->PutCString("{...}\n"); 820b9c1b51eSKate Stone } else 821245b3caaSEnrico Granata m_stream->EOL(); 8224d93b8cdSEnrico Granata } 8230f883ffbSEnrico Granata 824b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldPrintValidation() { 82526014690SGreg Clayton return m_options.m_run_validator; 8260f883ffbSEnrico Granata } 8270f883ffbSEnrico Granata 828b9c1b51eSKate Stone bool ValueObjectPrinter::PrintValidationMarkerIfNeeded() { 8290f883ffbSEnrico Granata if (!ShouldPrintValidation()) 8300f883ffbSEnrico Granata return false; 8310f883ffbSEnrico Granata 8320f883ffbSEnrico Granata m_validation = m_valobj->GetValidationStatus(); 8330f883ffbSEnrico Granata 834b9c1b51eSKate Stone if (TypeValidatorResult::Failure == m_validation.first) { 8350f883ffbSEnrico Granata m_stream->Printf("! "); 8360f883ffbSEnrico Granata return true; 8370f883ffbSEnrico Granata } 8380f883ffbSEnrico Granata 8390f883ffbSEnrico Granata return false; 8400f883ffbSEnrico Granata } 8410f883ffbSEnrico Granata 842b9c1b51eSKate Stone bool ValueObjectPrinter::PrintValidationErrorIfNeeded() { 8430f883ffbSEnrico Granata if (!ShouldPrintValidation()) 8440f883ffbSEnrico Granata return false; 8450f883ffbSEnrico Granata 8460f883ffbSEnrico Granata if (TypeValidatorResult::Success == m_validation.first) 8470f883ffbSEnrico Granata return false; 8480f883ffbSEnrico Granata 8490f883ffbSEnrico Granata if (m_validation.second.empty()) 8500f883ffbSEnrico Granata m_validation.second.assign("unknown error"); 8510f883ffbSEnrico Granata 8520f883ffbSEnrico Granata m_stream->Printf(" ! validation error: %s", m_validation.second.c_str()); 8530f883ffbSEnrico Granata m_stream->EOL(); 8540f883ffbSEnrico Granata 8550f883ffbSEnrico Granata return true; 8560f883ffbSEnrico Granata } 857