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