1 //===-- ValueObjectPrinter.cpp -------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/DataFormatters/ValueObjectPrinter.h"
14 // Other libraries and framework includes
16 #include "lldb/Core/Stream.h"
17 #include "lldb/Core/ValueObject.h"
18 #include "lldb/DataFormatters/DataVisualization.h"
19 #include "lldb/Interpreter/CommandInterpreter.h"
20 #include "lldb/Target/Language.h"
21 #include "lldb/Target/Target.h"
24 using namespace lldb_private;
26 ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
31 DumpValueObjectOptions options(*valobj);
32 Init (valobj,s,options,m_options.m_max_ptr_depth,0, nullptr);
36 DumpValueObjectOptions options;
37 Init (valobj,s,options,m_options.m_max_ptr_depth,0, nullptr);
41 ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
43 const DumpValueObjectOptions& options)
45 Init(valobj,s,options,m_options.m_max_ptr_depth,0, nullptr);
48 ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
50 const DumpValueObjectOptions& options,
51 const DumpValueObjectOptions::PointerDepth& ptr_depth,
53 InstancePointersSetSP printed_instance_pointers)
55 Init(valobj,s,options,ptr_depth,curr_depth, printed_instance_pointers);
59 ValueObjectPrinter::Init (ValueObject* valobj,
61 const DumpValueObjectOptions& options,
62 const DumpValueObjectOptions::PointerDepth& ptr_depth,
64 InstancePointersSetSP printed_instance_pointers)
66 m_orig_valobj = valobj;
70 m_ptr_depth = ptr_depth;
71 m_curr_depth = curr_depth;
72 assert (m_orig_valobj && "cannot print a NULL ValueObject");
73 assert (m_stream && "cannot print to a NULL Stream");
74 m_should_print = eLazyBoolCalculate;
75 m_is_nil = eLazyBoolCalculate;
76 m_is_uninit = eLazyBoolCalculate;
77 m_is_ptr = eLazyBoolCalculate;
78 m_is_ref = eLazyBoolCalculate;
79 m_is_aggregate = eLazyBoolCalculate;
80 m_is_instance_ptr = eLazyBoolCalculate;
81 m_summary_formatter = {nullptr,false};
85 m_val_summary_ok = false;
86 m_printed_instance_pointers = printed_instance_pointers ? printed_instance_pointers : InstancePointersSetSP(new InstancePointersSet());
90 ValueObjectPrinter::PrintValueObject ()
92 if (!GetMostSpecializedValue () || m_valobj == nullptr)
95 if (ShouldPrintValueObject())
97 PrintValidationMarkerIfNeeded();
99 PrintLocationIfNeeded();
105 bool value_printed = false;
106 bool summary_printed = false;
108 m_val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed);
110 if (m_val_summary_ok)
111 PrintChildrenIfNeeded (value_printed, summary_printed);
115 PrintValidationErrorIfNeeded();
121 ValueObjectPrinter::GetMostSpecializedValue ()
125 bool update_success = m_orig_valobj->UpdateValueIfNeeded (true);
128 m_valobj = m_orig_valobj;
132 if (m_orig_valobj->IsDynamic())
134 if (m_options.m_use_dynamic == eNoDynamicValues)
136 ValueObject *static_value = m_orig_valobj->GetStaticValue().get();
138 m_valobj = static_value;
140 m_valobj = m_orig_valobj;
143 m_valobj = m_orig_valobj;
147 if (m_options.m_use_dynamic != eNoDynamicValues)
149 ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(m_options.m_use_dynamic).get();
151 m_valobj = dynamic_value;
153 m_valobj = m_orig_valobj;
156 m_valobj = m_orig_valobj;
159 if (m_valobj->IsSynthetic())
161 if (m_options.m_use_synthetic == false)
163 ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get();
165 m_valobj = non_synthetic;
170 if (m_options.m_use_synthetic == true)
172 ValueObject *synthetic = m_valobj->GetSyntheticValue().get();
174 m_valobj = synthetic;
178 m_compiler_type = m_valobj->GetCompilerType();
179 m_type_flags = m_compiler_type.GetTypeInfo ();
184 ValueObjectPrinter::GetDescriptionForDisplay ()
186 const char* str = m_valobj->GetObjectDescription();
188 str = m_valobj->GetSummaryAsCString();
190 str = m_valobj->GetValueAsCString();
195 ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail)
197 const char *root_valobj_name = m_options.m_root_valobj_name.empty() ?
198 m_valobj->GetName().AsCString() :
199 m_options.m_root_valobj_name.c_str();
200 return root_valobj_name ? root_valobj_name : if_fail;
204 ValueObjectPrinter::ShouldPrintValueObject ()
206 if (m_should_print == eLazyBoolCalculate)
207 m_should_print = (m_options.m_flat_output == false || m_type_flags.Test (eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo;
208 return m_should_print == eLazyBoolYes;
212 ValueObjectPrinter::IsNil ()
214 if (m_is_nil == eLazyBoolCalculate)
215 m_is_nil = m_valobj->IsNilReference() ? eLazyBoolYes : eLazyBoolNo;
216 return m_is_nil == eLazyBoolYes;
220 ValueObjectPrinter::IsUninitialized ()
222 if (m_is_uninit == eLazyBoolCalculate)
223 m_is_uninit = m_valobj->IsUninitializedReference() ? eLazyBoolYes : eLazyBoolNo;
224 return m_is_uninit == eLazyBoolYes;
228 ValueObjectPrinter::IsPtr ()
230 if (m_is_ptr == eLazyBoolCalculate)
231 m_is_ptr = m_type_flags.Test (eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo;
232 return m_is_ptr == eLazyBoolYes;
236 ValueObjectPrinter::IsRef ()
238 if (m_is_ref == eLazyBoolCalculate)
239 m_is_ref = m_type_flags.Test (eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo;
240 return m_is_ref == eLazyBoolYes;
244 ValueObjectPrinter::IsAggregate ()
246 if (m_is_aggregate == eLazyBoolCalculate)
247 m_is_aggregate = m_type_flags.Test (eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo;
248 return m_is_aggregate == eLazyBoolYes;
252 ValueObjectPrinter::IsInstancePointer ()
254 // you need to do this check on the value's clang type
255 if (m_is_instance_ptr == eLazyBoolCalculate)
256 m_is_instance_ptr = (m_valobj->GetValue().GetCompilerType().GetTypeInfo() & eTypeInstanceIsPointer) != 0 ? eLazyBoolYes : eLazyBoolNo;
257 if ((eLazyBoolYes == m_is_instance_ptr) && m_valobj->IsBaseClass())
258 m_is_instance_ptr = eLazyBoolNo;
259 return m_is_instance_ptr == eLazyBoolYes;
263 ValueObjectPrinter::PrintLocationIfNeeded ()
265 if (m_options.m_show_location)
267 m_stream->Printf("%s: ", m_valobj->GetLocationAsCString());
274 ValueObjectPrinter::PrintDecl ()
276 bool show_type = true;
277 // if we are at the root-level and been asked to hide the root's type, then hide it
278 if (m_curr_depth == 0 && m_options.m_hide_root_type)
281 // otherwise decide according to the usual rules (asked to show types - always at the root level)
282 show_type = m_options.m_show_types || (m_curr_depth == 0 && !m_options.m_flat_output);
284 StreamString typeName;
286 // always show the type at the root level if it is invalid
289 // Some ValueObjects don't have types (like registers sets). Only print
290 // the type if there is one to print
291 ConstString type_name;
292 if (m_compiler_type.IsValid())
294 if (m_options.m_use_type_display_name)
295 type_name = m_valobj->GetDisplayTypeName();
297 type_name = m_valobj->GetQualifiedTypeName();
301 // only show an invalid type name if the user explicitly triggered show_type
302 if (m_options.m_show_types)
303 type_name = ConstString("<invalid type>");
310 std::string type_name_str(type_name.GetCString());
311 if (m_options.m_hide_pointer_value)
313 for(auto iter = type_name_str.find(" *");
314 iter != std::string::npos;
315 iter = type_name_str.find(" *"))
317 type_name_str.erase(iter, 2);
320 typeName.Printf("%s", type_name_str.c_str());
324 StreamString varName;
326 if (m_options.m_flat_output)
328 // If we are showing types, also qualify the C++ base classes
329 const bool qualify_cxx_base_classes = show_type;
330 if (!m_options.m_hide_name)
332 m_valobj->GetExpressionPath(varName, qualify_cxx_base_classes);
335 else if (!m_options.m_hide_name)
337 const char *name_cstr = GetRootNameForDisplay("");
338 varName.Printf ("%s", name_cstr);
341 bool decl_printed = false;
342 if (!m_options.m_decl_printing_helper)
344 // 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
345 lldb::LanguageType lang_type = (m_options.m_varformat_language == lldb::eLanguageTypeUnknown) ? m_valobj->GetPreferredDisplayLanguage() : m_options.m_varformat_language;
346 if (Language *lang_plugin = Language::FindPlugin(lang_type))
348 m_options.m_decl_printing_helper = lang_plugin->GetDeclPrintingHelper();
352 if (m_options.m_decl_printing_helper)
354 ConstString type_name_cstr(typeName.GetData());
355 ConstString var_name_cstr(varName.GetData());
357 StreamString dest_stream;
358 if (m_options.m_decl_printing_helper (type_name_cstr,
364 m_stream->Printf("%s", dest_stream.GetData());
368 // if the helper failed, or there is none, do a default thing
371 if (typeName.GetSize())
372 m_stream->Printf("(%s) ", typeName.GetData());
373 if (varName.GetSize())
374 m_stream->Printf("%s =", varName.GetData());
375 else if (!m_options.m_hide_name)
376 m_stream->Printf(" =");
381 ValueObjectPrinter::CheckScopeIfNeeded ()
383 if (m_options.m_scope_already_checked)
385 return m_valobj->IsInScope();
389 ValueObjectPrinter::GetSummaryFormatter (bool null_if_omitted)
391 if (m_summary_formatter.second == false)
393 TypeSummaryImpl* entry = m_options.m_summary_sp ? m_options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get();
395 if (m_options.m_omit_summary_depth > 0)
397 m_summary_formatter.first = entry;
398 m_summary_formatter.second = true;
400 if (m_options.m_omit_summary_depth > 0 && null_if_omitted)
402 return m_summary_formatter.first;
406 IsPointerValue (const CompilerType &type)
408 Flags type_flags(type.GetTypeInfo());
409 if (type_flags.AnySet(eTypeInstanceIsPointer | eTypeIsPointer))
410 return type_flags.AllClear(eTypeIsBuiltIn);
415 ValueObjectPrinter::GetValueSummaryError (std::string& value,
416 std::string& summary,
419 lldb::Format format = m_options.m_format;
420 // if I am printing synthetized elements, apply the format to those elements only
421 if (m_options.m_element_count > 0)
422 m_valobj->GetValueAsCString(lldb::eFormatDefault, value);
423 else if (format != eFormatDefault && format != m_valobj->GetFormat())
424 m_valobj->GetValueAsCString(format, value);
427 const char* val_cstr = m_valobj->GetValueAsCString();
429 value.assign(val_cstr);
431 const char* err_cstr = m_valobj->GetError().AsCString();
433 error.assign(err_cstr);
435 if (ShouldPrintValueObject())
438 summary.assign("nil");
439 else if (IsUninitialized())
440 summary.assign("<uninitialized>");
441 else if (m_options.m_omit_summary_depth == 0)
443 TypeSummaryImpl* entry = GetSummaryFormatter();
445 m_valobj->GetSummaryAsCString(entry, summary, m_options.m_varformat_language);
448 const char* sum_cstr = m_valobj->GetSummaryAsCString(m_options.m_varformat_language);
450 summary.assign(sum_cstr);
457 ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed,
458 bool& summary_printed)
460 bool error_printed = false;
461 if (ShouldPrintValueObject())
463 if (!CheckScopeIfNeeded())
464 m_error.assign("out of scope");
467 GetValueSummaryError(m_value, m_summary, m_error);
471 // we need to support scenarios in which it is actually fine for a value to have no type
472 // but - on the other hand - if we get an error *AND* have no type, we try to get out
473 // gracefully, since most often that combination means "could not resolve a type"
474 // and the default failure mode is quite ugly
475 if (!m_compiler_type.IsValid())
477 m_stream->Printf(" <could not resolve type>");
481 error_printed = true;
482 m_stream->Printf (" <%s>\n", m_error.c_str());
486 // Make sure we have a value and make sure the summary didn't
487 // specify that the value should not be printed - and do not print
488 // the value if this thing is nil
489 // (but show the value if the user passes a format explicitly)
490 TypeSummaryImpl* entry = GetSummaryFormatter();
491 if (!IsNil() && !IsUninitialized() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue(m_valobj) || m_options.m_format != eFormatDefault) || m_summary.empty()) && !m_options.m_hide_value)
493 if (m_options.m_hide_pointer_value && IsPointerValue(m_valobj->GetCompilerType())) {}
496 m_stream->Printf(" %s", m_value.c_str());
497 value_printed = true;
501 if (m_summary.size())
503 m_stream->Printf(" %s", m_summary.c_str());
504 summary_printed = true;
508 return !error_printed;
512 ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed,
513 bool summary_printed)
515 if (ShouldPrintValueObject())
517 // let's avoid the overly verbose no description error for a nil thing
518 if (m_options.m_use_objc && !IsNil() && !IsUninitialized() && (m_options.m_element_count == 0))
520 if (!m_options.m_hide_value || !m_options.m_hide_name)
521 m_stream->Printf(" ");
522 const char *object_desc = nullptr;
523 if (value_printed || summary_printed)
524 object_desc = m_valobj->GetObjectDescription();
526 object_desc = GetDescriptionForDisplay();
527 if (object_desc && *object_desc)
529 m_stream->Printf("%s\n", object_desc);
532 else if (value_printed == false && summary_printed == false)
542 DumpValueObjectOptions::PointerDepth::CanAllowExpansion (bool is_root,
543 TypeSummaryImpl* entry,
545 const std::string& summary)
550 return (m_count > 0);
555 m_count = std::min<decltype(m_count)>(m_count,1);
557 case Mode::Formatters:
558 if (!entry || entry->DoesPrintChildren(valobj) || summary.empty())
566 DumpValueObjectOptions::PointerDepth::CanAllowExpansion () const
572 case Mode::Formatters:
573 return (m_count > 0);
581 ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description,
582 DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
584 const bool is_ref = IsRef ();
585 const bool is_ptr = IsPtr ();
586 const bool is_uninit = IsUninitialized();
591 // if the user has specified an element count, always print children
592 // as it is explicit user demand being honored
593 if (m_options.m_element_count > 0)
596 TypeSummaryImpl* entry = GetSummaryFormatter();
598 if (m_options.m_use_objc)
601 if (is_failed_description || m_curr_depth < m_options.m_max_depth)
603 // We will show children for all concrete types. We won't show
604 // pointer contents unless a pointer depth has been specified.
605 // We won't reference contents unless the reference is the
606 // root object (depth of zero).
608 // Use a new temporary pointer depth in case we override the
609 // current pointer depth below...
611 if (is_ptr || is_ref)
613 // We have a pointer or reference whose value is an address.
614 // Make sure that address is not NULL
615 AddressType ptr_address_type;
616 if (m_valobj->GetPointerValue (&ptr_address_type) == 0)
619 const bool is_root_level = m_curr_depth == 0;
624 // If this is the root object (depth is zero) that we are showing
625 // and it is a reference, and no pointer depth has been supplied
626 // print out what it references. Don't do this at deeper depths
627 // otherwise we can end up with infinite recursion...
631 return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, m_summary);
634 return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty());
640 ValueObjectPrinter::ShouldExpandEmptyAggregates ()
642 TypeSummaryImpl* entry = GetSummaryFormatter();
647 return entry->DoesPrintEmptyAggregates();
651 ValueObjectPrinter::GetValueObjectForChildrenGeneration ()
657 ValueObjectPrinter::PrintChildrenPreamble ()
659 if (m_options.m_flat_output)
661 if (ShouldPrintValueObject())
666 if (ShouldPrintValueObject())
667 m_stream->PutCString(IsRef () ? ": {\n" : " {\n");
668 m_stream->IndentMore();
673 ValueObjectPrinter::PrintChild (ValueObjectSP child_sp,
674 const DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
676 const uint32_t consumed_depth = (m_options.m_element_count == 0) ? 1 : 0;
677 const bool does_consume_ptr_depth = ((IsPtr() && m_options.m_element_count == 0) || IsRef());
679 DumpValueObjectOptions child_options(m_options);
680 child_options.SetFormat(m_options.m_format).SetSummary().SetRootValueObjectName();
681 child_options.SetScopeChecked(true).SetHideName(m_options.m_hide_name).SetHideValue(m_options.m_hide_value)
682 .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - consumed_depth : 0)
687 ValueObjectPrinter child_printer(child_sp.get(),
690 does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth,
691 m_curr_depth + consumed_depth,
692 m_printed_instance_pointers);
693 child_printer.PrintValueObject();
698 ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot)
700 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
702 if (m_options.m_element_count > 0)
703 return m_options.m_element_count;
705 size_t num_children = synth_m_valobj->GetNumChildren();
706 print_dotdotdot = false;
709 const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
711 if (num_children > max_num_children && !m_options.m_ignore_cap)
713 print_dotdotdot = true;
714 return max_num_children;
721 ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot)
723 if (!m_options.m_flat_output)
727 m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated();
728 m_stream->Indent("...\n");
730 m_stream->IndentLess();
731 m_stream->Indent("}\n");
736 ValueObjectPrinter::ShouldPrintEmptyBrackets (bool value_printed,
737 bool summary_printed)
739 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
744 if (m_options.m_reveal_empty_aggregates == false)
746 if (value_printed || summary_printed)
750 if (synth_m_valobj->MightHaveChildren())
753 if (m_val_summary_ok)
760 ValueObjectPrinter::GenerateChild (ValueObject* synth_valobj, size_t idx)
762 if (m_options.m_element_count > 0)
764 // if generating pointer-as-array children, use GetSyntheticArrayMember
765 return synth_valobj->GetSyntheticArrayMember(idx, true);
769 // otherwise, do the usual thing
770 return synth_valobj->GetChildAtIndex(idx, true);
775 ValueObjectPrinter::PrintChildren (bool value_printed,
776 bool summary_printed,
777 const DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
779 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
781 bool print_dotdotdot = false;
782 size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
785 bool any_children_printed = false;
787 for (size_t idx=0; idx<num_children; ++idx)
789 if (ValueObjectSP child_sp = GenerateChild(synth_m_valobj, idx))
791 if (!any_children_printed)
793 PrintChildrenPreamble ();
794 any_children_printed = true;
796 PrintChild (child_sp, curr_ptr_depth);
800 if (any_children_printed)
801 PrintChildrenPostamble (print_dotdotdot);
804 if (ShouldPrintEmptyBrackets(value_printed, summary_printed))
806 if (ShouldPrintValueObject())
807 m_stream->PutCString(" {}\n");
815 else if (ShouldPrintEmptyBrackets(value_printed, summary_printed))
817 // Aggregate, no children...
818 if (ShouldPrintValueObject())
820 // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value
821 if (m_valobj->DoesProvideSyntheticValue() || !ShouldExpandEmptyAggregates())
822 m_stream->PutCString( "\n");
824 m_stream->PutCString(" {}\n");
829 if (ShouldPrintValueObject())
835 ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names)
837 if (!GetMostSpecializedValue () || m_valobj == nullptr)
840 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
842 bool print_dotdotdot = false;
843 size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
847 m_stream->PutChar('(');
849 for (uint32_t idx=0; idx<num_children; ++idx)
851 lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
853 child_sp = child_sp->GetQualifiedRepresentationIfAvailable(m_options.m_use_dynamic, m_options.m_use_synthetic);
857 m_stream->PutCString(", ");
860 const char* name = child_sp.get()->GetName().AsCString();
863 m_stream->PutCString(name);
864 m_stream->PutCString(" = ");
867 child_sp->DumpPrintableRepresentation(*m_stream,
868 ValueObject::eValueObjectRepresentationStyleSummary,
870 ValueObject::ePrintableRepresentationSpecialCasesDisable);
875 m_stream->PutCString(", ...)");
877 m_stream->PutChar(')');
883 ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed,
884 bool summary_printed)
886 // this flag controls whether we tried to display a description for this object and failed
887 // if that happens, we want to display the children, if any
888 bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
890 auto curr_ptr_depth = m_ptr_depth;
891 bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth);
892 bool print_oneline = (curr_ptr_depth.CanAllowExpansion() ||
893 m_options.m_show_types ||
894 !m_options.m_allow_oneliner_mode ||
895 m_options.m_flat_output ||
896 (m_options.m_element_count > 0) ||
897 m_options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj);
898 bool is_instance_ptr = IsInstancePointer();
899 uint64_t instance_ptr_value = LLDB_INVALID_ADDRESS;
901 if (print_children && is_instance_ptr)
903 instance_ptr_value = m_valobj->GetValueAsUnsigned(0);
904 if (m_printed_instance_pointers->count(instance_ptr_value))
906 // we already printed this instance-is-pointer thing, so don't expand it
907 m_stream->PutCString(" {...}\n");
909 // we're done here - get out fast
913 m_printed_instance_pointers->emplace(instance_ptr_value); // remember this guy for future reference
920 m_stream->PutChar(' ');
921 PrintChildrenOneLiner (false);
925 PrintChildren (value_printed, summary_printed, curr_ptr_depth);
927 else if (m_curr_depth >= m_options.m_max_depth && IsAggregate() && ShouldPrintValueObject())
929 m_stream->PutCString("{...}\n");
936 ValueObjectPrinter::ShouldPrintValidation ()
938 return m_options.m_run_validator;
942 ValueObjectPrinter::PrintValidationMarkerIfNeeded ()
944 if (!ShouldPrintValidation())
947 m_validation = m_valobj->GetValidationStatus();
949 if (TypeValidatorResult::Failure == m_validation.first)
951 m_stream->Printf("! ");
959 ValueObjectPrinter::PrintValidationErrorIfNeeded ()
961 if (!ShouldPrintValidation())
964 if (TypeValidatorResult::Success == m_validation.first)
967 if (m_validation.second.empty())
968 m_validation.second.assign("unknown error");
970 m_stream->Printf(" ! validation error: %s", m_validation.second.c_str());