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); 32*26014690SGreg Clayton Init (valobj,s,options,m_options.m_max_ptr_depth,0); 33d5957336SEnrico Granata } 34d5957336SEnrico Granata else 35d5957336SEnrico Granata { 36d5957336SEnrico Granata DumpValueObjectOptions options; 37*26014690SGreg Clayton Init (valobj,s,options,m_options.m_max_ptr_depth,0); 38d5957336SEnrico Granata } 39d5957336SEnrico Granata } 40d5957336SEnrico Granata 414d93b8cdSEnrico Granata ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, 424d93b8cdSEnrico Granata Stream* s, 43938d1d67SEnrico Granata const DumpValueObjectOptions& options) 444d93b8cdSEnrico Granata { 45*26014690SGreg Clayton Init(valobj,s,options,m_options.m_max_ptr_depth,0); 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, 52938d1d67SEnrico Granata uint32_t curr_depth) 53938d1d67SEnrico Granata { 54938d1d67SEnrico Granata Init(valobj,s,options,ptr_depth,curr_depth); 55938d1d67SEnrico Granata } 56938d1d67SEnrico Granata 57938d1d67SEnrico Granata void 58938d1d67SEnrico Granata ValueObjectPrinter::Init (ValueObject* valobj, 59938d1d67SEnrico Granata Stream* s, 60938d1d67SEnrico Granata const DumpValueObjectOptions& options, 61c1b7c09aSEnrico Granata const DumpValueObjectOptions::PointerDepth& ptr_depth, 62938d1d67SEnrico Granata uint32_t curr_depth) 63938d1d67SEnrico Granata { 64938d1d67SEnrico Granata m_orig_valobj = valobj; 65938d1d67SEnrico Granata m_valobj = nullptr; 66938d1d67SEnrico Granata m_stream = s; 67*26014690SGreg Clayton m_options = options; 68938d1d67SEnrico Granata m_ptr_depth = ptr_depth; 69938d1d67SEnrico Granata m_curr_depth = curr_depth; 70938d1d67SEnrico Granata assert (m_orig_valobj && "cannot print a NULL ValueObject"); 71938d1d67SEnrico Granata assert (m_stream && "cannot print to a NULL Stream"); 72938d1d67SEnrico Granata m_should_print = eLazyBoolCalculate; 73938d1d67SEnrico Granata m_is_nil = eLazyBoolCalculate; 74938d1d67SEnrico Granata m_is_ptr = eLazyBoolCalculate; 75938d1d67SEnrico Granata m_is_ref = eLazyBoolCalculate; 76938d1d67SEnrico Granata m_is_aggregate = eLazyBoolCalculate; 77938d1d67SEnrico Granata m_summary_formatter = {nullptr,false}; 78938d1d67SEnrico Granata m_value.assign(""); 79938d1d67SEnrico Granata m_summary.assign(""); 80938d1d67SEnrico Granata m_error.assign(""); 81938d1d67SEnrico Granata } 824d93b8cdSEnrico Granata 834d93b8cdSEnrico Granata bool 844d93b8cdSEnrico Granata ValueObjectPrinter::PrintValueObject () 854d93b8cdSEnrico Granata { 86d07cfd3aSEnrico Granata if (!GetMostSpecializedValue () || m_valobj == nullptr) 874d93b8cdSEnrico Granata return false; 884d93b8cdSEnrico Granata 894d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 904d93b8cdSEnrico Granata { 910f883ffbSEnrico Granata PrintValidationMarkerIfNeeded(); 920f883ffbSEnrico Granata 934d93b8cdSEnrico Granata PrintLocationIfNeeded(); 944d93b8cdSEnrico Granata m_stream->Indent(); 954d93b8cdSEnrico Granata 96e0ee1e1cSEnrico Granata PrintDecl(); 974d93b8cdSEnrico Granata } 984d93b8cdSEnrico Granata 994d93b8cdSEnrico Granata bool value_printed = false; 1004d93b8cdSEnrico Granata bool summary_printed = false; 1014d93b8cdSEnrico Granata 1024d93b8cdSEnrico Granata bool val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed); 1034d93b8cdSEnrico Granata 1044d93b8cdSEnrico Granata if (val_summary_ok) 1054d93b8cdSEnrico Granata PrintChildrenIfNeeded (value_printed, summary_printed); 10639938938SEnrico Granata else 1074d93b8cdSEnrico Granata m_stream->EOL(); 1084d93b8cdSEnrico Granata 1090f883ffbSEnrico Granata PrintValidationErrorIfNeeded(); 1100f883ffbSEnrico Granata 1114d93b8cdSEnrico Granata return true; 1124d93b8cdSEnrico Granata } 1134d93b8cdSEnrico Granata 1144d93b8cdSEnrico Granata bool 115d07cfd3aSEnrico Granata ValueObjectPrinter::GetMostSpecializedValue () 1164d93b8cdSEnrico Granata { 117a29cb0baSEnrico Granata if (m_valobj) 118a29cb0baSEnrico Granata return true; 1194d93b8cdSEnrico Granata bool update_success = m_orig_valobj->UpdateValueIfNeeded (true); 1204d93b8cdSEnrico Granata if (!update_success) 121106260c5SEnrico Granata { 122106260c5SEnrico Granata m_valobj = m_orig_valobj; 123106260c5SEnrico Granata } 124106260c5SEnrico Granata else 125106260c5SEnrico Granata { 126106260c5SEnrico Granata if (m_orig_valobj->IsDynamic()) 127106260c5SEnrico Granata { 128*26014690SGreg Clayton if (m_options.m_use_dynamic == eNoDynamicValues) 129106260c5SEnrico Granata { 130106260c5SEnrico Granata ValueObject *static_value = m_orig_valobj->GetStaticValue().get(); 131106260c5SEnrico Granata if (static_value) 132106260c5SEnrico Granata m_valobj = static_value; 133106260c5SEnrico Granata else 134106260c5SEnrico Granata m_valobj = m_orig_valobj; 135106260c5SEnrico Granata } 136106260c5SEnrico Granata else 137106260c5SEnrico Granata m_valobj = m_orig_valobj; 138106260c5SEnrico Granata } 139106260c5SEnrico Granata else 140106260c5SEnrico Granata { 141*26014690SGreg Clayton if (m_options.m_use_dynamic != eNoDynamicValues) 1424d93b8cdSEnrico Granata { 143*26014690SGreg Clayton ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(m_options.m_use_dynamic).get(); 1444d93b8cdSEnrico Granata if (dynamic_value) 1454d93b8cdSEnrico Granata m_valobj = dynamic_value; 1464d93b8cdSEnrico Granata else 1474d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 1484d93b8cdSEnrico Granata } 1494d93b8cdSEnrico Granata else 1504d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 151106260c5SEnrico Granata } 152d07cfd3aSEnrico Granata 153d07cfd3aSEnrico Granata if (m_valobj->IsSynthetic()) 154d07cfd3aSEnrico Granata { 155*26014690SGreg Clayton if (m_options.m_use_synthetic == false) 156d07cfd3aSEnrico Granata { 157d07cfd3aSEnrico Granata ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get(); 158d07cfd3aSEnrico Granata if (non_synthetic) 159d07cfd3aSEnrico Granata m_valobj = non_synthetic; 160d07cfd3aSEnrico Granata } 161d07cfd3aSEnrico Granata } 162d07cfd3aSEnrico Granata else 163d07cfd3aSEnrico Granata { 164*26014690SGreg Clayton if (m_options.m_use_synthetic == true) 165d07cfd3aSEnrico Granata { 166d07cfd3aSEnrico Granata ValueObject *synthetic = m_valobj->GetSyntheticValue().get(); 167d07cfd3aSEnrico Granata if (synthetic) 168d07cfd3aSEnrico Granata m_valobj = synthetic; 169d07cfd3aSEnrico Granata } 170d07cfd3aSEnrico Granata } 171106260c5SEnrico Granata } 17259b5a37dSBruce Mitchener m_compiler_type = m_valobj->GetCompilerType(); 17359b5a37dSBruce Mitchener m_type_flags = m_compiler_type.GetTypeInfo (); 1744d93b8cdSEnrico Granata return true; 1754d93b8cdSEnrico Granata } 1764d93b8cdSEnrico Granata 1774d93b8cdSEnrico Granata const char* 1784d93b8cdSEnrico Granata ValueObjectPrinter::GetDescriptionForDisplay () 1794d93b8cdSEnrico Granata { 1804d93b8cdSEnrico Granata const char* str = m_valobj->GetObjectDescription(); 1814d93b8cdSEnrico Granata if (!str) 1824d93b8cdSEnrico Granata str = m_valobj->GetSummaryAsCString(); 1834d93b8cdSEnrico Granata if (!str) 1844d93b8cdSEnrico Granata str = m_valobj->GetValueAsCString(); 1854d93b8cdSEnrico Granata return str; 1864d93b8cdSEnrico Granata } 1874d93b8cdSEnrico Granata 1884d93b8cdSEnrico Granata const char* 1894d93b8cdSEnrico Granata ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail) 1904d93b8cdSEnrico Granata { 191*26014690SGreg Clayton const char *root_valobj_name = m_options.m_root_valobj_name.empty() ? 1924d93b8cdSEnrico Granata m_valobj->GetName().AsCString() : 193*26014690SGreg Clayton m_options.m_root_valobj_name.c_str(); 1944d93b8cdSEnrico Granata return root_valobj_name ? root_valobj_name : if_fail; 1954d93b8cdSEnrico Granata } 1964d93b8cdSEnrico Granata 1974d93b8cdSEnrico Granata bool 1984d93b8cdSEnrico Granata ValueObjectPrinter::ShouldPrintValueObject () 1994d93b8cdSEnrico Granata { 2004d93b8cdSEnrico Granata if (m_should_print == eLazyBoolCalculate) 201*26014690SGreg Clayton m_should_print = (m_options.m_flat_output == false || m_type_flags.Test (eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo; 2024d93b8cdSEnrico Granata return m_should_print == eLazyBoolYes; 2034d93b8cdSEnrico Granata } 2044d93b8cdSEnrico Granata 2054d93b8cdSEnrico Granata bool 2064d93b8cdSEnrico Granata ValueObjectPrinter::IsNil () 2074d93b8cdSEnrico Granata { 2084d93b8cdSEnrico Granata if (m_is_nil == eLazyBoolCalculate) 2094d93b8cdSEnrico Granata m_is_nil = m_valobj->IsObjCNil() ? eLazyBoolYes : eLazyBoolNo; 2104d93b8cdSEnrico Granata return m_is_nil == eLazyBoolYes; 2114d93b8cdSEnrico Granata } 2124d93b8cdSEnrico Granata 2134d93b8cdSEnrico Granata bool 2144d93b8cdSEnrico Granata ValueObjectPrinter::IsPtr () 2154d93b8cdSEnrico Granata { 2164d93b8cdSEnrico Granata if (m_is_ptr == eLazyBoolCalculate) 217622be238SEnrico Granata m_is_ptr = m_type_flags.Test (eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo; 2184d93b8cdSEnrico Granata return m_is_ptr == eLazyBoolYes; 2194d93b8cdSEnrico Granata } 2204d93b8cdSEnrico Granata 2214d93b8cdSEnrico Granata bool 2224d93b8cdSEnrico Granata ValueObjectPrinter::IsRef () 2234d93b8cdSEnrico Granata { 2244d93b8cdSEnrico Granata if (m_is_ref == eLazyBoolCalculate) 225622be238SEnrico Granata m_is_ref = m_type_flags.Test (eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo; 2264d93b8cdSEnrico Granata return m_is_ref == eLazyBoolYes; 2274d93b8cdSEnrico Granata } 2284d93b8cdSEnrico Granata 2294d93b8cdSEnrico Granata bool 2304d93b8cdSEnrico Granata ValueObjectPrinter::IsAggregate () 2314d93b8cdSEnrico Granata { 2324d93b8cdSEnrico Granata if (m_is_aggregate == eLazyBoolCalculate) 233622be238SEnrico Granata m_is_aggregate = m_type_flags.Test (eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo; 2344d93b8cdSEnrico Granata return m_is_aggregate == eLazyBoolYes; 2354d93b8cdSEnrico Granata } 2364d93b8cdSEnrico Granata 2374d93b8cdSEnrico Granata bool 2384d93b8cdSEnrico Granata ValueObjectPrinter::PrintLocationIfNeeded () 2394d93b8cdSEnrico Granata { 240*26014690SGreg Clayton if (m_options.m_show_location) 2414d93b8cdSEnrico Granata { 2424d93b8cdSEnrico Granata m_stream->Printf("%s: ", m_valobj->GetLocationAsCString()); 2434d93b8cdSEnrico Granata return true; 2444d93b8cdSEnrico Granata } 2454d93b8cdSEnrico Granata return false; 2464d93b8cdSEnrico Granata } 2474d93b8cdSEnrico Granata 248e0ee1e1cSEnrico Granata void 249e0ee1e1cSEnrico Granata ValueObjectPrinter::PrintDecl () 2504d93b8cdSEnrico Granata { 2514d93b8cdSEnrico Granata bool show_type = true; 2524d93b8cdSEnrico Granata // if we are at the root-level and been asked to hide the root's type, then hide it 253*26014690SGreg Clayton if (m_curr_depth == 0 && m_options.m_hide_root_type) 2544d93b8cdSEnrico Granata show_type = false; 2554d93b8cdSEnrico Granata else 2564d93b8cdSEnrico Granata // otherwise decide according to the usual rules (asked to show types - always at the root level) 257*26014690SGreg Clayton show_type = m_options.m_show_types || (m_curr_depth == 0 && !m_options.m_flat_output); 2584d93b8cdSEnrico Granata 259e0ee1e1cSEnrico Granata StreamString typeName; 260e0ee1e1cSEnrico Granata 261e0ee1e1cSEnrico Granata // always show the type at the root level if it is invalid 2624d93b8cdSEnrico Granata if (show_type) 2634d93b8cdSEnrico Granata { 2644d93b8cdSEnrico Granata // Some ValueObjects don't have types (like registers sets). Only print 2654d93b8cdSEnrico Granata // the type if there is one to print 266a126e462SEnrico Granata ConstString type_name; 267e0ee1e1cSEnrico Granata if (m_compiler_type.IsValid()) 268e0ee1e1cSEnrico Granata { 269*26014690SGreg Clayton if (m_options.m_use_type_display_name) 270a126e462SEnrico Granata type_name = m_valobj->GetDisplayTypeName(); 271e8daa2f8SEnrico Granata else 272a126e462SEnrico Granata type_name = m_valobj->GetQualifiedTypeName(); 2734d93b8cdSEnrico Granata } 274e0ee1e1cSEnrico Granata else 275e0ee1e1cSEnrico Granata { 276e0ee1e1cSEnrico Granata // only show an invalid type name if the user explicitly triggered show_type 277*26014690SGreg Clayton if (m_options.m_show_types) 278e0ee1e1cSEnrico Granata type_name = ConstString("<invalid type>"); 279e0ee1e1cSEnrico Granata else 280e0ee1e1cSEnrico Granata type_name.Clear(); 2814d93b8cdSEnrico Granata } 2824d93b8cdSEnrico Granata 283e0ee1e1cSEnrico Granata if (type_name) 2844d93b8cdSEnrico Granata { 285e0ee1e1cSEnrico Granata std::string type_name_str(type_name.GetCString()); 286*26014690SGreg Clayton if (m_options.m_hide_pointer_value) 287e0ee1e1cSEnrico Granata { 288e0ee1e1cSEnrico Granata for(auto iter = type_name_str.find(" *"); 289e0ee1e1cSEnrico Granata iter != std::string::npos; 290e0ee1e1cSEnrico Granata iter = type_name_str.find(" *")) 291e0ee1e1cSEnrico Granata { 292e0ee1e1cSEnrico Granata type_name_str.erase(iter, 2); 293e0ee1e1cSEnrico Granata } 294e0ee1e1cSEnrico Granata } 295c8e7649aSEnrico Granata typeName.Printf("%s", type_name_str.c_str()); 296e0ee1e1cSEnrico Granata } 297e0ee1e1cSEnrico Granata } 298e0ee1e1cSEnrico Granata 299e0ee1e1cSEnrico Granata StreamString varName; 300e0ee1e1cSEnrico Granata 301*26014690SGreg Clayton if (m_options.m_flat_output) 3024d93b8cdSEnrico Granata { 3034d93b8cdSEnrico Granata // If we are showing types, also qualify the C++ base classes 3044d93b8cdSEnrico Granata const bool qualify_cxx_base_classes = show_type; 305*26014690SGreg Clayton if (!m_options.m_hide_name) 3064d93b8cdSEnrico Granata { 307e0ee1e1cSEnrico Granata m_valobj->GetExpressionPath(varName, qualify_cxx_base_classes); 3084d93b8cdSEnrico Granata } 3094d93b8cdSEnrico Granata } 310*26014690SGreg Clayton else if (!m_options.m_hide_name) 3114d93b8cdSEnrico Granata { 3124d93b8cdSEnrico Granata const char *name_cstr = GetRootNameForDisplay(""); 313e0ee1e1cSEnrico Granata varName.Printf ("%s", name_cstr); 3144d93b8cdSEnrico Granata } 315e0ee1e1cSEnrico Granata 316e0ee1e1cSEnrico Granata bool decl_printed = false; 317*26014690SGreg Clayton if (!m_options.m_decl_printing_helper) 318c8e7649aSEnrico Granata { 319c8e7649aSEnrico 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 320*26014690SGreg Clayton lldb::LanguageType lang_type = (m_options.m_varformat_language == lldb::eLanguageTypeUnknown) ? m_valobj->GetPreferredDisplayLanguage() : m_options.m_varformat_language; 321c8e7649aSEnrico Granata if (Language *lang_plugin = Language::FindPlugin(lang_type)) 322c8e7649aSEnrico Granata { 323*26014690SGreg Clayton m_options.m_decl_printing_helper = lang_plugin->GetDeclPrintingHelper(); 324c8e7649aSEnrico Granata } 325c8e7649aSEnrico Granata } 326c8e7649aSEnrico Granata 327*26014690SGreg Clayton if (m_options.m_decl_printing_helper) 328e0ee1e1cSEnrico Granata { 329e0ee1e1cSEnrico Granata ConstString type_name_cstr(typeName.GetData()); 330e0ee1e1cSEnrico Granata ConstString var_name_cstr(varName.GetData()); 331e0ee1e1cSEnrico Granata 332e0ee1e1cSEnrico Granata StreamString dest_stream; 333*26014690SGreg Clayton if (m_options.m_decl_printing_helper (type_name_cstr, 334e0ee1e1cSEnrico Granata var_name_cstr, 335*26014690SGreg Clayton m_options, 336e0ee1e1cSEnrico Granata dest_stream)) 337e0ee1e1cSEnrico Granata { 338e0ee1e1cSEnrico Granata decl_printed = true; 339e0ee1e1cSEnrico Granata m_stream->Printf("%s", dest_stream.GetData()); 340e0ee1e1cSEnrico Granata } 341e0ee1e1cSEnrico Granata } 342e0ee1e1cSEnrico Granata 343c8e7649aSEnrico Granata // if the helper failed, or there is none, do a default thing 344e0ee1e1cSEnrico Granata if (!decl_printed) 345e0ee1e1cSEnrico Granata { 346e0ee1e1cSEnrico Granata if (typeName.GetSize()) 347c8e7649aSEnrico Granata m_stream->Printf("(%s) ", typeName.GetData()); 348e0ee1e1cSEnrico Granata if (varName.GetSize()) 349e0ee1e1cSEnrico Granata m_stream->Printf("%s =", varName.GetData()); 350*26014690SGreg Clayton else if (!m_options.m_hide_name) 351e0ee1e1cSEnrico Granata m_stream->Printf(" ="); 352e0ee1e1cSEnrico Granata } 3534d93b8cdSEnrico Granata } 3544d93b8cdSEnrico Granata 3554d93b8cdSEnrico Granata bool 3564d93b8cdSEnrico Granata ValueObjectPrinter::CheckScopeIfNeeded () 3574d93b8cdSEnrico Granata { 358*26014690SGreg Clayton if (m_options.m_scope_already_checked) 3594d93b8cdSEnrico Granata return true; 3604d93b8cdSEnrico Granata return m_valobj->IsInScope(); 3614d93b8cdSEnrico Granata } 3624d93b8cdSEnrico Granata 3634d93b8cdSEnrico Granata TypeSummaryImpl* 3644d93b8cdSEnrico Granata ValueObjectPrinter::GetSummaryFormatter () 3654d93b8cdSEnrico Granata { 3664d93b8cdSEnrico Granata if (m_summary_formatter.second == false) 3674d93b8cdSEnrico Granata { 368*26014690SGreg Clayton TypeSummaryImpl* entry = m_options.m_summary_sp ? m_options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get(); 3694d93b8cdSEnrico Granata 370*26014690SGreg Clayton if (m_options.m_omit_summary_depth > 0) 3714d93b8cdSEnrico Granata entry = NULL; 3724d93b8cdSEnrico Granata m_summary_formatter.first = entry; 3734d93b8cdSEnrico Granata m_summary_formatter.second = true; 3744d93b8cdSEnrico Granata } 3754d93b8cdSEnrico Granata return m_summary_formatter.first; 3764d93b8cdSEnrico Granata } 3774d93b8cdSEnrico Granata 378e0ee1e1cSEnrico Granata static bool 379e0ee1e1cSEnrico Granata IsPointerValue (const CompilerType &type) 380e0ee1e1cSEnrico Granata { 381e0ee1e1cSEnrico Granata Flags type_flags(type.GetTypeInfo()); 382e0ee1e1cSEnrico Granata if (type_flags.AnySet(eTypeIsPointer)) 383e0ee1e1cSEnrico Granata return type_flags.AllClear(eTypeIsBuiltIn); 384e0ee1e1cSEnrico Granata return false; 385e0ee1e1cSEnrico Granata } 386e0ee1e1cSEnrico Granata 3874d93b8cdSEnrico Granata void 3884d93b8cdSEnrico Granata ValueObjectPrinter::GetValueSummaryError (std::string& value, 3894d93b8cdSEnrico Granata std::string& summary, 3904d93b8cdSEnrico Granata std::string& error) 3914d93b8cdSEnrico Granata { 392*26014690SGreg Clayton if (m_options.m_format != eFormatDefault && m_options.m_format != m_valobj->GetFormat()) 3934d93b8cdSEnrico Granata { 394*26014690SGreg Clayton m_valobj->GetValueAsCString(m_options.m_format, 395465f4bc2SEnrico Granata value); 3964d93b8cdSEnrico Granata } 397465f4bc2SEnrico Granata else 398465f4bc2SEnrico Granata { 3994d93b8cdSEnrico Granata const char* val_cstr = m_valobj->GetValueAsCString(); 400465f4bc2SEnrico Granata if (val_cstr) 401465f4bc2SEnrico Granata value.assign(val_cstr); 402465f4bc2SEnrico Granata } 4034d93b8cdSEnrico Granata const char* err_cstr = m_valobj->GetError().AsCString(); 4044d93b8cdSEnrico Granata if (err_cstr) 4054d93b8cdSEnrico Granata error.assign(err_cstr); 4064d93b8cdSEnrico Granata 4074d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 4084d93b8cdSEnrico Granata { 4094d93b8cdSEnrico Granata if (IsNil()) 4104d93b8cdSEnrico Granata summary.assign("nil"); 411*26014690SGreg Clayton else if (m_options.m_omit_summary_depth == 0) 4124d93b8cdSEnrico Granata { 4134d93b8cdSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 4144d93b8cdSEnrico Granata if (entry) 415*26014690SGreg Clayton m_valobj->GetSummaryAsCString(entry, summary, m_options.m_varformat_language); 4164d93b8cdSEnrico Granata else 4174d93b8cdSEnrico Granata { 418*26014690SGreg Clayton const char* sum_cstr = m_valobj->GetSummaryAsCString(m_options.m_varformat_language); 4194d93b8cdSEnrico Granata if (sum_cstr) 4204d93b8cdSEnrico Granata summary.assign(sum_cstr); 4214d93b8cdSEnrico Granata } 4224d93b8cdSEnrico Granata } 4234d93b8cdSEnrico Granata } 4244d93b8cdSEnrico Granata } 4254d93b8cdSEnrico Granata 4264d93b8cdSEnrico Granata bool 4274d93b8cdSEnrico Granata ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed, 4284d93b8cdSEnrico Granata bool& summary_printed) 4294d93b8cdSEnrico Granata { 4304d93b8cdSEnrico Granata bool error_printed = false; 4314d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 4324d93b8cdSEnrico Granata { 4334d93b8cdSEnrico Granata if (!CheckScopeIfNeeded()) 4344d93b8cdSEnrico Granata m_error.assign("out of scope"); 4354d93b8cdSEnrico Granata if (m_error.empty()) 4364d93b8cdSEnrico Granata { 4374d93b8cdSEnrico Granata GetValueSummaryError(m_value, m_summary, m_error); 4384d93b8cdSEnrico Granata } 4394d93b8cdSEnrico Granata if (m_error.size()) 4404d93b8cdSEnrico Granata { 4414d93b8cdSEnrico Granata error_printed = true; 4424d93b8cdSEnrico Granata m_stream->Printf (" <%s>\n", m_error.c_str()); 4434d93b8cdSEnrico Granata } 4444d93b8cdSEnrico Granata else 4454d93b8cdSEnrico Granata { 4464d93b8cdSEnrico Granata // Make sure we have a value and make sure the summary didn't 4474d93b8cdSEnrico Granata // specify that the value should not be printed - and do not print 4484d93b8cdSEnrico Granata // the value if this thing is nil 4494d93b8cdSEnrico Granata // (but show the value if the user passes a format explicitly) 4504d93b8cdSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 451*26014690SGreg Clayton if (!IsNil() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue(m_valobj) || m_options.m_format != eFormatDefault) || m_summary.empty()) && !m_options.m_hide_value) 4524d93b8cdSEnrico Granata { 453*26014690SGreg Clayton if (m_options.m_hide_pointer_value && IsPointerValue(m_valobj->GetCompilerType())) {} 454e0ee1e1cSEnrico Granata else 455e0ee1e1cSEnrico Granata { 4564d93b8cdSEnrico Granata m_stream->Printf(" %s", m_value.c_str()); 4574d93b8cdSEnrico Granata value_printed = true; 4584d93b8cdSEnrico Granata } 459e0ee1e1cSEnrico Granata } 4604d93b8cdSEnrico Granata 4614d93b8cdSEnrico Granata if (m_summary.size()) 4624d93b8cdSEnrico Granata { 4634d93b8cdSEnrico Granata m_stream->Printf(" %s", m_summary.c_str()); 4644d93b8cdSEnrico Granata summary_printed = true; 4654d93b8cdSEnrico Granata } 4664d93b8cdSEnrico Granata } 4674d93b8cdSEnrico Granata } 4684d93b8cdSEnrico Granata return !error_printed; 4694d93b8cdSEnrico Granata } 4704d93b8cdSEnrico Granata 4714d93b8cdSEnrico Granata bool 4724d93b8cdSEnrico Granata ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed, 4734d93b8cdSEnrico Granata bool summary_printed) 4744d93b8cdSEnrico Granata { 4754d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 4764d93b8cdSEnrico Granata { 4774d93b8cdSEnrico Granata // let's avoid the overly verbose no description error for a nil thing 478*26014690SGreg Clayton if (m_options.m_use_objc && !IsNil()) 4794d93b8cdSEnrico Granata { 480*26014690SGreg Clayton if (!m_options.m_hide_value || !m_options.m_hide_name) 4814d93b8cdSEnrico Granata m_stream->Printf(" "); 4824d93b8cdSEnrico Granata const char *object_desc = nullptr; 4834d93b8cdSEnrico Granata if (value_printed || summary_printed) 4844d93b8cdSEnrico Granata object_desc = m_valobj->GetObjectDescription(); 4854d93b8cdSEnrico Granata else 4864d93b8cdSEnrico Granata object_desc = GetDescriptionForDisplay(); 4874d93b8cdSEnrico Granata if (object_desc && *object_desc) 4884d93b8cdSEnrico Granata { 4894d93b8cdSEnrico Granata m_stream->Printf("%s\n", object_desc); 4904d93b8cdSEnrico Granata return true; 4914d93b8cdSEnrico Granata } 4924d93b8cdSEnrico Granata else if (value_printed == false && summary_printed == false) 4934d93b8cdSEnrico Granata return true; 4944d93b8cdSEnrico Granata else 4954d93b8cdSEnrico Granata return false; 4964d93b8cdSEnrico Granata } 4974d93b8cdSEnrico Granata } 4984d93b8cdSEnrico Granata return true; 4994d93b8cdSEnrico Granata } 5004d93b8cdSEnrico Granata 5014d93b8cdSEnrico Granata bool 502c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth::CanAllowExpansion (bool is_root, 503c1b7c09aSEnrico Granata TypeSummaryImpl* entry, 504c1b7c09aSEnrico Granata ValueObject *valobj, 505c1b7c09aSEnrico Granata const std::string& summary) 506c1b7c09aSEnrico Granata { 507c1b7c09aSEnrico Granata switch (m_mode) 508c1b7c09aSEnrico Granata { 509c1b7c09aSEnrico Granata case Mode::Always: 510c1b7c09aSEnrico Granata return (m_count > 0); 511c1b7c09aSEnrico Granata case Mode::Never: 512c1b7c09aSEnrico Granata return false; 513c1b7c09aSEnrico Granata case Mode::Default: 514c1b7c09aSEnrico Granata if (is_root) 515c1b7c09aSEnrico Granata m_count = std::min<decltype(m_count)>(m_count,1); 516c1b7c09aSEnrico Granata return m_count > 0; 517c1b7c09aSEnrico Granata case Mode::Formatters: 518c1b7c09aSEnrico Granata if (!entry || entry->DoesPrintChildren(valobj) || summary.empty()) 519c1b7c09aSEnrico Granata return m_count > 0; 520c1b7c09aSEnrico Granata return false; 521c1b7c09aSEnrico Granata } 52284f5b0dfSZachary Turner return false; 523c1b7c09aSEnrico Granata } 524c1b7c09aSEnrico Granata 525c1b7c09aSEnrico Granata bool 526c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth::CanAllowExpansion () const 527c1b7c09aSEnrico Granata { 528c1b7c09aSEnrico Granata switch (m_mode) 529c1b7c09aSEnrico Granata { 530c1b7c09aSEnrico Granata case Mode::Always: 531c1b7c09aSEnrico Granata case Mode::Default: 532c1b7c09aSEnrico Granata case Mode::Formatters: 533c1b7c09aSEnrico Granata return (m_count > 0); 534c1b7c09aSEnrico Granata case Mode::Never: 535c1b7c09aSEnrico Granata return false; 536c1b7c09aSEnrico Granata } 53784f5b0dfSZachary Turner return false; 538c1b7c09aSEnrico Granata } 539c1b7c09aSEnrico Granata 540c1b7c09aSEnrico Granata bool 5414d93b8cdSEnrico Granata ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description, 542c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 5434d93b8cdSEnrico Granata { 5444d93b8cdSEnrico Granata const bool is_ref = IsRef (); 5454d93b8cdSEnrico Granata const bool is_ptr = IsPtr (); 5464d93b8cdSEnrico Granata 547c1b7c09aSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 548c1b7c09aSEnrico Granata 549*26014690SGreg Clayton if (is_failed_description || m_curr_depth < m_options.m_max_depth) 5504d93b8cdSEnrico Granata { 5514d93b8cdSEnrico Granata // We will show children for all concrete types. We won't show 5524d93b8cdSEnrico Granata // pointer contents unless a pointer depth has been specified. 5534d93b8cdSEnrico Granata // We won't reference contents unless the reference is the 5544d93b8cdSEnrico Granata // root object (depth of zero). 5554d93b8cdSEnrico Granata 5564d93b8cdSEnrico Granata // Use a new temporary pointer depth in case we override the 5574d93b8cdSEnrico Granata // current pointer depth below... 5584d93b8cdSEnrico Granata 5594d93b8cdSEnrico Granata if (is_ptr || is_ref) 5604d93b8cdSEnrico Granata { 5614d93b8cdSEnrico Granata // We have a pointer or reference whose value is an address. 5624d93b8cdSEnrico Granata // Make sure that address is not NULL 5634d93b8cdSEnrico Granata AddressType ptr_address_type; 5644d93b8cdSEnrico Granata if (m_valobj->GetPointerValue (&ptr_address_type) == 0) 5654d93b8cdSEnrico Granata return false; 5664d93b8cdSEnrico Granata 567c1b7c09aSEnrico Granata const bool is_root_level = m_curr_depth == 0; 568c1b7c09aSEnrico Granata 569c1b7c09aSEnrico Granata if (is_ref && 570c1b7c09aSEnrico Granata is_root_level) 5714d93b8cdSEnrico Granata { 5724d93b8cdSEnrico Granata // If this is the root object (depth is zero) that we are showing 5734d93b8cdSEnrico Granata // and it is a reference, and no pointer depth has been supplied 5744d93b8cdSEnrico Granata // print out what it references. Don't do this at deeper depths 5754d93b8cdSEnrico Granata // otherwise we can end up with infinite recursion... 576c1b7c09aSEnrico Granata return true; 5774d93b8cdSEnrico Granata } 5784d93b8cdSEnrico Granata 579c1b7c09aSEnrico Granata return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, m_summary); 5804d93b8cdSEnrico Granata } 5814d93b8cdSEnrico Granata 5828a068e6cSEnrico Granata return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty()); 5834d93b8cdSEnrico Granata } 5844d93b8cdSEnrico Granata return false; 5854d93b8cdSEnrico Granata } 5864d93b8cdSEnrico Granata 587d26eb907SSiva Chandra bool 588d26eb907SSiva Chandra ValueObjectPrinter::ShouldExpandEmptyAggregates () 589d26eb907SSiva Chandra { 590d26eb907SSiva Chandra TypeSummaryImpl* entry = GetSummaryFormatter(); 591d26eb907SSiva Chandra 592d26eb907SSiva Chandra if (!entry) 593d26eb907SSiva Chandra return true; 594d26eb907SSiva Chandra 595d26eb907SSiva Chandra return entry->DoesPrintEmptyAggregates(); 596d26eb907SSiva Chandra } 597d26eb907SSiva Chandra 5984d93b8cdSEnrico Granata ValueObject* 5994d93b8cdSEnrico Granata ValueObjectPrinter::GetValueObjectForChildrenGeneration () 6004d93b8cdSEnrico Granata { 601d07cfd3aSEnrico Granata return m_valobj; 6024d93b8cdSEnrico Granata } 6034d93b8cdSEnrico Granata 6044d93b8cdSEnrico Granata void 6054d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPreamble () 6064d93b8cdSEnrico Granata { 607*26014690SGreg Clayton if (m_options.m_flat_output) 6084d93b8cdSEnrico Granata { 6094d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 6104d93b8cdSEnrico Granata m_stream->EOL(); 6114d93b8cdSEnrico Granata } 6124d93b8cdSEnrico Granata else 6134d93b8cdSEnrico Granata { 6144d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 6154d93b8cdSEnrico Granata m_stream->PutCString(IsRef () ? ": {\n" : " {\n"); 6164d93b8cdSEnrico Granata m_stream->IndentMore(); 6174d93b8cdSEnrico Granata } 6184d93b8cdSEnrico Granata } 6194d93b8cdSEnrico Granata 6204d93b8cdSEnrico Granata void 6214d93b8cdSEnrico Granata ValueObjectPrinter::PrintChild (ValueObjectSP child_sp, 622c1b7c09aSEnrico Granata const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 6234d93b8cdSEnrico Granata { 624*26014690SGreg Clayton DumpValueObjectOptions child_options(m_options); 625*26014690SGreg Clayton child_options.SetFormat(m_options.m_format).SetSummary().SetRootValueObjectName(); 626*26014690SGreg Clayton child_options.SetScopeChecked(true).SetHideName(m_options.m_hide_name).SetHideValue(m_options.m_hide_value) 6274d93b8cdSEnrico Granata .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0); 6284d93b8cdSEnrico Granata if (child_sp.get()) 6294d93b8cdSEnrico Granata { 6304d93b8cdSEnrico Granata ValueObjectPrinter child_printer(child_sp.get(), 6314d93b8cdSEnrico Granata m_stream, 6324d93b8cdSEnrico Granata child_options, 633c1b7c09aSEnrico Granata (IsPtr() || IsRef()) ? --curr_ptr_depth : curr_ptr_depth, 6344d93b8cdSEnrico Granata m_curr_depth + 1); 6354d93b8cdSEnrico Granata child_printer.PrintValueObject(); 6364d93b8cdSEnrico Granata } 6374d93b8cdSEnrico Granata } 6384d93b8cdSEnrico Granata 6394d93b8cdSEnrico Granata uint32_t 6404d93b8cdSEnrico Granata ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot) 6414d93b8cdSEnrico Granata { 6424d93b8cdSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 6434d93b8cdSEnrico Granata 6444d93b8cdSEnrico Granata size_t num_children = synth_m_valobj->GetNumChildren(); 6454d93b8cdSEnrico Granata print_dotdotdot = false; 6464d93b8cdSEnrico Granata if (num_children) 6474d93b8cdSEnrico Granata { 6484d93b8cdSEnrico Granata const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 6494d93b8cdSEnrico Granata 650*26014690SGreg Clayton if (num_children > max_num_children && !m_options.m_ignore_cap) 6514d93b8cdSEnrico Granata { 6524d93b8cdSEnrico Granata print_dotdotdot = true; 6534d93b8cdSEnrico Granata return max_num_children; 6544d93b8cdSEnrico Granata } 6554d93b8cdSEnrico Granata } 6564d93b8cdSEnrico Granata return num_children; 6574d93b8cdSEnrico Granata } 6584d93b8cdSEnrico Granata 6594d93b8cdSEnrico Granata void 6604d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot) 6614d93b8cdSEnrico Granata { 662*26014690SGreg Clayton if (!m_options.m_flat_output) 6634d93b8cdSEnrico Granata { 6644d93b8cdSEnrico Granata if (print_dotdotdot) 6654d93b8cdSEnrico Granata { 6664d93b8cdSEnrico Granata m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated(); 6674d93b8cdSEnrico Granata m_stream->Indent("...\n"); 6684d93b8cdSEnrico Granata } 6694d93b8cdSEnrico Granata m_stream->IndentLess(); 6704d93b8cdSEnrico Granata m_stream->Indent("}\n"); 6714d93b8cdSEnrico Granata } 6724d93b8cdSEnrico Granata } 6734d93b8cdSEnrico Granata 6744d93b8cdSEnrico Granata void 675c1b7c09aSEnrico Granata ValueObjectPrinter::PrintChildren (bool value_printed, 676c1b7c09aSEnrico Granata bool summary_printed, 677c1b7c09aSEnrico Granata const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 6784d93b8cdSEnrico Granata { 6794d93b8cdSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 6804d93b8cdSEnrico Granata 6814d93b8cdSEnrico Granata bool print_dotdotdot = false; 6824d93b8cdSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 6834d93b8cdSEnrico Granata if (num_children) 6844d93b8cdSEnrico Granata { 6854d93b8cdSEnrico Granata PrintChildrenPreamble (); 6864d93b8cdSEnrico Granata 6874d93b8cdSEnrico Granata for (size_t idx=0; idx<num_children; ++idx) 6884d93b8cdSEnrico Granata { 6894d93b8cdSEnrico Granata ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 6904d93b8cdSEnrico Granata PrintChild (child_sp, curr_ptr_depth); 6914d93b8cdSEnrico Granata } 6924d93b8cdSEnrico Granata 6934d93b8cdSEnrico Granata PrintChildrenPostamble (print_dotdotdot); 6944d93b8cdSEnrico Granata } 6954d93b8cdSEnrico Granata else if (IsAggregate()) 6964d93b8cdSEnrico Granata { 6974d93b8cdSEnrico Granata // Aggregate, no children... 6984d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 699d07cfd3aSEnrico Granata { 700d07cfd3aSEnrico Granata // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value 701d26eb907SSiva Chandra if (m_valobj->DoesProvideSyntheticValue() || !ShouldExpandEmptyAggregates()) 702d07cfd3aSEnrico Granata m_stream->PutCString( "\n"); 703d07cfd3aSEnrico Granata else 7044d93b8cdSEnrico Granata m_stream->PutCString(" {}\n"); 7054d93b8cdSEnrico Granata } 706d07cfd3aSEnrico Granata } 7074d93b8cdSEnrico Granata else 7084d93b8cdSEnrico Granata { 7094d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 7104d93b8cdSEnrico Granata m_stream->EOL(); 7114d93b8cdSEnrico Granata } 7124d93b8cdSEnrico Granata } 7134d93b8cdSEnrico Granata 714a29cb0baSEnrico Granata bool 715a29cb0baSEnrico Granata ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names) 716a29cb0baSEnrico Granata { 717d07cfd3aSEnrico Granata if (!GetMostSpecializedValue () || m_valobj == nullptr) 718a29cb0baSEnrico Granata return false; 719a29cb0baSEnrico Granata 720a29cb0baSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 721a29cb0baSEnrico Granata 722a29cb0baSEnrico Granata bool print_dotdotdot = false; 723a29cb0baSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 724a29cb0baSEnrico Granata 725a29cb0baSEnrico Granata if (num_children) 726a29cb0baSEnrico Granata { 727a29cb0baSEnrico Granata m_stream->PutChar('('); 728a29cb0baSEnrico Granata 729a29cb0baSEnrico Granata for (uint32_t idx=0; idx<num_children; ++idx) 730a29cb0baSEnrico Granata { 731a29cb0baSEnrico Granata lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 732ddac7611SEnrico Granata if (child_sp) 733*26014690SGreg Clayton child_sp = child_sp->GetQualifiedRepresentationIfAvailable(m_options.m_use_dynamic, m_options.m_use_synthetic); 734a29cb0baSEnrico Granata if (child_sp) 735a29cb0baSEnrico Granata { 736a29cb0baSEnrico Granata if (idx) 737a29cb0baSEnrico Granata m_stream->PutCString(", "); 738a29cb0baSEnrico Granata if (!hide_names) 739a29cb0baSEnrico Granata { 740a29cb0baSEnrico Granata const char* name = child_sp.get()->GetName().AsCString(); 741a29cb0baSEnrico Granata if (name && *name) 742a29cb0baSEnrico Granata { 743a29cb0baSEnrico Granata m_stream->PutCString(name); 744a29cb0baSEnrico Granata m_stream->PutCString(" = "); 745a29cb0baSEnrico Granata } 746a29cb0baSEnrico Granata } 747a29cb0baSEnrico Granata child_sp->DumpPrintableRepresentation(*m_stream, 748a29cb0baSEnrico Granata ValueObject::eValueObjectRepresentationStyleSummary, 749443844c4SEnrico Granata lldb::eFormatInvalid, 750a29cb0baSEnrico Granata ValueObject::ePrintableRepresentationSpecialCasesDisable); 751a29cb0baSEnrico Granata } 752a29cb0baSEnrico Granata } 753a29cb0baSEnrico Granata 754a29cb0baSEnrico Granata if (print_dotdotdot) 755a29cb0baSEnrico Granata m_stream->PutCString(", ...)"); 756a29cb0baSEnrico Granata else 757a29cb0baSEnrico Granata m_stream->PutChar(')'); 758a29cb0baSEnrico Granata } 759a29cb0baSEnrico Granata return true; 760a29cb0baSEnrico Granata } 761a29cb0baSEnrico Granata 7624d93b8cdSEnrico Granata void 7634d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed, 7644d93b8cdSEnrico Granata bool summary_printed) 7654d93b8cdSEnrico Granata { 7664d93b8cdSEnrico Granata // this flag controls whether we tried to display a description for this object and failed 7674d93b8cdSEnrico Granata // if that happens, we want to display the children, if any 7684d93b8cdSEnrico Granata bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed); 7694d93b8cdSEnrico Granata 770c1b7c09aSEnrico Granata auto curr_ptr_depth = m_ptr_depth; 7714d93b8cdSEnrico Granata bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth); 772c1b7c09aSEnrico Granata bool print_oneline = (curr_ptr_depth.CanAllowExpansion() || 773*26014690SGreg Clayton m_options.m_show_types || 774*26014690SGreg Clayton !m_options.m_allow_oneliner_mode || 775*26014690SGreg Clayton m_options.m_flat_output || 776*26014690SGreg Clayton m_options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj); 7774d93b8cdSEnrico Granata 7784d93b8cdSEnrico Granata if (print_children) 7794d93b8cdSEnrico Granata { 780a29cb0baSEnrico Granata if (print_oneline) 781a29cb0baSEnrico Granata { 782a29cb0baSEnrico Granata m_stream->PutChar(' '); 783a29cb0baSEnrico Granata PrintChildrenOneLiner (false); 784a29cb0baSEnrico Granata m_stream->EOL(); 785a29cb0baSEnrico Granata } 786a29cb0baSEnrico Granata else 787c1b7c09aSEnrico Granata PrintChildren (value_printed, summary_printed, curr_ptr_depth); 7884d93b8cdSEnrico Granata } 789*26014690SGreg Clayton else if (m_curr_depth >= m_options.m_max_depth && IsAggregate() && ShouldPrintValueObject()) 7904d93b8cdSEnrico Granata { 7914d93b8cdSEnrico Granata m_stream->PutCString("{...}\n"); 7924d93b8cdSEnrico Granata } 793245b3caaSEnrico Granata else 794245b3caaSEnrico Granata m_stream->EOL(); 7954d93b8cdSEnrico Granata } 7960f883ffbSEnrico Granata 7970f883ffbSEnrico Granata bool 7980f883ffbSEnrico Granata ValueObjectPrinter::ShouldPrintValidation () 7990f883ffbSEnrico Granata { 800*26014690SGreg Clayton return m_options.m_run_validator; 8010f883ffbSEnrico Granata } 8020f883ffbSEnrico Granata 8030f883ffbSEnrico Granata bool 8040f883ffbSEnrico Granata ValueObjectPrinter::PrintValidationMarkerIfNeeded () 8050f883ffbSEnrico Granata { 8060f883ffbSEnrico Granata if (!ShouldPrintValidation()) 8070f883ffbSEnrico Granata return false; 8080f883ffbSEnrico Granata 8090f883ffbSEnrico Granata m_validation = m_valobj->GetValidationStatus(); 8100f883ffbSEnrico Granata 8110f883ffbSEnrico Granata if (TypeValidatorResult::Failure == m_validation.first) 8120f883ffbSEnrico Granata { 8130f883ffbSEnrico Granata m_stream->Printf("! "); 8140f883ffbSEnrico Granata return true; 8150f883ffbSEnrico Granata } 8160f883ffbSEnrico Granata 8170f883ffbSEnrico Granata return false; 8180f883ffbSEnrico Granata } 8190f883ffbSEnrico Granata 8200f883ffbSEnrico Granata bool 8210f883ffbSEnrico Granata ValueObjectPrinter::PrintValidationErrorIfNeeded () 8220f883ffbSEnrico Granata { 8230f883ffbSEnrico Granata if (!ShouldPrintValidation()) 8240f883ffbSEnrico Granata return false; 8250f883ffbSEnrico Granata 8260f883ffbSEnrico Granata if (TypeValidatorResult::Success == m_validation.first) 8270f883ffbSEnrico Granata return false; 8280f883ffbSEnrico Granata 8290f883ffbSEnrico Granata if (m_validation.second.empty()) 8300f883ffbSEnrico Granata m_validation.second.assign("unknown error"); 8310f883ffbSEnrico Granata 8320f883ffbSEnrico Granata m_stream->Printf(" ! validation error: %s", m_validation.second.c_str()); 8330f883ffbSEnrico Granata m_stream->EOL(); 8340f883ffbSEnrico Granata 8350f883ffbSEnrico Granata return true; 8360f883ffbSEnrico Granata } 837