ValueObjectPrinter.cpp revision 288943
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 21using namespace lldb; 22using namespace lldb_private; 23 24DumpValueObjectOptions::DumpValueObjectOptions (ValueObject& valobj) : 25DumpValueObjectOptions() 26{ 27 m_use_dynamic = valobj.GetDynamicValueType(); 28 m_use_synthetic = valobj.IsSynthetic(); 29} 30 31ValueObjectPrinter::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 46ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj, 47 Stream* s, 48 const DumpValueObjectOptions& options) 49{ 50 Init(valobj,s,options,options.m_max_ptr_depth,0); 51} 52 53ValueObjectPrinter::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 62void 63ValueObjectPrinter::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 88bool 89ValueObjectPrinter::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 121bool 122ValueObjectPrinter::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 184const char* 185ValueObjectPrinter::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 195const char* 196ValueObjectPrinter::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 204bool 205ValueObjectPrinter::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 212bool 213ValueObjectPrinter::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 220bool 221ValueObjectPrinter::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 228bool 229ValueObjectPrinter::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 236bool 237ValueObjectPrinter::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 244bool 245ValueObjectPrinter::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 255bool 256ValueObjectPrinter::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 283bool 284ValueObjectPrinter::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 306bool 307ValueObjectPrinter::CheckScopeIfNeeded () 308{ 309 if (options.m_scope_already_checked) 310 return true; 311 return m_valobj->IsInScope(); 312} 313 314TypeSummaryImpl* 315ValueObjectPrinter::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 329void 330ValueObjectPrinter::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 368bool 369ValueObjectPrinter::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 409bool 410ValueObjectPrinter::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 439bool 440ValueObjectPrinter::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 483ValueObject* 484ValueObjectPrinter::GetValueObjectForChildrenGeneration () 485{ 486 return m_valobj; 487} 488 489void 490ValueObjectPrinter::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 505void 506ValueObjectPrinter::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 525uint32_t 526ValueObjectPrinter::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 545void 546ValueObjectPrinter::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 560void 561ValueObjectPrinter::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 598bool 599ValueObjectPrinter::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 646void 647ValueObjectPrinter::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 681bool 682ValueObjectPrinter::ShouldPrintValidation () 683{ 684 return options.m_run_validator; 685} 686 687bool 688ValueObjectPrinter::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 704bool 705ValueObjectPrinter::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