ValueObject.cpp revision 0baa394cd55c6dfb7a6259d215d0dea2b708067b
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 37using namespace lldb; 38using namespace lldb_private; 39 40static lldb::user_id_t g_value_obj_uid = 0; 41 42//---------------------------------------------------------------------- 43// ValueObject constructor 44//---------------------------------------------------------------------- 45ValueObject::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//---------------------------------------------------------------------- 72ValueObject::~ValueObject () 73{ 74} 75 76user_id_t 77ValueObject::GetUpdateID() const 78{ 79 return m_update_id; 80} 81 82bool 83ValueObject::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 143const DataExtractor & 144ValueObject::GetDataExtractor () const 145{ 146 return m_data; 147} 148 149DataExtractor & 150ValueObject::GetDataExtractor () 151{ 152 return m_data; 153} 154 155const Error & 156ValueObject::GetError() const 157{ 158 return m_error; 159} 160 161const ConstString & 162ValueObject::GetName() const 163{ 164 return m_name; 165} 166 167const char * 168ValueObject::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 212Value & 213ValueObject::GetValue() 214{ 215 return m_value; 216} 217 218const Value & 219ValueObject::GetValue() const 220{ 221 return m_value; 222} 223 224bool 225ValueObject::ResolveValue (ExecutionContextScope *exe_scope, Scalar &scalar) 226{ 227 ExecutionContext exe_ctx; 228 exe_scope->CalculateExecutionContext(exe_ctx); 229 scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ()); 230 return scalar.IsValid(); 231} 232 233bool 234ValueObject::GetValueIsValid () const 235{ 236 return m_value_is_valid; 237} 238 239 240void 241ValueObject::SetValueIsValid (bool b) 242{ 243 m_value_is_valid = b; 244} 245 246bool 247ValueObject::GetValueDidChange (ExecutionContextScope *exe_scope) 248{ 249 GetValueAsCString (exe_scope); 250 return m_value_did_change; 251} 252 253void 254ValueObject::SetValueDidChange (bool value_changed) 255{ 256 m_value_did_change = value_changed; 257} 258 259ValueObjectSP 260ValueObject::GetChildAtIndex (uint32_t idx, bool can_create) 261{ 262 ValueObjectSP child_sp; 263 if (idx < GetNumChildren()) 264 { 265 // Check if we have already made the child value object? 266 if (can_create && m_children[idx].get() == NULL) 267 { 268 // No we haven't created the child at this index, so lets have our 269 // subclass do it and cache the result for quick future access. 270 m_children[idx] = CreateChildAtIndex (idx, false, 0); 271 } 272 273 child_sp = m_children[idx]; 274 } 275 return child_sp; 276} 277 278uint32_t 279ValueObject::GetIndexOfChildWithName (const ConstString &name) 280{ 281 bool omit_empty_base_classes = true; 282 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(), 283 GetClangType(), 284 name.AsCString(), 285 omit_empty_base_classes); 286} 287 288ValueObjectSP 289ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create) 290{ 291 // when getting a child by name, it could be burried inside some base 292 // classes (which really aren't part of the expression path), so we 293 // need a vector of indexes that can get us down to the correct child 294 std::vector<uint32_t> child_indexes; 295 clang::ASTContext *clang_ast = GetClangAST(); 296 void *clang_type = GetClangType(); 297 bool omit_empty_base_classes = true; 298 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast, 299 clang_type, 300 name.AsCString(), 301 omit_empty_base_classes, 302 child_indexes); 303 ValueObjectSP child_sp; 304 if (num_child_indexes > 0) 305 { 306 std::vector<uint32_t>::const_iterator pos = child_indexes.begin (); 307 std::vector<uint32_t>::const_iterator end = child_indexes.end (); 308 309 child_sp = GetChildAtIndex(*pos, can_create); 310 for (++pos; pos != end; ++pos) 311 { 312 if (child_sp) 313 { 314 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create)); 315 child_sp = new_child_sp; 316 } 317 else 318 { 319 child_sp.reset(); 320 } 321 322 } 323 } 324 return child_sp; 325} 326 327 328uint32_t 329ValueObject::GetNumChildren () 330{ 331 if (!m_children_count_valid) 332 { 333 SetNumChildren (CalculateNumChildren()); 334 } 335 return m_children.size(); 336} 337void 338ValueObject::SetNumChildren (uint32_t num_children) 339{ 340 m_children_count_valid = true; 341 m_children.resize(num_children); 342} 343 344void 345ValueObject::SetName (const char *name) 346{ 347 m_name.SetCString(name); 348} 349 350void 351ValueObject::SetName (const ConstString &name) 352{ 353 m_name = name; 354} 355 356ValueObjectSP 357ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index) 358{ 359 ValueObjectSP valobj_sp; 360 bool omit_empty_base_classes = true; 361 362 std::string child_name_str; 363 uint32_t child_byte_size = 0; 364 int32_t child_byte_offset = 0; 365 uint32_t child_bitfield_bit_size = 0; 366 uint32_t child_bitfield_bit_offset = 0; 367 bool child_is_base_class = false; 368 const bool transparent_pointers = synthetic_array_member == false; 369 clang::ASTContext *clang_ast = GetClangAST(); 370 clang_type_t clang_type = GetClangType(); 371 clang_type_t child_clang_type; 372 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (clang_ast, 373 GetName().AsCString(), 374 clang_type, 375 idx, 376 transparent_pointers, 377 omit_empty_base_classes, 378 child_name_str, 379 child_byte_size, 380 child_byte_offset, 381 child_bitfield_bit_size, 382 child_bitfield_bit_offset, 383 child_is_base_class); 384 if (child_clang_type) 385 { 386 if (synthetic_index) 387 child_byte_offset += child_byte_size * synthetic_index; 388 389 ConstString child_name; 390 if (!child_name_str.empty()) 391 child_name.SetCString (child_name_str.c_str()); 392 393 valobj_sp.reset (new ValueObjectChild (this, 394 clang_ast, 395 child_clang_type, 396 child_name, 397 child_byte_size, 398 child_byte_offset, 399 child_bitfield_bit_size, 400 child_bitfield_bit_offset, 401 child_is_base_class)); 402 } 403 return valobj_sp; 404} 405 406const char * 407ValueObject::GetSummaryAsCString (ExecutionContextScope *exe_scope) 408{ 409 if (UpdateValueIfNeeded (exe_scope)) 410 { 411 if (m_summary_str.empty()) 412 { 413 clang_type_t clang_type = GetClangType(); 414 415 // See if this is a pointer to a C string? 416 if (clang_type) 417 { 418 StreamString sstr; 419 clang_type_t elem_or_pointee_clang_type; 420 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, 421 GetClangAST(), 422 &elem_or_pointee_clang_type)); 423 424 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) && 425 ClangASTContext::IsCharType (elem_or_pointee_clang_type)) 426 { 427 Process *process = exe_scope->CalculateProcess(); 428 if (process != NULL) 429 { 430 lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS; 431 lldb::AddressType cstr_address_type = eAddressTypeInvalid; 432 433 size_t cstr_len = 0; 434 if (type_flags.Test (ClangASTContext::eTypeIsArray)) 435 { 436 // We have an array 437 cstr_len = ClangASTContext::GetArraySize (clang_type); 438 cstr_address = GetAddressOf (cstr_address_type, true); 439 } 440 else 441 { 442 // We have a pointer 443 cstr_address = GetPointerValue (cstr_address_type, true); 444 } 445 if (cstr_address != LLDB_INVALID_ADDRESS) 446 { 447 DataExtractor data; 448 size_t bytes_read = 0; 449 std::vector<char> data_buffer; 450 std::vector<char> cstr_buffer; 451 size_t cstr_length; 452 Error error; 453 if (cstr_len > 0) 454 { 455 data_buffer.resize(cstr_len); 456 // Resize the formatted buffer in case every character 457 // uses the "\xXX" format and one extra byte for a NULL 458 cstr_buffer.resize(data_buffer.size() * 4 + 1); 459 data.SetData (&data_buffer.front(), data_buffer.size(), eByteOrderHost); 460 bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), cstr_len, error); 461 if (bytes_read > 0) 462 { 463 sstr << '"'; 464 cstr_length = data.Dump (&sstr, 465 0, // Start offset in "data" 466 eFormatChar, // Print as characters 467 1, // Size of item (1 byte for a char!) 468 bytes_read, // How many bytes to print? 469 UINT32_MAX, // num per line 470 LLDB_INVALID_ADDRESS,// base address 471 0, // bitfield bit size 472 0); // bitfield bit offset 473 sstr << '"'; 474 } 475 } 476 else 477 { 478 const size_t k_max_buf_size = 256; 479 data_buffer.resize (k_max_buf_size + 1); 480 // NULL terminate in case we don't get the entire C string 481 data_buffer.back() = '\0'; 482 // Make a formatted buffer that can contain take 4 483 // bytes per character in case each byte uses the 484 // "\xXX" format and one extra byte for a NULL 485 cstr_buffer.resize (k_max_buf_size * 4 + 1); 486 487 data.SetData (&data_buffer.front(), data_buffer.size(), eByteOrderHost); 488 size_t total_cstr_len = 0; 489 while ((bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), k_max_buf_size, error)) > 0) 490 { 491 size_t len = strlen(&data_buffer.front()); 492 if (len == 0) 493 break; 494 if (len > bytes_read) 495 len = bytes_read; 496 if (sstr.GetSize() == 0) 497 sstr << '"'; 498 499 cstr_length = data.Dump (&sstr, 500 0, // Start offset in "data" 501 eFormatChar, // Print as characters 502 1, // Size of item (1 byte for a char!) 503 len, // How many bytes to print? 504 UINT32_MAX, // num per line 505 LLDB_INVALID_ADDRESS,// base address 506 0, // bitfield bit size 507 0); // bitfield bit offset 508 509 if (len < k_max_buf_size) 510 break; 511 cstr_address += total_cstr_len; 512 } 513 if (sstr.GetSize() > 0) 514 sstr << '"'; 515 } 516 } 517 } 518 519 if (sstr.GetSize() > 0) 520 m_summary_str.assign (sstr.GetData(), sstr.GetSize()); 521 } 522 else if (ClangASTContext::IsFunctionPointerType (clang_type)) 523 { 524 lldb::AddressType func_ptr_address_type = eAddressTypeInvalid; 525 lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true); 526 527 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS) 528 { 529 switch (func_ptr_address_type) 530 { 531 case eAddressTypeInvalid: 532 case eAddressTypeFile: 533 break; 534 535 case eAddressTypeLoad: 536 { 537 Address so_addr; 538 Target *target = exe_scope->CalculateTarget(); 539 if (target && target->GetSectionLoadList().IsEmpty() == false) 540 { 541 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr)) 542 { 543 so_addr.Dump (&sstr, 544 exe_scope, 545 Address::DumpStyleResolvedDescription, 546 Address::DumpStyleSectionNameOffset); 547 } 548 } 549 } 550 break; 551 552 case eAddressTypeHost: 553 break; 554 } 555 } 556 if (sstr.GetSize() > 0) 557 { 558 m_summary_str.assign (1, '('); 559 m_summary_str.append (sstr.GetData(), sstr.GetSize()); 560 m_summary_str.append (1, ')'); 561 } 562 } 563 } 564 } 565 } 566 if (m_summary_str.empty()) 567 return NULL; 568 return m_summary_str.c_str(); 569} 570 571const char * 572ValueObject::GetObjectDescription (ExecutionContextScope *exe_scope) 573{ 574 if (!m_object_desc_str.empty()) 575 return m_object_desc_str.c_str(); 576 577 if (!GetValueIsValid()) 578 return NULL; 579 580 Process *process = exe_scope->CalculateProcess(); 581 if (process == NULL) 582 return NULL; 583 584 StreamString s; 585 586 lldb::LanguageType language = GetObjectRuntimeLanguage(); 587 LanguageRuntime *runtime = process->GetLanguageRuntime(language); 588 589 if (runtime && runtime->GetObjectDescription(s, *this, exe_scope)) 590 { 591 m_object_desc_str.append (s.GetData()); 592 } 593 594 if (m_object_desc_str.empty()) 595 return NULL; 596 else 597 return m_object_desc_str.c_str(); 598} 599 600const char * 601ValueObject::GetValueAsCString (ExecutionContextScope *exe_scope) 602{ 603 // If our byte size is zero this is an aggregate type that has children 604 if (ClangASTContext::IsAggregateType (GetClangType()) == false) 605 { 606 if (UpdateValueIfNeeded(exe_scope)) 607 { 608 if (m_value_str.empty()) 609 { 610 const Value::ContextType context_type = m_value.GetContextType(); 611 612 switch (context_type) 613 { 614 case Value::eContextTypeOpaqueClangQualType: 615 case Value::eContextTypeDCType: 616 case Value::eContextTypeDCVariable: 617 { 618 clang_type_t clang_type = GetClangType (); 619 if (clang_type) 620 { 621 StreamString sstr; 622 if (m_format == eFormatDefault) 623 m_format = ClangASTType::GetFormat(clang_type); 624 625 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST 626 clang_type, // The clang type to display 627 &sstr, 628 m_format, // Format to display this type with 629 m_data, // Data to extract from 630 0, // Byte offset into "m_data" 631 GetByteSize(), // Byte size of item in "m_data" 632 GetBitfieldBitSize(), // Bitfield bit size 633 GetBitfieldBitOffset())) // Bitfield bit offset 634 m_value_str.swap(sstr.GetString()); 635 else 636 m_value_str.clear(); 637 } 638 } 639 break; 640 641 case Value::eContextTypeDCRegisterInfo: 642 { 643 const RegisterInfo *reg_info = m_value.GetRegisterInfo(); 644 if (reg_info) 645 { 646 StreamString reg_sstr; 647 m_data.Dump(®_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 648 m_value_str.swap(reg_sstr.GetString()); 649 } 650 } 651 break; 652 653 default: 654 break; 655 } 656 } 657 658 if (!m_value_did_change && m_old_value_valid) 659 { 660 // The value was gotten successfully, so we consider the 661 // value as changed if the value string differs 662 SetValueDidChange (m_old_value_str != m_value_str); 663 } 664 } 665 } 666 if (m_value_str.empty()) 667 return NULL; 668 return m_value_str.c_str(); 669} 670 671addr_t 672ValueObject::GetAddressOf (lldb::AddressType &address_type, bool scalar_is_load_address) 673{ 674 switch (m_value.GetValueType()) 675 { 676 case Value::eValueTypeScalar: 677 if (scalar_is_load_address) 678 { 679 address_type = eAddressTypeLoad; 680 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 681 } 682 break; 683 684 case Value::eValueTypeLoadAddress: 685 case Value::eValueTypeFileAddress: 686 case Value::eValueTypeHostAddress: 687 { 688 address_type = m_value.GetValueAddressType (); 689 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 690 } 691 break; 692 } 693 address_type = eAddressTypeInvalid; 694 return LLDB_INVALID_ADDRESS; 695} 696 697addr_t 698ValueObject::GetPointerValue (lldb::AddressType &address_type, bool scalar_is_load_address) 699{ 700 lldb::addr_t address = LLDB_INVALID_ADDRESS; 701 address_type = eAddressTypeInvalid; 702 switch (m_value.GetValueType()) 703 { 704 case Value::eValueTypeScalar: 705 if (scalar_is_load_address) 706 { 707 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 708 address_type = eAddressTypeLoad; 709 } 710 break; 711 712 case Value::eValueTypeLoadAddress: 713 case Value::eValueTypeFileAddress: 714 case Value::eValueTypeHostAddress: 715 { 716 uint32_t data_offset = 0; 717 address = m_data.GetPointer(&data_offset); 718 address_type = m_value.GetValueAddressType(); 719 if (address_type == eAddressTypeInvalid) 720 address_type = eAddressTypeLoad; 721 } 722 break; 723 } 724 return address; 725} 726 727bool 728ValueObject::SetValueFromCString (ExecutionContextScope *exe_scope, const char *value_str) 729{ 730 // Make sure our value is up to date first so that our location and location 731 // type is valid. 732 if (!UpdateValueIfNeeded(exe_scope)) 733 return false; 734 735 uint32_t count = 0; 736 lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count); 737 738 char *end = NULL; 739 const size_t byte_size = GetByteSize(); 740 switch (encoding) 741 { 742 case eEncodingInvalid: 743 return false; 744 745 case eEncodingUint: 746 if (byte_size > sizeof(unsigned long long)) 747 { 748 return false; 749 } 750 else 751 { 752 unsigned long long ull_val = strtoull(value_str, &end, 0); 753 if (end && *end != '\0') 754 return false; 755 m_value = ull_val; 756 // Limit the bytes in our m_data appropriately. 757 m_value.GetScalar().GetData (m_data, byte_size); 758 } 759 break; 760 761 case eEncodingSint: 762 if (byte_size > sizeof(long long)) 763 { 764 return false; 765 } 766 else 767 { 768 long long sll_val = strtoll(value_str, &end, 0); 769 if (end && *end != '\0') 770 return false; 771 m_value = sll_val; 772 // Limit the bytes in our m_data appropriately. 773 m_value.GetScalar().GetData (m_data, byte_size); 774 } 775 break; 776 777 case eEncodingIEEE754: 778 { 779 const off_t byte_offset = GetByteOffset(); 780 uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size)); 781 if (dst != NULL) 782 { 783 // We are decoding a float into host byte order below, so make 784 // sure m_data knows what it contains. 785 m_data.SetByteOrder(eByteOrderHost); 786 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue ( 787 GetClangAST(), 788 GetClangType(), 789 value_str, 790 dst, 791 byte_size); 792 793 if (converted_byte_size == byte_size) 794 { 795 } 796 } 797 } 798 break; 799 800 case eEncodingVector: 801 return false; 802 803 default: 804 return false; 805 } 806 807 // If we have made it here the value is in m_data and we should write it 808 // out to the target 809 return Write (); 810} 811 812bool 813ValueObject::Write () 814{ 815 // Clear the update ID so the next time we try and read the value 816 // we try and read it again. 817 m_update_id = 0; 818 819 // TODO: when Value has a method to write a value back, call it from here. 820 return false; 821 822} 823 824lldb::LanguageType 825ValueObject::GetObjectRuntimeLanguage () 826{ 827 clang_type_t opaque_qual_type = GetClangType(); 828 if (opaque_qual_type == NULL) 829 return lldb::eLanguageTypeC; 830 831 // If the type is a reference, then resolve it to what it refers to first: 832 clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType()); 833 if (qual_type->isAnyPointerType()) 834 { 835 if (qual_type->isObjCObjectPointerType()) 836 return lldb::eLanguageTypeObjC; 837 838 clang::QualType pointee_type (qual_type->getPointeeType()); 839 if (pointee_type->getCXXRecordDeclForPointerType() != NULL) 840 return lldb::eLanguageTypeC_plus_plus; 841 if (pointee_type->isObjCObjectOrInterfaceType()) 842 return lldb::eLanguageTypeObjC; 843 if (pointee_type->isObjCClassType()) 844 return lldb::eLanguageTypeObjC; 845 } 846 else 847 { 848 if (ClangASTContext::IsObjCClassType (opaque_qual_type)) 849 return lldb::eLanguageTypeObjC; 850 if (ClangASTContext::IsCXXClassType (opaque_qual_type)) 851 return lldb::eLanguageTypeC_plus_plus; 852 } 853 854 return lldb::eLanguageTypeC; 855} 856 857void 858ValueObject::AddSyntheticChild (const ConstString &key, ValueObjectSP& valobj_sp) 859{ 860 m_synthetic_children[key] = valobj_sp; 861} 862 863ValueObjectSP 864ValueObject::GetSyntheticChild (const ConstString &key) const 865{ 866 ValueObjectSP synthetic_child_sp; 867 std::map<ConstString, ValueObjectSP>::const_iterator pos = m_synthetic_children.find (key); 868 if (pos != m_synthetic_children.end()) 869 synthetic_child_sp = pos->second; 870 return synthetic_child_sp; 871} 872 873bool 874ValueObject::IsPointerType () 875{ 876 return ClangASTContext::IsPointerType (GetClangType()); 877} 878 879 880 881bool 882ValueObject::IsPointerOrReferenceType () 883{ 884 return ClangASTContext::IsPointerOrReferenceType(GetClangType()); 885} 886 887ValueObjectSP 888ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create) 889{ 890 ValueObjectSP synthetic_child_sp; 891 if (IsPointerType ()) 892 { 893 char index_str[64]; 894 snprintf(index_str, sizeof(index_str), "[%i]", index); 895 ConstString index_const_str(index_str); 896 // Check if we have already created a synthetic array member in this 897 // valid object. If we have we will re-use it. 898 synthetic_child_sp = GetSyntheticChild (index_const_str); 899 if (!synthetic_child_sp) 900 { 901 // We haven't made a synthetic array member for INDEX yet, so 902 // lets make one and cache it for any future reference. 903 synthetic_child_sp = CreateChildAtIndex(0, true, index); 904 905 // Cache the value if we got one back... 906 if (synthetic_child_sp) 907 AddSyntheticChild(index_const_str, synthetic_child_sp); 908 } 909 } 910 return synthetic_child_sp; 911} 912 913bool 914ValueObject::SetDynamicValue () 915{ 916 if (!IsPointerOrReferenceType()) 917 return false; 918 919 // Check that the runtime class is correct for determining the most specific class. 920 // If it is a C++ class, see if it is dynamic: 921 922 return true; 923} 924 925 926void 927ValueObject::GetExpressionPath (Stream &s) 928{ 929 if (m_parent) 930 { 931 m_parent->GetExpressionPath (s); 932 clang_type_t parent_clang_type = m_parent->GetClangType(); 933 if (parent_clang_type) 934 { 935 if (ClangASTContext::IsPointerType(parent_clang_type)) 936 { 937 s.PutCString("->"); 938 } 939 else if (ClangASTContext::IsAggregateType (parent_clang_type)) 940 { 941 if (ClangASTContext::IsArrayType (parent_clang_type) == false && 942 m_parent->IsBaseClass() == false) 943 s.PutChar('.'); 944 } 945 } 946 } 947 948 if (IsBaseClass()) 949 { 950 clang_type_t clang_type = GetClangType(); 951 std::string cxx_class_name; 952 if (ClangASTContext::GetCXXClassName (clang_type, cxx_class_name)) 953 { 954 s << cxx_class_name.c_str() << "::"; 955 } 956 } 957 else 958 { 959 const char *name = GetName().AsCString(); 960 if (name) 961 s.PutCString(name); 962 } 963} 964 965void 966ValueObject::DumpValueObject 967( 968 Stream &s, 969 ExecutionContextScope *exe_scope, 970 ValueObject *valobj, 971 const char *root_valobj_name, 972 uint32_t ptr_depth, 973 uint32_t curr_depth, 974 uint32_t max_depth, 975 bool show_types, 976 bool show_location, 977 bool use_objc, 978 bool scope_already_checked, 979 bool flat_output 980) 981{ 982 if (valobj) 983 { 984 clang_type_t clang_type = valobj->GetClangType(); 985 986 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL)); 987 const char *err_cstr = NULL; 988 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren); 989 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue); 990 991 const bool print_valobj = flat_output == false || has_value; 992 993 if (print_valobj) 994 { 995 if (show_location) 996 { 997 s.Printf("%s: ", valobj->GetLocationAsCString(exe_scope)); 998 } 999 1000 s.Indent(); 1001 1002 // Always show the type for the top level items. 1003 if (show_types || curr_depth == 0) 1004 s.Printf("(%s) ", valobj->GetTypeName().AsCString()); 1005 1006 1007 if (flat_output) 1008 { 1009 valobj->GetExpressionPath(s); 1010 s.PutCString(" ="); 1011 } 1012 else 1013 { 1014 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString(""); 1015 s.Printf ("%s =", name_cstr); 1016 } 1017 1018 if (!scope_already_checked && !valobj->IsInScope(exe_scope->CalculateStackFrame())) 1019 { 1020 err_cstr = "error: out of scope"; 1021 } 1022 } 1023 1024 const char *val_cstr = NULL; 1025 1026 if (err_cstr == NULL) 1027 { 1028 val_cstr = valobj->GetValueAsCString(exe_scope); 1029 err_cstr = valobj->GetError().AsCString(); 1030 } 1031 1032 if (err_cstr) 1033 { 1034 s.Printf (" error: %s\n", err_cstr); 1035 } 1036 else 1037 { 1038 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference); 1039 if (print_valobj) 1040 { 1041 const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope); 1042 1043 if (val_cstr) 1044 s.Printf(" %s", val_cstr); 1045 1046 if (sum_cstr) 1047 s.Printf(" %s", sum_cstr); 1048 1049 if (use_objc) 1050 { 1051 const char *object_desc = valobj->GetObjectDescription(exe_scope); 1052 if (object_desc) 1053 s.Printf(" %s\n", object_desc); 1054 else 1055 s.Printf (" [no Objective-C description available]\n"); 1056 return; 1057 } 1058 } 1059 1060 if (curr_depth < max_depth) 1061 { 1062 // We will show children for all concrete types. We won't show 1063 // pointer contents unless a pointer depth has been specified. 1064 // We won't reference contents unless the reference is the 1065 // root object (depth of zero). 1066 bool print_children = true; 1067 1068 // Use a new temporary pointer depth in case we override the 1069 // current pointer depth below... 1070 uint32_t curr_ptr_depth = ptr_depth; 1071 1072 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer); 1073 if (is_ptr || is_ref) 1074 { 1075 // We have a pointer or reference whose value is an address. 1076 // Make sure that address is not NULL 1077 lldb::AddressType ptr_address_type; 1078 if (valobj->GetPointerValue (ptr_address_type, true) == 0) 1079 print_children = false; 1080 1081 else if (is_ref && curr_depth == 0) 1082 { 1083 // If this is the root object (depth is zero) that we are showing 1084 // and it is a reference, and no pointer depth has been supplied 1085 // print out what it references. Don't do this at deeper depths 1086 // otherwise we can end up with infinite recursion... 1087 curr_ptr_depth = 1; 1088 } 1089 1090 if (curr_ptr_depth == 0) 1091 print_children = false; 1092 } 1093 1094 if (print_children) 1095 { 1096 const uint32_t num_children = valobj->GetNumChildren(); 1097 if (num_children) 1098 { 1099 if (flat_output) 1100 { 1101 if (print_valobj) 1102 s.EOL(); 1103 } 1104 else 1105 { 1106 if (print_valobj) 1107 s.PutCString(is_ref ? ": {\n" : " {\n"); 1108 s.IndentMore(); 1109 } 1110 1111 for (uint32_t idx=0; idx<num_children; ++idx) 1112 { 1113 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true)); 1114 if (child_sp.get()) 1115 { 1116 DumpValueObject (s, 1117 exe_scope, 1118 child_sp.get(), 1119 NULL, 1120 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth, 1121 curr_depth + 1, 1122 max_depth, 1123 show_types, 1124 show_location, 1125 false, 1126 true, 1127 flat_output); 1128 } 1129 } 1130 1131 if (!flat_output) 1132 { 1133 s.IndentLess(); 1134 s.Indent("}\n"); 1135 } 1136 } 1137 else if (has_children) 1138 { 1139 // Aggregate, no children... 1140 if (print_valobj) 1141 s.PutCString(" {}\n"); 1142 } 1143 else 1144 { 1145 if (print_valobj) 1146 s.EOL(); 1147 } 1148 1149 } 1150 else 1151 { 1152 s.EOL(); 1153 } 1154 } 1155 else 1156 { 1157 if (has_children && print_valobj) 1158 { 1159 s.PutCString("{...}\n"); 1160 } 1161 } 1162 } 1163 } 1164} 1165 1166