1c156427dSZachary Turner //===-- 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 16c8e7649aSEnrico Granata #include "lldb/Core/ValueObject.h" 17a29cb0baSEnrico Granata #include "lldb/DataFormatters/DataVisualization.h" 184d93b8cdSEnrico Granata #include "lldb/Interpreter/CommandInterpreter.h" 19c8e7649aSEnrico Granata #include "lldb/Target/Language.h" 204d93b8cdSEnrico Granata #include "lldb/Target/Target.h" 21bf9a7730SZachary Turner #include "lldb/Utility/Stream.h" 224d93b8cdSEnrico Granata 234d93b8cdSEnrico Granata using namespace lldb; 244d93b8cdSEnrico Granata using namespace lldb_private; 254d93b8cdSEnrico Granata 26b9c1b51eSKate Stone ValueObjectPrinter::ValueObjectPrinter(ValueObject *valobj, Stream *s) { 27b9c1b51eSKate Stone if (valobj) { 28d5957336SEnrico Granata DumpValueObjectOptions options(*valobj); 298cf44d96SEnrico Granata Init(valobj, s, options, m_options.m_max_ptr_depth, 0, nullptr); 30b9c1b51eSKate Stone } else { 31d5957336SEnrico Granata DumpValueObjectOptions options; 328cf44d96SEnrico Granata Init(valobj, s, options, m_options.m_max_ptr_depth, 0, nullptr); 33d5957336SEnrico Granata } 34d5957336SEnrico Granata } 35d5957336SEnrico Granata 36b9c1b51eSKate Stone ValueObjectPrinter::ValueObjectPrinter(ValueObject *valobj, Stream *s, 37b9c1b51eSKate Stone const DumpValueObjectOptions &options) { 388cf44d96SEnrico Granata Init(valobj, s, options, m_options.m_max_ptr_depth, 0, nullptr); 394d93b8cdSEnrico Granata } 404d93b8cdSEnrico Granata 41b9c1b51eSKate Stone ValueObjectPrinter::ValueObjectPrinter( 42b9c1b51eSKate Stone ValueObject *valobj, Stream *s, const DumpValueObjectOptions &options, 43b9c1b51eSKate Stone const DumpValueObjectOptions::PointerDepth &ptr_depth, uint32_t curr_depth, 44b9c1b51eSKate Stone InstancePointersSetSP printed_instance_pointers) { 458cf44d96SEnrico Granata Init(valobj, s, options, ptr_depth, curr_depth, printed_instance_pointers); 46938d1d67SEnrico Granata } 47938d1d67SEnrico Granata 48b9c1b51eSKate Stone void ValueObjectPrinter::Init( 49b9c1b51eSKate Stone ValueObject *valobj, Stream *s, const DumpValueObjectOptions &options, 50b9c1b51eSKate Stone const DumpValueObjectOptions::PointerDepth &ptr_depth, uint32_t curr_depth, 51b9c1b51eSKate Stone InstancePointersSetSP printed_instance_pointers) { 52938d1d67SEnrico Granata m_orig_valobj = valobj; 53938d1d67SEnrico Granata m_valobj = nullptr; 54938d1d67SEnrico Granata m_stream = s; 5526014690SGreg Clayton m_options = options; 56938d1d67SEnrico Granata m_ptr_depth = ptr_depth; 57938d1d67SEnrico Granata m_curr_depth = curr_depth; 58938d1d67SEnrico Granata assert(m_orig_valobj && "cannot print a NULL ValueObject"); 59938d1d67SEnrico Granata assert(m_stream && "cannot print to a NULL Stream"); 60938d1d67SEnrico Granata m_should_print = eLazyBoolCalculate; 61938d1d67SEnrico Granata m_is_nil = eLazyBoolCalculate; 62608d67c1SEnrico Granata m_is_uninit = eLazyBoolCalculate; 63938d1d67SEnrico Granata m_is_ptr = eLazyBoolCalculate; 64938d1d67SEnrico Granata m_is_ref = eLazyBoolCalculate; 65938d1d67SEnrico Granata m_is_aggregate = eLazyBoolCalculate; 668cf44d96SEnrico Granata m_is_instance_ptr = eLazyBoolCalculate; 67938d1d67SEnrico Granata m_summary_formatter = {nullptr, false}; 68938d1d67SEnrico Granata m_value.assign(""); 69938d1d67SEnrico Granata m_summary.assign(""); 70938d1d67SEnrico Granata m_error.assign(""); 718cf44d96SEnrico Granata m_val_summary_ok = false; 72b9c1b51eSKate Stone m_printed_instance_pointers = 73b9c1b51eSKate Stone printed_instance_pointers 74b9c1b51eSKate Stone ? printed_instance_pointers 75b9c1b51eSKate Stone : InstancePointersSetSP(new InstancePointersSet()); 76938d1d67SEnrico Granata } 774d93b8cdSEnrico Granata 78b9c1b51eSKate Stone bool ValueObjectPrinter::PrintValueObject() { 79d07cfd3aSEnrico Granata if (!GetMostSpecializedValue() || m_valobj == nullptr) 804d93b8cdSEnrico Granata return false; 814d93b8cdSEnrico Granata 82b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 830f883ffbSEnrico Granata PrintValidationMarkerIfNeeded(); 840f883ffbSEnrico Granata 854d93b8cdSEnrico Granata PrintLocationIfNeeded(); 864d93b8cdSEnrico Granata m_stream->Indent(); 874d93b8cdSEnrico Granata 88e0ee1e1cSEnrico Granata PrintDecl(); 894d93b8cdSEnrico Granata } 904d93b8cdSEnrico Granata 914d93b8cdSEnrico Granata bool value_printed = false; 924d93b8cdSEnrico Granata bool summary_printed = false; 934d93b8cdSEnrico Granata 94b9c1b51eSKate Stone m_val_summary_ok = 95b9c1b51eSKate Stone PrintValueAndSummaryIfNeeded(value_printed, summary_printed); 964d93b8cdSEnrico Granata 978cf44d96SEnrico Granata if (m_val_summary_ok) 984d93b8cdSEnrico Granata PrintChildrenIfNeeded(value_printed, summary_printed); 9939938938SEnrico Granata else 1004d93b8cdSEnrico Granata m_stream->EOL(); 1014d93b8cdSEnrico Granata 1020f883ffbSEnrico Granata PrintValidationErrorIfNeeded(); 1030f883ffbSEnrico Granata 1044d93b8cdSEnrico Granata return true; 1054d93b8cdSEnrico Granata } 1064d93b8cdSEnrico Granata 107b9c1b51eSKate Stone bool ValueObjectPrinter::GetMostSpecializedValue() { 108a29cb0baSEnrico Granata if (m_valobj) 109a29cb0baSEnrico Granata return true; 1104d93b8cdSEnrico Granata bool update_success = m_orig_valobj->UpdateValueIfNeeded(true); 111b9c1b51eSKate Stone if (!update_success) { 112106260c5SEnrico Granata m_valobj = m_orig_valobj; 113b9c1b51eSKate Stone } else { 114b9c1b51eSKate Stone if (m_orig_valobj->IsDynamic()) { 115b9c1b51eSKate Stone if (m_options.m_use_dynamic == eNoDynamicValues) { 116106260c5SEnrico Granata ValueObject *static_value = m_orig_valobj->GetStaticValue().get(); 117106260c5SEnrico Granata if (static_value) 118106260c5SEnrico Granata m_valobj = static_value; 119106260c5SEnrico Granata else 120106260c5SEnrico Granata m_valobj = m_orig_valobj; 121b9c1b51eSKate Stone } else 122106260c5SEnrico Granata m_valobj = m_orig_valobj; 123b9c1b51eSKate Stone } else { 124b9c1b51eSKate Stone if (m_options.m_use_dynamic != eNoDynamicValues) { 125b9c1b51eSKate Stone ValueObject *dynamic_value = 126b9c1b51eSKate Stone m_orig_valobj->GetDynamicValue(m_options.m_use_dynamic).get(); 1274d93b8cdSEnrico Granata if (dynamic_value) 1284d93b8cdSEnrico Granata m_valobj = dynamic_value; 1294d93b8cdSEnrico Granata else 1304d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 131b9c1b51eSKate Stone } else 1324d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 133106260c5SEnrico Granata } 134d07cfd3aSEnrico Granata 135b9c1b51eSKate Stone if (m_valobj->IsSynthetic()) { 136b9c1b51eSKate Stone if (m_options.m_use_synthetic == false) { 137d07cfd3aSEnrico Granata ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get(); 138d07cfd3aSEnrico Granata if (non_synthetic) 139d07cfd3aSEnrico Granata m_valobj = non_synthetic; 140d07cfd3aSEnrico Granata } 141b9c1b51eSKate Stone } else { 142b9c1b51eSKate Stone if (m_options.m_use_synthetic == true) { 143d07cfd3aSEnrico Granata ValueObject *synthetic = m_valobj->GetSyntheticValue().get(); 144d07cfd3aSEnrico Granata if (synthetic) 145d07cfd3aSEnrico Granata m_valobj = synthetic; 146d07cfd3aSEnrico Granata } 147d07cfd3aSEnrico Granata } 148106260c5SEnrico Granata } 14959b5a37dSBruce Mitchener m_compiler_type = m_valobj->GetCompilerType(); 15059b5a37dSBruce Mitchener m_type_flags = m_compiler_type.GetTypeInfo(); 1514d93b8cdSEnrico Granata return true; 1524d93b8cdSEnrico Granata } 1534d93b8cdSEnrico Granata 154b9c1b51eSKate Stone const char *ValueObjectPrinter::GetDescriptionForDisplay() { 1554d93b8cdSEnrico Granata const char *str = m_valobj->GetObjectDescription(); 1564d93b8cdSEnrico Granata if (!str) 1574d93b8cdSEnrico Granata str = m_valobj->GetSummaryAsCString(); 1584d93b8cdSEnrico Granata if (!str) 1594d93b8cdSEnrico Granata str = m_valobj->GetValueAsCString(); 1604d93b8cdSEnrico Granata return str; 1614d93b8cdSEnrico Granata } 1624d93b8cdSEnrico Granata 163b9c1b51eSKate Stone const char *ValueObjectPrinter::GetRootNameForDisplay(const char *if_fail) { 164b9c1b51eSKate Stone const char *root_valobj_name = m_options.m_root_valobj_name.empty() 165b9c1b51eSKate Stone ? m_valobj->GetName().AsCString() 166b9c1b51eSKate Stone : m_options.m_root_valobj_name.c_str(); 1674d93b8cdSEnrico Granata return root_valobj_name ? root_valobj_name : if_fail; 1684d93b8cdSEnrico Granata } 1694d93b8cdSEnrico Granata 170b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldPrintValueObject() { 1714d93b8cdSEnrico Granata if (m_should_print == eLazyBoolCalculate) 172b9c1b51eSKate Stone m_should_print = 173b9c1b51eSKate Stone (m_options.m_flat_output == false || m_type_flags.Test(eTypeHasValue)) 174b9c1b51eSKate Stone ? eLazyBoolYes 175b9c1b51eSKate Stone : eLazyBoolNo; 1764d93b8cdSEnrico Granata return m_should_print == eLazyBoolYes; 1774d93b8cdSEnrico Granata } 1784d93b8cdSEnrico Granata 179b9c1b51eSKate Stone bool ValueObjectPrinter::IsNil() { 1804d93b8cdSEnrico Granata if (m_is_nil == eLazyBoolCalculate) 181608d67c1SEnrico Granata m_is_nil = m_valobj->IsNilReference() ? eLazyBoolYes : eLazyBoolNo; 1824d93b8cdSEnrico Granata return m_is_nil == eLazyBoolYes; 1834d93b8cdSEnrico Granata } 1844d93b8cdSEnrico Granata 185b9c1b51eSKate Stone bool ValueObjectPrinter::IsUninitialized() { 186608d67c1SEnrico Granata if (m_is_uninit == eLazyBoolCalculate) 187b9c1b51eSKate Stone m_is_uninit = 188b9c1b51eSKate Stone m_valobj->IsUninitializedReference() ? eLazyBoolYes : eLazyBoolNo; 189608d67c1SEnrico Granata return m_is_uninit == eLazyBoolYes; 190608d67c1SEnrico Granata } 191608d67c1SEnrico Granata 192b9c1b51eSKate Stone bool ValueObjectPrinter::IsPtr() { 1934d93b8cdSEnrico Granata if (m_is_ptr == eLazyBoolCalculate) 194622be238SEnrico Granata m_is_ptr = m_type_flags.Test(eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo; 1954d93b8cdSEnrico Granata return m_is_ptr == eLazyBoolYes; 1964d93b8cdSEnrico Granata } 1974d93b8cdSEnrico Granata 198b9c1b51eSKate Stone bool ValueObjectPrinter::IsRef() { 1994d93b8cdSEnrico Granata if (m_is_ref == eLazyBoolCalculate) 200622be238SEnrico Granata m_is_ref = m_type_flags.Test(eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo; 2014d93b8cdSEnrico Granata return m_is_ref == eLazyBoolYes; 2024d93b8cdSEnrico Granata } 2034d93b8cdSEnrico Granata 204b9c1b51eSKate Stone bool ValueObjectPrinter::IsAggregate() { 2054d93b8cdSEnrico Granata if (m_is_aggregate == eLazyBoolCalculate) 206b9c1b51eSKate Stone m_is_aggregate = 207b9c1b51eSKate Stone m_type_flags.Test(eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo; 2084d93b8cdSEnrico Granata return m_is_aggregate == eLazyBoolYes; 2094d93b8cdSEnrico Granata } 2104d93b8cdSEnrico Granata 211b9c1b51eSKate Stone bool ValueObjectPrinter::IsInstancePointer() { 2128cf44d96SEnrico Granata // you need to do this check on the value's clang type 2138cf44d96SEnrico Granata if (m_is_instance_ptr == eLazyBoolCalculate) 214b9c1b51eSKate Stone m_is_instance_ptr = (m_valobj->GetValue().GetCompilerType().GetTypeInfo() & 215b9c1b51eSKate Stone eTypeInstanceIsPointer) != 0 216b9c1b51eSKate Stone ? eLazyBoolYes 217b9c1b51eSKate Stone : eLazyBoolNo; 2188cf44d96SEnrico Granata if ((eLazyBoolYes == m_is_instance_ptr) && m_valobj->IsBaseClass()) 2198cf44d96SEnrico Granata m_is_instance_ptr = eLazyBoolNo; 2208cf44d96SEnrico Granata return m_is_instance_ptr == eLazyBoolYes; 2218cf44d96SEnrico Granata } 2228cf44d96SEnrico Granata 223b9c1b51eSKate Stone bool ValueObjectPrinter::PrintLocationIfNeeded() { 224b9c1b51eSKate Stone if (m_options.m_show_location) { 2254d93b8cdSEnrico Granata m_stream->Printf("%s: ", m_valobj->GetLocationAsCString()); 2264d93b8cdSEnrico Granata return true; 2274d93b8cdSEnrico Granata } 2284d93b8cdSEnrico Granata return false; 2294d93b8cdSEnrico Granata } 2304d93b8cdSEnrico Granata 231b9c1b51eSKate Stone void ValueObjectPrinter::PrintDecl() { 2324d93b8cdSEnrico Granata bool show_type = true; 233b9c1b51eSKate Stone // if we are at the root-level and been asked to hide the root's type, then 234b9c1b51eSKate Stone // hide it 23526014690SGreg Clayton if (m_curr_depth == 0 && m_options.m_hide_root_type) 2364d93b8cdSEnrico Granata show_type = false; 2374d93b8cdSEnrico Granata else 238b9c1b51eSKate Stone // otherwise decide according to the usual rules (asked to show types - 239b9c1b51eSKate Stone // always at the root level) 240b9c1b51eSKate Stone show_type = m_options.m_show_types || 241b9c1b51eSKate Stone (m_curr_depth == 0 && !m_options.m_flat_output); 2424d93b8cdSEnrico Granata 243e0ee1e1cSEnrico Granata StreamString typeName; 244e0ee1e1cSEnrico Granata 245e0ee1e1cSEnrico Granata // always show the type at the root level if it is invalid 246b9c1b51eSKate Stone if (show_type) { 2474d93b8cdSEnrico Granata // Some ValueObjects don't have types (like registers sets). Only print 2484d93b8cdSEnrico Granata // the type if there is one to print 249a126e462SEnrico Granata ConstString type_name; 250b9c1b51eSKate Stone if (m_compiler_type.IsValid()) { 25126014690SGreg Clayton if (m_options.m_use_type_display_name) 252a126e462SEnrico Granata type_name = m_valobj->GetDisplayTypeName(); 253e8daa2f8SEnrico Granata else 254a126e462SEnrico Granata type_name = m_valobj->GetQualifiedTypeName(); 255b9c1b51eSKate Stone } else { 256b9c1b51eSKate Stone // only show an invalid type name if the user explicitly triggered 257b9c1b51eSKate Stone // show_type 25826014690SGreg Clayton if (m_options.m_show_types) 259e0ee1e1cSEnrico Granata type_name = ConstString("<invalid type>"); 260e0ee1e1cSEnrico Granata else 261e0ee1e1cSEnrico Granata type_name.Clear(); 2624d93b8cdSEnrico Granata } 2634d93b8cdSEnrico Granata 264b9c1b51eSKate Stone if (type_name) { 265e0ee1e1cSEnrico Granata std::string type_name_str(type_name.GetCString()); 266b9c1b51eSKate Stone if (m_options.m_hide_pointer_value) { 267b9c1b51eSKate Stone for (auto iter = type_name_str.find(" *"); iter != std::string::npos; 268b9c1b51eSKate Stone iter = type_name_str.find(" *")) { 269e0ee1e1cSEnrico Granata type_name_str.erase(iter, 2); 270e0ee1e1cSEnrico Granata } 271e0ee1e1cSEnrico Granata } 272c8e7649aSEnrico Granata typeName.Printf("%s", type_name_str.c_str()); 273e0ee1e1cSEnrico Granata } 274e0ee1e1cSEnrico Granata } 275e0ee1e1cSEnrico Granata 276e0ee1e1cSEnrico Granata StreamString varName; 277e0ee1e1cSEnrico Granata 278b9c1b51eSKate Stone if (m_options.m_flat_output) { 2794d93b8cdSEnrico Granata // If we are showing types, also qualify the C++ base classes 2804d93b8cdSEnrico Granata const bool qualify_cxx_base_classes = show_type; 281b9c1b51eSKate Stone if (!m_options.m_hide_name) { 282e0ee1e1cSEnrico Granata m_valobj->GetExpressionPath(varName, qualify_cxx_base_classes); 2834d93b8cdSEnrico Granata } 284b9c1b51eSKate Stone } else if (!m_options.m_hide_name) { 2854d93b8cdSEnrico Granata const char *name_cstr = GetRootNameForDisplay(""); 286e0ee1e1cSEnrico Granata varName.Printf("%s", name_cstr); 2874d93b8cdSEnrico Granata } 288e0ee1e1cSEnrico Granata 289e0ee1e1cSEnrico Granata bool decl_printed = false; 290b9c1b51eSKate Stone if (!m_options.m_decl_printing_helper) { 291b9c1b51eSKate Stone // if the user didn't give us a custom helper, pick one based upon the 292b9c1b51eSKate Stone // language, either the one that this printer is bound to, or the preferred 293b9c1b51eSKate Stone // one for the ValueObject 294b9c1b51eSKate Stone lldb::LanguageType lang_type = 295b9c1b51eSKate Stone (m_options.m_varformat_language == lldb::eLanguageTypeUnknown) 296b9c1b51eSKate Stone ? m_valobj->GetPreferredDisplayLanguage() 297b9c1b51eSKate Stone : m_options.m_varformat_language; 298b9c1b51eSKate Stone if (Language *lang_plugin = Language::FindPlugin(lang_type)) { 29926014690SGreg Clayton m_options.m_decl_printing_helper = lang_plugin->GetDeclPrintingHelper(); 300c8e7649aSEnrico Granata } 301c8e7649aSEnrico Granata } 302c8e7649aSEnrico Granata 303b9c1b51eSKate Stone if (m_options.m_decl_printing_helper) { 304c156427dSZachary Turner ConstString type_name_cstr(typeName.GetString()); 305c156427dSZachary Turner ConstString var_name_cstr(varName.GetString()); 306e0ee1e1cSEnrico Granata 307e0ee1e1cSEnrico Granata StreamString dest_stream; 308b9c1b51eSKate Stone if (m_options.m_decl_printing_helper(type_name_cstr, var_name_cstr, 309b9c1b51eSKate Stone m_options, dest_stream)) { 310e0ee1e1cSEnrico Granata decl_printed = true; 311c156427dSZachary Turner m_stream->PutCString(dest_stream.GetString()); 312e0ee1e1cSEnrico Granata } 313e0ee1e1cSEnrico Granata } 314e0ee1e1cSEnrico Granata 315c8e7649aSEnrico Granata // if the helper failed, or there is none, do a default thing 316b9c1b51eSKate Stone if (!decl_printed) { 317c156427dSZachary Turner if (!typeName.Empty()) 318c8e7649aSEnrico Granata m_stream->Printf("(%s) ", typeName.GetData()); 319c156427dSZachary Turner if (!varName.Empty()) 320e0ee1e1cSEnrico Granata m_stream->Printf("%s =", varName.GetData()); 32126014690SGreg Clayton else if (!m_options.m_hide_name) 322e0ee1e1cSEnrico Granata m_stream->Printf(" ="); 323e0ee1e1cSEnrico Granata } 3244d93b8cdSEnrico Granata } 3254d93b8cdSEnrico Granata 326b9c1b51eSKate Stone bool ValueObjectPrinter::CheckScopeIfNeeded() { 32726014690SGreg Clayton if (m_options.m_scope_already_checked) 3284d93b8cdSEnrico Granata return true; 3294d93b8cdSEnrico Granata return m_valobj->IsInScope(); 3304d93b8cdSEnrico Granata } 3314d93b8cdSEnrico Granata 332b9c1b51eSKate Stone TypeSummaryImpl *ValueObjectPrinter::GetSummaryFormatter(bool null_if_omitted) { 333b9c1b51eSKate Stone if (m_summary_formatter.second == false) { 334b9c1b51eSKate Stone TypeSummaryImpl *entry = m_options.m_summary_sp 335b9c1b51eSKate Stone ? m_options.m_summary_sp.get() 336b9c1b51eSKate Stone : m_valobj->GetSummaryFormat().get(); 3374d93b8cdSEnrico Granata 33826014690SGreg Clayton if (m_options.m_omit_summary_depth > 0) 3394d93b8cdSEnrico Granata entry = NULL; 3404d93b8cdSEnrico Granata m_summary_formatter.first = entry; 3414d93b8cdSEnrico Granata m_summary_formatter.second = true; 3424d93b8cdSEnrico Granata } 3438cf44d96SEnrico Granata if (m_options.m_omit_summary_depth > 0 && null_if_omitted) 3448cf44d96SEnrico Granata return nullptr; 3454d93b8cdSEnrico Granata return m_summary_formatter.first; 3464d93b8cdSEnrico Granata } 3474d93b8cdSEnrico Granata 348b9c1b51eSKate Stone static bool IsPointerValue(const CompilerType &type) { 349e0ee1e1cSEnrico Granata Flags type_flags(type.GetTypeInfo()); 3508cf44d96SEnrico Granata if (type_flags.AnySet(eTypeInstanceIsPointer | eTypeIsPointer)) 351e0ee1e1cSEnrico Granata return type_flags.AllClear(eTypeIsBuiltIn); 352e0ee1e1cSEnrico Granata return false; 353e0ee1e1cSEnrico Granata } 354e0ee1e1cSEnrico Granata 355b9c1b51eSKate Stone void ValueObjectPrinter::GetValueSummaryError(std::string &value, 3564d93b8cdSEnrico Granata std::string &summary, 357b9c1b51eSKate Stone std::string &error) { 358520a422bSEnrico Granata lldb::Format format = m_options.m_format; 359b9c1b51eSKate Stone // if I am printing synthetized elements, apply the format to those elements 360b9c1b51eSKate Stone // only 3619ac0dac1SEnrico Granata if (m_options.m_pointer_as_array) 362520a422bSEnrico Granata m_valobj->GetValueAsCString(lldb::eFormatDefault, value); 363520a422bSEnrico Granata else if (format != eFormatDefault && format != m_valobj->GetFormat()) 364520a422bSEnrico Granata m_valobj->GetValueAsCString(format, value); 365b9c1b51eSKate Stone else { 3664d93b8cdSEnrico Granata const char *val_cstr = m_valobj->GetValueAsCString(); 367465f4bc2SEnrico Granata if (val_cstr) 368465f4bc2SEnrico Granata value.assign(val_cstr); 369465f4bc2SEnrico Granata } 3704d93b8cdSEnrico Granata const char *err_cstr = m_valobj->GetError().AsCString(); 3714d93b8cdSEnrico Granata if (err_cstr) 3724d93b8cdSEnrico Granata error.assign(err_cstr); 3734d93b8cdSEnrico Granata 374b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 3754d93b8cdSEnrico Granata if (IsNil()) 3764d93b8cdSEnrico Granata summary.assign("nil"); 377608d67c1SEnrico Granata else if (IsUninitialized()) 378608d67c1SEnrico Granata summary.assign("<uninitialized>"); 379b9c1b51eSKate Stone else if (m_options.m_omit_summary_depth == 0) { 3804d93b8cdSEnrico Granata TypeSummaryImpl *entry = GetSummaryFormatter(); 3814d93b8cdSEnrico Granata if (entry) 382b9c1b51eSKate Stone m_valobj->GetSummaryAsCString(entry, summary, 383b9c1b51eSKate Stone m_options.m_varformat_language); 384b9c1b51eSKate Stone else { 385b9c1b51eSKate Stone const char *sum_cstr = 386b9c1b51eSKate Stone m_valobj->GetSummaryAsCString(m_options.m_varformat_language); 3874d93b8cdSEnrico Granata if (sum_cstr) 3884d93b8cdSEnrico Granata summary.assign(sum_cstr); 3894d93b8cdSEnrico Granata } 3904d93b8cdSEnrico Granata } 3914d93b8cdSEnrico Granata } 3924d93b8cdSEnrico Granata } 3934d93b8cdSEnrico Granata 394b9c1b51eSKate Stone bool ValueObjectPrinter::PrintValueAndSummaryIfNeeded(bool &value_printed, 395b9c1b51eSKate Stone bool &summary_printed) { 3964d93b8cdSEnrico Granata bool error_printed = false; 397b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 3984d93b8cdSEnrico Granata if (!CheckScopeIfNeeded()) 3994d93b8cdSEnrico Granata m_error.assign("out of scope"); 400b9c1b51eSKate Stone if (m_error.empty()) { 4014d93b8cdSEnrico Granata GetValueSummaryError(m_value, m_summary, m_error); 4024d93b8cdSEnrico Granata } 403b9c1b51eSKate Stone if (m_error.size()) { 404b9c1b51eSKate Stone // we need to support scenarios in which it is actually fine for a value 405b9c1b51eSKate Stone // to have no type 406b9c1b51eSKate Stone // but - on the other hand - if we get an error *AND* have no type, we try 407b9c1b51eSKate Stone // to get out 408b9c1b51eSKate Stone // gracefully, since most often that combination means "could not resolve 409b9c1b51eSKate Stone // a type" 4108cf44d96SEnrico Granata // and the default failure mode is quite ugly 411b9c1b51eSKate Stone if (!m_compiler_type.IsValid()) { 4128cf44d96SEnrico Granata m_stream->Printf(" <could not resolve type>"); 4138cf44d96SEnrico Granata return false; 4148cf44d96SEnrico Granata } 4158cf44d96SEnrico Granata 4164d93b8cdSEnrico Granata error_printed = true; 4174d93b8cdSEnrico Granata m_stream->Printf(" <%s>\n", m_error.c_str()); 418b9c1b51eSKate Stone } else { 4194d93b8cdSEnrico Granata // Make sure we have a value and make sure the summary didn't 4204d93b8cdSEnrico Granata // specify that the value should not be printed - and do not print 4214d93b8cdSEnrico Granata // the value if this thing is nil 4224d93b8cdSEnrico Granata // (but show the value if the user passes a format explicitly) 4234d93b8cdSEnrico Granata TypeSummaryImpl *entry = GetSummaryFormatter(); 424b9c1b51eSKate Stone if (!IsNil() && !IsUninitialized() && !m_value.empty() && 425b9c1b51eSKate Stone (entry == NULL || (entry->DoesPrintValue(m_valobj) || 426b9c1b51eSKate Stone m_options.m_format != eFormatDefault) || 427b9c1b51eSKate Stone m_summary.empty()) && 428b9c1b51eSKate Stone !m_options.m_hide_value) { 429b9c1b51eSKate Stone if (m_options.m_hide_pointer_value && 430b9c1b51eSKate Stone IsPointerValue(m_valobj->GetCompilerType())) { 431b9c1b51eSKate Stone } else { 4324d93b8cdSEnrico Granata m_stream->Printf(" %s", m_value.c_str()); 4334d93b8cdSEnrico Granata value_printed = true; 4344d93b8cdSEnrico Granata } 435e0ee1e1cSEnrico Granata } 4364d93b8cdSEnrico Granata 437b9c1b51eSKate Stone if (m_summary.size()) { 4384d93b8cdSEnrico Granata m_stream->Printf(" %s", m_summary.c_str()); 4394d93b8cdSEnrico Granata summary_printed = true; 4404d93b8cdSEnrico Granata } 4414d93b8cdSEnrico Granata } 4424d93b8cdSEnrico Granata } 4434d93b8cdSEnrico Granata return !error_printed; 4444d93b8cdSEnrico Granata } 4454d93b8cdSEnrico Granata 446b9c1b51eSKate Stone bool ValueObjectPrinter::PrintObjectDescriptionIfNeeded(bool value_printed, 447b9c1b51eSKate Stone bool summary_printed) { 448b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 4494d93b8cdSEnrico Granata // let's avoid the overly verbose no description error for a nil thing 450b9c1b51eSKate Stone if (m_options.m_use_objc && !IsNil() && !IsUninitialized() && 4519ac0dac1SEnrico Granata (!m_options.m_pointer_as_array)) { 45226014690SGreg Clayton if (!m_options.m_hide_value || !m_options.m_hide_name) 4534d93b8cdSEnrico Granata m_stream->Printf(" "); 4544d93b8cdSEnrico Granata const char *object_desc = nullptr; 4554d93b8cdSEnrico Granata if (value_printed || summary_printed) 4564d93b8cdSEnrico Granata object_desc = m_valobj->GetObjectDescription(); 4574d93b8cdSEnrico Granata else 4584d93b8cdSEnrico Granata object_desc = GetDescriptionForDisplay(); 459b9c1b51eSKate Stone if (object_desc && *object_desc) { 4604d93b8cdSEnrico Granata m_stream->Printf("%s\n", object_desc); 4614d93b8cdSEnrico Granata return true; 462b9c1b51eSKate Stone } else if (value_printed == false && summary_printed == false) 4634d93b8cdSEnrico Granata return true; 4644d93b8cdSEnrico Granata else 4654d93b8cdSEnrico Granata return false; 4664d93b8cdSEnrico Granata } 4674d93b8cdSEnrico Granata } 4684d93b8cdSEnrico Granata return true; 4694d93b8cdSEnrico Granata } 4704d93b8cdSEnrico Granata 471b9c1b51eSKate Stone bool DumpValueObjectOptions::PointerDepth::CanAllowExpansion() const { 472b9c1b51eSKate Stone switch (m_mode) { 473c1b7c09aSEnrico Granata case Mode::Always: 474c1b7c09aSEnrico Granata case Mode::Default: 475*e4e17b8cSTamas Berghammer return m_count > 0; 476c1b7c09aSEnrico Granata case Mode::Never: 477c1b7c09aSEnrico Granata return false; 478c1b7c09aSEnrico Granata } 47984f5b0dfSZachary Turner return false; 480c1b7c09aSEnrico Granata } 481c1b7c09aSEnrico Granata 482b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldPrintChildren( 483b9c1b51eSKate Stone bool is_failed_description, 484b9c1b51eSKate Stone DumpValueObjectOptions::PointerDepth &curr_ptr_depth) { 4854d93b8cdSEnrico Granata const bool is_ref = IsRef(); 4864d93b8cdSEnrico Granata const bool is_ptr = IsPtr(); 487608d67c1SEnrico Granata const bool is_uninit = IsUninitialized(); 488608d67c1SEnrico Granata 489608d67c1SEnrico Granata if (is_uninit) 490608d67c1SEnrico Granata return false; 4914d93b8cdSEnrico Granata 492520a422bSEnrico Granata // if the user has specified an element count, always print children 493520a422bSEnrico Granata // as it is explicit user demand being honored 4949ac0dac1SEnrico Granata if (m_options.m_pointer_as_array) 495520a422bSEnrico Granata return true; 496520a422bSEnrico Granata 497c1b7c09aSEnrico Granata TypeSummaryImpl *entry = GetSummaryFormatter(); 498c1b7c09aSEnrico Granata 4998cf44d96SEnrico Granata if (m_options.m_use_objc) 5008cf44d96SEnrico Granata return false; 5018cf44d96SEnrico Granata 502b9c1b51eSKate Stone if (is_failed_description || m_curr_depth < m_options.m_max_depth) { 5034d93b8cdSEnrico Granata // We will show children for all concrete types. We won't show 5044d93b8cdSEnrico Granata // pointer contents unless a pointer depth has been specified. 5054d93b8cdSEnrico Granata // We won't reference contents unless the reference is the 5064d93b8cdSEnrico Granata // root object (depth of zero). 5074d93b8cdSEnrico Granata 5084d93b8cdSEnrico Granata // Use a new temporary pointer depth in case we override the 5094d93b8cdSEnrico Granata // current pointer depth below... 5104d93b8cdSEnrico Granata 511b9c1b51eSKate Stone if (is_ptr || is_ref) { 5124d93b8cdSEnrico Granata // We have a pointer or reference whose value is an address. 5134d93b8cdSEnrico Granata // Make sure that address is not NULL 5144d93b8cdSEnrico Granata AddressType ptr_address_type; 5154d93b8cdSEnrico Granata if (m_valobj->GetPointerValue(&ptr_address_type) == 0) 5164d93b8cdSEnrico Granata return false; 5174d93b8cdSEnrico Granata 518c1b7c09aSEnrico Granata const bool is_root_level = m_curr_depth == 0; 519c1b7c09aSEnrico Granata 520b9c1b51eSKate Stone if (is_ref && is_root_level) { 5214d93b8cdSEnrico Granata // If this is the root object (depth is zero) that we are showing 5224d93b8cdSEnrico Granata // and it is a reference, and no pointer depth has been supplied 5234d93b8cdSEnrico Granata // print out what it references. Don't do this at deeper depths 5244d93b8cdSEnrico Granata // otherwise we can end up with infinite recursion... 525c1b7c09aSEnrico Granata return true; 5264d93b8cdSEnrico Granata } 5274d93b8cdSEnrico Granata 528*e4e17b8cSTamas Berghammer return curr_ptr_depth.CanAllowExpansion(); 5294d93b8cdSEnrico Granata } 5304d93b8cdSEnrico Granata 5318a068e6cSEnrico Granata return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty()); 5324d93b8cdSEnrico Granata } 5334d93b8cdSEnrico Granata return false; 5344d93b8cdSEnrico Granata } 5354d93b8cdSEnrico Granata 536b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldExpandEmptyAggregates() { 537d26eb907SSiva Chandra TypeSummaryImpl *entry = GetSummaryFormatter(); 538d26eb907SSiva Chandra 539d26eb907SSiva Chandra if (!entry) 540d26eb907SSiva Chandra return true; 541d26eb907SSiva Chandra 542d26eb907SSiva Chandra return entry->DoesPrintEmptyAggregates(); 543d26eb907SSiva Chandra } 544d26eb907SSiva Chandra 545b9c1b51eSKate Stone ValueObject *ValueObjectPrinter::GetValueObjectForChildrenGeneration() { 546d07cfd3aSEnrico Granata return m_valobj; 5474d93b8cdSEnrico Granata } 5484d93b8cdSEnrico Granata 549b9c1b51eSKate Stone void ValueObjectPrinter::PrintChildrenPreamble() { 550b9c1b51eSKate Stone if (m_options.m_flat_output) { 5514d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 5524d93b8cdSEnrico Granata m_stream->EOL(); 553b9c1b51eSKate Stone } else { 5544d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 5554d93b8cdSEnrico Granata m_stream->PutCString(IsRef() ? ": {\n" : " {\n"); 5564d93b8cdSEnrico Granata m_stream->IndentMore(); 5574d93b8cdSEnrico Granata } 5584d93b8cdSEnrico Granata } 5594d93b8cdSEnrico Granata 560b9c1b51eSKate Stone void ValueObjectPrinter::PrintChild( 561b9c1b51eSKate Stone ValueObjectSP child_sp, 562b9c1b51eSKate Stone const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) { 5639ac0dac1SEnrico Granata const uint32_t consumed_depth = (!m_options.m_pointer_as_array) ? 1 : 0; 564b9c1b51eSKate Stone const bool does_consume_ptr_depth = 5659ac0dac1SEnrico Granata ((IsPtr() && !m_options.m_pointer_as_array) || IsRef()); 566520a422bSEnrico Granata 56726014690SGreg Clayton DumpValueObjectOptions child_options(m_options); 568b9c1b51eSKate Stone child_options.SetFormat(m_options.m_format) 569b9c1b51eSKate Stone .SetSummary() 570b9c1b51eSKate Stone .SetRootValueObjectName(); 571b9c1b51eSKate Stone child_options.SetScopeChecked(true) 572b9c1b51eSKate Stone .SetHideName(m_options.m_hide_name) 573b9c1b51eSKate Stone .SetHideValue(m_options.m_hide_value) 574b9c1b51eSKate Stone .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 575b9c1b51eSKate Stone ? child_options.m_omit_summary_depth - 576b9c1b51eSKate Stone consumed_depth 577b9c1b51eSKate Stone : 0) 578520a422bSEnrico Granata .SetElementCount(0); 5798cf44d96SEnrico Granata 580b9c1b51eSKate Stone if (child_sp.get()) { 581b9c1b51eSKate Stone ValueObjectPrinter child_printer( 582b9c1b51eSKate Stone child_sp.get(), m_stream, child_options, 583520a422bSEnrico Granata does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth, 584b9c1b51eSKate Stone m_curr_depth + consumed_depth, m_printed_instance_pointers); 5854d93b8cdSEnrico Granata child_printer.PrintValueObject(); 5864d93b8cdSEnrico Granata } 5874d93b8cdSEnrico Granata } 5884d93b8cdSEnrico Granata 589b9c1b51eSKate Stone uint32_t ValueObjectPrinter::GetMaxNumChildrenToPrint(bool &print_dotdotdot) { 5904d93b8cdSEnrico Granata ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration(); 5914d93b8cdSEnrico Granata 5929ac0dac1SEnrico Granata if (m_options.m_pointer_as_array) 5939ac0dac1SEnrico Granata return m_options.m_pointer_as_array.m_element_count; 594520a422bSEnrico Granata 5954d93b8cdSEnrico Granata size_t num_children = synth_m_valobj->GetNumChildren(); 5964d93b8cdSEnrico Granata print_dotdotdot = false; 597b9c1b51eSKate Stone if (num_children) { 598b9c1b51eSKate Stone const size_t max_num_children = 599b9c1b51eSKate Stone m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 6004d93b8cdSEnrico Granata 601b9c1b51eSKate Stone if (num_children > max_num_children && !m_options.m_ignore_cap) { 6024d93b8cdSEnrico Granata print_dotdotdot = true; 6034d93b8cdSEnrico Granata return max_num_children; 6044d93b8cdSEnrico Granata } 6054d93b8cdSEnrico Granata } 6064d93b8cdSEnrico Granata return num_children; 6074d93b8cdSEnrico Granata } 6084d93b8cdSEnrico Granata 609b9c1b51eSKate Stone void ValueObjectPrinter::PrintChildrenPostamble(bool print_dotdotdot) { 610b9c1b51eSKate Stone if (!m_options.m_flat_output) { 611b9c1b51eSKate Stone if (print_dotdotdot) { 612b9c1b51eSKate Stone m_valobj->GetTargetSP() 613b9c1b51eSKate Stone ->GetDebugger() 614b9c1b51eSKate Stone .GetCommandInterpreter() 615b9c1b51eSKate Stone .ChildrenTruncated(); 6164d93b8cdSEnrico Granata m_stream->Indent("...\n"); 6174d93b8cdSEnrico Granata } 6184d93b8cdSEnrico Granata m_stream->IndentLess(); 6194d93b8cdSEnrico Granata m_stream->Indent("}\n"); 6204d93b8cdSEnrico Granata } 6214d93b8cdSEnrico Granata } 6224d93b8cdSEnrico Granata 623b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldPrintEmptyBrackets(bool value_printed, 624b9c1b51eSKate Stone bool summary_printed) { 6258cf44d96SEnrico Granata ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration(); 6268cf44d96SEnrico Granata 6278cf44d96SEnrico Granata if (!IsAggregate()) 6288cf44d96SEnrico Granata return false; 6298cf44d96SEnrico Granata 630b9c1b51eSKate Stone if (m_options.m_reveal_empty_aggregates == false) { 6318cf44d96SEnrico Granata if (value_printed || summary_printed) 6328cf44d96SEnrico Granata return false; 6338cf44d96SEnrico Granata } 6348cf44d96SEnrico Granata 6358cf44d96SEnrico Granata if (synth_m_valobj->MightHaveChildren()) 6368cf44d96SEnrico Granata return true; 6378cf44d96SEnrico Granata 6388cf44d96SEnrico Granata if (m_val_summary_ok) 6398cf44d96SEnrico Granata return false; 6408cf44d96SEnrico Granata 6418cf44d96SEnrico Granata return true; 6428cf44d96SEnrico Granata } 6438cf44d96SEnrico Granata 6449ac0dac1SEnrico Granata static constexpr size_t PhysicalIndexForLogicalIndex(size_t base, size_t stride, 6459ac0dac1SEnrico Granata size_t logical) { 6469ac0dac1SEnrico Granata return base + logical * stride; 6479ac0dac1SEnrico Granata } 6489ac0dac1SEnrico Granata 649b9c1b51eSKate Stone ValueObjectSP ValueObjectPrinter::GenerateChild(ValueObject *synth_valobj, 650b9c1b51eSKate Stone size_t idx) { 6519ac0dac1SEnrico Granata if (m_options.m_pointer_as_array) { 652520a422bSEnrico Granata // if generating pointer-as-array children, use GetSyntheticArrayMember 6539ac0dac1SEnrico Granata return synth_valobj->GetSyntheticArrayMember( 6549ac0dac1SEnrico Granata PhysicalIndexForLogicalIndex( 6559ac0dac1SEnrico Granata m_options.m_pointer_as_array.m_base_element, 6569ac0dac1SEnrico Granata m_options.m_pointer_as_array.m_stride, idx), 6579ac0dac1SEnrico Granata true); 658b9c1b51eSKate Stone } else { 659520a422bSEnrico Granata // otherwise, do the usual thing 660520a422bSEnrico Granata return synth_valobj->GetChildAtIndex(idx, true); 661520a422bSEnrico Granata } 662520a422bSEnrico Granata } 663520a422bSEnrico Granata 664b9c1b51eSKate Stone void ValueObjectPrinter::PrintChildren( 665b9c1b51eSKate Stone bool value_printed, bool summary_printed, 666b9c1b51eSKate Stone const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) { 6674d93b8cdSEnrico Granata ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration(); 6684d93b8cdSEnrico Granata 6694d93b8cdSEnrico Granata bool print_dotdotdot = false; 6704d93b8cdSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 671b9c1b51eSKate Stone if (num_children) { 6728cf44d96SEnrico Granata bool any_children_printed = false; 6734d93b8cdSEnrico Granata 674b9c1b51eSKate Stone for (size_t idx = 0; idx < num_children; ++idx) { 675b9c1b51eSKate Stone if (ValueObjectSP child_sp = GenerateChild(synth_m_valobj, idx)) { 676b9c1b51eSKate Stone if (!any_children_printed) { 6778cf44d96SEnrico Granata PrintChildrenPreamble(); 6788cf44d96SEnrico Granata any_children_printed = true; 6798cf44d96SEnrico Granata } 6804d93b8cdSEnrico Granata PrintChild(child_sp, curr_ptr_depth); 6814d93b8cdSEnrico Granata } 6824d93b8cdSEnrico Granata } 6838cf44d96SEnrico Granata 6848cf44d96SEnrico Granata if (any_children_printed) 6858cf44d96SEnrico Granata PrintChildrenPostamble(print_dotdotdot); 686b9c1b51eSKate Stone else { 687b9c1b51eSKate Stone if (ShouldPrintEmptyBrackets(value_printed, summary_printed)) { 6888cf44d96SEnrico Granata if (ShouldPrintValueObject()) 6898cf44d96SEnrico Granata m_stream->PutCString(" {}\n"); 6908cf44d96SEnrico Granata else 6918cf44d96SEnrico Granata m_stream->EOL(); 692b9c1b51eSKate Stone } else 6938cf44d96SEnrico Granata m_stream->EOL(); 6948cf44d96SEnrico Granata } 695b9c1b51eSKate Stone } else if (ShouldPrintEmptyBrackets(value_printed, summary_printed)) { 6964d93b8cdSEnrico Granata // Aggregate, no children... 697b9c1b51eSKate Stone if (ShouldPrintValueObject()) { 698b9c1b51eSKate Stone // if it has a synthetic value, then don't print {}, the synthetic 699b9c1b51eSKate Stone // children are probably only being used to vend a value 700b9c1b51eSKate Stone if (m_valobj->DoesProvideSyntheticValue() || 701b9c1b51eSKate Stone !ShouldExpandEmptyAggregates()) 702d07cfd3aSEnrico Granata m_stream->PutCString("\n"); 703d07cfd3aSEnrico Granata else 7044d93b8cdSEnrico Granata m_stream->PutCString(" {}\n"); 7054d93b8cdSEnrico Granata } 706b9c1b51eSKate Stone } else { 7074d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 7084d93b8cdSEnrico Granata m_stream->EOL(); 7094d93b8cdSEnrico Granata } 7104d93b8cdSEnrico Granata } 7114d93b8cdSEnrico Granata 712b9c1b51eSKate Stone bool ValueObjectPrinter::PrintChildrenOneLiner(bool hide_names) { 713d07cfd3aSEnrico Granata if (!GetMostSpecializedValue() || m_valobj == nullptr) 714a29cb0baSEnrico Granata return false; 715a29cb0baSEnrico Granata 716a29cb0baSEnrico Granata ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration(); 717a29cb0baSEnrico Granata 718a29cb0baSEnrico Granata bool print_dotdotdot = false; 719a29cb0baSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 720a29cb0baSEnrico Granata 721b9c1b51eSKate Stone if (num_children) { 722a29cb0baSEnrico Granata m_stream->PutChar('('); 723a29cb0baSEnrico Granata 724b9c1b51eSKate Stone for (uint32_t idx = 0; idx < num_children; ++idx) { 725a29cb0baSEnrico Granata lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 726ddac7611SEnrico Granata if (child_sp) 727b9c1b51eSKate Stone child_sp = child_sp->GetQualifiedRepresentationIfAvailable( 728b9c1b51eSKate Stone m_options.m_use_dynamic, m_options.m_use_synthetic); 729b9c1b51eSKate Stone if (child_sp) { 730a29cb0baSEnrico Granata if (idx) 731a29cb0baSEnrico Granata m_stream->PutCString(", "); 732b9c1b51eSKate Stone if (!hide_names) { 733a29cb0baSEnrico Granata const char *name = child_sp.get()->GetName().AsCString(); 734b9c1b51eSKate Stone if (name && *name) { 735a29cb0baSEnrico Granata m_stream->PutCString(name); 736a29cb0baSEnrico Granata m_stream->PutCString(" = "); 737a29cb0baSEnrico Granata } 738a29cb0baSEnrico Granata } 739b9c1b51eSKate Stone child_sp->DumpPrintableRepresentation( 740b9c1b51eSKate Stone *m_stream, ValueObject::eValueObjectRepresentationStyleSummary, 7417aafb6a1SEnrico Granata m_options.m_format, 74265d86e4fSEnrico Granata ValueObject::PrintableRepresentationSpecialCases::eDisable); 743a29cb0baSEnrico Granata } 744a29cb0baSEnrico Granata } 745a29cb0baSEnrico Granata 746a29cb0baSEnrico Granata if (print_dotdotdot) 747a29cb0baSEnrico Granata m_stream->PutCString(", ...)"); 748a29cb0baSEnrico Granata else 749a29cb0baSEnrico Granata m_stream->PutChar(')'); 750a29cb0baSEnrico Granata } 751a29cb0baSEnrico Granata return true; 752a29cb0baSEnrico Granata } 753a29cb0baSEnrico Granata 754b9c1b51eSKate Stone void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed, 755b9c1b51eSKate Stone bool summary_printed) { 756b9c1b51eSKate Stone // this flag controls whether we tried to display a description for this 757b9c1b51eSKate Stone // object and failed 7584d93b8cdSEnrico Granata // if that happens, we want to display the children, if any 759b9c1b51eSKate Stone bool is_failed_description = 760b9c1b51eSKate Stone !PrintObjectDescriptionIfNeeded(value_printed, summary_printed); 7614d93b8cdSEnrico Granata 762c1b7c09aSEnrico Granata auto curr_ptr_depth = m_ptr_depth; 763b9c1b51eSKate Stone bool print_children = 764b9c1b51eSKate Stone ShouldPrintChildren(is_failed_description, curr_ptr_depth); 765b9c1b51eSKate Stone bool print_oneline = 766b9c1b51eSKate Stone (curr_ptr_depth.CanAllowExpansion() || m_options.m_show_types || 767b9c1b51eSKate Stone !m_options.m_allow_oneliner_mode || m_options.m_flat_output || 7689ac0dac1SEnrico Granata (m_options.m_pointer_as_array) || m_options.m_show_location) 769b9c1b51eSKate Stone ? false 770b9c1b51eSKate Stone : DataVisualization::ShouldPrintAsOneLiner(*m_valobj); 7718cf44d96SEnrico Granata bool is_instance_ptr = IsInstancePointer(); 7728cf44d96SEnrico Granata uint64_t instance_ptr_value = LLDB_INVALID_ADDRESS; 7738cf44d96SEnrico Granata 774b9c1b51eSKate Stone if (print_children && is_instance_ptr) { 7758cf44d96SEnrico Granata instance_ptr_value = m_valobj->GetValueAsUnsigned(0); 776b9c1b51eSKate Stone if (m_printed_instance_pointers->count(instance_ptr_value)) { 7778cf44d96SEnrico Granata // we already printed this instance-is-pointer thing, so don't expand it 7788cf44d96SEnrico Granata m_stream->PutCString(" {...}\n"); 7798cf44d96SEnrico Granata 7808cf44d96SEnrico Granata // we're done here - get out fast 7818cf44d96SEnrico Granata return; 782b9c1b51eSKate Stone } else 783b9c1b51eSKate Stone m_printed_instance_pointers->emplace( 784b9c1b51eSKate Stone instance_ptr_value); // remember this guy for future reference 7858cf44d96SEnrico Granata } 7864d93b8cdSEnrico Granata 787b9c1b51eSKate Stone if (print_children) { 788b9c1b51eSKate Stone if (print_oneline) { 789a29cb0baSEnrico Granata m_stream->PutChar(' '); 790a29cb0baSEnrico Granata PrintChildrenOneLiner(false); 791a29cb0baSEnrico Granata m_stream->EOL(); 792b9c1b51eSKate Stone } else 793c1b7c09aSEnrico Granata PrintChildren(value_printed, summary_printed, curr_ptr_depth); 794b9c1b51eSKate Stone } else if (m_curr_depth >= m_options.m_max_depth && IsAggregate() && 795b9c1b51eSKate Stone ShouldPrintValueObject()) { 7964d93b8cdSEnrico Granata m_stream->PutCString("{...}\n"); 797b9c1b51eSKate Stone } else 798245b3caaSEnrico Granata m_stream->EOL(); 7994d93b8cdSEnrico Granata } 8000f883ffbSEnrico Granata 801b9c1b51eSKate Stone bool ValueObjectPrinter::ShouldPrintValidation() { 80226014690SGreg Clayton return m_options.m_run_validator; 8030f883ffbSEnrico Granata } 8040f883ffbSEnrico Granata 805b9c1b51eSKate Stone bool ValueObjectPrinter::PrintValidationMarkerIfNeeded() { 8060f883ffbSEnrico Granata if (!ShouldPrintValidation()) 8070f883ffbSEnrico Granata return false; 8080f883ffbSEnrico Granata 8090f883ffbSEnrico Granata m_validation = m_valobj->GetValidationStatus(); 8100f883ffbSEnrico Granata 811b9c1b51eSKate Stone if (TypeValidatorResult::Failure == m_validation.first) { 8120f883ffbSEnrico Granata m_stream->Printf("! "); 8130f883ffbSEnrico Granata return true; 8140f883ffbSEnrico Granata } 8150f883ffbSEnrico Granata 8160f883ffbSEnrico Granata return false; 8170f883ffbSEnrico Granata } 8180f883ffbSEnrico Granata 819b9c1b51eSKate Stone bool ValueObjectPrinter::PrintValidationErrorIfNeeded() { 8200f883ffbSEnrico Granata if (!ShouldPrintValidation()) 8210f883ffbSEnrico Granata return false; 8220f883ffbSEnrico Granata 8230f883ffbSEnrico Granata if (TypeValidatorResult::Success == m_validation.first) 8240f883ffbSEnrico Granata return false; 8250f883ffbSEnrico Granata 8260f883ffbSEnrico Granata if (m_validation.second.empty()) 8270f883ffbSEnrico Granata m_validation.second.assign("unknown error"); 8280f883ffbSEnrico Granata 8290f883ffbSEnrico Granata m_stream->Printf(" ! validation error: %s", m_validation.second.c_str()); 8300f883ffbSEnrico Granata m_stream->EOL(); 8310f883ffbSEnrico Granata 8320f883ffbSEnrico Granata return true; 8330f883ffbSEnrico Granata } 834