14d93b8cdSEnrico Granata //===-- ValueObjectPrinter.cpp -------------------------------------*- C++ -*-===// 24d93b8cdSEnrico Granata // 34d93b8cdSEnrico Granata // The LLVM Compiler Infrastructure 44d93b8cdSEnrico Granata // 54d93b8cdSEnrico Granata // This file is distributed under the University of Illinois Open Source 64d93b8cdSEnrico Granata // License. See LICENSE.TXT for details. 74d93b8cdSEnrico Granata // 84d93b8cdSEnrico Granata //===----------------------------------------------------------------------===// 94d93b8cdSEnrico Granata 104d93b8cdSEnrico Granata #include "lldb/DataFormatters/ValueObjectPrinter.h" 114d93b8cdSEnrico Granata 124d93b8cdSEnrico Granata // C Includes 134d93b8cdSEnrico Granata // C++ Includes 144d93b8cdSEnrico Granata // Other libraries and framework includes 154d93b8cdSEnrico Granata // Project includes 16c8e7649aSEnrico Granata #include "lldb/Core/Stream.h" 17c8e7649aSEnrico Granata #include "lldb/Core/ValueObject.h" 18a29cb0baSEnrico Granata #include "lldb/DataFormatters/DataVisualization.h" 194d93b8cdSEnrico Granata #include "lldb/Interpreter/CommandInterpreter.h" 20c8e7649aSEnrico Granata #include "lldb/Target/Language.h" 214d93b8cdSEnrico Granata #include "lldb/Target/Target.h" 224d93b8cdSEnrico Granata 234d93b8cdSEnrico Granata using namespace lldb; 244d93b8cdSEnrico Granata using namespace lldb_private; 254d93b8cdSEnrico Granata 26d5957336SEnrico Granata ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, 27d5957336SEnrico Granata Stream* s) 28d5957336SEnrico Granata { 29d5957336SEnrico Granata if (valobj) 30d5957336SEnrico Granata { 31d5957336SEnrico Granata DumpValueObjectOptions options(*valobj); 328cf44d96SEnrico Granata Init (valobj,s,options,m_options.m_max_ptr_depth,0, nullptr); 33d5957336SEnrico Granata } 34d5957336SEnrico Granata else 35d5957336SEnrico Granata { 36d5957336SEnrico Granata DumpValueObjectOptions options; 378cf44d96SEnrico Granata Init (valobj,s,options,m_options.m_max_ptr_depth,0, nullptr); 38d5957336SEnrico Granata } 39d5957336SEnrico Granata } 40d5957336SEnrico Granata 414d93b8cdSEnrico Granata ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, 424d93b8cdSEnrico Granata Stream* s, 43938d1d67SEnrico Granata const DumpValueObjectOptions& options) 444d93b8cdSEnrico Granata { 458cf44d96SEnrico Granata Init(valobj,s,options,m_options.m_max_ptr_depth,0, nullptr); 464d93b8cdSEnrico Granata } 474d93b8cdSEnrico Granata 484d93b8cdSEnrico Granata ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, 494d93b8cdSEnrico Granata Stream* s, 504d93b8cdSEnrico Granata const DumpValueObjectOptions& options, 51c1b7c09aSEnrico Granata const DumpValueObjectOptions::PointerDepth& ptr_depth, 528cf44d96SEnrico Granata uint32_t curr_depth, 538cf44d96SEnrico Granata InstancePointersSetSP printed_instance_pointers) 54938d1d67SEnrico Granata { 558cf44d96SEnrico Granata Init(valobj,s,options,ptr_depth,curr_depth, printed_instance_pointers); 56938d1d67SEnrico Granata } 57938d1d67SEnrico Granata 58938d1d67SEnrico Granata void 59938d1d67SEnrico Granata ValueObjectPrinter::Init (ValueObject* valobj, 60938d1d67SEnrico Granata Stream* s, 61938d1d67SEnrico Granata const DumpValueObjectOptions& options, 62c1b7c09aSEnrico Granata const DumpValueObjectOptions::PointerDepth& ptr_depth, 638cf44d96SEnrico Granata uint32_t curr_depth, 648cf44d96SEnrico Granata InstancePointersSetSP printed_instance_pointers) 65938d1d67SEnrico Granata { 66938d1d67SEnrico Granata m_orig_valobj = valobj; 67938d1d67SEnrico Granata m_valobj = nullptr; 68938d1d67SEnrico Granata m_stream = s; 6926014690SGreg Clayton m_options = options; 70938d1d67SEnrico Granata m_ptr_depth = ptr_depth; 71938d1d67SEnrico Granata m_curr_depth = curr_depth; 72938d1d67SEnrico Granata assert (m_orig_valobj && "cannot print a NULL ValueObject"); 73938d1d67SEnrico Granata assert (m_stream && "cannot print to a NULL Stream"); 74938d1d67SEnrico Granata m_should_print = eLazyBoolCalculate; 75938d1d67SEnrico Granata m_is_nil = eLazyBoolCalculate; 76608d67c1SEnrico Granata m_is_uninit = eLazyBoolCalculate; 77938d1d67SEnrico Granata m_is_ptr = eLazyBoolCalculate; 78938d1d67SEnrico Granata m_is_ref = eLazyBoolCalculate; 79938d1d67SEnrico Granata m_is_aggregate = eLazyBoolCalculate; 808cf44d96SEnrico Granata m_is_instance_ptr = eLazyBoolCalculate; 81938d1d67SEnrico Granata m_summary_formatter = {nullptr,false}; 82938d1d67SEnrico Granata m_value.assign(""); 83938d1d67SEnrico Granata m_summary.assign(""); 84938d1d67SEnrico Granata m_error.assign(""); 858cf44d96SEnrico Granata m_val_summary_ok = false; 868cf44d96SEnrico Granata m_printed_instance_pointers = printed_instance_pointers ? printed_instance_pointers : InstancePointersSetSP(new InstancePointersSet()); 87938d1d67SEnrico Granata } 884d93b8cdSEnrico Granata 894d93b8cdSEnrico Granata bool 904d93b8cdSEnrico Granata ValueObjectPrinter::PrintValueObject () 914d93b8cdSEnrico Granata { 92d07cfd3aSEnrico Granata if (!GetMostSpecializedValue () || m_valobj == nullptr) 934d93b8cdSEnrico Granata return false; 944d93b8cdSEnrico Granata 954d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 964d93b8cdSEnrico Granata { 970f883ffbSEnrico Granata PrintValidationMarkerIfNeeded(); 980f883ffbSEnrico Granata 994d93b8cdSEnrico Granata PrintLocationIfNeeded(); 1004d93b8cdSEnrico Granata m_stream->Indent(); 1014d93b8cdSEnrico Granata 102e0ee1e1cSEnrico Granata PrintDecl(); 1034d93b8cdSEnrico Granata } 1044d93b8cdSEnrico Granata 1054d93b8cdSEnrico Granata bool value_printed = false; 1064d93b8cdSEnrico Granata bool summary_printed = false; 1074d93b8cdSEnrico Granata 1088cf44d96SEnrico Granata m_val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed); 1094d93b8cdSEnrico Granata 1108cf44d96SEnrico Granata if (m_val_summary_ok) 1114d93b8cdSEnrico Granata PrintChildrenIfNeeded (value_printed, summary_printed); 11239938938SEnrico Granata else 1134d93b8cdSEnrico Granata m_stream->EOL(); 1144d93b8cdSEnrico Granata 1150f883ffbSEnrico Granata PrintValidationErrorIfNeeded(); 1160f883ffbSEnrico Granata 1174d93b8cdSEnrico Granata return true; 1184d93b8cdSEnrico Granata } 1194d93b8cdSEnrico Granata 1204d93b8cdSEnrico Granata bool 121d07cfd3aSEnrico Granata ValueObjectPrinter::GetMostSpecializedValue () 1224d93b8cdSEnrico Granata { 123a29cb0baSEnrico Granata if (m_valobj) 124a29cb0baSEnrico Granata return true; 1254d93b8cdSEnrico Granata bool update_success = m_orig_valobj->UpdateValueIfNeeded (true); 1264d93b8cdSEnrico Granata if (!update_success) 127106260c5SEnrico Granata { 128106260c5SEnrico Granata m_valobj = m_orig_valobj; 129106260c5SEnrico Granata } 130106260c5SEnrico Granata else 131106260c5SEnrico Granata { 132106260c5SEnrico Granata if (m_orig_valobj->IsDynamic()) 133106260c5SEnrico Granata { 13426014690SGreg Clayton if (m_options.m_use_dynamic == eNoDynamicValues) 135106260c5SEnrico Granata { 136106260c5SEnrico Granata ValueObject *static_value = m_orig_valobj->GetStaticValue().get(); 137106260c5SEnrico Granata if (static_value) 138106260c5SEnrico Granata m_valobj = static_value; 139106260c5SEnrico Granata else 140106260c5SEnrico Granata m_valobj = m_orig_valobj; 141106260c5SEnrico Granata } 142106260c5SEnrico Granata else 143106260c5SEnrico Granata m_valobj = m_orig_valobj; 144106260c5SEnrico Granata } 145106260c5SEnrico Granata else 146106260c5SEnrico Granata { 14726014690SGreg Clayton if (m_options.m_use_dynamic != eNoDynamicValues) 1484d93b8cdSEnrico Granata { 14926014690SGreg Clayton ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(m_options.m_use_dynamic).get(); 1504d93b8cdSEnrico Granata if (dynamic_value) 1514d93b8cdSEnrico Granata m_valobj = dynamic_value; 1524d93b8cdSEnrico Granata else 1534d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 1544d93b8cdSEnrico Granata } 1554d93b8cdSEnrico Granata else 1564d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 157106260c5SEnrico Granata } 158d07cfd3aSEnrico Granata 159d07cfd3aSEnrico Granata if (m_valobj->IsSynthetic()) 160d07cfd3aSEnrico Granata { 16126014690SGreg Clayton if (m_options.m_use_synthetic == false) 162d07cfd3aSEnrico Granata { 163d07cfd3aSEnrico Granata ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get(); 164d07cfd3aSEnrico Granata if (non_synthetic) 165d07cfd3aSEnrico Granata m_valobj = non_synthetic; 166d07cfd3aSEnrico Granata } 167d07cfd3aSEnrico Granata } 168d07cfd3aSEnrico Granata else 169d07cfd3aSEnrico Granata { 17026014690SGreg Clayton if (m_options.m_use_synthetic == true) 171d07cfd3aSEnrico Granata { 172d07cfd3aSEnrico Granata ValueObject *synthetic = m_valobj->GetSyntheticValue().get(); 173d07cfd3aSEnrico Granata if (synthetic) 174d07cfd3aSEnrico Granata m_valobj = synthetic; 175d07cfd3aSEnrico Granata } 176d07cfd3aSEnrico Granata } 177106260c5SEnrico Granata } 17859b5a37dSBruce Mitchener m_compiler_type = m_valobj->GetCompilerType(); 17959b5a37dSBruce Mitchener m_type_flags = m_compiler_type.GetTypeInfo (); 1804d93b8cdSEnrico Granata return true; 1814d93b8cdSEnrico Granata } 1824d93b8cdSEnrico Granata 1834d93b8cdSEnrico Granata const char* 1844d93b8cdSEnrico Granata ValueObjectPrinter::GetDescriptionForDisplay () 1854d93b8cdSEnrico Granata { 1864d93b8cdSEnrico Granata const char* str = m_valobj->GetObjectDescription(); 1874d93b8cdSEnrico Granata if (!str) 1884d93b8cdSEnrico Granata str = m_valobj->GetSummaryAsCString(); 1894d93b8cdSEnrico Granata if (!str) 1904d93b8cdSEnrico Granata str = m_valobj->GetValueAsCString(); 1914d93b8cdSEnrico Granata return str; 1924d93b8cdSEnrico Granata } 1934d93b8cdSEnrico Granata 1944d93b8cdSEnrico Granata const char* 1954d93b8cdSEnrico Granata ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail) 1964d93b8cdSEnrico Granata { 19726014690SGreg Clayton const char *root_valobj_name = m_options.m_root_valobj_name.empty() ? 1984d93b8cdSEnrico Granata m_valobj->GetName().AsCString() : 19926014690SGreg Clayton m_options.m_root_valobj_name.c_str(); 2004d93b8cdSEnrico Granata return root_valobj_name ? root_valobj_name : if_fail; 2014d93b8cdSEnrico Granata } 2024d93b8cdSEnrico Granata 2034d93b8cdSEnrico Granata bool 2044d93b8cdSEnrico Granata ValueObjectPrinter::ShouldPrintValueObject () 2054d93b8cdSEnrico Granata { 2064d93b8cdSEnrico Granata if (m_should_print == eLazyBoolCalculate) 20726014690SGreg Clayton m_should_print = (m_options.m_flat_output == false || m_type_flags.Test (eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo; 2084d93b8cdSEnrico Granata return m_should_print == eLazyBoolYes; 2094d93b8cdSEnrico Granata } 2104d93b8cdSEnrico Granata 2114d93b8cdSEnrico Granata bool 2124d93b8cdSEnrico Granata ValueObjectPrinter::IsNil () 2134d93b8cdSEnrico Granata { 2144d93b8cdSEnrico Granata if (m_is_nil == eLazyBoolCalculate) 215608d67c1SEnrico Granata m_is_nil = m_valobj->IsNilReference() ? eLazyBoolYes : eLazyBoolNo; 2164d93b8cdSEnrico Granata return m_is_nil == eLazyBoolYes; 2174d93b8cdSEnrico Granata } 2184d93b8cdSEnrico Granata 2194d93b8cdSEnrico Granata bool 220608d67c1SEnrico Granata ValueObjectPrinter::IsUninitialized () 221608d67c1SEnrico Granata { 222608d67c1SEnrico Granata if (m_is_uninit == eLazyBoolCalculate) 223608d67c1SEnrico Granata m_is_uninit = m_valobj->IsUninitializedReference() ? eLazyBoolYes : eLazyBoolNo; 224608d67c1SEnrico Granata return m_is_uninit == eLazyBoolYes; 225608d67c1SEnrico Granata } 226608d67c1SEnrico Granata 227608d67c1SEnrico Granata bool 2284d93b8cdSEnrico Granata ValueObjectPrinter::IsPtr () 2294d93b8cdSEnrico Granata { 2304d93b8cdSEnrico Granata if (m_is_ptr == eLazyBoolCalculate) 231622be238SEnrico Granata m_is_ptr = m_type_flags.Test (eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo; 2324d93b8cdSEnrico Granata return m_is_ptr == eLazyBoolYes; 2334d93b8cdSEnrico Granata } 2344d93b8cdSEnrico Granata 2354d93b8cdSEnrico Granata bool 2364d93b8cdSEnrico Granata ValueObjectPrinter::IsRef () 2374d93b8cdSEnrico Granata { 2384d93b8cdSEnrico Granata if (m_is_ref == eLazyBoolCalculate) 239622be238SEnrico Granata m_is_ref = m_type_flags.Test (eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo; 2404d93b8cdSEnrico Granata return m_is_ref == eLazyBoolYes; 2414d93b8cdSEnrico Granata } 2424d93b8cdSEnrico Granata 2434d93b8cdSEnrico Granata bool 2444d93b8cdSEnrico Granata ValueObjectPrinter::IsAggregate () 2454d93b8cdSEnrico Granata { 2464d93b8cdSEnrico Granata if (m_is_aggregate == eLazyBoolCalculate) 247622be238SEnrico Granata m_is_aggregate = m_type_flags.Test (eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo; 2484d93b8cdSEnrico Granata return m_is_aggregate == eLazyBoolYes; 2494d93b8cdSEnrico Granata } 2504d93b8cdSEnrico Granata 2514d93b8cdSEnrico Granata bool 2528cf44d96SEnrico Granata ValueObjectPrinter::IsInstancePointer () 2538cf44d96SEnrico Granata { 2548cf44d96SEnrico Granata // you need to do this check on the value's clang type 2558cf44d96SEnrico Granata if (m_is_instance_ptr == eLazyBoolCalculate) 2568cf44d96SEnrico Granata m_is_instance_ptr = (m_valobj->GetValue().GetCompilerType().GetTypeInfo() & eTypeInstanceIsPointer) != 0 ? eLazyBoolYes : eLazyBoolNo; 2578cf44d96SEnrico Granata if ((eLazyBoolYes == m_is_instance_ptr) && m_valobj->IsBaseClass()) 2588cf44d96SEnrico Granata m_is_instance_ptr = eLazyBoolNo; 2598cf44d96SEnrico Granata return m_is_instance_ptr == eLazyBoolYes; 2608cf44d96SEnrico Granata } 2618cf44d96SEnrico Granata 2628cf44d96SEnrico Granata bool 2634d93b8cdSEnrico Granata ValueObjectPrinter::PrintLocationIfNeeded () 2644d93b8cdSEnrico Granata { 26526014690SGreg Clayton if (m_options.m_show_location) 2664d93b8cdSEnrico Granata { 2674d93b8cdSEnrico Granata m_stream->Printf("%s: ", m_valobj->GetLocationAsCString()); 2684d93b8cdSEnrico Granata return true; 2694d93b8cdSEnrico Granata } 2704d93b8cdSEnrico Granata return false; 2714d93b8cdSEnrico Granata } 2724d93b8cdSEnrico Granata 273e0ee1e1cSEnrico Granata void 274e0ee1e1cSEnrico Granata ValueObjectPrinter::PrintDecl () 2754d93b8cdSEnrico Granata { 2764d93b8cdSEnrico Granata bool show_type = true; 2774d93b8cdSEnrico Granata // if we are at the root-level and been asked to hide the root's type, then hide it 27826014690SGreg Clayton if (m_curr_depth == 0 && m_options.m_hide_root_type) 2794d93b8cdSEnrico Granata show_type = false; 2804d93b8cdSEnrico Granata else 2814d93b8cdSEnrico Granata // otherwise decide according to the usual rules (asked to show types - always at the root level) 28226014690SGreg Clayton show_type = m_options.m_show_types || (m_curr_depth == 0 && !m_options.m_flat_output); 2834d93b8cdSEnrico Granata 284e0ee1e1cSEnrico Granata StreamString typeName; 285e0ee1e1cSEnrico Granata 286e0ee1e1cSEnrico Granata // always show the type at the root level if it is invalid 2874d93b8cdSEnrico Granata if (show_type) 2884d93b8cdSEnrico Granata { 2894d93b8cdSEnrico Granata // Some ValueObjects don't have types (like registers sets). Only print 2904d93b8cdSEnrico Granata // the type if there is one to print 291a126e462SEnrico Granata ConstString type_name; 292e0ee1e1cSEnrico Granata if (m_compiler_type.IsValid()) 293e0ee1e1cSEnrico Granata { 29426014690SGreg Clayton if (m_options.m_use_type_display_name) 295a126e462SEnrico Granata type_name = m_valobj->GetDisplayTypeName(); 296e8daa2f8SEnrico Granata else 297a126e462SEnrico Granata type_name = m_valobj->GetQualifiedTypeName(); 2984d93b8cdSEnrico Granata } 299e0ee1e1cSEnrico Granata else 300e0ee1e1cSEnrico Granata { 301e0ee1e1cSEnrico Granata // only show an invalid type name if the user explicitly triggered show_type 30226014690SGreg Clayton if (m_options.m_show_types) 303e0ee1e1cSEnrico Granata type_name = ConstString("<invalid type>"); 304e0ee1e1cSEnrico Granata else 305e0ee1e1cSEnrico Granata type_name.Clear(); 3064d93b8cdSEnrico Granata } 3074d93b8cdSEnrico Granata 308e0ee1e1cSEnrico Granata if (type_name) 3094d93b8cdSEnrico Granata { 310e0ee1e1cSEnrico Granata std::string type_name_str(type_name.GetCString()); 31126014690SGreg Clayton if (m_options.m_hide_pointer_value) 312e0ee1e1cSEnrico Granata { 313e0ee1e1cSEnrico Granata for(auto iter = type_name_str.find(" *"); 314e0ee1e1cSEnrico Granata iter != std::string::npos; 315e0ee1e1cSEnrico Granata iter = type_name_str.find(" *")) 316e0ee1e1cSEnrico Granata { 317e0ee1e1cSEnrico Granata type_name_str.erase(iter, 2); 318e0ee1e1cSEnrico Granata } 319e0ee1e1cSEnrico Granata } 320c8e7649aSEnrico Granata typeName.Printf("%s", type_name_str.c_str()); 321e0ee1e1cSEnrico Granata } 322e0ee1e1cSEnrico Granata } 323e0ee1e1cSEnrico Granata 324e0ee1e1cSEnrico Granata StreamString varName; 325e0ee1e1cSEnrico Granata 32626014690SGreg Clayton if (m_options.m_flat_output) 3274d93b8cdSEnrico Granata { 3284d93b8cdSEnrico Granata // If we are showing types, also qualify the C++ base classes 3294d93b8cdSEnrico Granata const bool qualify_cxx_base_classes = show_type; 33026014690SGreg Clayton if (!m_options.m_hide_name) 3314d93b8cdSEnrico Granata { 332e0ee1e1cSEnrico Granata m_valobj->GetExpressionPath(varName, qualify_cxx_base_classes); 3334d93b8cdSEnrico Granata } 3344d93b8cdSEnrico Granata } 33526014690SGreg Clayton else if (!m_options.m_hide_name) 3364d93b8cdSEnrico Granata { 3374d93b8cdSEnrico Granata const char *name_cstr = GetRootNameForDisplay(""); 338e0ee1e1cSEnrico Granata varName.Printf ("%s", name_cstr); 3394d93b8cdSEnrico Granata } 340e0ee1e1cSEnrico Granata 341e0ee1e1cSEnrico Granata bool decl_printed = false; 34226014690SGreg Clayton if (!m_options.m_decl_printing_helper) 343c8e7649aSEnrico Granata { 344c8e7649aSEnrico Granata // if the user didn't give us a custom helper, pick one based upon the language, either the one that this printer is bound to, or the preferred one for the ValueObject 34526014690SGreg Clayton lldb::LanguageType lang_type = (m_options.m_varformat_language == lldb::eLanguageTypeUnknown) ? m_valobj->GetPreferredDisplayLanguage() : m_options.m_varformat_language; 346c8e7649aSEnrico Granata if (Language *lang_plugin = Language::FindPlugin(lang_type)) 347c8e7649aSEnrico Granata { 34826014690SGreg Clayton m_options.m_decl_printing_helper = lang_plugin->GetDeclPrintingHelper(); 349c8e7649aSEnrico Granata } 350c8e7649aSEnrico Granata } 351c8e7649aSEnrico Granata 35226014690SGreg Clayton if (m_options.m_decl_printing_helper) 353e0ee1e1cSEnrico Granata { 354e0ee1e1cSEnrico Granata ConstString type_name_cstr(typeName.GetData()); 355e0ee1e1cSEnrico Granata ConstString var_name_cstr(varName.GetData()); 356e0ee1e1cSEnrico Granata 357e0ee1e1cSEnrico Granata StreamString dest_stream; 35826014690SGreg Clayton if (m_options.m_decl_printing_helper (type_name_cstr, 359e0ee1e1cSEnrico Granata var_name_cstr, 36026014690SGreg Clayton m_options, 361e0ee1e1cSEnrico Granata dest_stream)) 362e0ee1e1cSEnrico Granata { 363e0ee1e1cSEnrico Granata decl_printed = true; 364e0ee1e1cSEnrico Granata m_stream->Printf("%s", dest_stream.GetData()); 365e0ee1e1cSEnrico Granata } 366e0ee1e1cSEnrico Granata } 367e0ee1e1cSEnrico Granata 368c8e7649aSEnrico Granata // if the helper failed, or there is none, do a default thing 369e0ee1e1cSEnrico Granata if (!decl_printed) 370e0ee1e1cSEnrico Granata { 371e0ee1e1cSEnrico Granata if (typeName.GetSize()) 372c8e7649aSEnrico Granata m_stream->Printf("(%s) ", typeName.GetData()); 373e0ee1e1cSEnrico Granata if (varName.GetSize()) 374e0ee1e1cSEnrico Granata m_stream->Printf("%s =", varName.GetData()); 37526014690SGreg Clayton else if (!m_options.m_hide_name) 376e0ee1e1cSEnrico Granata m_stream->Printf(" ="); 377e0ee1e1cSEnrico Granata } 3784d93b8cdSEnrico Granata } 3794d93b8cdSEnrico Granata 3804d93b8cdSEnrico Granata bool 3814d93b8cdSEnrico Granata ValueObjectPrinter::CheckScopeIfNeeded () 3824d93b8cdSEnrico Granata { 38326014690SGreg Clayton if (m_options.m_scope_already_checked) 3844d93b8cdSEnrico Granata return true; 3854d93b8cdSEnrico Granata return m_valobj->IsInScope(); 3864d93b8cdSEnrico Granata } 3874d93b8cdSEnrico Granata 3884d93b8cdSEnrico Granata TypeSummaryImpl* 3898cf44d96SEnrico Granata ValueObjectPrinter::GetSummaryFormatter (bool null_if_omitted) 3904d93b8cdSEnrico Granata { 3914d93b8cdSEnrico Granata if (m_summary_formatter.second == false) 3924d93b8cdSEnrico Granata { 39326014690SGreg Clayton TypeSummaryImpl* entry = m_options.m_summary_sp ? m_options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get(); 3944d93b8cdSEnrico Granata 39526014690SGreg Clayton if (m_options.m_omit_summary_depth > 0) 3964d93b8cdSEnrico Granata entry = NULL; 3974d93b8cdSEnrico Granata m_summary_formatter.first = entry; 3984d93b8cdSEnrico Granata m_summary_formatter.second = true; 3994d93b8cdSEnrico Granata } 4008cf44d96SEnrico Granata if (m_options.m_omit_summary_depth > 0 && null_if_omitted) 4018cf44d96SEnrico Granata return nullptr; 4024d93b8cdSEnrico Granata return m_summary_formatter.first; 4034d93b8cdSEnrico Granata } 4044d93b8cdSEnrico Granata 405e0ee1e1cSEnrico Granata static bool 406e0ee1e1cSEnrico Granata IsPointerValue (const CompilerType &type) 407e0ee1e1cSEnrico Granata { 408e0ee1e1cSEnrico Granata Flags type_flags(type.GetTypeInfo()); 4098cf44d96SEnrico Granata if (type_flags.AnySet(eTypeInstanceIsPointer | eTypeIsPointer)) 410e0ee1e1cSEnrico Granata return type_flags.AllClear(eTypeIsBuiltIn); 411e0ee1e1cSEnrico Granata return false; 412e0ee1e1cSEnrico Granata } 413e0ee1e1cSEnrico Granata 4144d93b8cdSEnrico Granata void 4154d93b8cdSEnrico Granata ValueObjectPrinter::GetValueSummaryError (std::string& value, 4164d93b8cdSEnrico Granata std::string& summary, 4174d93b8cdSEnrico Granata std::string& error) 4184d93b8cdSEnrico Granata { 419*520a422bSEnrico Granata lldb::Format format = m_options.m_format; 420*520a422bSEnrico Granata // if I am printing synthetized elements, apply the format to those elements only 421*520a422bSEnrico Granata if (m_options.m_element_count > 0) 422*520a422bSEnrico Granata m_valobj->GetValueAsCString(lldb::eFormatDefault, value); 423*520a422bSEnrico Granata else if (format != eFormatDefault && format != m_valobj->GetFormat()) 424*520a422bSEnrico Granata m_valobj->GetValueAsCString(format, value); 425465f4bc2SEnrico Granata else 426465f4bc2SEnrico Granata { 4274d93b8cdSEnrico Granata const char* val_cstr = m_valobj->GetValueAsCString(); 428465f4bc2SEnrico Granata if (val_cstr) 429465f4bc2SEnrico Granata value.assign(val_cstr); 430465f4bc2SEnrico Granata } 4314d93b8cdSEnrico Granata const char* err_cstr = m_valobj->GetError().AsCString(); 4324d93b8cdSEnrico Granata if (err_cstr) 4334d93b8cdSEnrico Granata error.assign(err_cstr); 4344d93b8cdSEnrico Granata 4354d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 4364d93b8cdSEnrico Granata { 4374d93b8cdSEnrico Granata if (IsNil()) 4384d93b8cdSEnrico Granata summary.assign("nil"); 439608d67c1SEnrico Granata else if (IsUninitialized()) 440608d67c1SEnrico Granata summary.assign("<uninitialized>"); 44126014690SGreg Clayton else if (m_options.m_omit_summary_depth == 0) 4424d93b8cdSEnrico Granata { 4434d93b8cdSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 4444d93b8cdSEnrico Granata if (entry) 44526014690SGreg Clayton m_valobj->GetSummaryAsCString(entry, summary, m_options.m_varformat_language); 4464d93b8cdSEnrico Granata else 4474d93b8cdSEnrico Granata { 44826014690SGreg Clayton const char* sum_cstr = m_valobj->GetSummaryAsCString(m_options.m_varformat_language); 4494d93b8cdSEnrico Granata if (sum_cstr) 4504d93b8cdSEnrico Granata summary.assign(sum_cstr); 4514d93b8cdSEnrico Granata } 4524d93b8cdSEnrico Granata } 4534d93b8cdSEnrico Granata } 4544d93b8cdSEnrico Granata } 4554d93b8cdSEnrico Granata 4564d93b8cdSEnrico Granata bool 4574d93b8cdSEnrico Granata ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed, 4584d93b8cdSEnrico Granata bool& summary_printed) 4594d93b8cdSEnrico Granata { 4604d93b8cdSEnrico Granata bool error_printed = false; 4614d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 4624d93b8cdSEnrico Granata { 4634d93b8cdSEnrico Granata if (!CheckScopeIfNeeded()) 4644d93b8cdSEnrico Granata m_error.assign("out of scope"); 4654d93b8cdSEnrico Granata if (m_error.empty()) 4664d93b8cdSEnrico Granata { 4674d93b8cdSEnrico Granata GetValueSummaryError(m_value, m_summary, m_error); 4684d93b8cdSEnrico Granata } 4694d93b8cdSEnrico Granata if (m_error.size()) 4704d93b8cdSEnrico Granata { 4718cf44d96SEnrico Granata // we need to support scenarios in which it is actually fine for a value to have no type 4728cf44d96SEnrico Granata // but - on the other hand - if we get an error *AND* have no type, we try to get out 4738cf44d96SEnrico Granata // gracefully, since most often that combination means "could not resolve a type" 4748cf44d96SEnrico Granata // and the default failure mode is quite ugly 4758cf44d96SEnrico Granata if (!m_compiler_type.IsValid()) 4768cf44d96SEnrico Granata { 4778cf44d96SEnrico Granata m_stream->Printf(" <could not resolve type>"); 4788cf44d96SEnrico Granata return false; 4798cf44d96SEnrico Granata } 4808cf44d96SEnrico Granata 4814d93b8cdSEnrico Granata error_printed = true; 4824d93b8cdSEnrico Granata m_stream->Printf (" <%s>\n", m_error.c_str()); 4834d93b8cdSEnrico Granata } 4844d93b8cdSEnrico Granata else 4854d93b8cdSEnrico Granata { 4864d93b8cdSEnrico Granata // Make sure we have a value and make sure the summary didn't 4874d93b8cdSEnrico Granata // specify that the value should not be printed - and do not print 4884d93b8cdSEnrico Granata // the value if this thing is nil 4894d93b8cdSEnrico Granata // (but show the value if the user passes a format explicitly) 4904d93b8cdSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 491608d67c1SEnrico Granata if (!IsNil() && !IsUninitialized() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue(m_valobj) || m_options.m_format != eFormatDefault) || m_summary.empty()) && !m_options.m_hide_value) 4924d93b8cdSEnrico Granata { 49326014690SGreg Clayton if (m_options.m_hide_pointer_value && IsPointerValue(m_valobj->GetCompilerType())) {} 494e0ee1e1cSEnrico Granata else 495e0ee1e1cSEnrico Granata { 4964d93b8cdSEnrico Granata m_stream->Printf(" %s", m_value.c_str()); 4974d93b8cdSEnrico Granata value_printed = true; 4984d93b8cdSEnrico Granata } 499e0ee1e1cSEnrico Granata } 5004d93b8cdSEnrico Granata 5014d93b8cdSEnrico Granata if (m_summary.size()) 5024d93b8cdSEnrico Granata { 5034d93b8cdSEnrico Granata m_stream->Printf(" %s", m_summary.c_str()); 5044d93b8cdSEnrico Granata summary_printed = true; 5054d93b8cdSEnrico Granata } 5064d93b8cdSEnrico Granata } 5074d93b8cdSEnrico Granata } 5084d93b8cdSEnrico Granata return !error_printed; 5094d93b8cdSEnrico Granata } 5104d93b8cdSEnrico Granata 5114d93b8cdSEnrico Granata bool 5124d93b8cdSEnrico Granata ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed, 5134d93b8cdSEnrico Granata bool summary_printed) 5144d93b8cdSEnrico Granata { 5154d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 5164d93b8cdSEnrico Granata { 5174d93b8cdSEnrico Granata // let's avoid the overly verbose no description error for a nil thing 518*520a422bSEnrico Granata if (m_options.m_use_objc && !IsNil() && !IsUninitialized() && (m_options.m_element_count == 0)) 5194d93b8cdSEnrico Granata { 52026014690SGreg Clayton if (!m_options.m_hide_value || !m_options.m_hide_name) 5214d93b8cdSEnrico Granata m_stream->Printf(" "); 5224d93b8cdSEnrico Granata const char *object_desc = nullptr; 5234d93b8cdSEnrico Granata if (value_printed || summary_printed) 5244d93b8cdSEnrico Granata object_desc = m_valobj->GetObjectDescription(); 5254d93b8cdSEnrico Granata else 5264d93b8cdSEnrico Granata object_desc = GetDescriptionForDisplay(); 5274d93b8cdSEnrico Granata if (object_desc && *object_desc) 5284d93b8cdSEnrico Granata { 5294d93b8cdSEnrico Granata m_stream->Printf("%s\n", object_desc); 5304d93b8cdSEnrico Granata return true; 5314d93b8cdSEnrico Granata } 5324d93b8cdSEnrico Granata else if (value_printed == false && summary_printed == false) 5334d93b8cdSEnrico Granata return true; 5344d93b8cdSEnrico Granata else 5354d93b8cdSEnrico Granata return false; 5364d93b8cdSEnrico Granata } 5374d93b8cdSEnrico Granata } 5384d93b8cdSEnrico Granata return true; 5394d93b8cdSEnrico Granata } 5404d93b8cdSEnrico Granata 5414d93b8cdSEnrico Granata bool 542c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth::CanAllowExpansion (bool is_root, 543c1b7c09aSEnrico Granata TypeSummaryImpl* entry, 544c1b7c09aSEnrico Granata ValueObject *valobj, 545c1b7c09aSEnrico Granata const std::string& summary) 546c1b7c09aSEnrico Granata { 547c1b7c09aSEnrico Granata switch (m_mode) 548c1b7c09aSEnrico Granata { 549c1b7c09aSEnrico Granata case Mode::Always: 550c1b7c09aSEnrico Granata return (m_count > 0); 551c1b7c09aSEnrico Granata case Mode::Never: 552c1b7c09aSEnrico Granata return false; 553c1b7c09aSEnrico Granata case Mode::Default: 554c1b7c09aSEnrico Granata if (is_root) 555c1b7c09aSEnrico Granata m_count = std::min<decltype(m_count)>(m_count,1); 556c1b7c09aSEnrico Granata return m_count > 0; 557c1b7c09aSEnrico Granata case Mode::Formatters: 558c1b7c09aSEnrico Granata if (!entry || entry->DoesPrintChildren(valobj) || summary.empty()) 559c1b7c09aSEnrico Granata return m_count > 0; 560c1b7c09aSEnrico Granata return false; 561c1b7c09aSEnrico Granata } 56284f5b0dfSZachary Turner return false; 563c1b7c09aSEnrico Granata } 564c1b7c09aSEnrico Granata 565c1b7c09aSEnrico Granata bool 566c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth::CanAllowExpansion () const 567c1b7c09aSEnrico Granata { 568c1b7c09aSEnrico Granata switch (m_mode) 569c1b7c09aSEnrico Granata { 570c1b7c09aSEnrico Granata case Mode::Always: 571c1b7c09aSEnrico Granata case Mode::Default: 572c1b7c09aSEnrico Granata case Mode::Formatters: 573c1b7c09aSEnrico Granata return (m_count > 0); 574c1b7c09aSEnrico Granata case Mode::Never: 575c1b7c09aSEnrico Granata return false; 576c1b7c09aSEnrico Granata } 57784f5b0dfSZachary Turner return false; 578c1b7c09aSEnrico Granata } 579c1b7c09aSEnrico Granata 580c1b7c09aSEnrico Granata bool 5814d93b8cdSEnrico Granata ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description, 582c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 5834d93b8cdSEnrico Granata { 5844d93b8cdSEnrico Granata const bool is_ref = IsRef (); 5854d93b8cdSEnrico Granata const bool is_ptr = IsPtr (); 586608d67c1SEnrico Granata const bool is_uninit = IsUninitialized(); 587608d67c1SEnrico Granata 588608d67c1SEnrico Granata if (is_uninit) 589608d67c1SEnrico Granata return false; 5904d93b8cdSEnrico Granata 591*520a422bSEnrico Granata // if the user has specified an element count, always print children 592*520a422bSEnrico Granata // as it is explicit user demand being honored 593*520a422bSEnrico Granata if (m_options.m_element_count > 0) 594*520a422bSEnrico Granata return true; 595*520a422bSEnrico Granata 596c1b7c09aSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 597c1b7c09aSEnrico Granata 5988cf44d96SEnrico Granata if (m_options.m_use_objc) 5998cf44d96SEnrico Granata return false; 6008cf44d96SEnrico Granata 60126014690SGreg Clayton if (is_failed_description || m_curr_depth < m_options.m_max_depth) 6024d93b8cdSEnrico Granata { 6034d93b8cdSEnrico Granata // We will show children for all concrete types. We won't show 6044d93b8cdSEnrico Granata // pointer contents unless a pointer depth has been specified. 6054d93b8cdSEnrico Granata // We won't reference contents unless the reference is the 6064d93b8cdSEnrico Granata // root object (depth of zero). 6074d93b8cdSEnrico Granata 6084d93b8cdSEnrico Granata // Use a new temporary pointer depth in case we override the 6094d93b8cdSEnrico Granata // current pointer depth below... 6104d93b8cdSEnrico Granata 6114d93b8cdSEnrico Granata if (is_ptr || is_ref) 6124d93b8cdSEnrico Granata { 6134d93b8cdSEnrico Granata // We have a pointer or reference whose value is an address. 6144d93b8cdSEnrico Granata // Make sure that address is not NULL 6154d93b8cdSEnrico Granata AddressType ptr_address_type; 6164d93b8cdSEnrico Granata if (m_valobj->GetPointerValue (&ptr_address_type) == 0) 6174d93b8cdSEnrico Granata return false; 6184d93b8cdSEnrico Granata 619c1b7c09aSEnrico Granata const bool is_root_level = m_curr_depth == 0; 620c1b7c09aSEnrico Granata 621c1b7c09aSEnrico Granata if (is_ref && 622c1b7c09aSEnrico Granata is_root_level) 6234d93b8cdSEnrico Granata { 6244d93b8cdSEnrico Granata // If this is the root object (depth is zero) that we are showing 6254d93b8cdSEnrico Granata // and it is a reference, and no pointer depth has been supplied 6264d93b8cdSEnrico Granata // print out what it references. Don't do this at deeper depths 6274d93b8cdSEnrico Granata // otherwise we can end up with infinite recursion... 628c1b7c09aSEnrico Granata return true; 6294d93b8cdSEnrico Granata } 6304d93b8cdSEnrico Granata 631c1b7c09aSEnrico Granata return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, m_summary); 6324d93b8cdSEnrico Granata } 6334d93b8cdSEnrico Granata 6348a068e6cSEnrico Granata return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty()); 6354d93b8cdSEnrico Granata } 6364d93b8cdSEnrico Granata return false; 6374d93b8cdSEnrico Granata } 6384d93b8cdSEnrico Granata 639d26eb907SSiva Chandra bool 640d26eb907SSiva Chandra ValueObjectPrinter::ShouldExpandEmptyAggregates () 641d26eb907SSiva Chandra { 642d26eb907SSiva Chandra TypeSummaryImpl* entry = GetSummaryFormatter(); 643d26eb907SSiva Chandra 644d26eb907SSiva Chandra if (!entry) 645d26eb907SSiva Chandra return true; 646d26eb907SSiva Chandra 647d26eb907SSiva Chandra return entry->DoesPrintEmptyAggregates(); 648d26eb907SSiva Chandra } 649d26eb907SSiva Chandra 6504d93b8cdSEnrico Granata ValueObject* 6514d93b8cdSEnrico Granata ValueObjectPrinter::GetValueObjectForChildrenGeneration () 6524d93b8cdSEnrico Granata { 653d07cfd3aSEnrico Granata return m_valobj; 6544d93b8cdSEnrico Granata } 6554d93b8cdSEnrico Granata 6564d93b8cdSEnrico Granata void 6574d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPreamble () 6584d93b8cdSEnrico Granata { 65926014690SGreg Clayton if (m_options.m_flat_output) 6604d93b8cdSEnrico Granata { 6614d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 6624d93b8cdSEnrico Granata m_stream->EOL(); 6634d93b8cdSEnrico Granata } 6644d93b8cdSEnrico Granata else 6654d93b8cdSEnrico Granata { 6664d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 6674d93b8cdSEnrico Granata m_stream->PutCString(IsRef () ? ": {\n" : " {\n"); 6684d93b8cdSEnrico Granata m_stream->IndentMore(); 6694d93b8cdSEnrico Granata } 6704d93b8cdSEnrico Granata } 6714d93b8cdSEnrico Granata 6724d93b8cdSEnrico Granata void 6734d93b8cdSEnrico Granata ValueObjectPrinter::PrintChild (ValueObjectSP child_sp, 674c1b7c09aSEnrico Granata const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 6754d93b8cdSEnrico Granata { 676*520a422bSEnrico Granata const uint32_t consumed_depth = (m_options.m_element_count == 0) ? 1 : 0; 677*520a422bSEnrico Granata const bool does_consume_ptr_depth = ((IsPtr() && m_options.m_element_count == 0) || IsRef()); 678*520a422bSEnrico Granata 67926014690SGreg Clayton DumpValueObjectOptions child_options(m_options); 68026014690SGreg Clayton child_options.SetFormat(m_options.m_format).SetSummary().SetRootValueObjectName(); 68126014690SGreg Clayton child_options.SetScopeChecked(true).SetHideName(m_options.m_hide_name).SetHideValue(m_options.m_hide_value) 682*520a422bSEnrico Granata .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - consumed_depth : 0) 683*520a422bSEnrico Granata .SetElementCount(0); 6848cf44d96SEnrico Granata 6854d93b8cdSEnrico Granata if (child_sp.get()) 6864d93b8cdSEnrico Granata { 6874d93b8cdSEnrico Granata ValueObjectPrinter child_printer(child_sp.get(), 6884d93b8cdSEnrico Granata m_stream, 6894d93b8cdSEnrico Granata child_options, 690*520a422bSEnrico Granata does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth, 691*520a422bSEnrico Granata m_curr_depth + consumed_depth, 6928cf44d96SEnrico Granata m_printed_instance_pointers); 6934d93b8cdSEnrico Granata child_printer.PrintValueObject(); 6944d93b8cdSEnrico Granata } 6954d93b8cdSEnrico Granata } 6964d93b8cdSEnrico Granata 6974d93b8cdSEnrico Granata uint32_t 6984d93b8cdSEnrico Granata ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot) 6994d93b8cdSEnrico Granata { 7004d93b8cdSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 7014d93b8cdSEnrico Granata 702*520a422bSEnrico Granata if (m_options.m_element_count > 0) 703*520a422bSEnrico Granata return m_options.m_element_count; 704*520a422bSEnrico Granata 7054d93b8cdSEnrico Granata size_t num_children = synth_m_valobj->GetNumChildren(); 7064d93b8cdSEnrico Granata print_dotdotdot = false; 7074d93b8cdSEnrico Granata if (num_children) 7084d93b8cdSEnrico Granata { 7094d93b8cdSEnrico Granata const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 7104d93b8cdSEnrico Granata 71126014690SGreg Clayton if (num_children > max_num_children && !m_options.m_ignore_cap) 7124d93b8cdSEnrico Granata { 7134d93b8cdSEnrico Granata print_dotdotdot = true; 7144d93b8cdSEnrico Granata return max_num_children; 7154d93b8cdSEnrico Granata } 7164d93b8cdSEnrico Granata } 7174d93b8cdSEnrico Granata return num_children; 7184d93b8cdSEnrico Granata } 7194d93b8cdSEnrico Granata 7204d93b8cdSEnrico Granata void 7214d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot) 7224d93b8cdSEnrico Granata { 72326014690SGreg Clayton if (!m_options.m_flat_output) 7244d93b8cdSEnrico Granata { 7254d93b8cdSEnrico Granata if (print_dotdotdot) 7264d93b8cdSEnrico Granata { 7274d93b8cdSEnrico Granata m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated(); 7284d93b8cdSEnrico Granata m_stream->Indent("...\n"); 7294d93b8cdSEnrico Granata } 7304d93b8cdSEnrico Granata m_stream->IndentLess(); 7314d93b8cdSEnrico Granata m_stream->Indent("}\n"); 7324d93b8cdSEnrico Granata } 7334d93b8cdSEnrico Granata } 7344d93b8cdSEnrico Granata 7358cf44d96SEnrico Granata bool 7368cf44d96SEnrico Granata ValueObjectPrinter::ShouldPrintEmptyBrackets (bool value_printed, 7378cf44d96SEnrico Granata bool summary_printed) 7388cf44d96SEnrico Granata { 7398cf44d96SEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 7408cf44d96SEnrico Granata 7418cf44d96SEnrico Granata if (!IsAggregate()) 7428cf44d96SEnrico Granata return false; 7438cf44d96SEnrico Granata 7448cf44d96SEnrico Granata if (m_options.m_reveal_empty_aggregates == false) 7458cf44d96SEnrico Granata { 7468cf44d96SEnrico Granata if (value_printed || summary_printed) 7478cf44d96SEnrico Granata return false; 7488cf44d96SEnrico Granata } 7498cf44d96SEnrico Granata 7508cf44d96SEnrico Granata if (synth_m_valobj->MightHaveChildren()) 7518cf44d96SEnrico Granata return true; 7528cf44d96SEnrico Granata 7538cf44d96SEnrico Granata if (m_val_summary_ok) 7548cf44d96SEnrico Granata return false; 7558cf44d96SEnrico Granata 7568cf44d96SEnrico Granata return true; 7578cf44d96SEnrico Granata } 7588cf44d96SEnrico Granata 759*520a422bSEnrico Granata ValueObjectSP 760*520a422bSEnrico Granata ValueObjectPrinter::GenerateChild (ValueObject* synth_valobj, size_t idx) 761*520a422bSEnrico Granata { 762*520a422bSEnrico Granata if (m_options.m_element_count > 0) 763*520a422bSEnrico Granata { 764*520a422bSEnrico Granata // if generating pointer-as-array children, use GetSyntheticArrayMember 765*520a422bSEnrico Granata return synth_valobj->GetSyntheticArrayMember(idx, true); 766*520a422bSEnrico Granata } 767*520a422bSEnrico Granata else 768*520a422bSEnrico Granata { 769*520a422bSEnrico Granata // otherwise, do the usual thing 770*520a422bSEnrico Granata return synth_valobj->GetChildAtIndex(idx, true); 771*520a422bSEnrico Granata } 772*520a422bSEnrico Granata } 773*520a422bSEnrico Granata 7744d93b8cdSEnrico Granata void 775c1b7c09aSEnrico Granata ValueObjectPrinter::PrintChildren (bool value_printed, 776c1b7c09aSEnrico Granata bool summary_printed, 777c1b7c09aSEnrico Granata const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 7784d93b8cdSEnrico Granata { 7794d93b8cdSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 7804d93b8cdSEnrico Granata 7814d93b8cdSEnrico Granata bool print_dotdotdot = false; 7824d93b8cdSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 7834d93b8cdSEnrico Granata if (num_children) 7844d93b8cdSEnrico Granata { 7858cf44d96SEnrico Granata bool any_children_printed = false; 7864d93b8cdSEnrico Granata 7874d93b8cdSEnrico Granata for (size_t idx=0; idx<num_children; ++idx) 7884d93b8cdSEnrico Granata { 789*520a422bSEnrico Granata if (ValueObjectSP child_sp = GenerateChild(synth_m_valobj, idx)) 7908cf44d96SEnrico Granata { 7918cf44d96SEnrico Granata if (!any_children_printed) 7928cf44d96SEnrico Granata { 7938cf44d96SEnrico Granata PrintChildrenPreamble (); 7948cf44d96SEnrico Granata any_children_printed = true; 7958cf44d96SEnrico Granata } 7964d93b8cdSEnrico Granata PrintChild (child_sp, curr_ptr_depth); 7974d93b8cdSEnrico Granata } 7984d93b8cdSEnrico Granata } 7998cf44d96SEnrico Granata 8008cf44d96SEnrico Granata if (any_children_printed) 8018cf44d96SEnrico Granata PrintChildrenPostamble (print_dotdotdot); 8028cf44d96SEnrico Granata else 8038cf44d96SEnrico Granata { 8048cf44d96SEnrico Granata if (ShouldPrintEmptyBrackets(value_printed, summary_printed)) 8058cf44d96SEnrico Granata { 8068cf44d96SEnrico Granata if (ShouldPrintValueObject()) 8078cf44d96SEnrico Granata m_stream->PutCString(" {}\n"); 8088cf44d96SEnrico Granata else 8098cf44d96SEnrico Granata m_stream->EOL(); 8108cf44d96SEnrico Granata } 8118cf44d96SEnrico Granata else 8128cf44d96SEnrico Granata m_stream->EOL(); 8138cf44d96SEnrico Granata } 8148cf44d96SEnrico Granata } 8158cf44d96SEnrico Granata else if (ShouldPrintEmptyBrackets(value_printed, summary_printed)) 8164d93b8cdSEnrico Granata { 8174d93b8cdSEnrico Granata // Aggregate, no children... 8184d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 819d07cfd3aSEnrico Granata { 820d07cfd3aSEnrico Granata // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value 821d26eb907SSiva Chandra if (m_valobj->DoesProvideSyntheticValue() || !ShouldExpandEmptyAggregates()) 822d07cfd3aSEnrico Granata m_stream->PutCString( "\n"); 823d07cfd3aSEnrico Granata else 8244d93b8cdSEnrico Granata m_stream->PutCString(" {}\n"); 8254d93b8cdSEnrico Granata } 826d07cfd3aSEnrico Granata } 8274d93b8cdSEnrico Granata else 8284d93b8cdSEnrico Granata { 8294d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 8304d93b8cdSEnrico Granata m_stream->EOL(); 8314d93b8cdSEnrico Granata } 8324d93b8cdSEnrico Granata } 8334d93b8cdSEnrico Granata 834a29cb0baSEnrico Granata bool 835a29cb0baSEnrico Granata ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names) 836a29cb0baSEnrico Granata { 837d07cfd3aSEnrico Granata if (!GetMostSpecializedValue () || m_valobj == nullptr) 838a29cb0baSEnrico Granata return false; 839a29cb0baSEnrico Granata 840a29cb0baSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 841a29cb0baSEnrico Granata 842a29cb0baSEnrico Granata bool print_dotdotdot = false; 843a29cb0baSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 844a29cb0baSEnrico Granata 845a29cb0baSEnrico Granata if (num_children) 846a29cb0baSEnrico Granata { 847a29cb0baSEnrico Granata m_stream->PutChar('('); 848a29cb0baSEnrico Granata 849a29cb0baSEnrico Granata for (uint32_t idx=0; idx<num_children; ++idx) 850a29cb0baSEnrico Granata { 851a29cb0baSEnrico Granata lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 852ddac7611SEnrico Granata if (child_sp) 85326014690SGreg Clayton child_sp = child_sp->GetQualifiedRepresentationIfAvailable(m_options.m_use_dynamic, m_options.m_use_synthetic); 854a29cb0baSEnrico Granata if (child_sp) 855a29cb0baSEnrico Granata { 856a29cb0baSEnrico Granata if (idx) 857a29cb0baSEnrico Granata m_stream->PutCString(", "); 858a29cb0baSEnrico Granata if (!hide_names) 859a29cb0baSEnrico Granata { 860a29cb0baSEnrico Granata const char* name = child_sp.get()->GetName().AsCString(); 861a29cb0baSEnrico Granata if (name && *name) 862a29cb0baSEnrico Granata { 863a29cb0baSEnrico Granata m_stream->PutCString(name); 864a29cb0baSEnrico Granata m_stream->PutCString(" = "); 865a29cb0baSEnrico Granata } 866a29cb0baSEnrico Granata } 867a29cb0baSEnrico Granata child_sp->DumpPrintableRepresentation(*m_stream, 868a29cb0baSEnrico Granata ValueObject::eValueObjectRepresentationStyleSummary, 8697aafb6a1SEnrico Granata m_options.m_format, 870a29cb0baSEnrico Granata ValueObject::ePrintableRepresentationSpecialCasesDisable); 871a29cb0baSEnrico Granata } 872a29cb0baSEnrico Granata } 873a29cb0baSEnrico Granata 874a29cb0baSEnrico Granata if (print_dotdotdot) 875a29cb0baSEnrico Granata m_stream->PutCString(", ...)"); 876a29cb0baSEnrico Granata else 877a29cb0baSEnrico Granata m_stream->PutChar(')'); 878a29cb0baSEnrico Granata } 879a29cb0baSEnrico Granata return true; 880a29cb0baSEnrico Granata } 881a29cb0baSEnrico Granata 8824d93b8cdSEnrico Granata void 8834d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed, 8844d93b8cdSEnrico Granata bool summary_printed) 8854d93b8cdSEnrico Granata { 8864d93b8cdSEnrico Granata // this flag controls whether we tried to display a description for this object and failed 8874d93b8cdSEnrico Granata // if that happens, we want to display the children, if any 8884d93b8cdSEnrico Granata bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed); 8894d93b8cdSEnrico Granata 890c1b7c09aSEnrico Granata auto curr_ptr_depth = m_ptr_depth; 8914d93b8cdSEnrico Granata bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth); 892c1b7c09aSEnrico Granata bool print_oneline = (curr_ptr_depth.CanAllowExpansion() || 89326014690SGreg Clayton m_options.m_show_types || 89426014690SGreg Clayton !m_options.m_allow_oneliner_mode || 89526014690SGreg Clayton m_options.m_flat_output || 896*520a422bSEnrico Granata (m_options.m_element_count > 0) || 89726014690SGreg Clayton m_options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj); 8988cf44d96SEnrico Granata bool is_instance_ptr = IsInstancePointer(); 8998cf44d96SEnrico Granata uint64_t instance_ptr_value = LLDB_INVALID_ADDRESS; 9008cf44d96SEnrico Granata 9018cf44d96SEnrico Granata if (print_children && is_instance_ptr) 9028cf44d96SEnrico Granata { 9038cf44d96SEnrico Granata instance_ptr_value = m_valobj->GetValueAsUnsigned(0); 9048cf44d96SEnrico Granata if (m_printed_instance_pointers->count(instance_ptr_value)) 9058cf44d96SEnrico Granata { 9068cf44d96SEnrico Granata // we already printed this instance-is-pointer thing, so don't expand it 9078cf44d96SEnrico Granata m_stream->PutCString(" {...}\n"); 9088cf44d96SEnrico Granata 9098cf44d96SEnrico Granata // we're done here - get out fast 9108cf44d96SEnrico Granata return; 9118cf44d96SEnrico Granata } 9128cf44d96SEnrico Granata else 9138cf44d96SEnrico Granata m_printed_instance_pointers->emplace(instance_ptr_value); // remember this guy for future reference 9148cf44d96SEnrico Granata } 9154d93b8cdSEnrico Granata 9164d93b8cdSEnrico Granata if (print_children) 9174d93b8cdSEnrico Granata { 918a29cb0baSEnrico Granata if (print_oneline) 919a29cb0baSEnrico Granata { 920a29cb0baSEnrico Granata m_stream->PutChar(' '); 921a29cb0baSEnrico Granata PrintChildrenOneLiner (false); 922a29cb0baSEnrico Granata m_stream->EOL(); 923a29cb0baSEnrico Granata } 924a29cb0baSEnrico Granata else 925c1b7c09aSEnrico Granata PrintChildren (value_printed, summary_printed, curr_ptr_depth); 9264d93b8cdSEnrico Granata } 92726014690SGreg Clayton else if (m_curr_depth >= m_options.m_max_depth && IsAggregate() && ShouldPrintValueObject()) 9284d93b8cdSEnrico Granata { 9294d93b8cdSEnrico Granata m_stream->PutCString("{...}\n"); 9304d93b8cdSEnrico Granata } 931245b3caaSEnrico Granata else 932245b3caaSEnrico Granata m_stream->EOL(); 9334d93b8cdSEnrico Granata } 9340f883ffbSEnrico Granata 9350f883ffbSEnrico Granata bool 9360f883ffbSEnrico Granata ValueObjectPrinter::ShouldPrintValidation () 9370f883ffbSEnrico Granata { 93826014690SGreg Clayton return m_options.m_run_validator; 9390f883ffbSEnrico Granata } 9400f883ffbSEnrico Granata 9410f883ffbSEnrico Granata bool 9420f883ffbSEnrico Granata ValueObjectPrinter::PrintValidationMarkerIfNeeded () 9430f883ffbSEnrico Granata { 9440f883ffbSEnrico Granata if (!ShouldPrintValidation()) 9450f883ffbSEnrico Granata return false; 9460f883ffbSEnrico Granata 9470f883ffbSEnrico Granata m_validation = m_valobj->GetValidationStatus(); 9480f883ffbSEnrico Granata 9490f883ffbSEnrico Granata if (TypeValidatorResult::Failure == m_validation.first) 9500f883ffbSEnrico Granata { 9510f883ffbSEnrico Granata m_stream->Printf("! "); 9520f883ffbSEnrico Granata return true; 9530f883ffbSEnrico Granata } 9540f883ffbSEnrico Granata 9550f883ffbSEnrico Granata return false; 9560f883ffbSEnrico Granata } 9570f883ffbSEnrico Granata 9580f883ffbSEnrico Granata bool 9590f883ffbSEnrico Granata ValueObjectPrinter::PrintValidationErrorIfNeeded () 9600f883ffbSEnrico Granata { 9610f883ffbSEnrico Granata if (!ShouldPrintValidation()) 9620f883ffbSEnrico Granata return false; 9630f883ffbSEnrico Granata 9640f883ffbSEnrico Granata if (TypeValidatorResult::Success == m_validation.first) 9650f883ffbSEnrico Granata return false; 9660f883ffbSEnrico Granata 9670f883ffbSEnrico Granata if (m_validation.second.empty()) 9680f883ffbSEnrico Granata m_validation.second.assign("unknown error"); 9690f883ffbSEnrico Granata 9700f883ffbSEnrico Granata m_stream->Printf(" ! validation error: %s", m_validation.second.c_str()); 9710f883ffbSEnrico Granata m_stream->EOL(); 9720f883ffbSEnrico Granata 9730f883ffbSEnrico Granata return true; 9740f883ffbSEnrico Granata } 975