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