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