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 164d93b8cdSEnrico Granata #include "lldb/Core/Debugger.h" 17a29cb0baSEnrico Granata #include "lldb/DataFormatters/DataVisualization.h" 184d93b8cdSEnrico Granata #include "lldb/Interpreter/CommandInterpreter.h" 194d93b8cdSEnrico Granata #include "lldb/Target/Target.h" 204d93b8cdSEnrico Granata 214d93b8cdSEnrico Granata using namespace lldb; 224d93b8cdSEnrico Granata using namespace lldb_private; 234d93b8cdSEnrico Granata 24d5957336SEnrico Granata DumpValueObjectOptions::DumpValueObjectOptions (ValueObject& valobj) : 25d5957336SEnrico Granata DumpValueObjectOptions() 26d5957336SEnrico Granata { 27d5957336SEnrico Granata m_use_dynamic = valobj.GetDynamicValueType(); 28d5957336SEnrico Granata m_use_synthetic = valobj.IsSynthetic(); 2973e8c4d0SEnrico Granata m_varformat_language = valobj.GetPreferredDisplayLanguage(); 30d5957336SEnrico Granata } 31d5957336SEnrico Granata 32d5957336SEnrico Granata ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, 33d5957336SEnrico Granata Stream* s) 34d5957336SEnrico Granata { 35d5957336SEnrico Granata if (valobj) 36d5957336SEnrico Granata { 37d5957336SEnrico Granata DumpValueObjectOptions options(*valobj); 38d5957336SEnrico Granata Init (valobj,s,options,options.m_max_ptr_depth,0); 39d5957336SEnrico Granata } 40d5957336SEnrico Granata else 41d5957336SEnrico Granata { 42d5957336SEnrico Granata DumpValueObjectOptions options; 43d5957336SEnrico Granata Init (valobj,s,options,options.m_max_ptr_depth,0); 44d5957336SEnrico Granata } 45d5957336SEnrico Granata } 46d5957336SEnrico Granata 474d93b8cdSEnrico Granata ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, 484d93b8cdSEnrico Granata Stream* s, 49938d1d67SEnrico Granata const DumpValueObjectOptions& options) 504d93b8cdSEnrico Granata { 51938d1d67SEnrico Granata Init(valobj,s,options,options.m_max_ptr_depth,0); 524d93b8cdSEnrico Granata } 534d93b8cdSEnrico Granata 544d93b8cdSEnrico Granata ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, 554d93b8cdSEnrico Granata Stream* s, 564d93b8cdSEnrico Granata const DumpValueObjectOptions& options, 57c1b7c09aSEnrico Granata const DumpValueObjectOptions::PointerDepth& ptr_depth, 58938d1d67SEnrico Granata uint32_t curr_depth) 59938d1d67SEnrico Granata { 60938d1d67SEnrico Granata Init(valobj,s,options,ptr_depth,curr_depth); 61938d1d67SEnrico Granata } 62938d1d67SEnrico Granata 63938d1d67SEnrico Granata void 64938d1d67SEnrico Granata ValueObjectPrinter::Init (ValueObject* valobj, 65938d1d67SEnrico Granata Stream* s, 66938d1d67SEnrico Granata const DumpValueObjectOptions& options, 67c1b7c09aSEnrico Granata const DumpValueObjectOptions::PointerDepth& ptr_depth, 68938d1d67SEnrico Granata uint32_t curr_depth) 69938d1d67SEnrico Granata { 70938d1d67SEnrico Granata m_orig_valobj = valobj; 71938d1d67SEnrico Granata m_valobj = nullptr; 72938d1d67SEnrico Granata m_stream = s; 73938d1d67SEnrico Granata this->options = options; 74938d1d67SEnrico Granata m_ptr_depth = ptr_depth; 75938d1d67SEnrico Granata m_curr_depth = curr_depth; 76938d1d67SEnrico Granata assert (m_orig_valobj && "cannot print a NULL ValueObject"); 77938d1d67SEnrico Granata assert (m_stream && "cannot print to a NULL Stream"); 78938d1d67SEnrico Granata m_should_print = eLazyBoolCalculate; 79938d1d67SEnrico Granata m_is_nil = eLazyBoolCalculate; 80938d1d67SEnrico Granata m_is_ptr = eLazyBoolCalculate; 81938d1d67SEnrico Granata m_is_ref = eLazyBoolCalculate; 82938d1d67SEnrico Granata m_is_aggregate = eLazyBoolCalculate; 83938d1d67SEnrico Granata m_summary_formatter = {nullptr,false}; 84938d1d67SEnrico Granata m_value.assign(""); 85938d1d67SEnrico Granata m_summary.assign(""); 86938d1d67SEnrico Granata m_error.assign(""); 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 102*e0ee1e1cSEnrico Granata PrintDecl(); 1034d93b8cdSEnrico Granata } 1044d93b8cdSEnrico Granata 1054d93b8cdSEnrico Granata bool value_printed = false; 1064d93b8cdSEnrico Granata bool summary_printed = false; 1074d93b8cdSEnrico Granata 1084d93b8cdSEnrico Granata bool val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed); 1094d93b8cdSEnrico Granata 1104d93b8cdSEnrico Granata if (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 { 134106260c5SEnrico Granata if (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 { 1474d93b8cdSEnrico Granata if (options.m_use_dynamic != eNoDynamicValues) 1484d93b8cdSEnrico Granata { 1494d93b8cdSEnrico Granata ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(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 { 161d07cfd3aSEnrico Granata if (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 { 170d07cfd3aSEnrico Granata if (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 { 1974d93b8cdSEnrico Granata const char *root_valobj_name = options.m_root_valobj_name.empty() ? 1984d93b8cdSEnrico Granata m_valobj->GetName().AsCString() : 1994d93b8cdSEnrico Granata 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) 207622be238SEnrico Granata m_should_print = (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) 2154d93b8cdSEnrico Granata m_is_nil = m_valobj->IsObjCNil() ? eLazyBoolYes : eLazyBoolNo; 2164d93b8cdSEnrico Granata return m_is_nil == eLazyBoolYes; 2174d93b8cdSEnrico Granata } 2184d93b8cdSEnrico Granata 2194d93b8cdSEnrico Granata bool 2204d93b8cdSEnrico Granata ValueObjectPrinter::IsPtr () 2214d93b8cdSEnrico Granata { 2224d93b8cdSEnrico Granata if (m_is_ptr == eLazyBoolCalculate) 223622be238SEnrico Granata m_is_ptr = m_type_flags.Test (eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo; 2244d93b8cdSEnrico Granata return m_is_ptr == eLazyBoolYes; 2254d93b8cdSEnrico Granata } 2264d93b8cdSEnrico Granata 2274d93b8cdSEnrico Granata bool 2284d93b8cdSEnrico Granata ValueObjectPrinter::IsRef () 2294d93b8cdSEnrico Granata { 2304d93b8cdSEnrico Granata if (m_is_ref == eLazyBoolCalculate) 231622be238SEnrico Granata m_is_ref = m_type_flags.Test (eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo; 2324d93b8cdSEnrico Granata return m_is_ref == eLazyBoolYes; 2334d93b8cdSEnrico Granata } 2344d93b8cdSEnrico Granata 2354d93b8cdSEnrico Granata bool 2364d93b8cdSEnrico Granata ValueObjectPrinter::IsAggregate () 2374d93b8cdSEnrico Granata { 2384d93b8cdSEnrico Granata if (m_is_aggregate == eLazyBoolCalculate) 239622be238SEnrico Granata m_is_aggregate = m_type_flags.Test (eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo; 2404d93b8cdSEnrico Granata return m_is_aggregate == eLazyBoolYes; 2414d93b8cdSEnrico Granata } 2424d93b8cdSEnrico Granata 2434d93b8cdSEnrico Granata bool 2444d93b8cdSEnrico Granata ValueObjectPrinter::PrintLocationIfNeeded () 2454d93b8cdSEnrico Granata { 2464d93b8cdSEnrico Granata if (options.m_show_location) 2474d93b8cdSEnrico Granata { 2484d93b8cdSEnrico Granata m_stream->Printf("%s: ", m_valobj->GetLocationAsCString()); 2494d93b8cdSEnrico Granata return true; 2504d93b8cdSEnrico Granata } 2514d93b8cdSEnrico Granata return false; 2524d93b8cdSEnrico Granata } 2534d93b8cdSEnrico Granata 254*e0ee1e1cSEnrico Granata void 255*e0ee1e1cSEnrico Granata ValueObjectPrinter::PrintDecl () 2564d93b8cdSEnrico Granata { 2574d93b8cdSEnrico Granata bool show_type = true; 2584d93b8cdSEnrico Granata // if we are at the root-level and been asked to hide the root's type, then hide it 2594d93b8cdSEnrico Granata if (m_curr_depth == 0 && options.m_hide_root_type) 2604d93b8cdSEnrico Granata show_type = false; 2614d93b8cdSEnrico Granata else 2624d93b8cdSEnrico Granata // otherwise decide according to the usual rules (asked to show types - always at the root level) 2634d93b8cdSEnrico Granata show_type = options.m_show_types || (m_curr_depth == 0 && !options.m_flat_output); 2644d93b8cdSEnrico Granata 265*e0ee1e1cSEnrico Granata StreamString typeName; 266*e0ee1e1cSEnrico Granata 267*e0ee1e1cSEnrico Granata // always show the type at the root level if it is invalid 2684d93b8cdSEnrico Granata if (show_type) 2694d93b8cdSEnrico Granata { 2704d93b8cdSEnrico Granata // Some ValueObjects don't have types (like registers sets). Only print 2714d93b8cdSEnrico Granata // the type if there is one to print 272a126e462SEnrico Granata ConstString type_name; 273*e0ee1e1cSEnrico Granata if (m_compiler_type.IsValid()) 274*e0ee1e1cSEnrico Granata { 275a126e462SEnrico Granata if (options.m_use_type_display_name) 276a126e462SEnrico Granata type_name = m_valobj->GetDisplayTypeName(); 277e8daa2f8SEnrico Granata else 278a126e462SEnrico Granata type_name = m_valobj->GetQualifiedTypeName(); 2794d93b8cdSEnrico Granata } 280*e0ee1e1cSEnrico Granata else 281*e0ee1e1cSEnrico Granata { 282*e0ee1e1cSEnrico Granata // only show an invalid type name if the user explicitly triggered show_type 283*e0ee1e1cSEnrico Granata if (options.m_show_types) 284*e0ee1e1cSEnrico Granata type_name = ConstString("<invalid type>"); 285*e0ee1e1cSEnrico Granata else 286*e0ee1e1cSEnrico Granata type_name.Clear(); 2874d93b8cdSEnrico Granata } 2884d93b8cdSEnrico Granata 289*e0ee1e1cSEnrico Granata if (type_name) 2904d93b8cdSEnrico Granata { 291*e0ee1e1cSEnrico Granata std::string type_name_str(type_name.GetCString()); 292*e0ee1e1cSEnrico Granata if (options.m_hide_pointer_value) 293*e0ee1e1cSEnrico Granata { 294*e0ee1e1cSEnrico Granata for(auto iter = type_name_str.find(" *"); 295*e0ee1e1cSEnrico Granata iter != std::string::npos; 296*e0ee1e1cSEnrico Granata iter = type_name_str.find(" *")) 297*e0ee1e1cSEnrico Granata { 298*e0ee1e1cSEnrico Granata type_name_str.erase(iter, 2); 299*e0ee1e1cSEnrico Granata } 300*e0ee1e1cSEnrico Granata } 301*e0ee1e1cSEnrico Granata typeName.Printf("(%s)", type_name_str.c_str()); 302*e0ee1e1cSEnrico Granata } 303*e0ee1e1cSEnrico Granata } 304*e0ee1e1cSEnrico Granata 305*e0ee1e1cSEnrico Granata StreamString varName; 306*e0ee1e1cSEnrico Granata 3074d93b8cdSEnrico Granata if (options.m_flat_output) 3084d93b8cdSEnrico Granata { 3094d93b8cdSEnrico Granata // If we are showing types, also qualify the C++ base classes 3104d93b8cdSEnrico Granata const bool qualify_cxx_base_classes = show_type; 3114d93b8cdSEnrico Granata if (!options.m_hide_name) 3124d93b8cdSEnrico Granata { 313*e0ee1e1cSEnrico Granata m_valobj->GetExpressionPath(varName, qualify_cxx_base_classes); 3144d93b8cdSEnrico Granata } 3154d93b8cdSEnrico Granata } 3164d93b8cdSEnrico Granata else if (!options.m_hide_name) 3174d93b8cdSEnrico Granata { 3184d93b8cdSEnrico Granata const char *name_cstr = GetRootNameForDisplay(""); 319*e0ee1e1cSEnrico Granata varName.Printf ("%s", name_cstr); 3204d93b8cdSEnrico Granata } 321*e0ee1e1cSEnrico Granata 322*e0ee1e1cSEnrico Granata bool decl_printed = false; 323*e0ee1e1cSEnrico Granata if (options.m_decl_printing_helper) 324*e0ee1e1cSEnrico Granata { 325*e0ee1e1cSEnrico Granata ConstString type_name_cstr(typeName.GetData()); 326*e0ee1e1cSEnrico Granata ConstString var_name_cstr(varName.GetData()); 327*e0ee1e1cSEnrico Granata 328*e0ee1e1cSEnrico Granata StreamString dest_stream; 329*e0ee1e1cSEnrico Granata if (options.m_decl_printing_helper(type_name_cstr, 330*e0ee1e1cSEnrico Granata var_name_cstr, 331*e0ee1e1cSEnrico Granata options, 332*e0ee1e1cSEnrico Granata dest_stream)) 333*e0ee1e1cSEnrico Granata { 334*e0ee1e1cSEnrico Granata decl_printed = true; 335*e0ee1e1cSEnrico Granata m_stream->Printf("%s", dest_stream.GetData()); 336*e0ee1e1cSEnrico Granata } 337*e0ee1e1cSEnrico Granata } 338*e0ee1e1cSEnrico Granata 339*e0ee1e1cSEnrico Granata if (!decl_printed) 340*e0ee1e1cSEnrico Granata { 341*e0ee1e1cSEnrico Granata if (typeName.GetSize()) 342*e0ee1e1cSEnrico Granata m_stream->Printf("%s ", typeName.GetData()); 343*e0ee1e1cSEnrico Granata if (varName.GetSize()) 344*e0ee1e1cSEnrico Granata m_stream->Printf("%s =", varName.GetData()); 345*e0ee1e1cSEnrico Granata else if (!options.m_hide_name) 346*e0ee1e1cSEnrico Granata m_stream->Printf(" ="); 347*e0ee1e1cSEnrico Granata } 3484d93b8cdSEnrico Granata } 3494d93b8cdSEnrico Granata 3504d93b8cdSEnrico Granata bool 3514d93b8cdSEnrico Granata ValueObjectPrinter::CheckScopeIfNeeded () 3524d93b8cdSEnrico Granata { 3534d93b8cdSEnrico Granata if (options.m_scope_already_checked) 3544d93b8cdSEnrico Granata return true; 3554d93b8cdSEnrico Granata return m_valobj->IsInScope(); 3564d93b8cdSEnrico Granata } 3574d93b8cdSEnrico Granata 3584d93b8cdSEnrico Granata TypeSummaryImpl* 3594d93b8cdSEnrico Granata ValueObjectPrinter::GetSummaryFormatter () 3604d93b8cdSEnrico Granata { 3614d93b8cdSEnrico Granata if (m_summary_formatter.second == false) 3624d93b8cdSEnrico Granata { 3634d93b8cdSEnrico Granata TypeSummaryImpl* entry = options.m_summary_sp ? options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get(); 3644d93b8cdSEnrico Granata 3654d93b8cdSEnrico Granata if (options.m_omit_summary_depth > 0) 3664d93b8cdSEnrico Granata entry = NULL; 3674d93b8cdSEnrico Granata m_summary_formatter.first = entry; 3684d93b8cdSEnrico Granata m_summary_formatter.second = true; 3694d93b8cdSEnrico Granata } 3704d93b8cdSEnrico Granata return m_summary_formatter.first; 3714d93b8cdSEnrico Granata } 3724d93b8cdSEnrico Granata 373*e0ee1e1cSEnrico Granata static bool 374*e0ee1e1cSEnrico Granata IsPointerValue (const CompilerType &type) 375*e0ee1e1cSEnrico Granata { 376*e0ee1e1cSEnrico Granata Flags type_flags(type.GetTypeInfo()); 377*e0ee1e1cSEnrico Granata if (type_flags.AnySet(eTypeIsPointer)) 378*e0ee1e1cSEnrico Granata return type_flags.AllClear(eTypeIsBuiltIn); 379*e0ee1e1cSEnrico Granata return false; 380*e0ee1e1cSEnrico Granata } 381*e0ee1e1cSEnrico Granata 3824d93b8cdSEnrico Granata void 3834d93b8cdSEnrico Granata ValueObjectPrinter::GetValueSummaryError (std::string& value, 3844d93b8cdSEnrico Granata std::string& summary, 3854d93b8cdSEnrico Granata std::string& error) 3864d93b8cdSEnrico Granata { 387465f4bc2SEnrico Granata if (options.m_format != eFormatDefault && options.m_format != m_valobj->GetFormat()) 3884d93b8cdSEnrico Granata { 389465f4bc2SEnrico Granata m_valobj->GetValueAsCString(options.m_format, 390465f4bc2SEnrico Granata value); 3914d93b8cdSEnrico Granata } 392465f4bc2SEnrico Granata else 393465f4bc2SEnrico Granata { 3944d93b8cdSEnrico Granata const char* val_cstr = m_valobj->GetValueAsCString(); 395465f4bc2SEnrico Granata if (val_cstr) 396465f4bc2SEnrico Granata value.assign(val_cstr); 397465f4bc2SEnrico Granata } 3984d93b8cdSEnrico Granata const char* err_cstr = m_valobj->GetError().AsCString(); 3994d93b8cdSEnrico Granata if (err_cstr) 4004d93b8cdSEnrico Granata error.assign(err_cstr); 4014d93b8cdSEnrico Granata 4024d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 4034d93b8cdSEnrico Granata { 4044d93b8cdSEnrico Granata if (IsNil()) 4054d93b8cdSEnrico Granata summary.assign("nil"); 4064d93b8cdSEnrico Granata else if (options.m_omit_summary_depth == 0) 4074d93b8cdSEnrico Granata { 4084d93b8cdSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 4094d93b8cdSEnrico Granata if (entry) 41073e8c4d0SEnrico Granata m_valobj->GetSummaryAsCString(entry, summary, options.m_varformat_language); 4114d93b8cdSEnrico Granata else 4124d93b8cdSEnrico Granata { 41373e8c4d0SEnrico Granata const char* sum_cstr = m_valobj->GetSummaryAsCString(options.m_varformat_language); 4144d93b8cdSEnrico Granata if (sum_cstr) 4154d93b8cdSEnrico Granata summary.assign(sum_cstr); 4164d93b8cdSEnrico Granata } 4174d93b8cdSEnrico Granata } 4184d93b8cdSEnrico Granata } 4194d93b8cdSEnrico Granata } 4204d93b8cdSEnrico Granata 4214d93b8cdSEnrico Granata bool 4224d93b8cdSEnrico Granata ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed, 4234d93b8cdSEnrico Granata bool& summary_printed) 4244d93b8cdSEnrico Granata { 4254d93b8cdSEnrico Granata bool error_printed = false; 4264d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 4274d93b8cdSEnrico Granata { 4284d93b8cdSEnrico Granata if (!CheckScopeIfNeeded()) 4294d93b8cdSEnrico Granata m_error.assign("out of scope"); 4304d93b8cdSEnrico Granata if (m_error.empty()) 4314d93b8cdSEnrico Granata { 4324d93b8cdSEnrico Granata GetValueSummaryError(m_value, m_summary, m_error); 4334d93b8cdSEnrico Granata } 4344d93b8cdSEnrico Granata if (m_error.size()) 4354d93b8cdSEnrico Granata { 4364d93b8cdSEnrico Granata error_printed = true; 4374d93b8cdSEnrico Granata m_stream->Printf (" <%s>\n", m_error.c_str()); 4384d93b8cdSEnrico Granata } 4394d93b8cdSEnrico Granata else 4404d93b8cdSEnrico Granata { 4414d93b8cdSEnrico Granata // Make sure we have a value and make sure the summary didn't 4424d93b8cdSEnrico Granata // specify that the value should not be printed - and do not print 4434d93b8cdSEnrico Granata // the value if this thing is nil 4444d93b8cdSEnrico Granata // (but show the value if the user passes a format explicitly) 4454d93b8cdSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 4468a068e6cSEnrico Granata if (!IsNil() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue(m_valobj) || options.m_format != eFormatDefault) || m_summary.empty()) && !options.m_hide_value) 4474d93b8cdSEnrico Granata { 448*e0ee1e1cSEnrico Granata if (options.m_hide_pointer_value && IsPointerValue(m_valobj->GetCompilerType())) {} 449*e0ee1e1cSEnrico Granata else 450*e0ee1e1cSEnrico Granata { 4514d93b8cdSEnrico Granata m_stream->Printf(" %s", m_value.c_str()); 4524d93b8cdSEnrico Granata value_printed = true; 4534d93b8cdSEnrico Granata } 454*e0ee1e1cSEnrico Granata } 4554d93b8cdSEnrico Granata 4564d93b8cdSEnrico Granata if (m_summary.size()) 4574d93b8cdSEnrico Granata { 4584d93b8cdSEnrico Granata m_stream->Printf(" %s", m_summary.c_str()); 4594d93b8cdSEnrico Granata summary_printed = true; 4604d93b8cdSEnrico Granata } 4614d93b8cdSEnrico Granata } 4624d93b8cdSEnrico Granata } 4634d93b8cdSEnrico Granata return !error_printed; 4644d93b8cdSEnrico Granata } 4654d93b8cdSEnrico Granata 4664d93b8cdSEnrico Granata bool 4674d93b8cdSEnrico Granata ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed, 4684d93b8cdSEnrico Granata bool summary_printed) 4694d93b8cdSEnrico Granata { 4704d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 4714d93b8cdSEnrico Granata { 4724d93b8cdSEnrico Granata // let's avoid the overly verbose no description error for a nil thing 4734d93b8cdSEnrico Granata if (options.m_use_objc && !IsNil()) 4744d93b8cdSEnrico Granata { 4754d93b8cdSEnrico Granata if (!options.m_hide_value || !options.m_hide_name) 4764d93b8cdSEnrico Granata m_stream->Printf(" "); 4774d93b8cdSEnrico Granata const char *object_desc = nullptr; 4784d93b8cdSEnrico Granata if (value_printed || summary_printed) 4794d93b8cdSEnrico Granata object_desc = m_valobj->GetObjectDescription(); 4804d93b8cdSEnrico Granata else 4814d93b8cdSEnrico Granata object_desc = GetDescriptionForDisplay(); 4824d93b8cdSEnrico Granata if (object_desc && *object_desc) 4834d93b8cdSEnrico Granata { 4844d93b8cdSEnrico Granata m_stream->Printf("%s\n", object_desc); 4854d93b8cdSEnrico Granata return true; 4864d93b8cdSEnrico Granata } 4874d93b8cdSEnrico Granata else if (value_printed == false && summary_printed == false) 4884d93b8cdSEnrico Granata return true; 4894d93b8cdSEnrico Granata else 4904d93b8cdSEnrico Granata return false; 4914d93b8cdSEnrico Granata } 4924d93b8cdSEnrico Granata } 4934d93b8cdSEnrico Granata return true; 4944d93b8cdSEnrico Granata } 4954d93b8cdSEnrico Granata 4964d93b8cdSEnrico Granata bool 497c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth::CanAllowExpansion (bool is_root, 498c1b7c09aSEnrico Granata TypeSummaryImpl* entry, 499c1b7c09aSEnrico Granata ValueObject *valobj, 500c1b7c09aSEnrico Granata const std::string& summary) 501c1b7c09aSEnrico Granata { 502c1b7c09aSEnrico Granata switch (m_mode) 503c1b7c09aSEnrico Granata { 504c1b7c09aSEnrico Granata case Mode::Always: 505c1b7c09aSEnrico Granata return (m_count > 0); 506c1b7c09aSEnrico Granata case Mode::Never: 507c1b7c09aSEnrico Granata return false; 508c1b7c09aSEnrico Granata case Mode::Default: 509c1b7c09aSEnrico Granata if (is_root) 510c1b7c09aSEnrico Granata m_count = std::min<decltype(m_count)>(m_count,1); 511c1b7c09aSEnrico Granata return m_count > 0; 512c1b7c09aSEnrico Granata case Mode::Formatters: 513c1b7c09aSEnrico Granata if (!entry || entry->DoesPrintChildren(valobj) || summary.empty()) 514c1b7c09aSEnrico Granata return m_count > 0; 515c1b7c09aSEnrico Granata return false; 516c1b7c09aSEnrico Granata } 51784f5b0dfSZachary Turner return false; 518c1b7c09aSEnrico Granata } 519c1b7c09aSEnrico Granata 520c1b7c09aSEnrico Granata bool 521c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth::CanAllowExpansion () const 522c1b7c09aSEnrico Granata { 523c1b7c09aSEnrico Granata switch (m_mode) 524c1b7c09aSEnrico Granata { 525c1b7c09aSEnrico Granata case Mode::Always: 526c1b7c09aSEnrico Granata case Mode::Default: 527c1b7c09aSEnrico Granata case Mode::Formatters: 528c1b7c09aSEnrico Granata return (m_count > 0); 529c1b7c09aSEnrico Granata case Mode::Never: 530c1b7c09aSEnrico Granata return false; 531c1b7c09aSEnrico Granata } 53284f5b0dfSZachary Turner return false; 533c1b7c09aSEnrico Granata } 534c1b7c09aSEnrico Granata 535c1b7c09aSEnrico Granata bool 5364d93b8cdSEnrico Granata ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description, 537c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 5384d93b8cdSEnrico Granata { 5394d93b8cdSEnrico Granata const bool is_ref = IsRef (); 5404d93b8cdSEnrico Granata const bool is_ptr = IsPtr (); 5414d93b8cdSEnrico Granata 542c1b7c09aSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 543c1b7c09aSEnrico Granata 5444d93b8cdSEnrico Granata if (is_failed_description || m_curr_depth < options.m_max_depth) 5454d93b8cdSEnrico Granata { 5464d93b8cdSEnrico Granata // We will show children for all concrete types. We won't show 5474d93b8cdSEnrico Granata // pointer contents unless a pointer depth has been specified. 5484d93b8cdSEnrico Granata // We won't reference contents unless the reference is the 5494d93b8cdSEnrico Granata // root object (depth of zero). 5504d93b8cdSEnrico Granata 5514d93b8cdSEnrico Granata // Use a new temporary pointer depth in case we override the 5524d93b8cdSEnrico Granata // current pointer depth below... 5534d93b8cdSEnrico Granata 5544d93b8cdSEnrico Granata if (is_ptr || is_ref) 5554d93b8cdSEnrico Granata { 5564d93b8cdSEnrico Granata // We have a pointer or reference whose value is an address. 5574d93b8cdSEnrico Granata // Make sure that address is not NULL 5584d93b8cdSEnrico Granata AddressType ptr_address_type; 5594d93b8cdSEnrico Granata if (m_valobj->GetPointerValue (&ptr_address_type) == 0) 5604d93b8cdSEnrico Granata return false; 5614d93b8cdSEnrico Granata 562c1b7c09aSEnrico Granata const bool is_root_level = m_curr_depth == 0; 563c1b7c09aSEnrico Granata 564c1b7c09aSEnrico Granata if (is_ref && 565c1b7c09aSEnrico Granata is_root_level) 5664d93b8cdSEnrico Granata { 5674d93b8cdSEnrico Granata // If this is the root object (depth is zero) that we are showing 5684d93b8cdSEnrico Granata // and it is a reference, and no pointer depth has been supplied 5694d93b8cdSEnrico Granata // print out what it references. Don't do this at deeper depths 5704d93b8cdSEnrico Granata // otherwise we can end up with infinite recursion... 571c1b7c09aSEnrico Granata return true; 5724d93b8cdSEnrico Granata } 5734d93b8cdSEnrico Granata 574c1b7c09aSEnrico Granata return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, m_summary); 5754d93b8cdSEnrico Granata } 5764d93b8cdSEnrico Granata 5778a068e6cSEnrico Granata return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty()); 5784d93b8cdSEnrico Granata } 5794d93b8cdSEnrico Granata return false; 5804d93b8cdSEnrico Granata } 5814d93b8cdSEnrico Granata 582d26eb907SSiva Chandra bool 583d26eb907SSiva Chandra ValueObjectPrinter::ShouldExpandEmptyAggregates () 584d26eb907SSiva Chandra { 585d26eb907SSiva Chandra TypeSummaryImpl* entry = GetSummaryFormatter(); 586d26eb907SSiva Chandra 587d26eb907SSiva Chandra if (!entry) 588d26eb907SSiva Chandra return true; 589d26eb907SSiva Chandra 590d26eb907SSiva Chandra return entry->DoesPrintEmptyAggregates(); 591d26eb907SSiva Chandra } 592d26eb907SSiva Chandra 5934d93b8cdSEnrico Granata ValueObject* 5944d93b8cdSEnrico Granata ValueObjectPrinter::GetValueObjectForChildrenGeneration () 5954d93b8cdSEnrico Granata { 596d07cfd3aSEnrico Granata return m_valobj; 5974d93b8cdSEnrico Granata } 5984d93b8cdSEnrico Granata 5994d93b8cdSEnrico Granata void 6004d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPreamble () 6014d93b8cdSEnrico Granata { 6024d93b8cdSEnrico Granata if (options.m_flat_output) 6034d93b8cdSEnrico Granata { 6044d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 6054d93b8cdSEnrico Granata m_stream->EOL(); 6064d93b8cdSEnrico Granata } 6074d93b8cdSEnrico Granata else 6084d93b8cdSEnrico Granata { 6094d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 6104d93b8cdSEnrico Granata m_stream->PutCString(IsRef () ? ": {\n" : " {\n"); 6114d93b8cdSEnrico Granata m_stream->IndentMore(); 6124d93b8cdSEnrico Granata } 6134d93b8cdSEnrico Granata } 6144d93b8cdSEnrico Granata 6154d93b8cdSEnrico Granata void 6164d93b8cdSEnrico Granata ValueObjectPrinter::PrintChild (ValueObjectSP child_sp, 617c1b7c09aSEnrico Granata const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 6184d93b8cdSEnrico Granata { 6194d93b8cdSEnrico Granata DumpValueObjectOptions child_options(options); 620443844c4SEnrico Granata child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName(); 6214d93b8cdSEnrico Granata child_options.SetScopeChecked(true).SetHideName(options.m_hide_name).SetHideValue(options.m_hide_value) 6224d93b8cdSEnrico Granata .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0); 6234d93b8cdSEnrico Granata if (child_sp.get()) 6244d93b8cdSEnrico Granata { 6254d93b8cdSEnrico Granata ValueObjectPrinter child_printer(child_sp.get(), 6264d93b8cdSEnrico Granata m_stream, 6274d93b8cdSEnrico Granata child_options, 628c1b7c09aSEnrico Granata (IsPtr() || IsRef()) ? --curr_ptr_depth : curr_ptr_depth, 6294d93b8cdSEnrico Granata m_curr_depth + 1); 6304d93b8cdSEnrico Granata child_printer.PrintValueObject(); 6314d93b8cdSEnrico Granata } 6324d93b8cdSEnrico Granata } 6334d93b8cdSEnrico Granata 6344d93b8cdSEnrico Granata uint32_t 6354d93b8cdSEnrico Granata ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot) 6364d93b8cdSEnrico Granata { 6374d93b8cdSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 6384d93b8cdSEnrico Granata 6394d93b8cdSEnrico Granata size_t num_children = synth_m_valobj->GetNumChildren(); 6404d93b8cdSEnrico Granata print_dotdotdot = false; 6414d93b8cdSEnrico Granata if (num_children) 6424d93b8cdSEnrico Granata { 6434d93b8cdSEnrico Granata const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 6444d93b8cdSEnrico Granata 6454d93b8cdSEnrico Granata if (num_children > max_num_children && !options.m_ignore_cap) 6464d93b8cdSEnrico Granata { 6474d93b8cdSEnrico Granata print_dotdotdot = true; 6484d93b8cdSEnrico Granata return max_num_children; 6494d93b8cdSEnrico Granata } 6504d93b8cdSEnrico Granata } 6514d93b8cdSEnrico Granata return num_children; 6524d93b8cdSEnrico Granata } 6534d93b8cdSEnrico Granata 6544d93b8cdSEnrico Granata void 6554d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot) 6564d93b8cdSEnrico Granata { 6574d93b8cdSEnrico Granata if (!options.m_flat_output) 6584d93b8cdSEnrico Granata { 6594d93b8cdSEnrico Granata if (print_dotdotdot) 6604d93b8cdSEnrico Granata { 6614d93b8cdSEnrico Granata m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated(); 6624d93b8cdSEnrico Granata m_stream->Indent("...\n"); 6634d93b8cdSEnrico Granata } 6644d93b8cdSEnrico Granata m_stream->IndentLess(); 6654d93b8cdSEnrico Granata m_stream->Indent("}\n"); 6664d93b8cdSEnrico Granata } 6674d93b8cdSEnrico Granata } 6684d93b8cdSEnrico Granata 6694d93b8cdSEnrico Granata void 670c1b7c09aSEnrico Granata ValueObjectPrinter::PrintChildren (bool value_printed, 671c1b7c09aSEnrico Granata bool summary_printed, 672c1b7c09aSEnrico Granata const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 6734d93b8cdSEnrico Granata { 6744d93b8cdSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 6754d93b8cdSEnrico Granata 6764d93b8cdSEnrico Granata bool print_dotdotdot = false; 6774d93b8cdSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 6784d93b8cdSEnrico Granata if (num_children) 6794d93b8cdSEnrico Granata { 6804d93b8cdSEnrico Granata PrintChildrenPreamble (); 6814d93b8cdSEnrico Granata 6824d93b8cdSEnrico Granata for (size_t idx=0; idx<num_children; ++idx) 6834d93b8cdSEnrico Granata { 6844d93b8cdSEnrico Granata ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 6854d93b8cdSEnrico Granata PrintChild (child_sp, curr_ptr_depth); 6864d93b8cdSEnrico Granata } 6874d93b8cdSEnrico Granata 6884d93b8cdSEnrico Granata PrintChildrenPostamble (print_dotdotdot); 6894d93b8cdSEnrico Granata } 6904d93b8cdSEnrico Granata else if (IsAggregate()) 6914d93b8cdSEnrico Granata { 6924d93b8cdSEnrico Granata // Aggregate, no children... 6934d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 694d07cfd3aSEnrico Granata { 695d07cfd3aSEnrico Granata // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value 696d26eb907SSiva Chandra if (m_valobj->DoesProvideSyntheticValue() || !ShouldExpandEmptyAggregates()) 697d07cfd3aSEnrico Granata m_stream->PutCString( "\n"); 698d07cfd3aSEnrico Granata else 6994d93b8cdSEnrico Granata m_stream->PutCString(" {}\n"); 7004d93b8cdSEnrico Granata } 701d07cfd3aSEnrico Granata } 7024d93b8cdSEnrico Granata else 7034d93b8cdSEnrico Granata { 7044d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 7054d93b8cdSEnrico Granata m_stream->EOL(); 7064d93b8cdSEnrico Granata } 7074d93b8cdSEnrico Granata } 7084d93b8cdSEnrico Granata 709a29cb0baSEnrico Granata bool 710a29cb0baSEnrico Granata ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names) 711a29cb0baSEnrico Granata { 712d07cfd3aSEnrico Granata if (!GetMostSpecializedValue () || m_valobj == nullptr) 713a29cb0baSEnrico Granata return false; 714a29cb0baSEnrico Granata 715a29cb0baSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 716a29cb0baSEnrico Granata 717a29cb0baSEnrico Granata bool print_dotdotdot = false; 718a29cb0baSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 719a29cb0baSEnrico Granata 720a29cb0baSEnrico Granata if (num_children) 721a29cb0baSEnrico Granata { 722a29cb0baSEnrico Granata m_stream->PutChar('('); 723a29cb0baSEnrico Granata 724a29cb0baSEnrico Granata for (uint32_t idx=0; idx<num_children; ++idx) 725a29cb0baSEnrico Granata { 726a29cb0baSEnrico Granata lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 727ddac7611SEnrico Granata if (child_sp) 728ddac7611SEnrico Granata child_sp = child_sp->GetQualifiedRepresentationIfAvailable(options.m_use_dynamic, options.m_use_synthetic); 729a29cb0baSEnrico Granata if (child_sp) 730a29cb0baSEnrico Granata { 731a29cb0baSEnrico Granata if (idx) 732a29cb0baSEnrico Granata m_stream->PutCString(", "); 733a29cb0baSEnrico Granata if (!hide_names) 734a29cb0baSEnrico Granata { 735a29cb0baSEnrico Granata const char* name = child_sp.get()->GetName().AsCString(); 736a29cb0baSEnrico Granata if (name && *name) 737a29cb0baSEnrico Granata { 738a29cb0baSEnrico Granata m_stream->PutCString(name); 739a29cb0baSEnrico Granata m_stream->PutCString(" = "); 740a29cb0baSEnrico Granata } 741a29cb0baSEnrico Granata } 742a29cb0baSEnrico Granata child_sp->DumpPrintableRepresentation(*m_stream, 743a29cb0baSEnrico Granata ValueObject::eValueObjectRepresentationStyleSummary, 744443844c4SEnrico Granata lldb::eFormatInvalid, 745a29cb0baSEnrico Granata ValueObject::ePrintableRepresentationSpecialCasesDisable); 746a29cb0baSEnrico Granata } 747a29cb0baSEnrico Granata } 748a29cb0baSEnrico Granata 749a29cb0baSEnrico Granata if (print_dotdotdot) 750a29cb0baSEnrico Granata m_stream->PutCString(", ...)"); 751a29cb0baSEnrico Granata else 752a29cb0baSEnrico Granata m_stream->PutChar(')'); 753a29cb0baSEnrico Granata } 754a29cb0baSEnrico Granata return true; 755a29cb0baSEnrico Granata } 756a29cb0baSEnrico Granata 7574d93b8cdSEnrico Granata void 7584d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed, 7594d93b8cdSEnrico Granata bool summary_printed) 7604d93b8cdSEnrico Granata { 7614d93b8cdSEnrico Granata // this flag controls whether we tried to display a description for this object and failed 7624d93b8cdSEnrico Granata // if that happens, we want to display the children, if any 7634d93b8cdSEnrico Granata bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed); 7644d93b8cdSEnrico Granata 765c1b7c09aSEnrico Granata auto curr_ptr_depth = m_ptr_depth; 7664d93b8cdSEnrico Granata bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth); 767c1b7c09aSEnrico Granata bool print_oneline = (curr_ptr_depth.CanAllowExpansion() || 7683fa6dc90SEnrico Granata options.m_show_types || 7693fa6dc90SEnrico Granata !options.m_allow_oneliner_mode || 7703fa6dc90SEnrico Granata options.m_flat_output || 7713fa6dc90SEnrico Granata options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj); 7724d93b8cdSEnrico Granata 7734d93b8cdSEnrico Granata if (print_children) 7744d93b8cdSEnrico Granata { 775a29cb0baSEnrico Granata if (print_oneline) 776a29cb0baSEnrico Granata { 777a29cb0baSEnrico Granata m_stream->PutChar(' '); 778a29cb0baSEnrico Granata PrintChildrenOneLiner (false); 779a29cb0baSEnrico Granata m_stream->EOL(); 780a29cb0baSEnrico Granata } 781a29cb0baSEnrico Granata else 782c1b7c09aSEnrico Granata PrintChildren (value_printed, summary_printed, curr_ptr_depth); 7834d93b8cdSEnrico Granata } 7844d93b8cdSEnrico Granata else if (m_curr_depth >= options.m_max_depth && IsAggregate() && ShouldPrintValueObject()) 7854d93b8cdSEnrico Granata { 7864d93b8cdSEnrico Granata m_stream->PutCString("{...}\n"); 7874d93b8cdSEnrico Granata } 788245b3caaSEnrico Granata else 789245b3caaSEnrico Granata m_stream->EOL(); 7904d93b8cdSEnrico Granata } 7910f883ffbSEnrico Granata 7920f883ffbSEnrico Granata bool 7930f883ffbSEnrico Granata ValueObjectPrinter::ShouldPrintValidation () 7940f883ffbSEnrico Granata { 7950f883ffbSEnrico Granata return options.m_run_validator; 7960f883ffbSEnrico Granata } 7970f883ffbSEnrico Granata 7980f883ffbSEnrico Granata bool 7990f883ffbSEnrico Granata ValueObjectPrinter::PrintValidationMarkerIfNeeded () 8000f883ffbSEnrico Granata { 8010f883ffbSEnrico Granata if (!ShouldPrintValidation()) 8020f883ffbSEnrico Granata return false; 8030f883ffbSEnrico Granata 8040f883ffbSEnrico Granata m_validation = m_valobj->GetValidationStatus(); 8050f883ffbSEnrico Granata 8060f883ffbSEnrico Granata if (TypeValidatorResult::Failure == m_validation.first) 8070f883ffbSEnrico Granata { 8080f883ffbSEnrico Granata m_stream->Printf("! "); 8090f883ffbSEnrico Granata return true; 8100f883ffbSEnrico Granata } 8110f883ffbSEnrico Granata 8120f883ffbSEnrico Granata return false; 8130f883ffbSEnrico Granata } 8140f883ffbSEnrico Granata 8150f883ffbSEnrico Granata bool 8160f883ffbSEnrico Granata ValueObjectPrinter::PrintValidationErrorIfNeeded () 8170f883ffbSEnrico Granata { 8180f883ffbSEnrico Granata if (!ShouldPrintValidation()) 8190f883ffbSEnrico Granata return false; 8200f883ffbSEnrico Granata 8210f883ffbSEnrico Granata if (TypeValidatorResult::Success == m_validation.first) 8220f883ffbSEnrico Granata return false; 8230f883ffbSEnrico Granata 8240f883ffbSEnrico Granata if (m_validation.second.empty()) 8250f883ffbSEnrico Granata m_validation.second.assign("unknown error"); 8260f883ffbSEnrico Granata 8270f883ffbSEnrico Granata m_stream->Printf(" ! validation error: %s", m_validation.second.c_str()); 8280f883ffbSEnrico Granata m_stream->EOL(); 8290f883ffbSEnrico Granata 8300f883ffbSEnrico Granata return true; 8310f883ffbSEnrico Granata } 832