36 ValueObjectPrinter::ValueObjectPrinter(
40 Init(valobj, s, options, ptr_depth, curr_depth, printed_instance_pointers);
43 void ValueObjectPrinter::Init(
47 m_orig_valobj = valobj;
51 m_ptr_depth = ptr_depth;
52 m_curr_depth = curr_depth;
53 assert(m_orig_valobj &&
"cannot print a NULL ValueObject");
54 assert(m_stream &&
"cannot print to a NULL Stream");
62 m_summary_formatter = {
nullptr,
false};
66 m_val_summary_ok =
false;
67 m_printed_instance_pointers =
68 printed_instance_pointers
69 ? printed_instance_pointers
73 bool ValueObjectPrinter::PrintValueObject() {
74 if (!GetMostSpecializedValue() || m_valobj ==
nullptr)
77 if (ShouldPrintValueObject()) {
78 PrintLocationIfNeeded();
84 bool value_printed =
false;
85 bool summary_printed =
false;
88 PrintValueAndSummaryIfNeeded(value_printed, summary_printed);
91 PrintChildrenIfNeeded(value_printed, summary_printed);
98 bool ValueObjectPrinter::GetMostSpecializedValue() {
101 bool update_success = m_orig_valobj->UpdateValueIfNeeded(
true);
102 if (!update_success) {
103 m_valobj = m_orig_valobj;
105 if (m_orig_valobj->IsDynamic()) {
109 m_valobj = static_value;
111 m_valobj = m_orig_valobj;
113 m_valobj = m_orig_valobj;
119 m_valobj = dynamic_value;
121 m_valobj = m_orig_valobj;
123 m_valobj = m_orig_valobj;
126 if (m_valobj->IsSynthetic()) {
127 if (!m_options.m_use_synthetic) {
130 m_valobj = non_synthetic;
133 if (m_options.m_use_synthetic) {
136 m_valobj = synthetic;
145 const char *ValueObjectPrinter::GetDescriptionForDisplay() {
146 const char *str = m_valobj->GetObjectDescription();
148 str = m_valobj->GetSummaryAsCString();
150 str = m_valobj->GetValueAsCString();
154 const char *ValueObjectPrinter::GetRootNameForDisplay() {
155 const char *root_valobj_name = m_options.m_root_valobj_name.empty()
156 ? m_valobj->GetName().AsCString()
157 : m_options.m_root_valobj_name.c_str();
158 return root_valobj_name ? root_valobj_name :
"";
161 bool ValueObjectPrinter::ShouldPrintValueObject() {
164 (!m_options.m_flat_output || m_type_flags.Test(eTypeHasValue))
170 bool ValueObjectPrinter::IsNil() {
176 bool ValueObjectPrinter::IsUninitialized() {
183 bool ValueObjectPrinter::IsPtr() {
189 bool ValueObjectPrinter::IsRef() {
195 bool ValueObjectPrinter::IsAggregate() {
202 bool ValueObjectPrinter::IsInstancePointer() {
205 m_is_instance_ptr = (m_valobj->GetValue().GetCompilerType().GetTypeInfo() &
206 eTypeInstanceIsPointer) != 0
209 if ((
eLazyBoolYes == m_is_instance_ptr) && m_valobj->IsBaseClass())
214 bool ValueObjectPrinter::PrintLocationIfNeeded() {
215 if (m_options.m_show_location) {
216 m_stream->Printf(
"%s: ", m_valobj->GetLocationAsCString());
222 void ValueObjectPrinter::PrintDecl() {
223 bool show_type =
true;
226 if (m_curr_depth == 0 && m_options.m_hide_root_type)
231 show_type = m_options.m_show_types ||
232 (m_curr_depth == 0 && !m_options.m_flat_output);
241 if (m_compiler_type.IsValid()) {
242 type_name = m_options.m_use_type_display_name
243 ? m_valobj->GetDisplayTypeName()
244 : m_valobj->GetQualifiedTypeName();
248 if (m_options.m_show_types)
254 if (m_options.m_hide_pointer_value) {
255 for (
auto iter = type_name_str.find(
" *"); iter != std::string::npos;
256 iter = type_name_str.find(
" *")) {
257 type_name_str.erase(iter, 2);
260 typeName << type_name_str.c_str();
266 if (!m_options.m_hide_name) {
267 if (m_options.m_flat_output)
268 m_valobj->GetExpressionPath(varName);
270 varName << GetRootNameForDisplay();
273 bool decl_printed =
false;
274 if (!m_options.m_decl_printing_helper) {
280 ? m_valobj->GetPreferredDisplayLanguage()
281 : m_options.m_varformat_language;
282 if (
Language *lang_plugin = Language::FindPlugin(lang_type)) {
283 m_options.m_decl_printing_helper = lang_plugin->GetDeclPrintingHelper();
287 if (m_options.m_decl_printing_helper) {
292 if (m_options.m_decl_printing_helper(type_name_cstr, var_name_cstr,
293 m_options, dest_stream)) {
301 if (!typeName.
Empty())
302 m_stream->Printf(
"(%s) ", typeName.
GetData());
303 if (!varName.
Empty())
304 m_stream->Printf(
"%s =", varName.
GetData());
305 else if (!m_options.m_hide_name)
306 m_stream->Printf(
" =");
310 bool ValueObjectPrinter::CheckScopeIfNeeded() {
311 if (m_options.m_scope_already_checked)
313 return m_valobj->IsInScope();
317 if (!m_summary_formatter.second) {
319 ? m_options.m_summary_sp.get()
320 : m_valobj->GetSummaryFormat().get();
322 if (m_options.m_omit_summary_depth > 0)
324 m_summary_formatter.first = entry;
325 m_summary_formatter.second =
true;
327 if (m_options.m_omit_summary_depth > 0 && null_if_omitted)
329 return m_summary_formatter.first;
334 if (type_flags.
AnySet(eTypeInstanceIsPointer | eTypeIsPointer))
335 return type_flags.
AllClear(eTypeIsBuiltIn);
345 if (m_options.m_pointer_as_array)
347 else if (format !=
eFormatDefault && format != m_valobj->GetFormat())
348 m_valobj->GetValueAsCString(format, value);
350 const char *val_cstr = m_valobj->GetValueAsCString();
352 value.assign(val_cstr);
354 const char *err_cstr = m_valobj->GetError().AsCString();
356 error.assign(err_cstr);
358 if (!ShouldPrintValueObject())
364 ? m_valobj->GetPreferredDisplayLanguage()
365 : m_options.m_varformat_language;
366 if (
Language *lang_plugin = Language::FindPlugin(lang_type)) {
367 summary.assign(lang_plugin->GetNilReferenceSummaryString().str());
371 summary.assign(
"NULL");
373 }
else if (IsUninitialized()) {
374 summary.assign(
"<uninitialized>");
375 }
else if (m_options.m_omit_summary_depth == 0) {
378 m_valobj->GetSummaryAsCString(entry, summary,
379 m_options.m_varformat_language);
381 const char *sum_cstr =
382 m_valobj->GetSummaryAsCString(m_options.m_varformat_language);
384 summary.assign(sum_cstr);
389 bool ValueObjectPrinter::PrintValueAndSummaryIfNeeded(
bool &value_printed,
390 bool &summary_printed) {
391 bool error_printed =
false;
392 if (ShouldPrintValueObject()) {
393 if (!CheckScopeIfNeeded())
394 m_error.assign(
"out of scope");
395 if (m_error.empty()) {
396 GetValueSummaryError(m_value, m_summary, m_error);
398 if (m_error.size()) {
404 if (!m_compiler_type.IsValid()) {
405 m_stream->Printf(
" <could not resolve type>");
409 error_printed =
true;
410 m_stream->Printf(
" <%s>\n", m_error.c_str());
417 const bool has_nil_or_uninitialized_summary =
418 (IsNil() || IsUninitialized()) && !m_summary.empty();
419 if (!has_nil_or_uninitialized_summary && !m_value.empty() &&
423 m_summary.empty()) &&
424 !m_options.m_hide_value) {
425 if (m_options.m_hide_pointer_value &&
428 m_stream->Printf(
" %s", m_value.c_str());
429 value_printed =
true;
433 if (m_summary.size()) {
434 m_stream->Printf(
" %s", m_summary.c_str());
435 summary_printed =
true;
439 return !error_printed;
442 bool ValueObjectPrinter::PrintObjectDescriptionIfNeeded(
bool value_printed,
443 bool summary_printed) {
444 if (ShouldPrintValueObject()) {
446 if (m_options.m_use_objc && !IsNil() && !IsUninitialized() &&
447 (!m_options.m_pointer_as_array)) {
448 if (!m_options.m_hide_value || !m_options.m_hide_name)
449 m_stream->Printf(
" ");
450 const char *object_desc =
nullptr;
451 if (value_printed || summary_printed)
452 object_desc = m_valobj->GetObjectDescription();
454 object_desc = GetDescriptionForDisplay();
455 if (object_desc && *object_desc) {
457 size_t object_end = strlen(object_desc) - 1;
458 if (object_desc[object_end] ==
'\n')
459 m_stream->Printf(
"%s", object_desc);
461 m_stream->Printf(
"%s\n", object_desc);
463 }
else if (!value_printed && !summary_printed)
472 bool DumpValueObjectOptions::PointerDepth::CanAllowExpansion()
const {
483 bool ValueObjectPrinter::ShouldPrintChildren(
484 bool is_failed_description,
486 const bool is_ref = IsRef();
487 const bool is_ptr = IsPtr();
488 const bool is_uninit = IsUninitialized();
495 if (m_options.m_pointer_as_array)
500 if (m_options.m_use_objc)
503 if (is_failed_description || !HasReachedMaximumDepth()) {
511 if (is_ptr || is_ref) {
515 if (m_valobj->GetPointerValue(&ptr_address_type) == 0)
518 const bool is_root_level = m_curr_depth == 0;
520 if (is_ref && is_root_level) {
536 bool ValueObjectPrinter::ShouldExpandEmptyAggregates() {
545 ValueObject *ValueObjectPrinter::GetValueObjectForChildrenGeneration() {
549 void ValueObjectPrinter::PrintChildrenPreamble() {
550 if (m_options.m_flat_output) {
551 if (ShouldPrintValueObject())
554 if (ShouldPrintValueObject())
555 m_stream->PutCString(IsRef() ?
": {\n" :
" {\n");
556 m_stream->IndentMore();
560 void ValueObjectPrinter::PrintChild(
561 ValueObjectSP child_sp,
563 const uint32_t consumed_depth = (!m_options.m_pointer_as_array) ? 1 : 0;
564 const bool does_consume_ptr_depth =
565 ((IsPtr() && !m_options.m_pointer_as_array) || IsRef());
568 child_options.
SetFormat(m_options.m_format)
580 if (child_sp.get()) {
582 child_sp.get(), m_stream, child_options,
583 does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth,
584 m_curr_depth + consumed_depth, m_printed_instance_pointers);
589 uint32_t ValueObjectPrinter::GetMaxNumChildrenToPrint(
bool &print_dotdotdot) {
590 ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration();
592 if (m_options.m_pointer_as_array)
593 return m_options.m_pointer_as_array.m_element_count;
596 print_dotdotdot =
false;
598 const size_t max_num_children =
599 m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
601 if (num_children > max_num_children && !m_options.m_ignore_cap) {
602 print_dotdotdot =
true;
603 return max_num_children;
609 void ValueObjectPrinter::PrintChildrenPostamble(
bool print_dotdotdot) {
610 if (!m_options.m_flat_output) {
611 if (print_dotdotdot) {
612 m_valobj->GetTargetSP()
614 .GetCommandInterpreter()
615 .ChildrenTruncated();
616 m_stream->Indent(
"...\n");
618 m_stream->IndentLess();
619 m_stream->Indent(
"}\n");
623 bool ValueObjectPrinter::ShouldPrintEmptyBrackets(
bool value_printed,
624 bool summary_printed) {
625 ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration();
630 if (!m_options.m_reveal_empty_aggregates) {
631 if (value_printed || summary_printed)
638 if (m_val_summary_ok)
646 return base + logical * stride;
649 ValueObjectSP ValueObjectPrinter::GenerateChild(
ValueObject *synth_valobj,
651 if (m_options.m_pointer_as_array) {
655 m_options.m_pointer_as_array.m_base_element,
656 m_options.m_pointer_as_array.m_stride, idx),
664 void ValueObjectPrinter::PrintChildren(
665 bool value_printed,
bool summary_printed,
667 ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration();
669 bool print_dotdotdot =
false;
670 size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
672 bool any_children_printed =
false;
674 for (
size_t idx = 0; idx < num_children; ++idx) {
675 if (ValueObjectSP child_sp = GenerateChild(synth_m_valobj, idx)) {
676 if (!any_children_printed) {
677 PrintChildrenPreamble();
678 any_children_printed =
true;
680 PrintChild(child_sp, curr_ptr_depth);
684 if (any_children_printed)
685 PrintChildrenPostamble(print_dotdotdot);
687 if (ShouldPrintEmptyBrackets(value_printed, summary_printed)) {
688 if (ShouldPrintValueObject())
689 m_stream->PutCString(
" {}\n");
695 }
else if (ShouldPrintEmptyBrackets(value_printed, summary_printed)) {
697 if (ShouldPrintValueObject()) {
700 if (m_valobj->DoesProvideSyntheticValue() ||
701 !ShouldExpandEmptyAggregates())
702 m_stream->PutCString(
"\n");
704 m_stream->PutCString(
" {}\n");
707 if (ShouldPrintValueObject())
712 bool ValueObjectPrinter::PrintChildrenOneLiner(
bool hide_names) {
713 if (!GetMostSpecializedValue() || m_valobj ==
nullptr)
716 ValueObject *synth_m_valobj = GetValueObjectForChildrenGeneration();
718 bool print_dotdotdot =
false;
719 size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
722 m_stream->PutChar(
'(');
724 for (
uint32_t idx = 0; idx < num_children; ++idx) {
725 lldb::ValueObjectSP child_sp(synth_m_valobj->
GetChildAtIndex(idx,
true));
727 child_sp = child_sp->GetQualifiedRepresentationIfAvailable(
728 m_options.m_use_dynamic, m_options.m_use_synthetic);
731 m_stream->PutCString(
", ");
733 const char *name = child_sp.get()->GetName().AsCString();
735 m_stream->PutCString(name);
736 m_stream->PutCString(
" = ");
739 child_sp->DumpPrintableRepresentation(
740 *m_stream, ValueObject::eValueObjectRepresentationStyleSummary,
742 ValueObject::PrintableRepresentationSpecialCases::eDisable);
747 m_stream->PutCString(
", ...)");
749 m_stream->PutChar(
')');
754 void ValueObjectPrinter::PrintChildrenIfNeeded(
bool value_printed,
755 bool summary_printed) {
758 bool is_failed_description =
759 !PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
762 const bool print_children =
763 ShouldPrintChildren(is_failed_description, curr_ptr_depth);
764 const bool print_oneline =
766 !m_options.m_allow_oneliner_mode || m_options.m_flat_output ||
767 (m_options.m_pointer_as_array) || m_options.m_show_location)
769 : DataVisualization::ShouldPrintAsOneLiner(*m_valobj);
770 if (print_children && IsInstancePointer()) {
771 uint64_t instance_ptr_value = m_valobj->GetValueAsUnsigned(0);
772 if (m_printed_instance_pointers->count(instance_ptr_value)) {
774 m_stream->PutCString(
" {...}\n");
778 m_printed_instance_pointers->emplace(instance_ptr_value);
782 if (print_children) {
784 m_stream->PutChar(
' ');
785 PrintChildrenOneLiner(
false);
788 PrintChildren(value_printed, summary_printed, curr_ptr_depth);
789 }
else if (HasReachedMaximumDepth() && IsAggregate() &&
790 ShouldPrintValueObject()) {
791 m_stream->PutCString(
"{...}\n");
796 if (m_options.m_max_depth_is_default)
797 m_valobj->GetTargetSP()
799 .GetCommandInterpreter()
800 .SetReachedMaximumDepth();
805 bool ValueObjectPrinter::HasReachedMaximumDepth() {
806 return m_curr_depth >= m_options.m_max_depth;