1 //===-- ValueObjectPrinter.cpp -------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/DataFormatters/ValueObjectPrinter.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Core/Debugger.h" 17 #include "lldb/DataFormatters/DataVisualization.h" 18 #include "lldb/Interpreter/CommandInterpreter.h" 19 #include "lldb/Target/Target.h" 20 21 using namespace lldb; 22 using namespace lldb_private; 23 24 DumpValueObjectOptions::DumpValueObjectOptions (ValueObject& valobj) : 25 DumpValueObjectOptions() 26 { 27 m_use_dynamic = valobj.GetDynamicValueType(); 28 m_use_synthetic = valobj.IsSynthetic(); 29 } 30 31 ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, 32 Stream* s) 33 { 34 if (valobj) 35 { 36 DumpValueObjectOptions options(*valobj); 37 Init (valobj,s,options,options.m_max_ptr_depth,0); 38 } 39 else 40 { 41 DumpValueObjectOptions options; 42 Init (valobj,s,options,options.m_max_ptr_depth,0); 43 } 44 } 45 46 ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, 47 Stream* s, 48 const DumpValueObjectOptions& options) 49 { 50 Init(valobj,s,options,options.m_max_ptr_depth,0); 51 } 52 53 ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, 54 Stream* s, 55 const DumpValueObjectOptions& options, 56 const DumpValueObjectOptions::PointerDepth& ptr_depth, 57 uint32_t curr_depth) 58 { 59 Init(valobj,s,options,ptr_depth,curr_depth); 60 } 61 62 void 63 ValueObjectPrinter::Init (ValueObject* valobj, 64 Stream* s, 65 const DumpValueObjectOptions& options, 66 const DumpValueObjectOptions::PointerDepth& ptr_depth, 67 uint32_t curr_depth) 68 { 69 m_orig_valobj = valobj; 70 m_valobj = nullptr; 71 m_stream = s; 72 this->options = options; 73 m_ptr_depth = ptr_depth; 74 m_curr_depth = curr_depth; 75 assert (m_orig_valobj && "cannot print a NULL ValueObject"); 76 assert (m_stream && "cannot print to a NULL Stream"); 77 m_should_print = eLazyBoolCalculate; 78 m_is_nil = eLazyBoolCalculate; 79 m_is_ptr = eLazyBoolCalculate; 80 m_is_ref = eLazyBoolCalculate; 81 m_is_aggregate = eLazyBoolCalculate; 82 m_summary_formatter = {nullptr,false}; 83 m_value.assign(""); 84 m_summary.assign(""); 85 m_error.assign(""); 86 } 87 88 bool 89 ValueObjectPrinter::PrintValueObject () 90 { 91 if (!GetMostSpecializedValue () || m_valobj == nullptr) 92 return false; 93 94 if (ShouldPrintValueObject()) 95 { 96 PrintValidationMarkerIfNeeded(); 97 98 PrintLocationIfNeeded(); 99 m_stream->Indent(); 100 101 bool show_type = PrintTypeIfNeeded(); 102 103 PrintNameIfNeeded(show_type); 104 } 105 106 bool value_printed = false; 107 bool summary_printed = false; 108 109 bool val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed); 110 111 if (val_summary_ok) 112 PrintChildrenIfNeeded (value_printed, summary_printed); 113 else 114 m_stream->EOL(); 115 116 PrintValidationErrorIfNeeded(); 117 118 return true; 119 } 120 121 bool 122 ValueObjectPrinter::GetMostSpecializedValue () 123 { 124 if (m_valobj) 125 return true; 126 bool update_success = m_orig_valobj->UpdateValueIfNeeded (true); 127 if (!update_success) 128 { 129 m_valobj = m_orig_valobj; 130 } 131 else 132 { 133 if (m_orig_valobj->IsDynamic()) 134 { 135 if (options.m_use_dynamic == eNoDynamicValues) 136 { 137 ValueObject *static_value = m_orig_valobj->GetStaticValue().get(); 138 if (static_value) 139 m_valobj = static_value; 140 else 141 m_valobj = m_orig_valobj; 142 } 143 else 144 m_valobj = m_orig_valobj; 145 } 146 else 147 { 148 if (options.m_use_dynamic != eNoDynamicValues) 149 { 150 ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(options.m_use_dynamic).get(); 151 if (dynamic_value) 152 m_valobj = dynamic_value; 153 else 154 m_valobj = m_orig_valobj; 155 } 156 else 157 m_valobj = m_orig_valobj; 158 } 159 160 if (m_valobj->IsSynthetic()) 161 { 162 if (options.m_use_synthetic == false) 163 { 164 ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get(); 165 if (non_synthetic) 166 m_valobj = non_synthetic; 167 } 168 } 169 else 170 { 171 if (options.m_use_synthetic == true) 172 { 173 ValueObject *synthetic = m_valobj->GetSyntheticValue().get(); 174 if (synthetic) 175 m_valobj = synthetic; 176 } 177 } 178 } 179 m_clang_type = m_valobj->GetClangType(); 180 m_type_flags = m_clang_type.GetTypeInfo (); 181 return true; 182 } 183 184 const char* 185 ValueObjectPrinter::GetDescriptionForDisplay () 186 { 187 const char* str = m_valobj->GetObjectDescription(); 188 if (!str) 189 str = m_valobj->GetSummaryAsCString(); 190 if (!str) 191 str = m_valobj->GetValueAsCString(); 192 return str; 193 } 194 195 const char* 196 ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail) 197 { 198 const char *root_valobj_name = options.m_root_valobj_name.empty() ? 199 m_valobj->GetName().AsCString() : 200 options.m_root_valobj_name.c_str(); 201 return root_valobj_name ? root_valobj_name : if_fail; 202 } 203 204 bool 205 ValueObjectPrinter::ShouldPrintValueObject () 206 { 207 if (m_should_print == eLazyBoolCalculate) 208 m_should_print = (options.m_flat_output == false || m_type_flags.Test (eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo; 209 return m_should_print == eLazyBoolYes; 210 } 211 212 bool 213 ValueObjectPrinter::IsNil () 214 { 215 if (m_is_nil == eLazyBoolCalculate) 216 m_is_nil = m_valobj->IsObjCNil() ? eLazyBoolYes : eLazyBoolNo; 217 return m_is_nil == eLazyBoolYes; 218 } 219 220 bool 221 ValueObjectPrinter::IsPtr () 222 { 223 if (m_is_ptr == eLazyBoolCalculate) 224 m_is_ptr = m_type_flags.Test (eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo; 225 return m_is_ptr == eLazyBoolYes; 226 } 227 228 bool 229 ValueObjectPrinter::IsRef () 230 { 231 if (m_is_ref == eLazyBoolCalculate) 232 m_is_ref = m_type_flags.Test (eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo; 233 return m_is_ref == eLazyBoolYes; 234 } 235 236 bool 237 ValueObjectPrinter::IsAggregate () 238 { 239 if (m_is_aggregate == eLazyBoolCalculate) 240 m_is_aggregate = m_type_flags.Test (eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo; 241 return m_is_aggregate == eLazyBoolYes; 242 } 243 244 bool 245 ValueObjectPrinter::PrintLocationIfNeeded () 246 { 247 if (options.m_show_location) 248 { 249 m_stream->Printf("%s: ", m_valobj->GetLocationAsCString()); 250 return true; 251 } 252 return false; 253 } 254 255 bool 256 ValueObjectPrinter::PrintTypeIfNeeded () 257 { 258 bool show_type = true; 259 // if we are at the root-level and been asked to hide the root's type, then hide it 260 if (m_curr_depth == 0 && options.m_hide_root_type) 261 show_type = false; 262 else 263 // otherwise decide according to the usual rules (asked to show types - always at the root level) 264 show_type = options.m_show_types || (m_curr_depth == 0 && !options.m_flat_output); 265 266 if (show_type) 267 { 268 // Some ValueObjects don't have types (like registers sets). Only print 269 // the type if there is one to print 270 ConstString type_name; 271 if (options.m_use_type_display_name) 272 type_name = m_valobj->GetDisplayTypeName(); 273 else 274 type_name = m_valobj->GetQualifiedTypeName(); 275 if (type_name) 276 m_stream->Printf("(%s) ", type_name.GetCString()); 277 else 278 show_type = false; 279 } 280 return show_type; 281 } 282 283 bool 284 ValueObjectPrinter::PrintNameIfNeeded (bool show_type) 285 { 286 if (options.m_flat_output) 287 { 288 // If we are showing types, also qualify the C++ base classes 289 const bool qualify_cxx_base_classes = show_type; 290 if (!options.m_hide_name) 291 { 292 m_valobj->GetExpressionPath(*m_stream, qualify_cxx_base_classes); 293 m_stream->PutCString(" ="); 294 return true; 295 } 296 } 297 else if (!options.m_hide_name) 298 { 299 const char *name_cstr = GetRootNameForDisplay(""); 300 m_stream->Printf ("%s =", name_cstr); 301 return true; 302 } 303 return false; 304 } 305 306 bool 307 ValueObjectPrinter::CheckScopeIfNeeded () 308 { 309 if (options.m_scope_already_checked) 310 return true; 311 return m_valobj->IsInScope(); 312 } 313 314 TypeSummaryImpl* 315 ValueObjectPrinter::GetSummaryFormatter () 316 { 317 if (m_summary_formatter.second == false) 318 { 319 TypeSummaryImpl* entry = options.m_summary_sp ? options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get(); 320 321 if (options.m_omit_summary_depth > 0) 322 entry = NULL; 323 m_summary_formatter.first = entry; 324 m_summary_formatter.second = true; 325 } 326 return m_summary_formatter.first; 327 } 328 329 void 330 ValueObjectPrinter::GetValueSummaryError (std::string& value, 331 std::string& summary, 332 std::string& error) 333 { 334 if (options.m_format != eFormatDefault && options.m_format != m_valobj->GetFormat()) 335 { 336 m_valobj->GetValueAsCString(options.m_format, 337 value); 338 } 339 else 340 { 341 const char* val_cstr = m_valobj->GetValueAsCString(); 342 if (val_cstr) 343 value.assign(val_cstr); 344 } 345 const char* err_cstr = m_valobj->GetError().AsCString(); 346 if (err_cstr) 347 error.assign(err_cstr); 348 349 if (ShouldPrintValueObject()) 350 { 351 if (IsNil()) 352 summary.assign("nil"); 353 else if (options.m_omit_summary_depth == 0) 354 { 355 TypeSummaryImpl* entry = GetSummaryFormatter(); 356 if (entry) 357 m_valobj->GetSummaryAsCString(entry, summary); 358 else 359 { 360 const char* sum_cstr = m_valobj->GetSummaryAsCString(); 361 if (sum_cstr) 362 summary.assign(sum_cstr); 363 } 364 } 365 } 366 } 367 368 bool 369 ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed, 370 bool& summary_printed) 371 { 372 bool error_printed = false; 373 if (ShouldPrintValueObject()) 374 { 375 if (!CheckScopeIfNeeded()) 376 m_error.assign("out of scope"); 377 if (m_error.empty()) 378 { 379 GetValueSummaryError(m_value, m_summary, m_error); 380 } 381 if (m_error.size()) 382 { 383 error_printed = true; 384 m_stream->Printf (" <%s>\n", m_error.c_str()); 385 } 386 else 387 { 388 // Make sure we have a value and make sure the summary didn't 389 // specify that the value should not be printed - and do not print 390 // the value if this thing is nil 391 // (but show the value if the user passes a format explicitly) 392 TypeSummaryImpl* entry = GetSummaryFormatter(); 393 if (!IsNil() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue(m_valobj) || options.m_format != eFormatDefault) || m_summary.empty()) && !options.m_hide_value) 394 { 395 m_stream->Printf(" %s", m_value.c_str()); 396 value_printed = true; 397 } 398 399 if (m_summary.size()) 400 { 401 m_stream->Printf(" %s", m_summary.c_str()); 402 summary_printed = true; 403 } 404 } 405 } 406 return !error_printed; 407 } 408 409 bool 410 ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed, 411 bool summary_printed) 412 { 413 if (ShouldPrintValueObject()) 414 { 415 // let's avoid the overly verbose no description error for a nil thing 416 if (options.m_use_objc && !IsNil()) 417 { 418 if (!options.m_hide_value || !options.m_hide_name) 419 m_stream->Printf(" "); 420 const char *object_desc = nullptr; 421 if (value_printed || summary_printed) 422 object_desc = m_valobj->GetObjectDescription(); 423 else 424 object_desc = GetDescriptionForDisplay(); 425 if (object_desc && *object_desc) 426 { 427 m_stream->Printf("%s\n", object_desc); 428 return true; 429 } 430 else if (value_printed == false && summary_printed == false) 431 return true; 432 else 433 return false; 434 } 435 } 436 return true; 437 } 438 439 bool 440 DumpValueObjectOptions::PointerDepth::CanAllowExpansion (bool is_root, 441 TypeSummaryImpl* entry, 442 ValueObject *valobj, 443 const std::string& summary) 444 { 445 switch (m_mode) 446 { 447 case Mode::Always: 448 return (m_count > 0); 449 case Mode::Never: 450 return false; 451 case Mode::Default: 452 if (is_root) 453 m_count = std::min<decltype(m_count)>(m_count,1); 454 return m_count > 0; 455 case Mode::Formatters: 456 if (!entry || entry->DoesPrintChildren(valobj) || summary.empty()) 457 return m_count > 0; 458 return false; 459 } 460 } 461 462 bool 463 DumpValueObjectOptions::PointerDepth::CanAllowExpansion () const 464 { 465 switch (m_mode) 466 { 467 case Mode::Always: 468 case Mode::Default: 469 case Mode::Formatters: 470 return (m_count > 0); 471 case Mode::Never: 472 return false; 473 } 474 } 475 476 bool 477 ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description, 478 DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 479 { 480 const bool is_ref = IsRef (); 481 const bool is_ptr = IsPtr (); 482 483 TypeSummaryImpl* entry = GetSummaryFormatter(); 484 485 if (is_failed_description || m_curr_depth < options.m_max_depth) 486 { 487 // We will show children for all concrete types. We won't show 488 // pointer contents unless a pointer depth has been specified. 489 // We won't reference contents unless the reference is the 490 // root object (depth of zero). 491 492 // Use a new temporary pointer depth in case we override the 493 // current pointer depth below... 494 495 if (is_ptr || is_ref) 496 { 497 // We have a pointer or reference whose value is an address. 498 // Make sure that address is not NULL 499 AddressType ptr_address_type; 500 if (m_valobj->GetPointerValue (&ptr_address_type) == 0) 501 return false; 502 503 const bool is_root_level = m_curr_depth == 0; 504 505 if (is_ref && 506 is_root_level) 507 { 508 // If this is the root object (depth is zero) that we are showing 509 // and it is a reference, and no pointer depth has been supplied 510 // print out what it references. Don't do this at deeper depths 511 // otherwise we can end up with infinite recursion... 512 return true; 513 } 514 515 return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, m_summary); 516 } 517 518 return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty()); 519 } 520 return false; 521 } 522 523 bool 524 ValueObjectPrinter::ShouldExpandEmptyAggregates () 525 { 526 TypeSummaryImpl* entry = GetSummaryFormatter(); 527 528 if (!entry) 529 return true; 530 531 return entry->DoesPrintEmptyAggregates(); 532 } 533 534 ValueObject* 535 ValueObjectPrinter::GetValueObjectForChildrenGeneration () 536 { 537 return m_valobj; 538 } 539 540 void 541 ValueObjectPrinter::PrintChildrenPreamble () 542 { 543 if (options.m_flat_output) 544 { 545 if (ShouldPrintValueObject()) 546 m_stream->EOL(); 547 } 548 else 549 { 550 if (ShouldPrintValueObject()) 551 m_stream->PutCString(IsRef () ? ": {\n" : " {\n"); 552 m_stream->IndentMore(); 553 } 554 } 555 556 void 557 ValueObjectPrinter::PrintChild (ValueObjectSP child_sp, 558 const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 559 { 560 DumpValueObjectOptions child_options(options); 561 child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName(); 562 child_options.SetScopeChecked(true).SetHideName(options.m_hide_name).SetHideValue(options.m_hide_value) 563 .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0); 564 if (child_sp.get()) 565 { 566 ValueObjectPrinter child_printer(child_sp.get(), 567 m_stream, 568 child_options, 569 (IsPtr() || IsRef()) ? --curr_ptr_depth : curr_ptr_depth, 570 m_curr_depth + 1); 571 child_printer.PrintValueObject(); 572 } 573 } 574 575 uint32_t 576 ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot) 577 { 578 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 579 580 size_t num_children = synth_m_valobj->GetNumChildren(); 581 print_dotdotdot = false; 582 if (num_children) 583 { 584 const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 585 586 if (num_children > max_num_children && !options.m_ignore_cap) 587 { 588 print_dotdotdot = true; 589 return max_num_children; 590 } 591 } 592 return num_children; 593 } 594 595 void 596 ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot) 597 { 598 if (!options.m_flat_output) 599 { 600 if (print_dotdotdot) 601 { 602 m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated(); 603 m_stream->Indent("...\n"); 604 } 605 m_stream->IndentLess(); 606 m_stream->Indent("}\n"); 607 } 608 } 609 610 void 611 ValueObjectPrinter::PrintChildren (bool value_printed, 612 bool summary_printed, 613 const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 614 { 615 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 616 617 bool print_dotdotdot = false; 618 size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 619 if (num_children) 620 { 621 PrintChildrenPreamble (); 622 623 for (size_t idx=0; idx<num_children; ++idx) 624 { 625 ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 626 PrintChild (child_sp, curr_ptr_depth); 627 } 628 629 PrintChildrenPostamble (print_dotdotdot); 630 } 631 else if (IsAggregate()) 632 { 633 // Aggregate, no children... 634 if (ShouldPrintValueObject()) 635 { 636 // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value 637 if (m_valobj->DoesProvideSyntheticValue() || !ShouldExpandEmptyAggregates()) 638 m_stream->PutCString( "\n"); 639 else 640 m_stream->PutCString(" {}\n"); 641 } 642 } 643 else 644 { 645 if (ShouldPrintValueObject()) 646 m_stream->EOL(); 647 } 648 } 649 650 bool 651 ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names) 652 { 653 if (!GetMostSpecializedValue () || m_valobj == nullptr) 654 return false; 655 656 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 657 658 bool print_dotdotdot = false; 659 size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 660 661 if (num_children) 662 { 663 m_stream->PutChar('('); 664 665 for (uint32_t idx=0; idx<num_children; ++idx) 666 { 667 lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 668 if (child_sp) 669 child_sp = child_sp->GetQualifiedRepresentationIfAvailable(options.m_use_dynamic, options.m_use_synthetic); 670 if (child_sp) 671 { 672 if (idx) 673 m_stream->PutCString(", "); 674 if (!hide_names) 675 { 676 const char* name = child_sp.get()->GetName().AsCString(); 677 if (name && *name) 678 { 679 m_stream->PutCString(name); 680 m_stream->PutCString(" = "); 681 } 682 } 683 child_sp->DumpPrintableRepresentation(*m_stream, 684 ValueObject::eValueObjectRepresentationStyleSummary, 685 lldb::eFormatInvalid, 686 ValueObject::ePrintableRepresentationSpecialCasesDisable); 687 } 688 } 689 690 if (print_dotdotdot) 691 m_stream->PutCString(", ...)"); 692 else 693 m_stream->PutChar(')'); 694 } 695 return true; 696 } 697 698 void 699 ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed, 700 bool summary_printed) 701 { 702 // this flag controls whether we tried to display a description for this object and failed 703 // if that happens, we want to display the children, if any 704 bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed); 705 706 auto curr_ptr_depth = m_ptr_depth; 707 bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth); 708 bool print_oneline = (curr_ptr_depth.CanAllowExpansion() || 709 options.m_show_types || 710 !options.m_allow_oneliner_mode || 711 options.m_flat_output || 712 options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj); 713 714 if (print_children) 715 { 716 if (print_oneline) 717 { 718 m_stream->PutChar(' '); 719 PrintChildrenOneLiner (false); 720 m_stream->EOL(); 721 } 722 else 723 PrintChildren (value_printed, summary_printed, curr_ptr_depth); 724 } 725 else if (m_curr_depth >= options.m_max_depth && IsAggregate() && ShouldPrintValueObject()) 726 { 727 m_stream->PutCString("{...}\n"); 728 } 729 else 730 m_stream->EOL(); 731 } 732 733 bool 734 ValueObjectPrinter::ShouldPrintValidation () 735 { 736 return options.m_run_validator; 737 } 738 739 bool 740 ValueObjectPrinter::PrintValidationMarkerIfNeeded () 741 { 742 if (!ShouldPrintValidation()) 743 return false; 744 745 m_validation = m_valobj->GetValidationStatus(); 746 747 if (TypeValidatorResult::Failure == m_validation.first) 748 { 749 m_stream->Printf("! "); 750 return true; 751 } 752 753 return false; 754 } 755 756 bool 757 ValueObjectPrinter::PrintValidationErrorIfNeeded () 758 { 759 if (!ShouldPrintValidation()) 760 return false; 761 762 if (TypeValidatorResult::Success == m_validation.first) 763 return false; 764 765 if (m_validation.second.empty()) 766 m_validation.second.assign("unknown error"); 767 768 m_stream->Printf(" ! validation error: %s", m_validation.second.c_str()); 769 m_stream->EOL(); 770 771 return true; 772 } 773