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(); 29*73e8c4d0SEnrico 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 1024d93b8cdSEnrico Granata bool show_type = PrintTypeIfNeeded(); 1034d93b8cdSEnrico Granata 1044d93b8cdSEnrico Granata PrintNameIfNeeded(show_type); 1054d93b8cdSEnrico Granata } 1064d93b8cdSEnrico Granata 1074d93b8cdSEnrico Granata bool value_printed = false; 1084d93b8cdSEnrico Granata bool summary_printed = false; 1094d93b8cdSEnrico Granata 1104d93b8cdSEnrico Granata bool val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed); 1114d93b8cdSEnrico Granata 1124d93b8cdSEnrico Granata if (val_summary_ok) 1134d93b8cdSEnrico Granata PrintChildrenIfNeeded (value_printed, summary_printed); 11439938938SEnrico Granata else 1154d93b8cdSEnrico Granata m_stream->EOL(); 1164d93b8cdSEnrico Granata 1170f883ffbSEnrico Granata PrintValidationErrorIfNeeded(); 1180f883ffbSEnrico Granata 1194d93b8cdSEnrico Granata return true; 1204d93b8cdSEnrico Granata } 1214d93b8cdSEnrico Granata 1224d93b8cdSEnrico Granata bool 123d07cfd3aSEnrico Granata ValueObjectPrinter::GetMostSpecializedValue () 1244d93b8cdSEnrico Granata { 125a29cb0baSEnrico Granata if (m_valobj) 126a29cb0baSEnrico Granata return true; 1274d93b8cdSEnrico Granata bool update_success = m_orig_valobj->UpdateValueIfNeeded (true); 1284d93b8cdSEnrico Granata if (!update_success) 129106260c5SEnrico Granata { 130106260c5SEnrico Granata m_valobj = m_orig_valobj; 131106260c5SEnrico Granata } 132106260c5SEnrico Granata else 133106260c5SEnrico Granata { 134106260c5SEnrico Granata if (m_orig_valobj->IsDynamic()) 135106260c5SEnrico Granata { 136106260c5SEnrico Granata if (options.m_use_dynamic == eNoDynamicValues) 137106260c5SEnrico Granata { 138106260c5SEnrico Granata ValueObject *static_value = m_orig_valobj->GetStaticValue().get(); 139106260c5SEnrico Granata if (static_value) 140106260c5SEnrico Granata m_valobj = static_value; 141106260c5SEnrico Granata else 142106260c5SEnrico Granata m_valobj = m_orig_valobj; 143106260c5SEnrico Granata } 144106260c5SEnrico Granata else 145106260c5SEnrico Granata m_valobj = m_orig_valobj; 146106260c5SEnrico Granata } 147106260c5SEnrico Granata else 148106260c5SEnrico Granata { 1494d93b8cdSEnrico Granata if (options.m_use_dynamic != eNoDynamicValues) 1504d93b8cdSEnrico Granata { 1514d93b8cdSEnrico Granata ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(options.m_use_dynamic).get(); 1524d93b8cdSEnrico Granata if (dynamic_value) 1534d93b8cdSEnrico Granata m_valobj = dynamic_value; 1544d93b8cdSEnrico Granata else 1554d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 1564d93b8cdSEnrico Granata } 1574d93b8cdSEnrico Granata else 1584d93b8cdSEnrico Granata m_valobj = m_orig_valobj; 159106260c5SEnrico Granata } 160d07cfd3aSEnrico Granata 161d07cfd3aSEnrico Granata if (m_valobj->IsSynthetic()) 162d07cfd3aSEnrico Granata { 163d07cfd3aSEnrico Granata if (options.m_use_synthetic == false) 164d07cfd3aSEnrico Granata { 165d07cfd3aSEnrico Granata ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get(); 166d07cfd3aSEnrico Granata if (non_synthetic) 167d07cfd3aSEnrico Granata m_valobj = non_synthetic; 168d07cfd3aSEnrico Granata } 169d07cfd3aSEnrico Granata } 170d07cfd3aSEnrico Granata else 171d07cfd3aSEnrico Granata { 172d07cfd3aSEnrico Granata if (options.m_use_synthetic == true) 173d07cfd3aSEnrico Granata { 174d07cfd3aSEnrico Granata ValueObject *synthetic = m_valobj->GetSyntheticValue().get(); 175d07cfd3aSEnrico Granata if (synthetic) 176d07cfd3aSEnrico Granata m_valobj = synthetic; 177d07cfd3aSEnrico Granata } 178d07cfd3aSEnrico Granata } 179106260c5SEnrico Granata } 18059b5a37dSBruce Mitchener m_compiler_type = m_valobj->GetCompilerType(); 18159b5a37dSBruce Mitchener m_type_flags = m_compiler_type.GetTypeInfo (); 1824d93b8cdSEnrico Granata return true; 1834d93b8cdSEnrico Granata } 1844d93b8cdSEnrico Granata 1854d93b8cdSEnrico Granata const char* 1864d93b8cdSEnrico Granata ValueObjectPrinter::GetDescriptionForDisplay () 1874d93b8cdSEnrico Granata { 1884d93b8cdSEnrico Granata const char* str = m_valobj->GetObjectDescription(); 1894d93b8cdSEnrico Granata if (!str) 1904d93b8cdSEnrico Granata str = m_valobj->GetSummaryAsCString(); 1914d93b8cdSEnrico Granata if (!str) 1924d93b8cdSEnrico Granata str = m_valobj->GetValueAsCString(); 1934d93b8cdSEnrico Granata return str; 1944d93b8cdSEnrico Granata } 1954d93b8cdSEnrico Granata 1964d93b8cdSEnrico Granata const char* 1974d93b8cdSEnrico Granata ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail) 1984d93b8cdSEnrico Granata { 1994d93b8cdSEnrico Granata const char *root_valobj_name = options.m_root_valobj_name.empty() ? 2004d93b8cdSEnrico Granata m_valobj->GetName().AsCString() : 2014d93b8cdSEnrico Granata options.m_root_valobj_name.c_str(); 2024d93b8cdSEnrico Granata return root_valobj_name ? root_valobj_name : if_fail; 2034d93b8cdSEnrico Granata } 2044d93b8cdSEnrico Granata 2054d93b8cdSEnrico Granata bool 2064d93b8cdSEnrico Granata ValueObjectPrinter::ShouldPrintValueObject () 2074d93b8cdSEnrico Granata { 2084d93b8cdSEnrico Granata if (m_should_print == eLazyBoolCalculate) 209622be238SEnrico Granata m_should_print = (options.m_flat_output == false || m_type_flags.Test (eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo; 2104d93b8cdSEnrico Granata return m_should_print == eLazyBoolYes; 2114d93b8cdSEnrico Granata } 2124d93b8cdSEnrico Granata 2134d93b8cdSEnrico Granata bool 2144d93b8cdSEnrico Granata ValueObjectPrinter::IsNil () 2154d93b8cdSEnrico Granata { 2164d93b8cdSEnrico Granata if (m_is_nil == eLazyBoolCalculate) 2174d93b8cdSEnrico Granata m_is_nil = m_valobj->IsObjCNil() ? eLazyBoolYes : eLazyBoolNo; 2184d93b8cdSEnrico Granata return m_is_nil == eLazyBoolYes; 2194d93b8cdSEnrico Granata } 2204d93b8cdSEnrico Granata 2214d93b8cdSEnrico Granata bool 2224d93b8cdSEnrico Granata ValueObjectPrinter::IsPtr () 2234d93b8cdSEnrico Granata { 2244d93b8cdSEnrico Granata if (m_is_ptr == eLazyBoolCalculate) 225622be238SEnrico Granata m_is_ptr = m_type_flags.Test (eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo; 2264d93b8cdSEnrico Granata return m_is_ptr == eLazyBoolYes; 2274d93b8cdSEnrico Granata } 2284d93b8cdSEnrico Granata 2294d93b8cdSEnrico Granata bool 2304d93b8cdSEnrico Granata ValueObjectPrinter::IsRef () 2314d93b8cdSEnrico Granata { 2324d93b8cdSEnrico Granata if (m_is_ref == eLazyBoolCalculate) 233622be238SEnrico Granata m_is_ref = m_type_flags.Test (eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo; 2344d93b8cdSEnrico Granata return m_is_ref == eLazyBoolYes; 2354d93b8cdSEnrico Granata } 2364d93b8cdSEnrico Granata 2374d93b8cdSEnrico Granata bool 2384d93b8cdSEnrico Granata ValueObjectPrinter::IsAggregate () 2394d93b8cdSEnrico Granata { 2404d93b8cdSEnrico Granata if (m_is_aggregate == eLazyBoolCalculate) 241622be238SEnrico Granata m_is_aggregate = m_type_flags.Test (eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo; 2424d93b8cdSEnrico Granata return m_is_aggregate == eLazyBoolYes; 2434d93b8cdSEnrico Granata } 2444d93b8cdSEnrico Granata 2454d93b8cdSEnrico Granata bool 2464d93b8cdSEnrico Granata ValueObjectPrinter::PrintLocationIfNeeded () 2474d93b8cdSEnrico Granata { 2484d93b8cdSEnrico Granata if (options.m_show_location) 2494d93b8cdSEnrico Granata { 2504d93b8cdSEnrico Granata m_stream->Printf("%s: ", m_valobj->GetLocationAsCString()); 2514d93b8cdSEnrico Granata return true; 2524d93b8cdSEnrico Granata } 2534d93b8cdSEnrico Granata return false; 2544d93b8cdSEnrico Granata } 2554d93b8cdSEnrico Granata 2564d93b8cdSEnrico Granata bool 2574d93b8cdSEnrico Granata ValueObjectPrinter::PrintTypeIfNeeded () 2584d93b8cdSEnrico Granata { 2594d93b8cdSEnrico Granata bool show_type = true; 2604d93b8cdSEnrico Granata // if we are at the root-level and been asked to hide the root's type, then hide it 2614d93b8cdSEnrico Granata if (m_curr_depth == 0 && options.m_hide_root_type) 2624d93b8cdSEnrico Granata show_type = false; 2634d93b8cdSEnrico Granata else 2644d93b8cdSEnrico Granata // otherwise decide according to the usual rules (asked to show types - always at the root level) 2654d93b8cdSEnrico Granata show_type = options.m_show_types || (m_curr_depth == 0 && !options.m_flat_output); 2664d93b8cdSEnrico Granata 2674d93b8cdSEnrico Granata if (show_type) 2684d93b8cdSEnrico Granata { 2694d93b8cdSEnrico Granata // Some ValueObjects don't have types (like registers sets). Only print 2704d93b8cdSEnrico Granata // the type if there is one to print 271a126e462SEnrico Granata ConstString type_name; 272a126e462SEnrico Granata if (options.m_use_type_display_name) 273a126e462SEnrico Granata type_name = m_valobj->GetDisplayTypeName(); 274e8daa2f8SEnrico Granata else 275a126e462SEnrico Granata type_name = m_valobj->GetQualifiedTypeName(); 276a126e462SEnrico Granata if (type_name) 277a126e462SEnrico Granata m_stream->Printf("(%s) ", type_name.GetCString()); 2784d93b8cdSEnrico Granata else 2794d93b8cdSEnrico Granata show_type = false; 2804d93b8cdSEnrico Granata } 2814d93b8cdSEnrico Granata return show_type; 2824d93b8cdSEnrico Granata } 2834d93b8cdSEnrico Granata 2844d93b8cdSEnrico Granata bool 2854d93b8cdSEnrico Granata ValueObjectPrinter::PrintNameIfNeeded (bool show_type) 2864d93b8cdSEnrico Granata { 2874d93b8cdSEnrico Granata if (options.m_flat_output) 2884d93b8cdSEnrico Granata { 2894d93b8cdSEnrico Granata // If we are showing types, also qualify the C++ base classes 2904d93b8cdSEnrico Granata const bool qualify_cxx_base_classes = show_type; 2914d93b8cdSEnrico Granata if (!options.m_hide_name) 2924d93b8cdSEnrico Granata { 2934d93b8cdSEnrico Granata m_valobj->GetExpressionPath(*m_stream, qualify_cxx_base_classes); 2944d93b8cdSEnrico Granata m_stream->PutCString(" ="); 2954d93b8cdSEnrico Granata return true; 2964d93b8cdSEnrico Granata } 2974d93b8cdSEnrico Granata } 2984d93b8cdSEnrico Granata else if (!options.m_hide_name) 2994d93b8cdSEnrico Granata { 3004d93b8cdSEnrico Granata const char *name_cstr = GetRootNameForDisplay(""); 3014d93b8cdSEnrico Granata m_stream->Printf ("%s =", name_cstr); 3024d93b8cdSEnrico Granata return true; 3034d93b8cdSEnrico Granata } 3044d93b8cdSEnrico Granata return false; 3054d93b8cdSEnrico Granata } 3064d93b8cdSEnrico Granata 3074d93b8cdSEnrico Granata bool 3084d93b8cdSEnrico Granata ValueObjectPrinter::CheckScopeIfNeeded () 3094d93b8cdSEnrico Granata { 3104d93b8cdSEnrico Granata if (options.m_scope_already_checked) 3114d93b8cdSEnrico Granata return true; 3124d93b8cdSEnrico Granata return m_valobj->IsInScope(); 3134d93b8cdSEnrico Granata } 3144d93b8cdSEnrico Granata 3154d93b8cdSEnrico Granata TypeSummaryImpl* 3164d93b8cdSEnrico Granata ValueObjectPrinter::GetSummaryFormatter () 3174d93b8cdSEnrico Granata { 3184d93b8cdSEnrico Granata if (m_summary_formatter.second == false) 3194d93b8cdSEnrico Granata { 3204d93b8cdSEnrico Granata TypeSummaryImpl* entry = options.m_summary_sp ? options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get(); 3214d93b8cdSEnrico Granata 3224d93b8cdSEnrico Granata if (options.m_omit_summary_depth > 0) 3234d93b8cdSEnrico Granata entry = NULL; 3244d93b8cdSEnrico Granata m_summary_formatter.first = entry; 3254d93b8cdSEnrico Granata m_summary_formatter.second = true; 3264d93b8cdSEnrico Granata } 3274d93b8cdSEnrico Granata return m_summary_formatter.first; 3284d93b8cdSEnrico Granata } 3294d93b8cdSEnrico Granata 3304d93b8cdSEnrico Granata void 3314d93b8cdSEnrico Granata ValueObjectPrinter::GetValueSummaryError (std::string& value, 3324d93b8cdSEnrico Granata std::string& summary, 3334d93b8cdSEnrico Granata std::string& error) 3344d93b8cdSEnrico Granata { 335465f4bc2SEnrico Granata if (options.m_format != eFormatDefault && options.m_format != m_valobj->GetFormat()) 3364d93b8cdSEnrico Granata { 337465f4bc2SEnrico Granata m_valobj->GetValueAsCString(options.m_format, 338465f4bc2SEnrico Granata value); 3394d93b8cdSEnrico Granata } 340465f4bc2SEnrico Granata else 341465f4bc2SEnrico Granata { 3424d93b8cdSEnrico Granata const char* val_cstr = m_valobj->GetValueAsCString(); 343465f4bc2SEnrico Granata if (val_cstr) 344465f4bc2SEnrico Granata value.assign(val_cstr); 345465f4bc2SEnrico Granata } 3464d93b8cdSEnrico Granata const char* err_cstr = m_valobj->GetError().AsCString(); 3474d93b8cdSEnrico Granata if (err_cstr) 3484d93b8cdSEnrico Granata error.assign(err_cstr); 3494d93b8cdSEnrico Granata 3504d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 3514d93b8cdSEnrico Granata { 3524d93b8cdSEnrico Granata if (IsNil()) 3534d93b8cdSEnrico Granata summary.assign("nil"); 3544d93b8cdSEnrico Granata else if (options.m_omit_summary_depth == 0) 3554d93b8cdSEnrico Granata { 3564d93b8cdSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 3574d93b8cdSEnrico Granata if (entry) 358*73e8c4d0SEnrico Granata m_valobj->GetSummaryAsCString(entry, summary, options.m_varformat_language); 3594d93b8cdSEnrico Granata else 3604d93b8cdSEnrico Granata { 361*73e8c4d0SEnrico Granata const char* sum_cstr = m_valobj->GetSummaryAsCString(options.m_varformat_language); 3624d93b8cdSEnrico Granata if (sum_cstr) 3634d93b8cdSEnrico Granata summary.assign(sum_cstr); 3644d93b8cdSEnrico Granata } 3654d93b8cdSEnrico Granata } 3664d93b8cdSEnrico Granata } 3674d93b8cdSEnrico Granata } 3684d93b8cdSEnrico Granata 3694d93b8cdSEnrico Granata bool 3704d93b8cdSEnrico Granata ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed, 3714d93b8cdSEnrico Granata bool& summary_printed) 3724d93b8cdSEnrico Granata { 3734d93b8cdSEnrico Granata bool error_printed = false; 3744d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 3754d93b8cdSEnrico Granata { 3764d93b8cdSEnrico Granata if (!CheckScopeIfNeeded()) 3774d93b8cdSEnrico Granata m_error.assign("out of scope"); 3784d93b8cdSEnrico Granata if (m_error.empty()) 3794d93b8cdSEnrico Granata { 3804d93b8cdSEnrico Granata GetValueSummaryError(m_value, m_summary, m_error); 3814d93b8cdSEnrico Granata } 3824d93b8cdSEnrico Granata if (m_error.size()) 3834d93b8cdSEnrico Granata { 3844d93b8cdSEnrico Granata error_printed = true; 3854d93b8cdSEnrico Granata m_stream->Printf (" <%s>\n", m_error.c_str()); 3864d93b8cdSEnrico Granata } 3874d93b8cdSEnrico Granata else 3884d93b8cdSEnrico Granata { 3894d93b8cdSEnrico Granata // Make sure we have a value and make sure the summary didn't 3904d93b8cdSEnrico Granata // specify that the value should not be printed - and do not print 3914d93b8cdSEnrico Granata // the value if this thing is nil 3924d93b8cdSEnrico Granata // (but show the value if the user passes a format explicitly) 3934d93b8cdSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 3948a068e6cSEnrico Granata if (!IsNil() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue(m_valobj) || options.m_format != eFormatDefault) || m_summary.empty()) && !options.m_hide_value) 3954d93b8cdSEnrico Granata { 3964d93b8cdSEnrico Granata m_stream->Printf(" %s", m_value.c_str()); 3974d93b8cdSEnrico Granata value_printed = true; 3984d93b8cdSEnrico Granata } 3994d93b8cdSEnrico Granata 4004d93b8cdSEnrico Granata if (m_summary.size()) 4014d93b8cdSEnrico Granata { 4024d93b8cdSEnrico Granata m_stream->Printf(" %s", m_summary.c_str()); 4034d93b8cdSEnrico Granata summary_printed = true; 4044d93b8cdSEnrico Granata } 4054d93b8cdSEnrico Granata } 4064d93b8cdSEnrico Granata } 4074d93b8cdSEnrico Granata return !error_printed; 4084d93b8cdSEnrico Granata } 4094d93b8cdSEnrico Granata 4104d93b8cdSEnrico Granata bool 4114d93b8cdSEnrico Granata ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed, 4124d93b8cdSEnrico Granata bool summary_printed) 4134d93b8cdSEnrico Granata { 4144d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 4154d93b8cdSEnrico Granata { 4164d93b8cdSEnrico Granata // let's avoid the overly verbose no description error for a nil thing 4174d93b8cdSEnrico Granata if (options.m_use_objc && !IsNil()) 4184d93b8cdSEnrico Granata { 4194d93b8cdSEnrico Granata if (!options.m_hide_value || !options.m_hide_name) 4204d93b8cdSEnrico Granata m_stream->Printf(" "); 4214d93b8cdSEnrico Granata const char *object_desc = nullptr; 4224d93b8cdSEnrico Granata if (value_printed || summary_printed) 4234d93b8cdSEnrico Granata object_desc = m_valobj->GetObjectDescription(); 4244d93b8cdSEnrico Granata else 4254d93b8cdSEnrico Granata object_desc = GetDescriptionForDisplay(); 4264d93b8cdSEnrico Granata if (object_desc && *object_desc) 4274d93b8cdSEnrico Granata { 4284d93b8cdSEnrico Granata m_stream->Printf("%s\n", object_desc); 4294d93b8cdSEnrico Granata return true; 4304d93b8cdSEnrico Granata } 4314d93b8cdSEnrico Granata else if (value_printed == false && summary_printed == false) 4324d93b8cdSEnrico Granata return true; 4334d93b8cdSEnrico Granata else 4344d93b8cdSEnrico Granata return false; 4354d93b8cdSEnrico Granata } 4364d93b8cdSEnrico Granata } 4374d93b8cdSEnrico Granata return true; 4384d93b8cdSEnrico Granata } 4394d93b8cdSEnrico Granata 4404d93b8cdSEnrico Granata bool 441c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth::CanAllowExpansion (bool is_root, 442c1b7c09aSEnrico Granata TypeSummaryImpl* entry, 443c1b7c09aSEnrico Granata ValueObject *valobj, 444c1b7c09aSEnrico Granata const std::string& summary) 445c1b7c09aSEnrico Granata { 446c1b7c09aSEnrico Granata switch (m_mode) 447c1b7c09aSEnrico Granata { 448c1b7c09aSEnrico Granata case Mode::Always: 449c1b7c09aSEnrico Granata return (m_count > 0); 450c1b7c09aSEnrico Granata case Mode::Never: 451c1b7c09aSEnrico Granata return false; 452c1b7c09aSEnrico Granata case Mode::Default: 453c1b7c09aSEnrico Granata if (is_root) 454c1b7c09aSEnrico Granata m_count = std::min<decltype(m_count)>(m_count,1); 455c1b7c09aSEnrico Granata return m_count > 0; 456c1b7c09aSEnrico Granata case Mode::Formatters: 457c1b7c09aSEnrico Granata if (!entry || entry->DoesPrintChildren(valobj) || summary.empty()) 458c1b7c09aSEnrico Granata return m_count > 0; 459c1b7c09aSEnrico Granata return false; 460c1b7c09aSEnrico Granata } 46184f5b0dfSZachary Turner return false; 462c1b7c09aSEnrico Granata } 463c1b7c09aSEnrico Granata 464c1b7c09aSEnrico Granata bool 465c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth::CanAllowExpansion () const 466c1b7c09aSEnrico Granata { 467c1b7c09aSEnrico Granata switch (m_mode) 468c1b7c09aSEnrico Granata { 469c1b7c09aSEnrico Granata case Mode::Always: 470c1b7c09aSEnrico Granata case Mode::Default: 471c1b7c09aSEnrico Granata case Mode::Formatters: 472c1b7c09aSEnrico Granata return (m_count > 0); 473c1b7c09aSEnrico Granata case Mode::Never: 474c1b7c09aSEnrico Granata return false; 475c1b7c09aSEnrico Granata } 47684f5b0dfSZachary Turner return false; 477c1b7c09aSEnrico Granata } 478c1b7c09aSEnrico Granata 479c1b7c09aSEnrico Granata bool 4804d93b8cdSEnrico Granata ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description, 481c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 4824d93b8cdSEnrico Granata { 4834d93b8cdSEnrico Granata const bool is_ref = IsRef (); 4844d93b8cdSEnrico Granata const bool is_ptr = IsPtr (); 4854d93b8cdSEnrico Granata 486c1b7c09aSEnrico Granata TypeSummaryImpl* entry = GetSummaryFormatter(); 487c1b7c09aSEnrico Granata 4884d93b8cdSEnrico Granata if (is_failed_description || m_curr_depth < options.m_max_depth) 4894d93b8cdSEnrico Granata { 4904d93b8cdSEnrico Granata // We will show children for all concrete types. We won't show 4914d93b8cdSEnrico Granata // pointer contents unless a pointer depth has been specified. 4924d93b8cdSEnrico Granata // We won't reference contents unless the reference is the 4934d93b8cdSEnrico Granata // root object (depth of zero). 4944d93b8cdSEnrico Granata 4954d93b8cdSEnrico Granata // Use a new temporary pointer depth in case we override the 4964d93b8cdSEnrico Granata // current pointer depth below... 4974d93b8cdSEnrico Granata 4984d93b8cdSEnrico Granata if (is_ptr || is_ref) 4994d93b8cdSEnrico Granata { 5004d93b8cdSEnrico Granata // We have a pointer or reference whose value is an address. 5014d93b8cdSEnrico Granata // Make sure that address is not NULL 5024d93b8cdSEnrico Granata AddressType ptr_address_type; 5034d93b8cdSEnrico Granata if (m_valobj->GetPointerValue (&ptr_address_type) == 0) 5044d93b8cdSEnrico Granata return false; 5054d93b8cdSEnrico Granata 506c1b7c09aSEnrico Granata const bool is_root_level = m_curr_depth == 0; 507c1b7c09aSEnrico Granata 508c1b7c09aSEnrico Granata if (is_ref && 509c1b7c09aSEnrico Granata is_root_level) 5104d93b8cdSEnrico Granata { 5114d93b8cdSEnrico Granata // If this is the root object (depth is zero) that we are showing 5124d93b8cdSEnrico Granata // and it is a reference, and no pointer depth has been supplied 5134d93b8cdSEnrico Granata // print out what it references. Don't do this at deeper depths 5144d93b8cdSEnrico Granata // otherwise we can end up with infinite recursion... 515c1b7c09aSEnrico Granata return true; 5164d93b8cdSEnrico Granata } 5174d93b8cdSEnrico Granata 518c1b7c09aSEnrico Granata return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, m_summary); 5194d93b8cdSEnrico Granata } 5204d93b8cdSEnrico Granata 5218a068e6cSEnrico Granata return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty()); 5224d93b8cdSEnrico Granata } 5234d93b8cdSEnrico Granata return false; 5244d93b8cdSEnrico Granata } 5254d93b8cdSEnrico Granata 526d26eb907SSiva Chandra bool 527d26eb907SSiva Chandra ValueObjectPrinter::ShouldExpandEmptyAggregates () 528d26eb907SSiva Chandra { 529d26eb907SSiva Chandra TypeSummaryImpl* entry = GetSummaryFormatter(); 530d26eb907SSiva Chandra 531d26eb907SSiva Chandra if (!entry) 532d26eb907SSiva Chandra return true; 533d26eb907SSiva Chandra 534d26eb907SSiva Chandra return entry->DoesPrintEmptyAggregates(); 535d26eb907SSiva Chandra } 536d26eb907SSiva Chandra 5374d93b8cdSEnrico Granata ValueObject* 5384d93b8cdSEnrico Granata ValueObjectPrinter::GetValueObjectForChildrenGeneration () 5394d93b8cdSEnrico Granata { 540d07cfd3aSEnrico Granata return m_valobj; 5414d93b8cdSEnrico Granata } 5424d93b8cdSEnrico Granata 5434d93b8cdSEnrico Granata void 5444d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPreamble () 5454d93b8cdSEnrico Granata { 5464d93b8cdSEnrico Granata if (options.m_flat_output) 5474d93b8cdSEnrico Granata { 5484d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 5494d93b8cdSEnrico Granata m_stream->EOL(); 5504d93b8cdSEnrico Granata } 5514d93b8cdSEnrico Granata else 5524d93b8cdSEnrico Granata { 5534d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 5544d93b8cdSEnrico Granata m_stream->PutCString(IsRef () ? ": {\n" : " {\n"); 5554d93b8cdSEnrico Granata m_stream->IndentMore(); 5564d93b8cdSEnrico Granata } 5574d93b8cdSEnrico Granata } 5584d93b8cdSEnrico Granata 5594d93b8cdSEnrico Granata void 5604d93b8cdSEnrico Granata ValueObjectPrinter::PrintChild (ValueObjectSP child_sp, 561c1b7c09aSEnrico Granata const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 5624d93b8cdSEnrico Granata { 5634d93b8cdSEnrico Granata DumpValueObjectOptions child_options(options); 564443844c4SEnrico Granata child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName(); 5654d93b8cdSEnrico Granata child_options.SetScopeChecked(true).SetHideName(options.m_hide_name).SetHideValue(options.m_hide_value) 5664d93b8cdSEnrico Granata .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0); 5674d93b8cdSEnrico Granata if (child_sp.get()) 5684d93b8cdSEnrico Granata { 5694d93b8cdSEnrico Granata ValueObjectPrinter child_printer(child_sp.get(), 5704d93b8cdSEnrico Granata m_stream, 5714d93b8cdSEnrico Granata child_options, 572c1b7c09aSEnrico Granata (IsPtr() || IsRef()) ? --curr_ptr_depth : curr_ptr_depth, 5734d93b8cdSEnrico Granata m_curr_depth + 1); 5744d93b8cdSEnrico Granata child_printer.PrintValueObject(); 5754d93b8cdSEnrico Granata } 5764d93b8cdSEnrico Granata } 5774d93b8cdSEnrico Granata 5784d93b8cdSEnrico Granata uint32_t 5794d93b8cdSEnrico Granata ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot) 5804d93b8cdSEnrico Granata { 5814d93b8cdSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 5824d93b8cdSEnrico Granata 5834d93b8cdSEnrico Granata size_t num_children = synth_m_valobj->GetNumChildren(); 5844d93b8cdSEnrico Granata print_dotdotdot = false; 5854d93b8cdSEnrico Granata if (num_children) 5864d93b8cdSEnrico Granata { 5874d93b8cdSEnrico Granata const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 5884d93b8cdSEnrico Granata 5894d93b8cdSEnrico Granata if (num_children > max_num_children && !options.m_ignore_cap) 5904d93b8cdSEnrico Granata { 5914d93b8cdSEnrico Granata print_dotdotdot = true; 5924d93b8cdSEnrico Granata return max_num_children; 5934d93b8cdSEnrico Granata } 5944d93b8cdSEnrico Granata } 5954d93b8cdSEnrico Granata return num_children; 5964d93b8cdSEnrico Granata } 5974d93b8cdSEnrico Granata 5984d93b8cdSEnrico Granata void 5994d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot) 6004d93b8cdSEnrico Granata { 6014d93b8cdSEnrico Granata if (!options.m_flat_output) 6024d93b8cdSEnrico Granata { 6034d93b8cdSEnrico Granata if (print_dotdotdot) 6044d93b8cdSEnrico Granata { 6054d93b8cdSEnrico Granata m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated(); 6064d93b8cdSEnrico Granata m_stream->Indent("...\n"); 6074d93b8cdSEnrico Granata } 6084d93b8cdSEnrico Granata m_stream->IndentLess(); 6094d93b8cdSEnrico Granata m_stream->Indent("}\n"); 6104d93b8cdSEnrico Granata } 6114d93b8cdSEnrico Granata } 6124d93b8cdSEnrico Granata 6134d93b8cdSEnrico Granata void 614c1b7c09aSEnrico Granata ValueObjectPrinter::PrintChildren (bool value_printed, 615c1b7c09aSEnrico Granata bool summary_printed, 616c1b7c09aSEnrico Granata const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 6174d93b8cdSEnrico Granata { 6184d93b8cdSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 6194d93b8cdSEnrico Granata 6204d93b8cdSEnrico Granata bool print_dotdotdot = false; 6214d93b8cdSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 6224d93b8cdSEnrico Granata if (num_children) 6234d93b8cdSEnrico Granata { 6244d93b8cdSEnrico Granata PrintChildrenPreamble (); 6254d93b8cdSEnrico Granata 6264d93b8cdSEnrico Granata for (size_t idx=0; idx<num_children; ++idx) 6274d93b8cdSEnrico Granata { 6284d93b8cdSEnrico Granata ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 6294d93b8cdSEnrico Granata PrintChild (child_sp, curr_ptr_depth); 6304d93b8cdSEnrico Granata } 6314d93b8cdSEnrico Granata 6324d93b8cdSEnrico Granata PrintChildrenPostamble (print_dotdotdot); 6334d93b8cdSEnrico Granata } 6344d93b8cdSEnrico Granata else if (IsAggregate()) 6354d93b8cdSEnrico Granata { 6364d93b8cdSEnrico Granata // Aggregate, no children... 6374d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 638d07cfd3aSEnrico Granata { 639d07cfd3aSEnrico Granata // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value 640d26eb907SSiva Chandra if (m_valobj->DoesProvideSyntheticValue() || !ShouldExpandEmptyAggregates()) 641d07cfd3aSEnrico Granata m_stream->PutCString( "\n"); 642d07cfd3aSEnrico Granata else 6434d93b8cdSEnrico Granata m_stream->PutCString(" {}\n"); 6444d93b8cdSEnrico Granata } 645d07cfd3aSEnrico Granata } 6464d93b8cdSEnrico Granata else 6474d93b8cdSEnrico Granata { 6484d93b8cdSEnrico Granata if (ShouldPrintValueObject()) 6494d93b8cdSEnrico Granata m_stream->EOL(); 6504d93b8cdSEnrico Granata } 6514d93b8cdSEnrico Granata } 6524d93b8cdSEnrico Granata 653a29cb0baSEnrico Granata bool 654a29cb0baSEnrico Granata ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names) 655a29cb0baSEnrico Granata { 656d07cfd3aSEnrico Granata if (!GetMostSpecializedValue () || m_valobj == nullptr) 657a29cb0baSEnrico Granata return false; 658a29cb0baSEnrico Granata 659a29cb0baSEnrico Granata ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 660a29cb0baSEnrico Granata 661a29cb0baSEnrico Granata bool print_dotdotdot = false; 662a29cb0baSEnrico Granata size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 663a29cb0baSEnrico Granata 664a29cb0baSEnrico Granata if (num_children) 665a29cb0baSEnrico Granata { 666a29cb0baSEnrico Granata m_stream->PutChar('('); 667a29cb0baSEnrico Granata 668a29cb0baSEnrico Granata for (uint32_t idx=0; idx<num_children; ++idx) 669a29cb0baSEnrico Granata { 670a29cb0baSEnrico Granata lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 671ddac7611SEnrico Granata if (child_sp) 672ddac7611SEnrico Granata child_sp = child_sp->GetQualifiedRepresentationIfAvailable(options.m_use_dynamic, options.m_use_synthetic); 673a29cb0baSEnrico Granata if (child_sp) 674a29cb0baSEnrico Granata { 675a29cb0baSEnrico Granata if (idx) 676a29cb0baSEnrico Granata m_stream->PutCString(", "); 677a29cb0baSEnrico Granata if (!hide_names) 678a29cb0baSEnrico Granata { 679a29cb0baSEnrico Granata const char* name = child_sp.get()->GetName().AsCString(); 680a29cb0baSEnrico Granata if (name && *name) 681a29cb0baSEnrico Granata { 682a29cb0baSEnrico Granata m_stream->PutCString(name); 683a29cb0baSEnrico Granata m_stream->PutCString(" = "); 684a29cb0baSEnrico Granata } 685a29cb0baSEnrico Granata } 686a29cb0baSEnrico Granata child_sp->DumpPrintableRepresentation(*m_stream, 687a29cb0baSEnrico Granata ValueObject::eValueObjectRepresentationStyleSummary, 688443844c4SEnrico Granata lldb::eFormatInvalid, 689a29cb0baSEnrico Granata ValueObject::ePrintableRepresentationSpecialCasesDisable); 690a29cb0baSEnrico Granata } 691a29cb0baSEnrico Granata } 692a29cb0baSEnrico Granata 693a29cb0baSEnrico Granata if (print_dotdotdot) 694a29cb0baSEnrico Granata m_stream->PutCString(", ...)"); 695a29cb0baSEnrico Granata else 696a29cb0baSEnrico Granata m_stream->PutChar(')'); 697a29cb0baSEnrico Granata } 698a29cb0baSEnrico Granata return true; 699a29cb0baSEnrico Granata } 700a29cb0baSEnrico Granata 7014d93b8cdSEnrico Granata void 7024d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed, 7034d93b8cdSEnrico Granata bool summary_printed) 7044d93b8cdSEnrico Granata { 7054d93b8cdSEnrico Granata // this flag controls whether we tried to display a description for this object and failed 7064d93b8cdSEnrico Granata // if that happens, we want to display the children, if any 7074d93b8cdSEnrico Granata bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed); 7084d93b8cdSEnrico Granata 709c1b7c09aSEnrico Granata auto curr_ptr_depth = m_ptr_depth; 7104d93b8cdSEnrico Granata bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth); 711c1b7c09aSEnrico Granata bool print_oneline = (curr_ptr_depth.CanAllowExpansion() || 7123fa6dc90SEnrico Granata options.m_show_types || 7133fa6dc90SEnrico Granata !options.m_allow_oneliner_mode || 7143fa6dc90SEnrico Granata options.m_flat_output || 7153fa6dc90SEnrico Granata options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj); 7164d93b8cdSEnrico Granata 7174d93b8cdSEnrico Granata if (print_children) 7184d93b8cdSEnrico Granata { 719a29cb0baSEnrico Granata if (print_oneline) 720a29cb0baSEnrico Granata { 721a29cb0baSEnrico Granata m_stream->PutChar(' '); 722a29cb0baSEnrico Granata PrintChildrenOneLiner (false); 723a29cb0baSEnrico Granata m_stream->EOL(); 724a29cb0baSEnrico Granata } 725a29cb0baSEnrico Granata else 726c1b7c09aSEnrico Granata PrintChildren (value_printed, summary_printed, curr_ptr_depth); 7274d93b8cdSEnrico Granata } 7284d93b8cdSEnrico Granata else if (m_curr_depth >= options.m_max_depth && IsAggregate() && ShouldPrintValueObject()) 7294d93b8cdSEnrico Granata { 7304d93b8cdSEnrico Granata m_stream->PutCString("{...}\n"); 7314d93b8cdSEnrico Granata } 732245b3caaSEnrico Granata else 733245b3caaSEnrico Granata m_stream->EOL(); 7344d93b8cdSEnrico Granata } 7350f883ffbSEnrico Granata 7360f883ffbSEnrico Granata bool 7370f883ffbSEnrico Granata ValueObjectPrinter::ShouldPrintValidation () 7380f883ffbSEnrico Granata { 7390f883ffbSEnrico Granata return options.m_run_validator; 7400f883ffbSEnrico Granata } 7410f883ffbSEnrico Granata 7420f883ffbSEnrico Granata bool 7430f883ffbSEnrico Granata ValueObjectPrinter::PrintValidationMarkerIfNeeded () 7440f883ffbSEnrico Granata { 7450f883ffbSEnrico Granata if (!ShouldPrintValidation()) 7460f883ffbSEnrico Granata return false; 7470f883ffbSEnrico Granata 7480f883ffbSEnrico Granata m_validation = m_valobj->GetValidationStatus(); 7490f883ffbSEnrico Granata 7500f883ffbSEnrico Granata if (TypeValidatorResult::Failure == m_validation.first) 7510f883ffbSEnrico Granata { 7520f883ffbSEnrico Granata m_stream->Printf("! "); 7530f883ffbSEnrico Granata return true; 7540f883ffbSEnrico Granata } 7550f883ffbSEnrico Granata 7560f883ffbSEnrico Granata return false; 7570f883ffbSEnrico Granata } 7580f883ffbSEnrico Granata 7590f883ffbSEnrico Granata bool 7600f883ffbSEnrico Granata ValueObjectPrinter::PrintValidationErrorIfNeeded () 7610f883ffbSEnrico Granata { 7620f883ffbSEnrico Granata if (!ShouldPrintValidation()) 7630f883ffbSEnrico Granata return false; 7640f883ffbSEnrico Granata 7650f883ffbSEnrico Granata if (TypeValidatorResult::Success == m_validation.first) 7660f883ffbSEnrico Granata return false; 7670f883ffbSEnrico Granata 7680f883ffbSEnrico Granata if (m_validation.second.empty()) 7690f883ffbSEnrico Granata m_validation.second.assign("unknown error"); 7700f883ffbSEnrico Granata 7710f883ffbSEnrico Granata m_stream->Printf(" ! validation error: %s", m_validation.second.c_str()); 7720f883ffbSEnrico Granata m_stream->EOL(); 7730f883ffbSEnrico Granata 7740f883ffbSEnrico Granata return true; 7750f883ffbSEnrico Granata } 776