1 //===-- ValueObject.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/Core/ValueObject.h" 11 12 // C Includes 13 #include <stdlib.h> 14 15 // C++ Includes 16 // Other libraries and framework includes 17 #include "llvm/Support/raw_ostream.h" 18 #include "clang/AST/Type.h" 19 20 // Project includes 21 #include "lldb/Core/DataBufferHeap.h" 22 #include "lldb/Core/StreamString.h" 23 #include "lldb/Core/ValueObjectChild.h" 24 #include "lldb/Core/ValueObjectList.h" 25 26 #include "lldb/Symbol/ClangASTType.h" 27 #include "lldb/Symbol/ClangASTContext.h" 28 #include "lldb/Symbol/Type.h" 29 30 #include "lldb/Target/ExecutionContext.h" 31 #include "lldb/Target/LanguageRuntime.h" 32 #include "lldb/Target/Process.h" 33 #include "lldb/Target/RegisterContext.h" 34 #include "lldb/Target/Target.h" 35 #include "lldb/Target/Thread.h" 36 37 using namespace lldb; 38 using namespace lldb_private; 39 40 static lldb::user_id_t g_value_obj_uid = 0; 41 42 //---------------------------------------------------------------------- 43 // ValueObject constructor 44 //---------------------------------------------------------------------- 45 ValueObject::ValueObject (ValueObject *parent) : 46 UserID (++g_value_obj_uid), // Unique identifier for every value object 47 m_parent (parent), 48 m_update_id (0), // Value object lists always start at 1, value objects start at zero 49 m_name (), 50 m_data (), 51 m_value (), 52 m_error (), 53 m_value_str (), 54 m_old_value_str (), 55 m_location_str (), 56 m_summary_str (), 57 m_object_desc_str (), 58 m_children (), 59 m_synthetic_children (), 60 m_dynamic_value_sp (), 61 m_format (eFormatDefault), 62 m_value_is_valid (false), 63 m_value_did_change (false), 64 m_children_count_valid (false), 65 m_old_value_valid (false) 66 { 67 } 68 69 //---------------------------------------------------------------------- 70 // Destructor 71 //---------------------------------------------------------------------- 72 ValueObject::~ValueObject () 73 { 74 } 75 76 user_id_t 77 ValueObject::GetUpdateID() const 78 { 79 return m_update_id; 80 } 81 82 bool 83 ValueObject::UpdateValueIfNeeded (ExecutionContextScope *exe_scope) 84 { 85 // If this is a constant value, then our success is predicated on whether 86 // we have an error or not 87 if (GetIsConstant()) 88 return m_error.Success(); 89 90 if (exe_scope) 91 { 92 Process *process = exe_scope->CalculateProcess(); 93 if (process) 94 { 95 const user_id_t stop_id = process->GetStopID(); 96 if (m_update_id != stop_id) 97 { 98 bool first_update = m_update_id == 0; 99 // Save the old value using swap to avoid a string copy which 100 // also will clear our m_value_str 101 if (m_value_str.empty()) 102 { 103 m_old_value_valid = false; 104 } 105 else 106 { 107 m_old_value_valid = true; 108 m_old_value_str.swap (m_value_str); 109 m_value_str.clear(); 110 } 111 m_location_str.clear(); 112 m_summary_str.clear(); 113 m_object_desc_str.clear(); 114 115 const bool value_was_valid = GetValueIsValid(); 116 SetValueDidChange (false); 117 118 m_error.Clear(); 119 120 // Call the pure virtual function to update the value 121 UpdateValue (exe_scope); 122 123 // Update the fact that we tried to update the value for this 124 // value object whether or not we succeed 125 m_update_id = stop_id; 126 bool success = m_error.Success(); 127 SetValueIsValid (success); 128 129 if (first_update) 130 SetValueDidChange (false); 131 else if (!m_value_did_change && success == false) 132 { 133 // The value wasn't gotten successfully, so we mark this 134 // as changed if the value used to be valid and now isn't 135 SetValueDidChange (value_was_valid); 136 } 137 } 138 } 139 } 140 return m_error.Success(); 141 } 142 143 const DataExtractor & 144 ValueObject::GetDataExtractor () const 145 { 146 return m_data; 147 } 148 149 DataExtractor & 150 ValueObject::GetDataExtractor () 151 { 152 return m_data; 153 } 154 155 const Error & 156 ValueObject::GetError() const 157 { 158 return m_error; 159 } 160 161 const ConstString & 162 ValueObject::GetName() const 163 { 164 return m_name; 165 } 166 167 const char * 168 ValueObject::GetLocationAsCString (ExecutionContextScope *exe_scope) 169 { 170 if (UpdateValueIfNeeded(exe_scope)) 171 { 172 if (m_location_str.empty()) 173 { 174 StreamString sstr; 175 176 switch (m_value.GetValueType()) 177 { 178 default: 179 break; 180 181 case Value::eValueTypeScalar: 182 if (m_value.GetContextType() == Value::eContextTypeDCRegisterInfo) 183 { 184 RegisterInfo *reg_info = m_value.GetRegisterInfo(); 185 if (reg_info) 186 { 187 if (reg_info->name) 188 m_location_str = reg_info->name; 189 else if (reg_info->alt_name) 190 m_location_str = reg_info->alt_name; 191 break; 192 } 193 } 194 m_location_str = "scalar"; 195 break; 196 197 case Value::eValueTypeLoadAddress: 198 case Value::eValueTypeFileAddress: 199 case Value::eValueTypeHostAddress: 200 { 201 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2; 202 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS)); 203 m_location_str.swap(sstr.GetString()); 204 } 205 break; 206 } 207 } 208 } 209 return m_location_str.c_str(); 210 } 211 212 Value & 213 ValueObject::GetValue() 214 { 215 return m_value; 216 } 217 218 const Value & 219 ValueObject::GetValue() const 220 { 221 return m_value; 222 } 223 224 bool 225 ValueObject::GetValueIsValid () const 226 { 227 return m_value_is_valid; 228 } 229 230 231 void 232 ValueObject::SetValueIsValid (bool b) 233 { 234 m_value_is_valid = b; 235 } 236 237 bool 238 ValueObject::GetValueDidChange (ExecutionContextScope *exe_scope) 239 { 240 GetValueAsCString (exe_scope); 241 return m_value_did_change; 242 } 243 244 void 245 ValueObject::SetValueDidChange (bool value_changed) 246 { 247 m_value_did_change = value_changed; 248 } 249 250 ValueObjectSP 251 ValueObject::GetChildAtIndex (uint32_t idx, bool can_create) 252 { 253 ValueObjectSP child_sp; 254 if (idx < GetNumChildren()) 255 { 256 // Check if we have already made the child value object? 257 if (can_create && m_children[idx].get() == NULL) 258 { 259 // No we haven't created the child at this index, so lets have our 260 // subclass do it and cache the result for quick future access. 261 m_children[idx] = CreateChildAtIndex (idx, false, 0); 262 } 263 264 child_sp = m_children[idx]; 265 } 266 return child_sp; 267 } 268 269 uint32_t 270 ValueObject::GetIndexOfChildWithName (const ConstString &name) 271 { 272 bool omit_empty_base_classes = true; 273 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(), 274 GetClangType(), 275 name.AsCString(), 276 omit_empty_base_classes); 277 } 278 279 ValueObjectSP 280 ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create) 281 { 282 // when getting a child by name, it could be burried inside some base 283 // classes (which really aren't part of the expression path), so we 284 // need a vector of indexes that can get us down to the correct child 285 std::vector<uint32_t> child_indexes; 286 clang::ASTContext *clang_ast = GetClangAST(); 287 void *clang_type = GetClangType(); 288 bool omit_empty_base_classes = true; 289 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast, 290 clang_type, 291 name.AsCString(), 292 omit_empty_base_classes, 293 child_indexes); 294 ValueObjectSP child_sp; 295 if (num_child_indexes > 0) 296 { 297 std::vector<uint32_t>::const_iterator pos = child_indexes.begin (); 298 std::vector<uint32_t>::const_iterator end = child_indexes.end (); 299 300 child_sp = GetChildAtIndex(*pos, can_create); 301 for (++pos; pos != end; ++pos) 302 { 303 if (child_sp) 304 { 305 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create)); 306 child_sp = new_child_sp; 307 } 308 else 309 { 310 child_sp.reset(); 311 } 312 313 } 314 } 315 return child_sp; 316 } 317 318 319 uint32_t 320 ValueObject::GetNumChildren () 321 { 322 if (!m_children_count_valid) 323 { 324 SetNumChildren (CalculateNumChildren()); 325 } 326 return m_children.size(); 327 } 328 void 329 ValueObject::SetNumChildren (uint32_t num_children) 330 { 331 m_children_count_valid = true; 332 m_children.resize(num_children); 333 } 334 335 void 336 ValueObject::SetName (const char *name) 337 { 338 m_name.SetCString(name); 339 } 340 341 void 342 ValueObject::SetName (const ConstString &name) 343 { 344 m_name = name; 345 } 346 347 ValueObjectSP 348 ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index) 349 { 350 ValueObjectSP valobj_sp; 351 bool omit_empty_base_classes = true; 352 353 std::string child_name_str; 354 uint32_t child_byte_size = 0; 355 int32_t child_byte_offset = 0; 356 uint32_t child_bitfield_bit_size = 0; 357 uint32_t child_bitfield_bit_offset = 0; 358 bool child_is_base_class = false; 359 const bool transparent_pointers = synthetic_array_member == false; 360 clang::ASTContext *clang_ast = GetClangAST(); 361 void *clang_type = GetClangType(); 362 void *child_clang_type; 363 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (clang_ast, 364 GetName().AsCString(), 365 clang_type, 366 idx, 367 transparent_pointers, 368 omit_empty_base_classes, 369 child_name_str, 370 child_byte_size, 371 child_byte_offset, 372 child_bitfield_bit_size, 373 child_bitfield_bit_offset, 374 child_is_base_class); 375 if (child_clang_type) 376 { 377 if (synthetic_index) 378 child_byte_offset += child_byte_size * synthetic_index; 379 380 ConstString child_name; 381 if (!child_name_str.empty()) 382 child_name.SetCString (child_name_str.c_str()); 383 384 valobj_sp.reset (new ValueObjectChild (this, 385 clang_ast, 386 child_clang_type, 387 child_name, 388 child_byte_size, 389 child_byte_offset, 390 child_bitfield_bit_size, 391 child_bitfield_bit_offset, 392 child_is_base_class)); 393 } 394 return valobj_sp; 395 } 396 397 const char * 398 ValueObject::GetSummaryAsCString (ExecutionContextScope *exe_scope) 399 { 400 if (UpdateValueIfNeeded (exe_scope)) 401 { 402 if (m_summary_str.empty()) 403 { 404 void *clang_type = GetClangType(); 405 406 // See if this is a pointer to a C string? 407 uint32_t fixed_length = 0; 408 if (clang_type) 409 { 410 StreamString sstr; 411 412 if (ClangASTContext::IsCStringType (clang_type, fixed_length)) 413 { 414 Process *process = exe_scope->CalculateProcess(); 415 if (process != NULL) 416 { 417 lldb::AddressType cstr_address_type = eAddressTypeInvalid; 418 lldb::addr_t cstr_address = GetPointerValue (cstr_address_type, true); 419 420 if (cstr_address != LLDB_INVALID_ADDRESS) 421 { 422 DataExtractor data; 423 size_t bytes_read = 0; 424 std::vector<char> data_buffer; 425 std::vector<char> cstr_buffer; 426 size_t cstr_length; 427 Error error; 428 if (fixed_length > 0) 429 { 430 data_buffer.resize(fixed_length); 431 // Resize the formatted buffer in case every character 432 // uses the "\xXX" format and one extra byte for a NULL 433 cstr_buffer.resize(data_buffer.size() * 4 + 1); 434 data.SetData (&data_buffer.front(), data_buffer.size(), eByteOrderHost); 435 bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), fixed_length, error); 436 if (bytes_read > 0) 437 { 438 sstr << '"'; 439 cstr_length = data.Dump (&sstr, 440 0, // Start offset in "data" 441 eFormatChar, // Print as characters 442 1, // Size of item (1 byte for a char!) 443 bytes_read, // How many bytes to print? 444 UINT32_MAX, // num per line 445 LLDB_INVALID_ADDRESS,// base address 446 0, // bitfield bit size 447 0); // bitfield bit offset 448 sstr << '"'; 449 } 450 } 451 else 452 { 453 const size_t k_max_buf_size = 256; 454 data_buffer.resize (k_max_buf_size + 1); 455 // NULL terminate in case we don't get the entire C string 456 data_buffer.back() = '\0'; 457 // Make a formatted buffer that can contain take 4 458 // bytes per character in case each byte uses the 459 // "\xXX" format and one extra byte for a NULL 460 cstr_buffer.resize (k_max_buf_size * 4 + 1); 461 462 data.SetData (&data_buffer.front(), data_buffer.size(), eByteOrderHost); 463 size_t total_cstr_len = 0; 464 while ((bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), k_max_buf_size, error)) > 0) 465 { 466 size_t len = strlen(&data_buffer.front()); 467 if (len == 0) 468 break; 469 if (len > bytes_read) 470 len = bytes_read; 471 if (sstr.GetSize() == 0) 472 sstr << '"'; 473 474 cstr_length = data.Dump (&sstr, 475 0, // Start offset in "data" 476 eFormatChar, // Print as characters 477 1, // Size of item (1 byte for a char!) 478 len, // How many bytes to print? 479 UINT32_MAX, // num per line 480 LLDB_INVALID_ADDRESS,// base address 481 0, // bitfield bit size 482 0); // bitfield bit offset 483 484 if (len < k_max_buf_size) 485 break; 486 cstr_address += total_cstr_len; 487 } 488 if (sstr.GetSize() > 0) 489 sstr << '"'; 490 } 491 } 492 } 493 494 if (sstr.GetSize() > 0) 495 m_summary_str.assign (sstr.GetData(), sstr.GetSize()); 496 } 497 else if (ClangASTContext::IsFunctionPointerType (clang_type)) 498 { 499 lldb::AddressType func_ptr_address_type = eAddressTypeInvalid; 500 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true); 501 502 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS) 503 { 504 switch (func_ptr_address_type) 505 { 506 case eAddressTypeInvalid: 507 case eAddressTypeFile: 508 break; 509 510 case eAddressTypeLoad: 511 { 512 Address so_addr; 513 Target *target = exe_scope->CalculateTarget(); 514 if (target && target->GetSectionLoadList().IsEmpty() == false) 515 { 516 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr)) 517 { 518 so_addr.Dump (&sstr, 519 exe_scope, 520 Address::DumpStyleResolvedDescription, 521 Address::DumpStyleSectionNameOffset); 522 } 523 } 524 } 525 break; 526 527 case eAddressTypeHost: 528 break; 529 } 530 } 531 if (sstr.GetSize() > 0) 532 { 533 m_summary_str.assign (1, '('); 534 m_summary_str.append (sstr.GetData(), sstr.GetSize()); 535 m_summary_str.append (1, ')'); 536 } 537 } 538 } 539 } 540 } 541 if (m_summary_str.empty()) 542 return NULL; 543 return m_summary_str.c_str(); 544 } 545 546 const char * 547 ValueObject::GetObjectDescription (ExecutionContextScope *exe_scope) 548 { 549 if (!m_object_desc_str.empty()) 550 return m_object_desc_str.c_str(); 551 552 if (!GetValueIsValid()) 553 return NULL; 554 555 Process *process = exe_scope->CalculateProcess(); 556 if (process == NULL) 557 return NULL; 558 559 StreamString s; 560 561 lldb::LanguageType language = GetObjectRuntimeLanguage(); 562 LanguageRuntime *runtime = process->GetLanguageRuntime(language); 563 564 if (runtime && runtime->GetObjectDescription(s, *this, exe_scope)) 565 { 566 m_object_desc_str.append (s.GetData()); 567 } 568 return m_object_desc_str.c_str(); 569 } 570 571 const char * 572 ValueObject::GetValueAsCString (ExecutionContextScope *exe_scope) 573 { 574 // If our byte size is zero this is an aggregate type that has children 575 if (ClangASTContext::IsAggregateType (GetClangType()) == false) 576 { 577 if (UpdateValueIfNeeded(exe_scope)) 578 { 579 if (m_value_str.empty()) 580 { 581 const Value::ContextType context_type = m_value.GetContextType(); 582 583 switch (context_type) 584 { 585 case Value::eContextTypeOpaqueClangQualType: 586 case Value::eContextTypeDCType: 587 case Value::eContextTypeDCVariable: 588 { 589 void *clang_type = GetClangType (); 590 if (clang_type) 591 { 592 StreamString sstr; 593 if (m_format == eFormatDefault) 594 m_format = ClangASTType::GetFormat(clang_type); 595 596 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST 597 clang_type, // The clang type to display 598 &sstr, 599 m_format, // Format to display this type with 600 m_data, // Data to extract from 601 0, // Byte offset into "m_data" 602 GetByteSize(), // Byte size of item in "m_data" 603 GetBitfieldBitSize(), // Bitfield bit size 604 GetBitfieldBitOffset())) // Bitfield bit offset 605 m_value_str.swap(sstr.GetString()); 606 else 607 m_value_str.clear(); 608 } 609 } 610 break; 611 612 case Value::eContextTypeDCRegisterInfo: 613 { 614 const RegisterInfo *reg_info = m_value.GetRegisterInfo(); 615 if (reg_info) 616 { 617 StreamString reg_sstr; 618 m_data.Dump(®_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 619 m_value_str.swap(reg_sstr.GetString()); 620 } 621 } 622 break; 623 624 default: 625 break; 626 } 627 } 628 629 if (!m_value_did_change && m_old_value_valid) 630 { 631 // The value was gotten successfully, so we consider the 632 // value as changed if the value string differs 633 SetValueDidChange (m_old_value_str != m_value_str); 634 } 635 } 636 } 637 if (m_value_str.empty()) 638 return NULL; 639 return m_value_str.c_str(); 640 } 641 642 addr_t 643 ValueObject::GetPointerValue (lldb::AddressType &address_type, bool scalar_is_load_address) 644 { 645 lldb::addr_t address = LLDB_INVALID_ADDRESS; 646 address_type = eAddressTypeInvalid; 647 switch (GetValue().GetValueType()) 648 { 649 case Value::eValueTypeScalar: 650 if (scalar_is_load_address) 651 { 652 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 653 address_type = eAddressTypeLoad; 654 } 655 break; 656 657 case Value::eValueTypeLoadAddress: 658 case Value::eValueTypeFileAddress: 659 case Value::eValueTypeHostAddress: 660 { 661 uint32_t data_offset = 0; 662 address = m_data.GetPointer(&data_offset); 663 address_type = m_value.GetValueAddressType(); 664 if (address_type == eAddressTypeInvalid) 665 address_type = eAddressTypeLoad; 666 } 667 break; 668 } 669 return address; 670 } 671 672 bool 673 ValueObject::SetValueFromCString (ExecutionContextScope *exe_scope, const char *value_str) 674 { 675 // Make sure our value is up to date first so that our location and location 676 // type is valid. 677 if (!UpdateValueIfNeeded(exe_scope)) 678 return false; 679 680 uint32_t count = 0; 681 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count); 682 683 char *end = NULL; 684 const size_t byte_size = GetByteSize(); 685 switch (encoding) 686 { 687 case eEncodingInvalid: 688 return false; 689 690 case eEncodingUint: 691 if (byte_size > sizeof(unsigned long long)) 692 { 693 return false; 694 } 695 else 696 { 697 unsigned long long ull_val = strtoull(value_str, &end, 0); 698 if (end && *end != '\0') 699 return false; 700 m_value = ull_val; 701 // Limit the bytes in our m_data appropriately. 702 m_value.GetScalar().GetData (m_data, byte_size); 703 } 704 break; 705 706 case eEncodingSint: 707 if (byte_size > sizeof(long long)) 708 { 709 return false; 710 } 711 else 712 { 713 long long sll_val = strtoll(value_str, &end, 0); 714 if (end && *end != '\0') 715 return false; 716 m_value = sll_val; 717 // Limit the bytes in our m_data appropriately. 718 m_value.GetScalar().GetData (m_data, byte_size); 719 } 720 break; 721 722 case eEncodingIEEE754: 723 { 724 const off_t byte_offset = GetByteOffset(); 725 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size)); 726 if (dst != NULL) 727 { 728 // We are decoding a float into host byte order below, so make 729 // sure m_data knows what it contains. 730 m_data.SetByteOrder(eByteOrderHost); 731 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue ( 732 GetClangAST(), 733 GetClangType(), 734 value_str, 735 dst, 736 byte_size); 737 738 if (converted_byte_size == byte_size) 739 { 740 } 741 } 742 } 743 break; 744 745 case eEncodingVector: 746 return false; 747 748 default: 749 return false; 750 } 751 752 // If we have made it here the value is in m_data and we should write it 753 // out to the target 754 return Write (); 755 } 756 757 bool 758 ValueObject::Write () 759 { 760 // Clear the update ID so the next time we try and read the value 761 // we try and read it again. 762 m_update_id = 0; 763 764 // TODO: when Value has a method to write a value back, call it from here. 765 return false; 766 767 } 768 769 lldb::LanguageType 770 ValueObject::GetObjectRuntimeLanguage () 771 { 772 void *opaque_qual_type = GetClangType(); 773 if (opaque_qual_type == NULL) 774 return lldb::eLanguageTypeC; 775 776 // If the type is a reference, then resolve it to what it refers to first: 777 clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType()); 778 if (qual_type->isAnyPointerType()) 779 { 780 if (qual_type->isObjCObjectPointerType()) 781 return lldb::eLanguageTypeObjC; 782 783 clang::QualType pointee_type (qual_type->getPointeeType()); 784 if (pointee_type->getCXXRecordDeclForPointerType() != NULL) 785 return lldb::eLanguageTypeC_plus_plus; 786 if (pointee_type->isObjCObjectOrInterfaceType()) 787 return lldb::eLanguageTypeObjC; 788 if (pointee_type->isObjCClassType()) 789 return lldb::eLanguageTypeObjC; 790 } 791 else 792 { 793 if (ClangASTContext::IsObjCClassType (opaque_qual_type)) 794 return lldb::eLanguageTypeObjC; 795 if (ClangASTContext::IsCXXClassType (opaque_qual_type)) 796 return lldb::eLanguageTypeC_plus_plus; 797 } 798 799 return lldb::eLanguageTypeC; 800 } 801 802 void 803 ValueObject::AddSyntheticChild (const ConstString &key, ValueObjectSP& valobj_sp) 804 { 805 m_synthetic_children[key] = valobj_sp; 806 } 807 808 ValueObjectSP 809 ValueObject::GetSyntheticChild (const ConstString &key) const 810 { 811 ValueObjectSP synthetic_child_sp; 812 std::map<ConstString, ValueObjectSP>::const_iterator pos = m_synthetic_children.find (key); 813 if (pos != m_synthetic_children.end()) 814 synthetic_child_sp = pos->second; 815 return synthetic_child_sp; 816 } 817 818 bool 819 ValueObject::IsPointerType () 820 { 821 return ClangASTContext::IsPointerType (GetClangType()); 822 } 823 824 bool 825 ValueObject::IsPointerOrReferenceType () 826 { 827 return ClangASTContext::IsPointerOrReferenceType(GetClangType()); 828 } 829 830 ValueObjectSP 831 ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create) 832 { 833 ValueObjectSP synthetic_child_sp; 834 if (IsPointerType ()) 835 { 836 char index_str[64]; 837 snprintf(index_str, sizeof(index_str), "[%i]", index); 838 ConstString index_const_str(index_str); 839 // Check if we have already created a synthetic array member in this 840 // valid object. If we have we will re-use it. 841 synthetic_child_sp = GetSyntheticChild (index_const_str); 842 if (!synthetic_child_sp) 843 { 844 // We haven't made a synthetic array member for INDEX yet, so 845 // lets make one and cache it for any future reference. 846 synthetic_child_sp = CreateChildAtIndex(0, true, index); 847 848 // Cache the value if we got one back... 849 if (synthetic_child_sp) 850 AddSyntheticChild(index_const_str, synthetic_child_sp); 851 } 852 } 853 return synthetic_child_sp; 854 } 855 856 bool 857 ValueObject::SetDynamicValue () 858 { 859 if (!IsPointerOrReferenceType()) 860 return false; 861 862 // Check that the runtime class is correct for determining the most specific class. 863 // If it is a C++ class, see if it is dynamic: 864 865 return true; 866 } 867 868 869 void 870 ValueObject::GetExpressionPath (Stream &s) 871 { 872 if (m_parent) 873 { 874 m_parent->GetExpressionPath (s); 875 clang_type_t parent_clang_type = m_parent->GetClangType(); 876 if (parent_clang_type) 877 { 878 if (ClangASTContext::IsPointerType(parent_clang_type)) 879 { 880 s.PutCString("->"); 881 } 882 else if (ClangASTContext::IsAggregateType (parent_clang_type)) 883 { 884 if (ClangASTContext::IsArrayType (parent_clang_type) == false && 885 m_parent->IsBaseClass() == false) 886 s.PutChar('.'); 887 } 888 } 889 } 890 891 if (IsBaseClass()) 892 { 893 clang_type_t clang_type = GetClangType(); 894 std::string cxx_class_name; 895 if (ClangASTContext::GetCXXClassName (clang_type, cxx_class_name)) 896 { 897 s << cxx_class_name.c_str() << "::"; 898 } 899 } 900 else 901 { 902 const char *name = GetName().AsCString(); 903 if (name) 904 s.PutCString(name); 905 } 906 } 907 908 909 void 910 ValueObject::DumpValueObject 911 ( 912 Stream &s, 913 ExecutionContextScope *exe_scope, 914 ValueObject *valobj, 915 const char *root_valobj_name, 916 uint32_t ptr_depth, 917 uint32_t curr_depth, 918 uint32_t max_depth, 919 bool show_types, 920 bool show_location, 921 bool use_objc, 922 bool scope_already_checked, 923 bool flat_output 924 ) 925 { 926 if (valobj) 927 { 928 //const char *loc_cstr = valobj->GetLocationAsCString(); 929 clang_type_t clang_type = valobj->GetClangType(); 930 931 const Flags type_info_flags (ClangASTContext::GetTypeInfoMask (clang_type)); 932 const char *err_cstr = NULL; 933 const bool has_children = type_info_flags.IsSet (ClangASTContext::eTypeHasChildren); 934 const bool has_value = type_info_flags.IsSet (ClangASTContext::eTypeHasValue); 935 936 const bool print_valobj = flat_output == false || has_value; 937 938 if (print_valobj) 939 { 940 if (show_location) 941 { 942 s.Printf("%s: ", valobj->GetLocationAsCString(exe_scope)); 943 } 944 945 s.Indent(); 946 947 if (show_types) 948 s.Printf("(%s) ", valobj->GetTypeName().AsCString()); 949 950 951 if (flat_output) 952 { 953 valobj->GetExpressionPath(s); 954 s.PutCString(" ="); 955 } 956 else 957 { 958 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString(""); 959 s.Printf ("%s =", name_cstr); 960 } 961 962 if (!scope_already_checked && !valobj->IsInScope(exe_scope->CalculateStackFrame())) 963 { 964 err_cstr = "error: out of scope"; 965 } 966 } 967 968 const char *val_cstr = NULL; 969 970 if (err_cstr == NULL) 971 { 972 val_cstr = valobj->GetValueAsCString(exe_scope); 973 err_cstr = valobj->GetError().AsCString(); 974 } 975 976 if (err_cstr) 977 { 978 s.Printf ("error: %s", err_cstr); 979 } 980 else 981 { 982 if (print_valobj) 983 { 984 const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope); 985 986 if (val_cstr) 987 s.Printf(" %s", val_cstr); 988 989 if (sum_cstr) 990 s.Printf(" %s", sum_cstr); 991 992 if (use_objc) 993 { 994 const char *object_desc = valobj->GetObjectDescription(exe_scope); 995 if (object_desc) 996 s.Printf(" %s\n", object_desc); 997 else 998 s.Printf ("No description available.\n"); 999 return; 1000 } 1001 } 1002 1003 if (curr_depth < max_depth) 1004 { 1005 bool is_ptr_or_ref = type_info_flags.IsSet (ClangASTContext::eTypeIsPointer | ClangASTContext::eTypeIsReference); 1006 1007 if (!is_ptr_or_ref || ptr_depth > 0) 1008 { 1009 const uint32_t num_children = valobj->GetNumChildren(); 1010 if (num_children) 1011 { 1012 if (flat_output) 1013 { 1014 if (print_valobj) 1015 s.EOL(); 1016 } 1017 else 1018 { 1019 if (print_valobj) 1020 s.PutCString(" {\n"); 1021 s.IndentMore(); 1022 } 1023 1024 for (uint32_t idx=0; idx<num_children; ++idx) 1025 { 1026 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true)); 1027 if (child_sp.get()) 1028 { 1029 DumpValueObject (s, 1030 exe_scope, 1031 child_sp.get(), 1032 NULL, 1033 is_ptr_or_ref ? ptr_depth - 1 : ptr_depth, 1034 curr_depth + 1, 1035 max_depth, 1036 show_types, 1037 show_location, 1038 false, 1039 true, 1040 flat_output); 1041 } 1042 } 1043 1044 if (!flat_output) 1045 { 1046 s.IndentLess(); 1047 s.Indent("}\n"); 1048 } 1049 } 1050 else if (has_children) 1051 { 1052 // Aggregate, no children... 1053 if (print_valobj) 1054 s.PutCString("{}\n"); 1055 } 1056 else 1057 { 1058 if (print_valobj) 1059 s.EOL(); 1060 } 1061 1062 } 1063 else 1064 { 1065 // We printed a pointer, but we are stopping and not printing 1066 // and children of this pointer... 1067 s.EOL(); 1068 } 1069 } 1070 else 1071 { 1072 if (has_children && print_valobj) 1073 { 1074 s.PutCString("{...}\n"); 1075 } 1076 } 1077 } 1078 } 1079 } 1080 1081