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_compiler_type = m_valobj->GetCompilerType(); 180 m_type_flags = m_compiler_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 return false; 461 } 462 463 bool 464 DumpValueObjectOptions::PointerDepth::CanAllowExpansion () const 465 { 466 switch (m_mode) 467 { 468 case Mode::Always: 469 case Mode::Default: 470 case Mode::Formatters: 471 return (m_count > 0); 472 case Mode::Never: 473 return false; 474 } 475 return false; 476 } 477 478 bool 479 ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description, 480 DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 481 { 482 const bool is_ref = IsRef (); 483 const bool is_ptr = IsPtr (); 484 485 TypeSummaryImpl* entry = GetSummaryFormatter(); 486 487 if (is_failed_description || m_curr_depth < options.m_max_depth) 488 { 489 // We will show children for all concrete types. We won't show 490 // pointer contents unless a pointer depth has been specified. 491 // We won't reference contents unless the reference is the 492 // root object (depth of zero). 493 494 // Use a new temporary pointer depth in case we override the 495 // current pointer depth below... 496 497 if (is_ptr || is_ref) 498 { 499 // We have a pointer or reference whose value is an address. 500 // Make sure that address is not NULL 501 AddressType ptr_address_type; 502 if (m_valobj->GetPointerValue (&ptr_address_type) == 0) 503 return false; 504 505 const bool is_root_level = m_curr_depth == 0; 506 507 if (is_ref && 508 is_root_level) 509 { 510 // If this is the root object (depth is zero) that we are showing 511 // and it is a reference, and no pointer depth has been supplied 512 // print out what it references. Don't do this at deeper depths 513 // otherwise we can end up with infinite recursion... 514 return true; 515 } 516 517 return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, m_summary); 518 } 519 520 return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty()); 521 } 522 return false; 523 } 524 525 bool 526 ValueObjectPrinter::ShouldExpandEmptyAggregates () 527 { 528 TypeSummaryImpl* entry = GetSummaryFormatter(); 529 530 if (!entry) 531 return true; 532 533 return entry->DoesPrintEmptyAggregates(); 534 } 535 536 ValueObject* 537 ValueObjectPrinter::GetValueObjectForChildrenGeneration () 538 { 539 return m_valobj; 540 } 541 542 void 543 ValueObjectPrinter::PrintChildrenPreamble () 544 { 545 if (options.m_flat_output) 546 { 547 if (ShouldPrintValueObject()) 548 m_stream->EOL(); 549 } 550 else 551 { 552 if (ShouldPrintValueObject()) 553 m_stream->PutCString(IsRef () ? ": {\n" : " {\n"); 554 m_stream->IndentMore(); 555 } 556 } 557 558 void 559 ValueObjectPrinter::PrintChild (ValueObjectSP child_sp, 560 const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 561 { 562 DumpValueObjectOptions child_options(options); 563 child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName(); 564 child_options.SetScopeChecked(true).SetHideName(options.m_hide_name).SetHideValue(options.m_hide_value) 565 .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0); 566 if (child_sp.get()) 567 { 568 ValueObjectPrinter child_printer(child_sp.get(), 569 m_stream, 570 child_options, 571 (IsPtr() || IsRef()) ? --curr_ptr_depth : curr_ptr_depth, 572 m_curr_depth + 1); 573 child_printer.PrintValueObject(); 574 } 575 } 576 577 uint32_t 578 ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot) 579 { 580 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 581 582 size_t num_children = synth_m_valobj->GetNumChildren(); 583 print_dotdotdot = false; 584 if (num_children) 585 { 586 const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 587 588 if (num_children > max_num_children && !options.m_ignore_cap) 589 { 590 print_dotdotdot = true; 591 return max_num_children; 592 } 593 } 594 return num_children; 595 } 596 597 void 598 ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot) 599 { 600 if (!options.m_flat_output) 601 { 602 if (print_dotdotdot) 603 { 604 m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated(); 605 m_stream->Indent("...\n"); 606 } 607 m_stream->IndentLess(); 608 m_stream->Indent("}\n"); 609 } 610 } 611 612 void 613 ValueObjectPrinter::PrintChildren (bool value_printed, 614 bool summary_printed, 615 const DumpValueObjectOptions::PointerDepth& curr_ptr_depth) 616 { 617 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 618 619 bool print_dotdotdot = false; 620 size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 621 if (num_children) 622 { 623 PrintChildrenPreamble (); 624 625 for (size_t idx=0; idx<num_children; ++idx) 626 { 627 ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 628 PrintChild (child_sp, curr_ptr_depth); 629 } 630 631 PrintChildrenPostamble (print_dotdotdot); 632 } 633 else if (IsAggregate()) 634 { 635 // Aggregate, no children... 636 if (ShouldPrintValueObject()) 637 { 638 // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value 639 if (m_valobj->DoesProvideSyntheticValue() || !ShouldExpandEmptyAggregates()) 640 m_stream->PutCString( "\n"); 641 else 642 m_stream->PutCString(" {}\n"); 643 } 644 } 645 else 646 { 647 if (ShouldPrintValueObject()) 648 m_stream->EOL(); 649 } 650 } 651 652 bool 653 ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names) 654 { 655 if (!GetMostSpecializedValue () || m_valobj == nullptr) 656 return false; 657 658 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration(); 659 660 bool print_dotdotdot = false; 661 size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot); 662 663 if (num_children) 664 { 665 m_stream->PutChar('('); 666 667 for (uint32_t idx=0; idx<num_children; ++idx) 668 { 669 lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); 670 if (child_sp) 671 child_sp = child_sp->GetQualifiedRepresentationIfAvailable(options.m_use_dynamic, options.m_use_synthetic); 672 if (child_sp) 673 { 674 if (idx) 675 m_stream->PutCString(", "); 676 if (!hide_names) 677 { 678 const char* name = child_sp.get()->GetName().AsCString(); 679 if (name && *name) 680 { 681 m_stream->PutCString(name); 682 m_stream->PutCString(" = "); 683 } 684 } 685 child_sp->DumpPrintableRepresentation(*m_stream, 686 ValueObject::eValueObjectRepresentationStyleSummary, 687 lldb::eFormatInvalid, 688 ValueObject::ePrintableRepresentationSpecialCasesDisable); 689 } 690 } 691 692 if (print_dotdotdot) 693 m_stream->PutCString(", ...)"); 694 else 695 m_stream->PutChar(')'); 696 } 697 return true; 698 } 699 700 void 701 ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed, 702 bool summary_printed) 703 { 704 // this flag controls whether we tried to display a description for this object and failed 705 // if that happens, we want to display the children, if any 706 bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed); 707 708 auto curr_ptr_depth = m_ptr_depth; 709 bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth); 710 bool print_oneline = (curr_ptr_depth.CanAllowExpansion() || 711 options.m_show_types || 712 !options.m_allow_oneliner_mode || 713 options.m_flat_output || 714 options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj); 715 716 if (print_children) 717 { 718 if (print_oneline) 719 { 720 m_stream->PutChar(' '); 721 PrintChildrenOneLiner (false); 722 m_stream->EOL(); 723 } 724 else 725 PrintChildren (value_printed, summary_printed, curr_ptr_depth); 726 } 727 else if (m_curr_depth >= options.m_max_depth && IsAggregate() && ShouldPrintValueObject()) 728 { 729 m_stream->PutCString("{...}\n"); 730 } 731 else 732 m_stream->EOL(); 733 } 734 735 bool 736 ValueObjectPrinter::ShouldPrintValidation () 737 { 738 return options.m_run_validator; 739 } 740 741 bool 742 ValueObjectPrinter::PrintValidationMarkerIfNeeded () 743 { 744 if (!ShouldPrintValidation()) 745 return false; 746 747 m_validation = m_valobj->GetValidationStatus(); 748 749 if (TypeValidatorResult::Failure == m_validation.first) 750 { 751 m_stream->Printf("! "); 752 return true; 753 } 754 755 return false; 756 } 757 758 bool 759 ValueObjectPrinter::PrintValidationErrorIfNeeded () 760 { 761 if (!ShouldPrintValidation()) 762 return false; 763 764 if (TypeValidatorResult::Success == m_validation.first) 765 return false; 766 767 if (m_validation.second.empty()) 768 m_validation.second.assign("unknown error"); 769 770 m_stream->Printf(" ! validation error: %s", m_validation.second.c_str()); 771 m_stream->EOL(); 772 773 return true; 774 } 775