ValueObject.cpp revision 24a6bd9835ed1655984397b0cdf35127e47681e9
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/DataVisualization.h" 23#include "lldb/Core/Debugger.h" 24#include "lldb/Core/Log.h" 25#include "lldb/Core/StreamString.h" 26#include "lldb/Core/ValueObjectChild.h" 27#include "lldb/Core/ValueObjectConstResult.h" 28#include "lldb/Core/ValueObjectDynamicValue.h" 29#include "lldb/Core/ValueObjectList.h" 30#include "lldb/Core/ValueObjectMemory.h" 31#include "lldb/Core/ValueObjectSyntheticFilter.h" 32 33#include "lldb/Host/Endian.h" 34 35#include "lldb/Interpreter/CommandInterpreter.h" 36#include "lldb/Interpreter/ScriptInterpreterPython.h" 37 38#include "lldb/Symbol/ClangASTType.h" 39#include "lldb/Symbol/ClangASTContext.h" 40#include "lldb/Symbol/Type.h" 41 42#include "lldb/Target/ExecutionContext.h" 43#include "lldb/Target/LanguageRuntime.h" 44#include "lldb/Target/ObjCLanguageRuntime.h" 45#include "lldb/Target/Process.h" 46#include "lldb/Target/RegisterContext.h" 47#include "lldb/Target/Target.h" 48#include "lldb/Target/Thread.h" 49 50#include "lldb/Utility/RefCounter.h" 51 52using namespace lldb; 53using namespace lldb_private; 54using namespace lldb_utility; 55 56static user_id_t g_value_obj_uid = 0; 57 58//---------------------------------------------------------------------- 59// ValueObject constructor 60//---------------------------------------------------------------------- 61ValueObject::ValueObject (ValueObject &parent) : 62 UserID (++g_value_obj_uid), // Unique identifier for every value object 63 m_parent (&parent), 64 m_update_point (parent.GetUpdatePoint ()), 65 m_name (), 66 m_data (), 67 m_value (), 68 m_error (), 69 m_value_str (), 70 m_old_value_str (), 71 m_location_str (), 72 m_summary_str (), 73 m_object_desc_str (), 74 m_manager(parent.GetManager()), 75 m_children (), 76 m_synthetic_children (), 77 m_dynamic_value (NULL), 78 m_synthetic_value(NULL), 79 m_deref_valobj(NULL), 80 m_format (eFormatDefault), 81 m_last_format_mgr_revision(0), 82 m_last_format_mgr_dynamic(parent.m_last_format_mgr_dynamic), 83 m_last_summary_format(), 84 m_forced_summary_format(), 85 m_last_value_format(), 86 m_last_synthetic_filter(), 87 m_user_id_of_forced_summary(), 88 m_value_is_valid (false), 89 m_value_did_change (false), 90 m_children_count_valid (false), 91 m_old_value_valid (false), 92 m_is_deref_of_parent (false), 93 m_is_array_item_for_pointer(false), 94 m_is_bitfield_for_scalar(false), 95 m_is_expression_path_child(false), 96 m_is_child_at_offset(false), 97 m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid), 98 m_trying_summary_already(false) 99{ 100 m_manager->ManageObject(this); 101} 102 103//---------------------------------------------------------------------- 104// ValueObject constructor 105//---------------------------------------------------------------------- 106ValueObject::ValueObject (ExecutionContextScope *exe_scope, 107 AddressType child_ptr_or_ref_addr_type) : 108 UserID (++g_value_obj_uid), // Unique identifier for every value object 109 m_parent (NULL), 110 m_update_point (exe_scope), 111 m_name (), 112 m_data (), 113 m_value (), 114 m_error (), 115 m_value_str (), 116 m_old_value_str (), 117 m_location_str (), 118 m_summary_str (), 119 m_object_desc_str (), 120 m_manager(), 121 m_children (), 122 m_synthetic_children (), 123 m_dynamic_value (NULL), 124 m_synthetic_value(NULL), 125 m_deref_valobj(NULL), 126 m_format (eFormatDefault), 127 m_last_format_mgr_revision(0), 128 m_last_format_mgr_dynamic(eNoDynamicValues), 129 m_last_summary_format(), 130 m_forced_summary_format(), 131 m_last_value_format(), 132 m_last_synthetic_filter(), 133 m_user_id_of_forced_summary(), 134 m_value_is_valid (false), 135 m_value_did_change (false), 136 m_children_count_valid (false), 137 m_old_value_valid (false), 138 m_is_deref_of_parent (false), 139 m_is_array_item_for_pointer(false), 140 m_is_bitfield_for_scalar(false), 141 m_is_expression_path_child(false), 142 m_is_child_at_offset(false), 143 m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type), 144 m_trying_summary_already(false) 145{ 146 m_manager = new ValueObjectManager(); 147 m_manager->ManageObject (this); 148} 149 150//---------------------------------------------------------------------- 151// Destructor 152//---------------------------------------------------------------------- 153ValueObject::~ValueObject () 154{ 155} 156 157bool 158ValueObject::UpdateValueIfNeeded (bool update_format) 159{ 160 return UpdateValueIfNeeded(m_last_format_mgr_dynamic, update_format); 161} 162 163bool 164ValueObject::UpdateValueIfNeeded (DynamicValueType use_dynamic, bool update_format) 165{ 166 167 bool did_change_formats = false; 168 169 if (update_format) 170 did_change_formats = UpdateFormatsIfNeeded(use_dynamic); 171 172 // If this is a constant value, then our success is predicated on whether 173 // we have an error or not 174 if (GetIsConstant()) 175 { 176 // if you were asked to update your formatters, but did not get a chance to do it 177 // clear your own values (this serves the purpose of faking a stop-id for frozen 178 // objects (which are regarded as constant, but could have changes behind their backs 179 // because of the frozen-pointer depth limit) 180 // TODO: decouple summary from value and then remove this code and only force-clear the summary 181 if (update_format && !did_change_formats) 182 m_summary_str.clear(); 183 return m_error.Success(); 184 } 185 186 bool first_update = m_update_point.IsFirstEvaluation(); 187 188 if (m_update_point.NeedsUpdating()) 189 { 190 m_update_point.SetUpdated(); 191 192 // Save the old value using swap to avoid a string copy which 193 // also will clear our m_value_str 194 if (m_value_str.empty()) 195 { 196 m_old_value_valid = false; 197 } 198 else 199 { 200 m_old_value_valid = true; 201 m_old_value_str.swap (m_value_str); 202 m_value_str.clear(); 203 } 204 205 ClearUserVisibleData(); 206 207 const bool value_was_valid = GetValueIsValid(); 208 SetValueDidChange (false); 209 210 m_error.Clear(); 211 212 // Call the pure virtual function to update the value 213 bool success = UpdateValue (); 214 215 SetValueIsValid (success); 216 217 if (first_update) 218 SetValueDidChange (false); 219 else if (!m_value_did_change && success == false) 220 { 221 // The value wasn't gotten successfully, so we mark this 222 // as changed if the value used to be valid and now isn't 223 SetValueDidChange (value_was_valid); 224 } 225 } 226 return m_error.Success(); 227} 228 229bool 230ValueObject::UpdateFormatsIfNeeded(DynamicValueType use_dynamic) 231{ 232 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 233 if (log) 234 log->Printf("checking for FormatManager revisions. VO named %s is at revision %d, while the format manager is at revision %d", 235 GetName().GetCString(), 236 m_last_format_mgr_revision, 237 DataVisualization::GetCurrentRevision()); 238 239 bool any_change = false; 240 241 if (HasCustomSummaryFormat() && m_update_point.GetModID() != m_user_id_of_forced_summary) 242 { 243 ClearCustomSummaryFormat(); 244 245 any_change = true; 246 } 247 248 if ( (m_last_format_mgr_revision != DataVisualization::GetCurrentRevision()) || 249 m_last_format_mgr_dynamic != use_dynamic) 250 { 251 SetValueFormat(DataVisualization::ValueFormats::GetFormat (*this, eNoDynamicValues)); 252 SetSummaryFormat(DataVisualization::GetSummaryFormat (*this, use_dynamic)); 253 SetSyntheticChildren(DataVisualization::GetSyntheticChildren (*this, use_dynamic)); 254 255 m_last_format_mgr_revision = DataVisualization::GetCurrentRevision(); 256 m_last_format_mgr_dynamic = use_dynamic; 257 258 any_change = true; 259 } 260 261 return any_change; 262 263} 264 265void 266ValueObject::SetNeedsUpdate () 267{ 268 m_update_point.SetNeedsUpdate(); 269 // We have to clear the value string here so ConstResult children will notice if their values are 270 // changed by hand (i.e. with SetValueAsCString). 271 m_value_str.clear(); 272} 273 274DataExtractor & 275ValueObject::GetDataExtractor () 276{ 277 UpdateValueIfNeeded(false); 278 return m_data; 279} 280 281const Error & 282ValueObject::GetError() 283{ 284 UpdateValueIfNeeded(false); 285 return m_error; 286} 287 288const ConstString & 289ValueObject::GetName() const 290{ 291 return m_name; 292} 293 294const char * 295ValueObject::GetLocationAsCString () 296{ 297 if (UpdateValueIfNeeded(false)) 298 { 299 if (m_location_str.empty()) 300 { 301 StreamString sstr; 302 303 switch (m_value.GetValueType()) 304 { 305 default: 306 break; 307 308 case Value::eValueTypeScalar: 309 if (m_value.GetContextType() == Value::eContextTypeRegisterInfo) 310 { 311 RegisterInfo *reg_info = m_value.GetRegisterInfo(); 312 if (reg_info) 313 { 314 if (reg_info->name) 315 m_location_str = reg_info->name; 316 else if (reg_info->alt_name) 317 m_location_str = reg_info->alt_name; 318 break; 319 } 320 } 321 m_location_str = "scalar"; 322 break; 323 324 case Value::eValueTypeLoadAddress: 325 case Value::eValueTypeFileAddress: 326 case Value::eValueTypeHostAddress: 327 { 328 uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2; 329 sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS)); 330 m_location_str.swap(sstr.GetString()); 331 } 332 break; 333 } 334 } 335 } 336 return m_location_str.c_str(); 337} 338 339Value & 340ValueObject::GetValue() 341{ 342 return m_value; 343} 344 345const Value & 346ValueObject::GetValue() const 347{ 348 return m_value; 349} 350 351bool 352ValueObject::ResolveValue (Scalar &scalar) 353{ 354 if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything 355 { 356 ExecutionContext exe_ctx; 357 ExecutionContextScope *exe_scope = GetExecutionContextScope(); 358 if (exe_scope) 359 exe_scope->CalculateExecutionContext(exe_ctx); 360 Value tmp_value(m_value); 361 scalar = tmp_value.ResolveValue(&exe_ctx, GetClangAST ()); 362 return scalar.IsValid(); 363 } 364 else 365 return false; 366} 367 368bool 369ValueObject::GetValueIsValid () const 370{ 371 return m_value_is_valid; 372} 373 374 375void 376ValueObject::SetValueIsValid (bool b) 377{ 378 m_value_is_valid = b; 379} 380 381bool 382ValueObject::GetValueDidChange () 383{ 384 GetValueAsCString (); 385 return m_value_did_change; 386} 387 388void 389ValueObject::SetValueDidChange (bool value_changed) 390{ 391 m_value_did_change = value_changed; 392} 393 394ValueObjectSP 395ValueObject::GetChildAtIndex (uint32_t idx, bool can_create) 396{ 397 ValueObjectSP child_sp; 398 // We may need to update our value if we are dynamic 399 if (IsPossibleDynamicType ()) 400 UpdateValueIfNeeded(false); 401 if (idx < GetNumChildren()) 402 { 403 // Check if we have already made the child value object? 404 if (can_create && m_children[idx] == NULL) 405 { 406 // No we haven't created the child at this index, so lets have our 407 // subclass do it and cache the result for quick future access. 408 m_children[idx] = CreateChildAtIndex (idx, false, 0); 409 } 410 411 if (m_children[idx] != NULL) 412 return m_children[idx]->GetSP(); 413 } 414 return child_sp; 415} 416 417uint32_t 418ValueObject::GetIndexOfChildWithName (const ConstString &name) 419{ 420 bool omit_empty_base_classes = true; 421 return ClangASTContext::GetIndexOfChildWithName (GetClangAST(), 422 GetClangType(), 423 name.GetCString(), 424 omit_empty_base_classes); 425} 426 427ValueObjectSP 428ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create) 429{ 430 // when getting a child by name, it could be buried inside some base 431 // classes (which really aren't part of the expression path), so we 432 // need a vector of indexes that can get us down to the correct child 433 ValueObjectSP child_sp; 434 435 // We may need to update our value if we are dynamic 436 if (IsPossibleDynamicType ()) 437 UpdateValueIfNeeded(false); 438 439 std::vector<uint32_t> child_indexes; 440 clang::ASTContext *clang_ast = GetClangAST(); 441 void *clang_type = GetClangType(); 442 bool omit_empty_base_classes = true; 443 const size_t num_child_indexes = ClangASTContext::GetIndexOfChildMemberWithName (clang_ast, 444 clang_type, 445 name.GetCString(), 446 omit_empty_base_classes, 447 child_indexes); 448 if (num_child_indexes > 0) 449 { 450 std::vector<uint32_t>::const_iterator pos = child_indexes.begin (); 451 std::vector<uint32_t>::const_iterator end = child_indexes.end (); 452 453 child_sp = GetChildAtIndex(*pos, can_create); 454 for (++pos; pos != end; ++pos) 455 { 456 if (child_sp) 457 { 458 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create)); 459 child_sp = new_child_sp; 460 } 461 else 462 { 463 child_sp.reset(); 464 } 465 466 } 467 } 468 return child_sp; 469} 470 471 472uint32_t 473ValueObject::GetNumChildren () 474{ 475 if (!m_children_count_valid) 476 { 477 SetNumChildren (CalculateNumChildren()); 478 } 479 return m_children.size(); 480} 481void 482ValueObject::SetNumChildren (uint32_t num_children) 483{ 484 m_children_count_valid = true; 485 m_children.resize(num_children); 486} 487 488void 489ValueObject::SetName (const ConstString &name) 490{ 491 m_name = name; 492} 493 494ValueObject * 495ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index) 496{ 497 ValueObject *valobj = NULL; 498 499 bool omit_empty_base_classes = true; 500 bool ignore_array_bounds = synthetic_array_member; 501 std::string child_name_str; 502 uint32_t child_byte_size = 0; 503 int32_t child_byte_offset = 0; 504 uint32_t child_bitfield_bit_size = 0; 505 uint32_t child_bitfield_bit_offset = 0; 506 bool child_is_base_class = false; 507 bool child_is_deref_of_parent = false; 508 509 const bool transparent_pointers = synthetic_array_member == false; 510 clang::ASTContext *clang_ast = GetClangAST(); 511 clang_type_t clang_type = GetClangType(); 512 clang_type_t child_clang_type; 513 514 ExecutionContext exe_ctx; 515 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx); 516 517 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx, 518 clang_ast, 519 GetName().GetCString(), 520 clang_type, 521 idx, 522 transparent_pointers, 523 omit_empty_base_classes, 524 ignore_array_bounds, 525 child_name_str, 526 child_byte_size, 527 child_byte_offset, 528 child_bitfield_bit_size, 529 child_bitfield_bit_offset, 530 child_is_base_class, 531 child_is_deref_of_parent); 532 if (child_clang_type && child_byte_size) 533 { 534 if (synthetic_index) 535 child_byte_offset += child_byte_size * synthetic_index; 536 537 ConstString child_name; 538 if (!child_name_str.empty()) 539 child_name.SetCString (child_name_str.c_str()); 540 541 valobj = new ValueObjectChild (*this, 542 clang_ast, 543 child_clang_type, 544 child_name, 545 child_byte_size, 546 child_byte_offset, 547 child_bitfield_bit_size, 548 child_bitfield_bit_offset, 549 child_is_base_class, 550 child_is_deref_of_parent, 551 eAddressTypeInvalid); 552 //if (valobj) 553 // valobj->SetAddressTypeOfChildren(eAddressTypeInvalid); 554 } 555 556 return valobj; 557} 558 559const char * 560ValueObject::GetSummaryAsCString () 561{ 562 if (UpdateValueIfNeeded (true)) 563 { 564 if (m_summary_str.empty()) 565 { 566 SummaryFormat *summary_format = GetSummaryFormat().get(); 567 568 if (summary_format) 569 { 570 m_summary_str = summary_format->FormatObject(GetSP()); 571 } 572 else 573 { 574 clang_type_t clang_type = GetClangType(); 575 576 // Do some default printout for function pointers 577 if (clang_type) 578 { 579 StreamString sstr; 580 clang_type_t elem_or_pointee_clang_type; 581 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, 582 GetClangAST(), 583 &elem_or_pointee_clang_type)); 584 585 ExecutionContextScope *exe_scope = GetExecutionContextScope(); 586 if (exe_scope) 587 { 588 if (ClangASTContext::IsFunctionPointerType (clang_type)) 589 { 590 AddressType func_ptr_address_type = eAddressTypeInvalid; 591 addr_t func_ptr_address = GetPointerValue (&func_ptr_address_type); 592 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS) 593 { 594 switch (func_ptr_address_type) 595 { 596 case eAddressTypeInvalid: 597 case eAddressTypeFile: 598 break; 599 600 case eAddressTypeLoad: 601 { 602 Address so_addr; 603 Target *target = exe_scope->CalculateTarget(); 604 if (target && target->GetSectionLoadList().IsEmpty() == false) 605 { 606 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr)) 607 { 608 so_addr.Dump (&sstr, 609 exe_scope, 610 Address::DumpStyleResolvedDescription, 611 Address::DumpStyleSectionNameOffset); 612 } 613 } 614 } 615 break; 616 617 case eAddressTypeHost: 618 break; 619 } 620 } 621 if (sstr.GetSize() > 0) 622 { 623 m_summary_str.assign (1, '('); 624 m_summary_str.append (sstr.GetData(), sstr.GetSize()); 625 m_summary_str.append (1, ')'); 626 } 627 } 628 } 629 } 630 } 631 } 632 } 633 if (m_summary_str.empty()) 634 return NULL; 635 return m_summary_str.c_str(); 636} 637 638bool 639ValueObject::IsCStringContainer(bool check_pointer) 640{ 641 clang_type_t elem_or_pointee_clang_type; 642 const Flags type_flags (ClangASTContext::GetTypeInfo (GetClangType(), 643 GetClangAST(), 644 &elem_or_pointee_clang_type)); 645 bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) && 646 ClangASTContext::IsCharType (elem_or_pointee_clang_type)); 647 if (!is_char_arr_ptr) 648 return false; 649 if (!check_pointer) 650 return true; 651 if (type_flags.Test(ClangASTContext::eTypeIsArray)) 652 return true; 653 addr_t cstr_address = LLDB_INVALID_ADDRESS; 654 AddressType cstr_address_type = eAddressTypeInvalid; 655 cstr_address = GetAddressOf (true, &cstr_address_type); 656 return (cstr_address != LLDB_INVALID_ADDRESS); 657} 658 659size_t 660ValueObject::GetPointeeData (DataExtractor& data, 661 uint32_t item_idx, 662 uint32_t item_count) 663{ 664 if (!IsPointerType() && !IsArrayType()) 665 return 0; 666 667 if (item_count == 0) 668 return 0; 669 670 uint32_t stride = 0; 671 672 ClangASTType type(GetClangAST(), 673 GetClangType()); 674 675 const uint64_t item_type_size = (IsPointerType() ? ClangASTType::GetTypeByteSize(GetClangAST(), type.GetPointeeType()) : 676 ClangASTType::GetTypeByteSize(GetClangAST(), type.GetArrayElementType(stride))); 677 678 const uint64_t bytes = item_count * item_type_size; 679 680 const uint64_t offset = item_idx * item_type_size; 681 682 if (item_idx == 0 && item_count == 1) // simply a deref 683 { 684 if (IsPointerType()) 685 { 686 Error error; 687 ValueObjectSP pointee_sp = Dereference(error); 688 if (error.Fail() || pointee_sp.get() == NULL) 689 return 0; 690 return pointee_sp->GetDataExtractor().Copy(data); 691 } 692 else 693 { 694 ValueObjectSP child_sp = GetChildAtIndex(0, true); 695 if (child_sp.get() == NULL) 696 return 0; 697 return child_sp->GetDataExtractor().Copy(data); 698 } 699 return true; 700 } 701 else /* (items > 1) */ 702 { 703 Error error; 704 lldb_private::DataBufferHeap* heap_buf_ptr = NULL; 705 lldb::DataBufferSP data_sp(heap_buf_ptr = new lldb_private::DataBufferHeap()); 706 707 AddressType addr_type; 708 lldb::addr_t addr = IsPointerType() ? GetPointerValue(&addr_type) : GetAddressOf(true, &addr_type); 709 710 ExecutionContextScope *exe_scope = m_update_point.GetExecutionContextScope(); 711 712 713 switch (addr_type) 714 { 715 case eAddressTypeFile: 716 { 717 Module* module = GetModule(); 718 if (module) 719 { 720 Address so_addr; 721 module->ResolveFileAddress(addr, so_addr); 722 if (exe_scope) 723 { 724 Target* target = exe_scope->CalculateTarget(); 725 if (target) 726 { 727 heap_buf_ptr->SetByteSize(bytes); 728 size_t bytes_read = target->ReadMemory(so_addr, false, heap_buf_ptr->GetBytes(), bytes, error); 729 if (error.Success()) 730 { 731 data.SetData(data_sp); 732 return bytes_read; 733 } 734 } 735 } 736 } 737 } 738 break; 739 case eAddressTypeLoad: 740 if (exe_scope) 741 { 742 Process *process = exe_scope->CalculateProcess(); 743 if (process) 744 { 745 heap_buf_ptr->SetByteSize(bytes); 746 size_t bytes_read = process->ReadMemory(addr + offset, heap_buf_ptr->GetBytes(), bytes, error); 747 if (error.Success()) 748 { 749 data.SetData(data_sp); 750 return bytes_read; 751 } 752 } 753 } 754 break; 755 case eAddressTypeHost: 756 { 757 heap_buf_ptr->CopyData((uint8_t*)(addr + offset), bytes); 758 data.SetData(data_sp); 759 return bytes; 760 } 761 break; 762 case eAddressTypeInvalid: 763 default: 764 break; 765 } 766 } 767 return 0; 768} 769 770size_t 771ValueObject::GetData (DataExtractor& data) 772{ 773 UpdateValueIfNeeded(false); 774 ExecutionContext exe_ctx; 775 GetExecutionContextScope()->CalculateExecutionContext(exe_ctx); 776 Error error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), data, 0, GetModule()); 777 if (error.Fail()) 778 return 0; 779 data.SetAddressByteSize(m_data.GetAddressByteSize()); 780 data.SetByteOrder(m_data.GetByteOrder()); 781 return data.GetByteSize(); 782} 783 784// will compute strlen(str), but without consuming more than 785// maxlen bytes out of str (this serves the purpose of reading 786// chunks of a string without having to worry about 787// missing NULL terminators in the chunk) 788// of course, if strlen(str) > maxlen, the function will return 789// maxlen_value (which should be != maxlen, because that allows you 790// to know whether strlen(str) == maxlen or strlen(str) > maxlen) 791static uint32_t 792strlen_or_inf (const char* str, 793 uint32_t maxlen, 794 uint32_t maxlen_value) 795{ 796 uint32_t len = 0; 797 if (str) 798 { 799 while(*str) 800 { 801 len++;str++; 802 if (len > maxlen) 803 return maxlen_value; 804 } 805 } 806 return len; 807} 808 809void 810ValueObject::ReadPointedString(Stream& s, 811 Error& error, 812 uint32_t max_length, 813 bool honor_array, 814 Format item_format) 815{ 816 817 if (max_length == 0) 818 max_length = GetUpdatePoint().GetTargetSP()->GetMaximumSizeOfStringSummary(); 819 820 clang_type_t clang_type = GetClangType(); 821 clang_type_t elem_or_pointee_clang_type; 822 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, 823 GetClangAST(), 824 &elem_or_pointee_clang_type)); 825 if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) && 826 ClangASTContext::IsCharType (elem_or_pointee_clang_type)) 827 { 828 ExecutionContextScope *exe_scope = GetExecutionContextScope(); 829 if (exe_scope) 830 { 831 Target *target = exe_scope->CalculateTarget(); 832 if (target == NULL) 833 { 834 s << "<no target to read from>"; 835 } 836 else 837 { 838 addr_t cstr_address = LLDB_INVALID_ADDRESS; 839 AddressType cstr_address_type = eAddressTypeInvalid; 840 841 size_t cstr_len = 0; 842 bool capped_data = false; 843 if (type_flags.Test (ClangASTContext::eTypeIsArray)) 844 { 845 // We have an array 846 cstr_len = ClangASTContext::GetArraySize (clang_type); 847 if (cstr_len > max_length) 848 { 849 capped_data = true; 850 cstr_len = max_length; 851 } 852 cstr_address = GetAddressOf (true, &cstr_address_type); 853 } 854 else 855 { 856 // We have a pointer 857 cstr_address = GetPointerValue (&cstr_address_type); 858 } 859 if (cstr_address != 0 && cstr_address != LLDB_INVALID_ADDRESS) 860 { 861 Address cstr_so_addr (NULL, cstr_address); 862 DataExtractor data; 863 size_t bytes_read = 0; 864 if (cstr_len > 0 && honor_array) 865 { 866 // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host 867 // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this 868 GetPointeeData(data, 0, cstr_len); 869 870 if ((bytes_read = data.GetByteSize()) > 0) 871 { 872 s << '"'; 873 data.Dump (&s, 874 0, // Start offset in "data" 875 item_format, 876 1, // Size of item (1 byte for a char!) 877 bytes_read, // How many bytes to print? 878 UINT32_MAX, // num per line 879 LLDB_INVALID_ADDRESS,// base address 880 0, // bitfield bit size 881 0); // bitfield bit offset 882 if (capped_data) 883 s << "..."; 884 s << '"'; 885 } 886 } 887 else 888 { 889 cstr_len = max_length; 890 const size_t k_max_buf_size = 64; 891 892 size_t offset = 0; 893 894 int cstr_len_displayed = -1; 895 bool capped_cstr = false; 896 // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host 897 // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this 898 while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0) 899 { 900 const char *cstr = data.PeekCStr(0); 901 size_t len = strlen_or_inf (cstr, k_max_buf_size, k_max_buf_size+1); 902 if (len > k_max_buf_size) 903 len = k_max_buf_size; 904 if (cstr && cstr_len_displayed < 0) 905 s << '"'; 906 907 if (cstr_len_displayed < 0) 908 cstr_len_displayed = len; 909 910 if (len == 0) 911 break; 912 cstr_len_displayed += len; 913 if (len > bytes_read) 914 len = bytes_read; 915 if (len > cstr_len) 916 len = cstr_len; 917 918 data.Dump (&s, 919 0, // Start offset in "data" 920 item_format, 921 1, // Size of item (1 byte for a char!) 922 len, // How many bytes to print? 923 UINT32_MAX, // num per line 924 LLDB_INVALID_ADDRESS,// base address 925 0, // bitfield bit size 926 0); // bitfield bit offset 927 928 if (len < k_max_buf_size) 929 break; 930 931 if (len >= cstr_len) 932 { 933 capped_cstr = true; 934 break; 935 } 936 937 cstr_len -= len; 938 offset += len; 939 } 940 941 if (cstr_len_displayed >= 0) 942 { 943 s << '"'; 944 if (capped_cstr) 945 s << "..."; 946 } 947 } 948 } 949 } 950 } 951 } 952 else 953 { 954 error.SetErrorString("impossible to read a string from this object"); 955 s << "<not a string object>"; 956 } 957} 958 959const char * 960ValueObject::GetObjectDescription () 961{ 962 963 if (!UpdateValueIfNeeded (true)) 964 return NULL; 965 966 if (!m_object_desc_str.empty()) 967 return m_object_desc_str.c_str(); 968 969 ExecutionContextScope *exe_scope = GetExecutionContextScope(); 970 if (exe_scope == NULL) 971 return NULL; 972 973 Process *process = exe_scope->CalculateProcess(); 974 if (process == NULL) 975 return NULL; 976 977 StreamString s; 978 979 LanguageType language = GetObjectRuntimeLanguage(); 980 LanguageRuntime *runtime = process->GetLanguageRuntime(language); 981 982 if (runtime == NULL) 983 { 984 // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway... 985 clang_type_t opaque_qual_type = GetClangType(); 986 if (opaque_qual_type != NULL) 987 { 988 bool is_signed; 989 if (ClangASTContext::IsIntegerType (opaque_qual_type, is_signed) 990 || ClangASTContext::IsPointerType (opaque_qual_type)) 991 { 992 runtime = process->GetLanguageRuntime(eLanguageTypeObjC); 993 } 994 } 995 } 996 997 if (runtime && runtime->GetObjectDescription(s, *this)) 998 { 999 m_object_desc_str.append (s.GetData()); 1000 } 1001 1002 if (m_object_desc_str.empty()) 1003 return NULL; 1004 else 1005 return m_object_desc_str.c_str(); 1006} 1007 1008const char * 1009ValueObject::GetValueAsCString () 1010{ 1011 // If our byte size is zero this is an aggregate type that has children 1012 if (ClangASTContext::IsAggregateType (GetClangType()) == false) 1013 { 1014 if (UpdateValueIfNeeded(true)) 1015 { 1016 if (m_value_str.empty()) 1017 { 1018 const Value::ContextType context_type = m_value.GetContextType(); 1019 1020 switch (context_type) 1021 { 1022 case Value::eContextTypeClangType: 1023 case Value::eContextTypeLLDBType: 1024 case Value::eContextTypeVariable: 1025 { 1026 lldb::Format my_format = GetFormat(); 1027 clang_type_t clang_type = GetClangType (); 1028 if (clang_type) 1029 { 1030 if (m_format == lldb::eFormatDefault) 1031 { 1032 if (m_last_value_format) 1033 my_format = m_last_value_format->GetFormat(); 1034 else 1035 { 1036 if (m_is_bitfield_for_scalar) 1037 my_format = eFormatUnsigned; 1038 else 1039 my_format = ClangASTType::GetFormat(clang_type); 1040 } 1041 } 1042 StreamString sstr; 1043 if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST 1044 clang_type, // The clang type to display 1045 &sstr, 1046 my_format, // Format to display this type with 1047 m_data, // Data to extract from 1048 0, // Byte offset into "m_data" 1049 GetByteSize(), // Byte size of item in "m_data" 1050 GetBitfieldBitSize(), // Bitfield bit size 1051 GetBitfieldBitOffset(), 1052 GetExecutionContextScope())) // Bitfield bit offset 1053 m_value_str.swap(sstr.GetString()); 1054 else 1055 { 1056 m_error.SetErrorStringWithFormat ("unsufficient data for value (only %lu of %lu bytes available)", 1057 m_data.GetByteSize(), 1058 GetByteSize()); 1059 m_value_str.clear(); 1060 } 1061 } 1062 } 1063 break; 1064 1065 case Value::eContextTypeRegisterInfo: 1066 { 1067 const RegisterInfo *reg_info = m_value.GetRegisterInfo(); 1068 if (reg_info) 1069 { 1070 StreamString reg_sstr; 1071 m_data.Dump(®_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0, GetExecutionContextScope()); 1072 m_value_str.swap(reg_sstr.GetString()); 1073 } 1074 } 1075 break; 1076 1077 default: 1078 break; 1079 } 1080 } 1081 1082 if (!m_value_did_change && m_old_value_valid) 1083 { 1084 // The value was gotten successfully, so we consider the 1085 // value as changed if the value string differs 1086 SetValueDidChange (m_old_value_str != m_value_str); 1087 } 1088 } 1089 } 1090 if (m_value_str.empty()) 1091 return NULL; 1092 return m_value_str.c_str(); 1093} 1094 1095// if > 8bytes, 0 is returned. this method should mostly be used 1096// to read address values out of pointers 1097uint64_t 1098ValueObject::GetValueAsUnsigned (uint64_t fail_value) 1099{ 1100 // If our byte size is zero this is an aggregate type that has children 1101 if (ClangASTContext::IsAggregateType (GetClangType()) == false) 1102 { 1103 Scalar scalar; 1104 if (ResolveValue (scalar)) 1105 return scalar.GetRawBits64(fail_value); 1106 } 1107 return fail_value; 1108} 1109 1110bool 1111ValueObject::GetPrintableRepresentation(Stream& s, 1112 ValueObjectRepresentationStyle val_obj_display, 1113 Format custom_format) 1114{ 1115 1116 if (custom_format != eFormatInvalid) 1117 SetFormat(custom_format); 1118 1119 const char * return_value; 1120 std::string alloc_mem; 1121 1122 switch(val_obj_display) 1123 { 1124 case eDisplayValue: 1125 return_value = GetValueAsCString(); 1126 break; 1127 case eDisplaySummary: 1128 if (m_trying_summary_already) 1129 return_value = NULL; 1130 else 1131 { 1132 m_trying_summary_already = true; 1133 return_value = GetSummaryAsCString(); 1134 m_trying_summary_already = false; 1135 break; 1136 } 1137 case eDisplayLanguageSpecific: 1138 return_value = GetObjectDescription(); 1139 break; 1140 case eDisplayLocation: 1141 return_value = GetLocationAsCString(); 1142 break; 1143 case eDisplayChildrenCount: 1144 { 1145 alloc_mem.resize(512); 1146 return_value = &alloc_mem[0]; 1147 int count = GetNumChildren(); 1148 snprintf((char*)return_value, 512, "%d", count); 1149 break; 1150 } 1151 case eDisplayType: 1152 return_value = GetTypeName().AsCString(); 1153 break; 1154 default: 1155 break; 1156 } 1157 1158 if (!return_value) 1159 { 1160 if (val_obj_display == eDisplayValue) 1161 return_value = GetSummaryAsCString(); 1162 else if (val_obj_display == eDisplaySummary) 1163 { 1164 if (ClangASTContext::IsAggregateType (GetClangType()) == true) 1165 { 1166 // this thing has no value, and it seems to have no summary 1167 // some combination of unitialized data and other factors can also 1168 // raise this condition, so let's print a nice generic description 1169 { 1170 alloc_mem.resize(684); 1171 return_value = &alloc_mem[0]; 1172 snprintf((char*)return_value, 684, "%s @ %s", GetTypeName().AsCString(), GetLocationAsCString()); 1173 } 1174 } 1175 else 1176 return_value = GetValueAsCString(); 1177 } 1178 } 1179 1180 if (return_value) 1181 s.PutCString(return_value); 1182 else 1183 { 1184 if (m_error.Fail()) 1185 s.Printf("<%s>", m_error.AsCString()); 1186 else if (val_obj_display == eDisplaySummary) 1187 s.PutCString("<no summary available>"); 1188 else if (val_obj_display == eDisplayValue) 1189 s.PutCString("<no value available>"); 1190 else if (val_obj_display == eDisplayLanguageSpecific) 1191 s.PutCString("<not a valid Objective-C object>"); // edit this if we have other runtimes that support a description 1192 else 1193 s.PutCString("<no printable representation>"); 1194 } 1195 1196 // we should only return false here if we could not do *anything* 1197 // even if we have an error message as output, that's a success 1198 // from our callers' perspective, so return true 1199 return true; 1200 1201} 1202 1203// if any more "special cases" are added to ValueObject::DumpPrintableRepresentation() please keep 1204// this call up to date by returning true for your new special cases. We will eventually move 1205// to checking this call result before trying to display special cases 1206bool 1207ValueObject::HasSpecialCasesForPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display, 1208 Format custom_format) 1209{ 1210 clang_type_t elem_or_pointee_type; 1211 Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type)); 1212 1213 if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) 1214 && val_obj_display == ValueObject::eDisplayValue) 1215 { 1216 if (IsCStringContainer(true) && 1217 (custom_format == eFormatCString || 1218 custom_format == eFormatCharArray || 1219 custom_format == eFormatChar || 1220 custom_format == eFormatVectorOfChar)) 1221 return true; 1222 1223 if (flags.Test(ClangASTContext::eTypeIsArray)) 1224 { 1225 if ((custom_format == eFormatBytes) || 1226 (custom_format == eFormatBytesWithASCII)) 1227 return true; 1228 1229 if ((custom_format == eFormatVectorOfChar) || 1230 (custom_format == eFormatVectorOfFloat32) || 1231 (custom_format == eFormatVectorOfFloat64) || 1232 (custom_format == eFormatVectorOfSInt16) || 1233 (custom_format == eFormatVectorOfSInt32) || 1234 (custom_format == eFormatVectorOfSInt64) || 1235 (custom_format == eFormatVectorOfSInt8) || 1236 (custom_format == eFormatVectorOfUInt128) || 1237 (custom_format == eFormatVectorOfUInt16) || 1238 (custom_format == eFormatVectorOfUInt32) || 1239 (custom_format == eFormatVectorOfUInt64) || 1240 (custom_format == eFormatVectorOfUInt8)) 1241 return true; 1242 } 1243 } 1244 return false; 1245} 1246 1247bool 1248ValueObject::DumpPrintableRepresentation(Stream& s, 1249 ValueObjectRepresentationStyle val_obj_display, 1250 Format custom_format, 1251 bool only_special) 1252{ 1253 1254 clang_type_t elem_or_pointee_type; 1255 Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type)); 1256 1257 if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) 1258 && val_obj_display == ValueObject::eDisplayValue) 1259 { 1260 // when being asked to get a printable display an array or pointer type directly, 1261 // try to "do the right thing" 1262 1263 if (IsCStringContainer(true) && 1264 (custom_format == eFormatCString || 1265 custom_format == eFormatCharArray || 1266 custom_format == eFormatChar || 1267 custom_format == eFormatVectorOfChar)) // print char[] & char* directly 1268 { 1269 Error error; 1270 ReadPointedString(s, 1271 error, 1272 0, 1273 (custom_format == eFormatVectorOfChar) || 1274 (custom_format == eFormatCharArray)); 1275 return !error.Fail(); 1276 } 1277 1278 if (custom_format == eFormatEnum) 1279 return false; 1280 1281 // this only works for arrays, because I have no way to know when 1282 // the pointed memory ends, and no special \0 end of data marker 1283 if (flags.Test(ClangASTContext::eTypeIsArray)) 1284 { 1285 if ((custom_format == eFormatBytes) || 1286 (custom_format == eFormatBytesWithASCII)) 1287 { 1288 uint32_t count = GetNumChildren(); 1289 1290 s << '['; 1291 for (uint32_t low = 0; low < count; low++) 1292 { 1293 1294 if (low) 1295 s << ','; 1296 1297 ValueObjectSP child = GetChildAtIndex(low,true); 1298 if (!child.get()) 1299 { 1300 s << "<invalid child>"; 1301 continue; 1302 } 1303 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, custom_format); 1304 } 1305 1306 s << ']'; 1307 1308 return true; 1309 } 1310 1311 if ((custom_format == eFormatVectorOfChar) || 1312 (custom_format == eFormatVectorOfFloat32) || 1313 (custom_format == eFormatVectorOfFloat64) || 1314 (custom_format == eFormatVectorOfSInt16) || 1315 (custom_format == eFormatVectorOfSInt32) || 1316 (custom_format == eFormatVectorOfSInt64) || 1317 (custom_format == eFormatVectorOfSInt8) || 1318 (custom_format == eFormatVectorOfUInt128) || 1319 (custom_format == eFormatVectorOfUInt16) || 1320 (custom_format == eFormatVectorOfUInt32) || 1321 (custom_format == eFormatVectorOfUInt64) || 1322 (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly 1323 { 1324 uint32_t count = GetNumChildren(); 1325 1326 Format format = FormatManager::GetSingleItemFormat(custom_format); 1327 1328 s << '['; 1329 for (uint32_t low = 0; low < count; low++) 1330 { 1331 1332 if (low) 1333 s << ','; 1334 1335 ValueObjectSP child = GetChildAtIndex(low,true); 1336 if (!child.get()) 1337 { 1338 s << "<invalid child>"; 1339 continue; 1340 } 1341 child->DumpPrintableRepresentation(s, ValueObject::eDisplayValue, format); 1342 } 1343 1344 s << ']'; 1345 1346 return true; 1347 } 1348 } 1349 1350 if ((custom_format == eFormatBoolean) || 1351 (custom_format == eFormatBinary) || 1352 (custom_format == eFormatChar) || 1353 (custom_format == eFormatCharPrintable) || 1354 (custom_format == eFormatComplexFloat) || 1355 (custom_format == eFormatDecimal) || 1356 (custom_format == eFormatHex) || 1357 (custom_format == eFormatFloat) || 1358 (custom_format == eFormatOctal) || 1359 (custom_format == eFormatOSType) || 1360 (custom_format == eFormatUnicode16) || 1361 (custom_format == eFormatUnicode32) || 1362 (custom_format == eFormatUnsigned) || 1363 (custom_format == eFormatPointer) || 1364 (custom_format == eFormatComplexInteger) || 1365 (custom_format == eFormatComplex) || 1366 (custom_format == eFormatDefault)) // use the [] operator 1367 return false; 1368 } 1369 1370 if (only_special) 1371 return false; 1372 1373 bool var_success = GetPrintableRepresentation(s, val_obj_display, custom_format); 1374 if (custom_format != eFormatInvalid) 1375 SetFormat(eFormatDefault); 1376 return var_success; 1377} 1378 1379addr_t 1380ValueObject::GetAddressOf (bool scalar_is_load_address, AddressType *address_type) 1381{ 1382 if (!UpdateValueIfNeeded(false)) 1383 return LLDB_INVALID_ADDRESS; 1384 1385 switch (m_value.GetValueType()) 1386 { 1387 case Value::eValueTypeScalar: 1388 if (scalar_is_load_address) 1389 { 1390 if(address_type) 1391 *address_type = eAddressTypeLoad; 1392 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 1393 } 1394 break; 1395 1396 case Value::eValueTypeLoadAddress: 1397 case Value::eValueTypeFileAddress: 1398 case Value::eValueTypeHostAddress: 1399 { 1400 if(address_type) 1401 *address_type = m_value.GetValueAddressType (); 1402 return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 1403 } 1404 break; 1405 } 1406 if (address_type) 1407 *address_type = eAddressTypeInvalid; 1408 return LLDB_INVALID_ADDRESS; 1409} 1410 1411addr_t 1412ValueObject::GetPointerValue (AddressType *address_type) 1413{ 1414 addr_t address = LLDB_INVALID_ADDRESS; 1415 if(address_type) 1416 *address_type = eAddressTypeInvalid; 1417 1418 if (!UpdateValueIfNeeded(false)) 1419 return address; 1420 1421 switch (m_value.GetValueType()) 1422 { 1423 case Value::eValueTypeScalar: 1424 address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); 1425 break; 1426 1427 case Value::eValueTypeHostAddress: 1428 case Value::eValueTypeLoadAddress: 1429 case Value::eValueTypeFileAddress: 1430 { 1431 uint32_t data_offset = 0; 1432 address = m_data.GetPointer(&data_offset); 1433 } 1434 break; 1435 } 1436 1437 if (address_type) 1438 *address_type = GetAddressTypeOfChildren(); 1439 1440 return address; 1441} 1442 1443bool 1444ValueObject::SetValueFromCString (const char *value_str) 1445{ 1446 // Make sure our value is up to date first so that our location and location 1447 // type is valid. 1448 if (!UpdateValueIfNeeded(false)) 1449 return false; 1450 1451 uint32_t count = 0; 1452 Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count); 1453 1454 const size_t byte_size = GetByteSize(); 1455 1456 Value::ValueType value_type = m_value.GetValueType(); 1457 1458 if (value_type == Value::eValueTypeScalar) 1459 { 1460 // If the value is already a scalar, then let the scalar change itself: 1461 m_value.GetScalar().SetValueFromCString (value_str, encoding, byte_size); 1462 } 1463 else if (byte_size <= Scalar::GetMaxByteSize()) 1464 { 1465 // If the value fits in a scalar, then make a new scalar and again let the 1466 // scalar code do the conversion, then figure out where to put the new value. 1467 Scalar new_scalar; 1468 Error error; 1469 error = new_scalar.SetValueFromCString (value_str, encoding, byte_size); 1470 if (error.Success()) 1471 { 1472 switch (value_type) 1473 { 1474 case Value::eValueTypeLoadAddress: 1475 { 1476 // If it is a load address, then the scalar value is the storage location 1477 // of the data, and we have to shove this value down to that load location. 1478 ProcessSP process_sp = GetUpdatePoint().GetProcessSP(); 1479 if (process_sp) 1480 { 1481 addr_t target_addr = m_value.GetScalar().GetRawBits64(LLDB_INVALID_ADDRESS); 1482 size_t bytes_written = process_sp->WriteScalarToMemory (target_addr, 1483 new_scalar, 1484 byte_size, 1485 error); 1486 if (!error.Success() || bytes_written != byte_size) 1487 return false; 1488 } 1489 } 1490 break; 1491 case Value::eValueTypeHostAddress: 1492 { 1493 // If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data. 1494 DataExtractor new_data; 1495 new_data.SetByteOrder (m_data.GetByteOrder()); 1496 1497 DataBufferSP buffer_sp (new DataBufferHeap(byte_size, 0)); 1498 m_data.SetData(buffer_sp, 0); 1499 bool success = new_scalar.GetData(new_data); 1500 if (success) 1501 { 1502 new_data.CopyByteOrderedData(0, 1503 byte_size, 1504 const_cast<uint8_t *>(m_data.GetDataStart()), 1505 byte_size, 1506 m_data.GetByteOrder()); 1507 } 1508 m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); 1509 1510 } 1511 break; 1512 case Value::eValueTypeFileAddress: 1513 case Value::eValueTypeScalar: 1514 break; 1515 } 1516 } 1517 else 1518 { 1519 return false; 1520 } 1521 } 1522 else 1523 { 1524 // We don't support setting things bigger than a scalar at present. 1525 return false; 1526 } 1527 1528 // If we have reached this point, then we have successfully changed the value. 1529 SetNeedsUpdate(); 1530 return true; 1531} 1532 1533LanguageType 1534ValueObject::GetObjectRuntimeLanguage () 1535{ 1536 return ClangASTType::GetMinimumLanguage (GetClangAST(), 1537 GetClangType()); 1538} 1539 1540void 1541ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj) 1542{ 1543 m_synthetic_children[key] = valobj; 1544} 1545 1546ValueObjectSP 1547ValueObject::GetSyntheticChild (const ConstString &key) const 1548{ 1549 ValueObjectSP synthetic_child_sp; 1550 std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key); 1551 if (pos != m_synthetic_children.end()) 1552 synthetic_child_sp = pos->second->GetSP(); 1553 return synthetic_child_sp; 1554} 1555 1556bool 1557ValueObject::IsPointerType () 1558{ 1559 return ClangASTContext::IsPointerType (GetClangType()); 1560} 1561 1562bool 1563ValueObject::IsArrayType () 1564{ 1565 return ClangASTContext::IsArrayType (GetClangType()); 1566} 1567 1568bool 1569ValueObject::IsScalarType () 1570{ 1571 return ClangASTContext::IsScalarType (GetClangType()); 1572} 1573 1574bool 1575ValueObject::IsIntegerType (bool &is_signed) 1576{ 1577 return ClangASTContext::IsIntegerType (GetClangType(), is_signed); 1578} 1579 1580bool 1581ValueObject::IsPointerOrReferenceType () 1582{ 1583 return ClangASTContext::IsPointerOrReferenceType (GetClangType()); 1584} 1585 1586bool 1587ValueObject::IsPossibleCPlusPlusDynamicType () 1588{ 1589 return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType()); 1590} 1591 1592bool 1593ValueObject::IsPossibleDynamicType () 1594{ 1595 return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType()); 1596} 1597 1598ValueObjectSP 1599ValueObject::GetSyntheticArrayMember (int32_t index, bool can_create) 1600{ 1601 if (IsArrayType()) 1602 return GetSyntheticArrayMemberFromArray(index, can_create); 1603 1604 if (IsPointerType()) 1605 return GetSyntheticArrayMemberFromPointer(index, can_create); 1606 1607 return ValueObjectSP(); 1608 1609} 1610 1611ValueObjectSP 1612ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create) 1613{ 1614 ValueObjectSP synthetic_child_sp; 1615 if (IsPointerType ()) 1616 { 1617 char index_str[64]; 1618 snprintf(index_str, sizeof(index_str), "[%i]", index); 1619 ConstString index_const_str(index_str); 1620 // Check if we have already created a synthetic array member in this 1621 // valid object. If we have we will re-use it. 1622 synthetic_child_sp = GetSyntheticChild (index_const_str); 1623 if (!synthetic_child_sp) 1624 { 1625 ValueObject *synthetic_child; 1626 // We haven't made a synthetic array member for INDEX yet, so 1627 // lets make one and cache it for any future reference. 1628 synthetic_child = CreateChildAtIndex(0, true, index); 1629 1630 // Cache the value if we got one back... 1631 if (synthetic_child) 1632 { 1633 AddSyntheticChild(index_const_str, synthetic_child); 1634 synthetic_child_sp = synthetic_child->GetSP(); 1635 synthetic_child_sp->SetName(ConstString(index_str)); 1636 synthetic_child_sp->m_is_array_item_for_pointer = true; 1637 } 1638 } 1639 } 1640 return synthetic_child_sp; 1641} 1642 1643// This allows you to create an array member using and index 1644// that doesn't not fall in the normal bounds of the array. 1645// Many times structure can be defined as: 1646// struct Collection 1647// { 1648// uint32_t item_count; 1649// Item item_array[0]; 1650// }; 1651// The size of the "item_array" is 1, but many times in practice 1652// there are more items in "item_array". 1653 1654ValueObjectSP 1655ValueObject::GetSyntheticArrayMemberFromArray (int32_t index, bool can_create) 1656{ 1657 ValueObjectSP synthetic_child_sp; 1658 if (IsArrayType ()) 1659 { 1660 char index_str[64]; 1661 snprintf(index_str, sizeof(index_str), "[%i]", index); 1662 ConstString index_const_str(index_str); 1663 // Check if we have already created a synthetic array member in this 1664 // valid object. If we have we will re-use it. 1665 synthetic_child_sp = GetSyntheticChild (index_const_str); 1666 if (!synthetic_child_sp) 1667 { 1668 ValueObject *synthetic_child; 1669 // We haven't made a synthetic array member for INDEX yet, so 1670 // lets make one and cache it for any future reference. 1671 synthetic_child = CreateChildAtIndex(0, true, index); 1672 1673 // Cache the value if we got one back... 1674 if (synthetic_child) 1675 { 1676 AddSyntheticChild(index_const_str, synthetic_child); 1677 synthetic_child_sp = synthetic_child->GetSP(); 1678 synthetic_child_sp->SetName(ConstString(index_str)); 1679 synthetic_child_sp->m_is_array_item_for_pointer = true; 1680 } 1681 } 1682 } 1683 return synthetic_child_sp; 1684} 1685 1686ValueObjectSP 1687ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create) 1688{ 1689 ValueObjectSP synthetic_child_sp; 1690 if (IsScalarType ()) 1691 { 1692 char index_str[64]; 1693 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to); 1694 ConstString index_const_str(index_str); 1695 // Check if we have already created a synthetic array member in this 1696 // valid object. If we have we will re-use it. 1697 synthetic_child_sp = GetSyntheticChild (index_const_str); 1698 if (!synthetic_child_sp) 1699 { 1700 ValueObjectChild *synthetic_child; 1701 // We haven't made a synthetic array member for INDEX yet, so 1702 // lets make one and cache it for any future reference. 1703 synthetic_child = new ValueObjectChild(*this, 1704 GetClangAST(), 1705 GetClangType(), 1706 index_const_str, 1707 GetByteSize(), 1708 0, 1709 to-from+1, 1710 from, 1711 false, 1712 false, 1713 eAddressTypeInvalid); 1714 1715 // Cache the value if we got one back... 1716 if (synthetic_child) 1717 { 1718 AddSyntheticChild(index_const_str, synthetic_child); 1719 synthetic_child_sp = synthetic_child->GetSP(); 1720 synthetic_child_sp->SetName(ConstString(index_str)); 1721 synthetic_child_sp->m_is_bitfield_for_scalar = true; 1722 } 1723 } 1724 } 1725 return synthetic_child_sp; 1726} 1727 1728ValueObjectSP 1729ValueObject::GetSyntheticArrayRangeChild (uint32_t from, uint32_t to, bool can_create) 1730{ 1731 ValueObjectSP synthetic_child_sp; 1732 if (IsArrayType () || IsPointerType ()) 1733 { 1734 char index_str[64]; 1735 snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to); 1736 ConstString index_const_str(index_str); 1737 // Check if we have already created a synthetic array member in this 1738 // valid object. If we have we will re-use it. 1739 synthetic_child_sp = GetSyntheticChild (index_const_str); 1740 if (!synthetic_child_sp) 1741 { 1742 ValueObjectSynthetic *synthetic_child; 1743 1744 // We haven't made a synthetic array member for INDEX yet, so 1745 // lets make one and cache it for any future reference. 1746 SyntheticArrayView *view = new SyntheticArrayView(); 1747 view->AddRange(from,to); 1748 SyntheticChildrenSP view_sp(view); 1749 synthetic_child = new ValueObjectSynthetic(*this, view_sp); 1750 1751 // Cache the value if we got one back... 1752 if (synthetic_child) 1753 { 1754 AddSyntheticChild(index_const_str, synthetic_child); 1755 synthetic_child_sp = synthetic_child->GetSP(); 1756 synthetic_child_sp->SetName(ConstString(index_str)); 1757 synthetic_child_sp->m_is_bitfield_for_scalar = true; 1758 } 1759 } 1760 } 1761 return synthetic_child_sp; 1762} 1763 1764ValueObjectSP 1765ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create) 1766{ 1767 1768 ValueObjectSP synthetic_child_sp; 1769 1770 char name_str[64]; 1771 snprintf(name_str, sizeof(name_str), "@%i", offset); 1772 ConstString name_const_str(name_str); 1773 1774 // Check if we have already created a synthetic array member in this 1775 // valid object. If we have we will re-use it. 1776 synthetic_child_sp = GetSyntheticChild (name_const_str); 1777 1778 if (synthetic_child_sp.get()) 1779 return synthetic_child_sp; 1780 1781 if (!can_create) 1782 return ValueObjectSP(); 1783 1784 ValueObjectChild *synthetic_child = new ValueObjectChild(*this, 1785 type.GetASTContext(), 1786 type.GetOpaqueQualType(), 1787 name_const_str, 1788 type.GetTypeByteSize(), 1789 offset, 1790 0, 1791 0, 1792 false, 1793 false, 1794 eAddressTypeInvalid); 1795 if (synthetic_child) 1796 { 1797 AddSyntheticChild(name_const_str, synthetic_child); 1798 synthetic_child_sp = synthetic_child->GetSP(); 1799 synthetic_child_sp->SetName(name_const_str); 1800 synthetic_child_sp->m_is_child_at_offset = true; 1801 } 1802 return synthetic_child_sp; 1803} 1804 1805// your expression path needs to have a leading . or -> 1806// (unless it somehow "looks like" an array, in which case it has 1807// a leading [ symbol). while the [ is meaningful and should be shown 1808// to the user, . and -> are just parser design, but by no means 1809// added information for the user.. strip them off 1810static const char* 1811SkipLeadingExpressionPathSeparators(const char* expression) 1812{ 1813 if (!expression || !expression[0]) 1814 return expression; 1815 if (expression[0] == '.') 1816 return expression+1; 1817 if (expression[0] == '-' && expression[1] == '>') 1818 return expression+2; 1819 return expression; 1820} 1821 1822ValueObjectSP 1823ValueObject::GetSyntheticExpressionPathChild(const char* expression, bool can_create) 1824{ 1825 ValueObjectSP synthetic_child_sp; 1826 ConstString name_const_string(expression); 1827 // Check if we have already created a synthetic array member in this 1828 // valid object. If we have we will re-use it. 1829 synthetic_child_sp = GetSyntheticChild (name_const_string); 1830 if (!synthetic_child_sp) 1831 { 1832 // We haven't made a synthetic array member for expression yet, so 1833 // lets make one and cache it for any future reference. 1834 synthetic_child_sp = GetValueForExpressionPath(expression); 1835 1836 // Cache the value if we got one back... 1837 if (synthetic_child_sp.get()) 1838 { 1839 AddSyntheticChild(name_const_string, synthetic_child_sp.get()); 1840 synthetic_child_sp->SetName(ConstString(SkipLeadingExpressionPathSeparators(expression))); 1841 synthetic_child_sp->m_is_expression_path_child = true; 1842 } 1843 } 1844 return synthetic_child_sp; 1845} 1846 1847void 1848ValueObject::CalculateSyntheticValue (SyntheticValueType use_synthetic) 1849{ 1850 if (use_synthetic == eNoSyntheticFilter) 1851 return; 1852 1853 UpdateFormatsIfNeeded(m_last_format_mgr_dynamic); 1854 1855 if (m_last_synthetic_filter.get() == NULL) 1856 return; 1857 1858 if (m_synthetic_value == NULL) 1859 m_synthetic_value = new ValueObjectSynthetic(*this, m_last_synthetic_filter); 1860 1861} 1862 1863void 1864ValueObject::CalculateDynamicValue (DynamicValueType use_dynamic) 1865{ 1866 if (use_dynamic == eNoDynamicValues) 1867 return; 1868 1869 if (!m_dynamic_value && !IsDynamic()) 1870 { 1871 Process *process = m_update_point.GetProcessSP().get(); 1872 bool worth_having_dynamic_value = false; 1873 1874 1875 // FIXME: Process should have some kind of "map over Runtimes" so we don't have to 1876 // hard code this everywhere. 1877 LanguageType known_type = GetObjectRuntimeLanguage(); 1878 if (known_type != eLanguageTypeUnknown && known_type != eLanguageTypeC) 1879 { 1880 LanguageRuntime *runtime = process->GetLanguageRuntime (known_type); 1881 if (runtime) 1882 worth_having_dynamic_value = runtime->CouldHaveDynamicValue(*this); 1883 } 1884 else 1885 { 1886 LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (eLanguageTypeC_plus_plus); 1887 if (cpp_runtime) 1888 worth_having_dynamic_value = cpp_runtime->CouldHaveDynamicValue(*this); 1889 1890 if (!worth_having_dynamic_value) 1891 { 1892 LanguageRuntime *objc_runtime = process->GetLanguageRuntime (eLanguageTypeObjC); 1893 if (objc_runtime) 1894 worth_having_dynamic_value = objc_runtime->CouldHaveDynamicValue(*this); 1895 } 1896 } 1897 1898 if (worth_having_dynamic_value) 1899 m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic); 1900 1901// if (worth_having_dynamic_value) 1902// printf ("Adding dynamic value %s (%p) to (%p) - manager %p.\n", m_name.GetCString(), m_dynamic_value, this, m_manager); 1903 1904 } 1905} 1906 1907ValueObjectSP 1908ValueObject::GetDynamicValue (DynamicValueType use_dynamic) 1909{ 1910 if (use_dynamic == eNoDynamicValues) 1911 return ValueObjectSP(); 1912 1913 if (!IsDynamic() && m_dynamic_value == NULL) 1914 { 1915 CalculateDynamicValue(use_dynamic); 1916 } 1917 if (m_dynamic_value) 1918 return m_dynamic_value->GetSP(); 1919 else 1920 return ValueObjectSP(); 1921} 1922 1923// GetDynamicValue() returns a NULL SharedPointer if the object is not dynamic 1924// or we do not really want a dynamic VO. this method instead returns this object 1925// itself when making it synthetic has no meaning. this makes it much simpler 1926// to replace the SyntheticValue for the ValueObject 1927ValueObjectSP 1928ValueObject::GetSyntheticValue (SyntheticValueType use_synthetic) 1929{ 1930 if (use_synthetic == eNoSyntheticFilter) 1931 return GetSP(); 1932 1933 UpdateFormatsIfNeeded(m_last_format_mgr_dynamic); 1934 1935 if (m_last_synthetic_filter.get() == NULL) 1936 return GetSP(); 1937 1938 CalculateSyntheticValue(use_synthetic); 1939 1940 if (m_synthetic_value) 1941 return m_synthetic_value->GetSP(); 1942 else 1943 return GetSP(); 1944} 1945 1946bool 1947ValueObject::HasSyntheticValue() 1948{ 1949 UpdateFormatsIfNeeded(m_last_format_mgr_dynamic); 1950 1951 if (m_last_synthetic_filter.get() == NULL) 1952 return false; 1953 1954 CalculateSyntheticValue(eUseSyntheticFilter); 1955 1956 if (m_synthetic_value) 1957 return true; 1958 else 1959 return false; 1960} 1961 1962bool 1963ValueObject::GetBaseClassPath (Stream &s) 1964{ 1965 if (IsBaseClass()) 1966 { 1967 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s); 1968 clang_type_t clang_type = GetClangType(); 1969 std::string cxx_class_name; 1970 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name); 1971 if (this_had_base_class) 1972 { 1973 if (parent_had_base_class) 1974 s.PutCString("::"); 1975 s.PutCString(cxx_class_name.c_str()); 1976 } 1977 return parent_had_base_class || this_had_base_class; 1978 } 1979 return false; 1980} 1981 1982 1983ValueObject * 1984ValueObject::GetNonBaseClassParent() 1985{ 1986 if (GetParent()) 1987 { 1988 if (GetParent()->IsBaseClass()) 1989 return GetParent()->GetNonBaseClassParent(); 1990 else 1991 return GetParent(); 1992 } 1993 return NULL; 1994} 1995 1996void 1997ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat) 1998{ 1999 const bool is_deref_of_parent = IsDereferenceOfParent (); 2000 2001 if (is_deref_of_parent && epformat == eDereferencePointers) 2002 { 2003 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely 2004 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName. 2005 // the eHonorPointers mode is meant to produce strings in this latter format 2006 s.PutCString("*("); 2007 } 2008 2009 ValueObject* parent = GetParent(); 2010 2011 if (parent) 2012 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat); 2013 2014 // if we are a deref_of_parent just because we are synthetic array 2015 // members made up to allow ptr[%d] syntax to work in variable 2016 // printing, then add our name ([%d]) to the expression path 2017 if (m_is_array_item_for_pointer && epformat == eHonorPointers) 2018 s.PutCString(m_name.AsCString()); 2019 2020 if (!IsBaseClass()) 2021 { 2022 if (!is_deref_of_parent) 2023 { 2024 ValueObject *non_base_class_parent = GetNonBaseClassParent(); 2025 if (non_base_class_parent) 2026 { 2027 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType(); 2028 if (non_base_class_parent_clang_type) 2029 { 2030 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL); 2031 2032 if (parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers) 2033 { 2034 s.PutCString("->"); 2035 } 2036 else 2037 { 2038 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer) 2039 { 2040 s.PutCString("->"); 2041 } 2042 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) && 2043 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray)) 2044 { 2045 s.PutChar('.'); 2046 } 2047 } 2048 } 2049 } 2050 2051 const char *name = GetName().GetCString(); 2052 if (name) 2053 { 2054 if (qualify_cxx_base_classes) 2055 { 2056 if (GetBaseClassPath (s)) 2057 s.PutCString("::"); 2058 } 2059 s.PutCString(name); 2060 } 2061 } 2062 } 2063 2064 if (is_deref_of_parent && epformat == eDereferencePointers) 2065 { 2066 s.PutChar(')'); 2067 } 2068} 2069 2070ValueObjectSP 2071ValueObject::GetValueForExpressionPath(const char* expression, 2072 const char** first_unparsed, 2073 ExpressionPathScanEndReason* reason_to_stop, 2074 ExpressionPathEndResultType* final_value_type, 2075 const GetValueForExpressionPathOptions& options, 2076 ExpressionPathAftermath* final_task_on_target) 2077{ 2078 2079 const char* dummy_first_unparsed; 2080 ExpressionPathScanEndReason dummy_reason_to_stop; 2081 ExpressionPathEndResultType dummy_final_value_type; 2082 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing; 2083 2084 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression, 2085 first_unparsed ? first_unparsed : &dummy_first_unparsed, 2086 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop, 2087 final_value_type ? final_value_type : &dummy_final_value_type, 2088 options, 2089 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target); 2090 2091 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing) 2092 { 2093 return ret_val; 2094 } 2095 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects 2096 { 2097 if (*final_task_on_target == ValueObject::eDereference) 2098 { 2099 Error error; 2100 ValueObjectSP final_value = ret_val->Dereference(error); 2101 if (error.Fail() || !final_value.get()) 2102 { 2103 *reason_to_stop = ValueObject::eDereferencingFailed; 2104 *final_value_type = ValueObject::eInvalid; 2105 return ValueObjectSP(); 2106 } 2107 else 2108 { 2109 *final_task_on_target = ValueObject::eNothing; 2110 return final_value; 2111 } 2112 } 2113 if (*final_task_on_target == ValueObject::eTakeAddress) 2114 { 2115 Error error; 2116 ValueObjectSP final_value = ret_val->AddressOf(error); 2117 if (error.Fail() || !final_value.get()) 2118 { 2119 *reason_to_stop = ValueObject::eTakingAddressFailed; 2120 *final_value_type = ValueObject::eInvalid; 2121 return ValueObjectSP(); 2122 } 2123 else 2124 { 2125 *final_task_on_target = ValueObject::eNothing; 2126 return final_value; 2127 } 2128 } 2129 } 2130 return ret_val; // final_task_on_target will still have its original value, so you know I did not do it 2131} 2132 2133int 2134ValueObject::GetValuesForExpressionPath(const char* expression, 2135 ValueObjectListSP& list, 2136 const char** first_unparsed, 2137 ExpressionPathScanEndReason* reason_to_stop, 2138 ExpressionPathEndResultType* final_value_type, 2139 const GetValueForExpressionPathOptions& options, 2140 ExpressionPathAftermath* final_task_on_target) 2141{ 2142 const char* dummy_first_unparsed; 2143 ExpressionPathScanEndReason dummy_reason_to_stop; 2144 ExpressionPathEndResultType dummy_final_value_type; 2145 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing; 2146 2147 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression, 2148 first_unparsed ? first_unparsed : &dummy_first_unparsed, 2149 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop, 2150 final_value_type ? final_value_type : &dummy_final_value_type, 2151 options, 2152 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target); 2153 2154 if (!ret_val.get()) // if there are errors, I add nothing to the list 2155 return 0; 2156 2157 if (*reason_to_stop != eArrayRangeOperatorMet) 2158 { 2159 // I need not expand a range, just post-process the final value and return 2160 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing) 2161 { 2162 list->Append(ret_val); 2163 return 1; 2164 } 2165 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects 2166 { 2167 if (*final_task_on_target == ValueObject::eDereference) 2168 { 2169 Error error; 2170 ValueObjectSP final_value = ret_val->Dereference(error); 2171 if (error.Fail() || !final_value.get()) 2172 { 2173 *reason_to_stop = ValueObject::eDereferencingFailed; 2174 *final_value_type = ValueObject::eInvalid; 2175 return 0; 2176 } 2177 else 2178 { 2179 *final_task_on_target = ValueObject::eNothing; 2180 list->Append(final_value); 2181 return 1; 2182 } 2183 } 2184 if (*final_task_on_target == ValueObject::eTakeAddress) 2185 { 2186 Error error; 2187 ValueObjectSP final_value = ret_val->AddressOf(error); 2188 if (error.Fail() || !final_value.get()) 2189 { 2190 *reason_to_stop = ValueObject::eTakingAddressFailed; 2191 *final_value_type = ValueObject::eInvalid; 2192 return 0; 2193 } 2194 else 2195 { 2196 *final_task_on_target = ValueObject::eNothing; 2197 list->Append(final_value); 2198 return 1; 2199 } 2200 } 2201 } 2202 } 2203 else 2204 { 2205 return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed, 2206 first_unparsed ? first_unparsed : &dummy_first_unparsed, 2207 ret_val, 2208 list, 2209 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop, 2210 final_value_type ? final_value_type : &dummy_final_value_type, 2211 options, 2212 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target); 2213 } 2214 // in any non-covered case, just do the obviously right thing 2215 list->Append(ret_val); 2216 return 1; 2217} 2218 2219ValueObjectSP 2220ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, 2221 const char** first_unparsed, 2222 ExpressionPathScanEndReason* reason_to_stop, 2223 ExpressionPathEndResultType* final_result, 2224 const GetValueForExpressionPathOptions& options, 2225 ExpressionPathAftermath* what_next) 2226{ 2227 ValueObjectSP root = GetSP(); 2228 2229 if (!root.get()) 2230 return ValueObjectSP(); 2231 2232 *first_unparsed = expression_cstr; 2233 2234 while (true) 2235 { 2236 2237 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr 2238 2239 clang_type_t root_clang_type = root->GetClangType(); 2240 clang_type_t pointee_clang_type; 2241 Flags root_clang_type_info,pointee_clang_type_info; 2242 2243 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type)); 2244 if (pointee_clang_type) 2245 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL)); 2246 2247 if (!expression_cstr || *expression_cstr == '\0') 2248 { 2249 *reason_to_stop = ValueObject::eEndOfString; 2250 return root; 2251 } 2252 2253 switch (*expression_cstr) 2254 { 2255 case '-': 2256 { 2257 if (options.m_check_dot_vs_arrow_syntax && 2258 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error 2259 { 2260 *first_unparsed = expression_cstr; 2261 *reason_to_stop = ValueObject::eArrowInsteadOfDot; 2262 *final_result = ValueObject::eInvalid; 2263 return ValueObjectSP(); 2264 } 2265 if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden 2266 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && 2267 options.m_no_fragile_ivar) 2268 { 2269 *first_unparsed = expression_cstr; 2270 *reason_to_stop = ValueObject::eFragileIVarNotAllowed; 2271 *final_result = ValueObject::eInvalid; 2272 return ValueObjectSP(); 2273 } 2274 if (expression_cstr[1] != '>') 2275 { 2276 *first_unparsed = expression_cstr; 2277 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2278 *final_result = ValueObject::eInvalid; 2279 return ValueObjectSP(); 2280 } 2281 expression_cstr++; // skip the - 2282 } 2283 case '.': // or fallthrough from -> 2284 { 2285 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' && 2286 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error 2287 { 2288 *first_unparsed = expression_cstr; 2289 *reason_to_stop = ValueObject::eDotInsteadOfArrow; 2290 *final_result = ValueObject::eInvalid; 2291 return ValueObjectSP(); 2292 } 2293 expression_cstr++; // skip . 2294 const char *next_separator = strpbrk(expression_cstr+1,"-.["); 2295 ConstString child_name; 2296 if (!next_separator) // if no other separator just expand this last layer 2297 { 2298 child_name.SetCString (expression_cstr); 2299 ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true); 2300 2301 if (child_valobj_sp.get()) // we know we are done, so just return 2302 { 2303 *first_unparsed = '\0'; 2304 *reason_to_stop = ValueObject::eEndOfString; 2305 *final_result = ValueObject::ePlain; 2306 return child_valobj_sp; 2307 } 2308 else if (options.m_no_synthetic_children == false) // let's try with synthetic children 2309 { 2310 child_valobj_sp = root->GetSyntheticValue(eUseSyntheticFilter)->GetChildMemberWithName(child_name, true); 2311 } 2312 2313 // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP, 2314 // so we hit the "else" branch, and return an error 2315 if(child_valobj_sp.get()) // if it worked, just return 2316 { 2317 *first_unparsed = '\0'; 2318 *reason_to_stop = ValueObject::eEndOfString; 2319 *final_result = ValueObject::ePlain; 2320 return child_valobj_sp; 2321 } 2322 else 2323 { 2324 *first_unparsed = expression_cstr; 2325 *reason_to_stop = ValueObject::eNoSuchChild; 2326 *final_result = ValueObject::eInvalid; 2327 return ValueObjectSP(); 2328 } 2329 } 2330 else // other layers do expand 2331 { 2332 child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr); 2333 ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true); 2334 if (child_valobj_sp.get()) // store the new root and move on 2335 { 2336 root = child_valobj_sp; 2337 *first_unparsed = next_separator; 2338 *final_result = ValueObject::ePlain; 2339 continue; 2340 } 2341 else if (options.m_no_synthetic_children == false) // let's try with synthetic children 2342 { 2343 child_valobj_sp = root->GetSyntheticValue(eUseSyntheticFilter)->GetChildMemberWithName(child_name, true); 2344 } 2345 2346 // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP, 2347 // so we hit the "else" branch, and return an error 2348 if(child_valobj_sp.get()) // if it worked, move on 2349 { 2350 root = child_valobj_sp; 2351 *first_unparsed = next_separator; 2352 *final_result = ValueObject::ePlain; 2353 continue; 2354 } 2355 else 2356 { 2357 *first_unparsed = expression_cstr; 2358 *reason_to_stop = ValueObject::eNoSuchChild; 2359 *final_result = ValueObject::eInvalid; 2360 return ValueObjectSP(); 2361 } 2362 } 2363 break; 2364 } 2365 case '[': 2366 { 2367 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T* 2368 { 2369 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar... 2370 { 2371 if (options.m_no_synthetic_children) // ...only chance left is synthetic 2372 { 2373 *first_unparsed = expression_cstr; 2374 *reason_to_stop = ValueObject::eRangeOperatorInvalid; 2375 *final_result = ValueObject::eInvalid; 2376 return ValueObjectSP(); 2377 } 2378 } 2379 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields 2380 { 2381 *first_unparsed = expression_cstr; 2382 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed; 2383 *final_result = ValueObject::eInvalid; 2384 return ValueObjectSP(); 2385 } 2386 } 2387 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays 2388 { 2389 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) 2390 { 2391 *first_unparsed = expression_cstr; 2392 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed; 2393 *final_result = ValueObject::eInvalid; 2394 return ValueObjectSP(); 2395 } 2396 else // even if something follows, we cannot expand unbounded ranges, just let the caller do it 2397 { 2398 *first_unparsed = expression_cstr+2; 2399 *reason_to_stop = ValueObject::eArrayRangeOperatorMet; 2400 *final_result = ValueObject::eUnboundedRange; 2401 return root; 2402 } 2403 } 2404 const char *separator_position = ::strchr(expression_cstr+1,'-'); 2405 const char *close_bracket_position = ::strchr(expression_cstr+1,']'); 2406 if (!close_bracket_position) // if there is no ], this is a syntax error 2407 { 2408 *first_unparsed = expression_cstr; 2409 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2410 *final_result = ValueObject::eInvalid; 2411 return ValueObjectSP(); 2412 } 2413 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N] 2414 { 2415 char *end = NULL; 2416 unsigned long index = ::strtoul (expression_cstr+1, &end, 0); 2417 if (!end || end != close_bracket_position) // if something weird is in our way return an error 2418 { 2419 *first_unparsed = expression_cstr; 2420 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2421 *final_result = ValueObject::eInvalid; 2422 return ValueObjectSP(); 2423 } 2424 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays 2425 { 2426 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) 2427 { 2428 *first_unparsed = expression_cstr+2; 2429 *reason_to_stop = ValueObject::eArrayRangeOperatorMet; 2430 *final_result = ValueObject::eUnboundedRange; 2431 return root; 2432 } 2433 else 2434 { 2435 *first_unparsed = expression_cstr; 2436 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed; 2437 *final_result = ValueObject::eInvalid; 2438 return ValueObjectSP(); 2439 } 2440 } 2441 // from here on we do have a valid index 2442 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) 2443 { 2444 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true); 2445 if (!child_valobj_sp) 2446 child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true); 2447 if (!child_valobj_sp) 2448 if (root->HasSyntheticValue() && root->GetSyntheticValue(eUseSyntheticFilter)->GetNumChildren() > index) 2449 child_valobj_sp = root->GetSyntheticValue(eUseSyntheticFilter)->GetChildAtIndex(index, true); 2450 if (child_valobj_sp) 2451 { 2452 root = child_valobj_sp; 2453 *first_unparsed = end+1; // skip ] 2454 *final_result = ValueObject::ePlain; 2455 continue; 2456 } 2457 else 2458 { 2459 *first_unparsed = expression_cstr; 2460 *reason_to_stop = ValueObject::eNoSuchChild; 2461 *final_result = ValueObject::eInvalid; 2462 return ValueObjectSP(); 2463 } 2464 } 2465 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) 2466 { 2467 if (*what_next == ValueObject::eDereference && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield 2468 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) 2469 { 2470 Error error; 2471 root = root->Dereference(error); 2472 if (error.Fail() || !root.get()) 2473 { 2474 *first_unparsed = expression_cstr; 2475 *reason_to_stop = ValueObject::eDereferencingFailed; 2476 *final_result = ValueObject::eInvalid; 2477 return ValueObjectSP(); 2478 } 2479 else 2480 { 2481 *what_next = eNothing; 2482 continue; 2483 } 2484 } 2485 else 2486 { 2487 if (ClangASTType::GetMinimumLanguage(root->GetClangAST(), 2488 root->GetClangType()) == eLanguageTypeObjC 2489 && 2490 ClangASTContext::IsPointerType(ClangASTType::GetPointeeType(root->GetClangType())) == false 2491 && 2492 root->HasSyntheticValue() 2493 && 2494 options.m_no_synthetic_children == false) 2495 { 2496 root = root->GetSyntheticValue(eUseSyntheticFilter)->GetChildAtIndex(index, true); 2497 } 2498 else 2499 root = root->GetSyntheticArrayMemberFromPointer(index, true); 2500 if (!root.get()) 2501 { 2502 *first_unparsed = expression_cstr; 2503 *reason_to_stop = ValueObject::eNoSuchChild; 2504 *final_result = ValueObject::eInvalid; 2505 return ValueObjectSP(); 2506 } 2507 else 2508 { 2509 *first_unparsed = end+1; // skip ] 2510 *final_result = ValueObject::ePlain; 2511 continue; 2512 } 2513 } 2514 } 2515 else if (ClangASTContext::IsScalarType(root_clang_type)) 2516 { 2517 root = root->GetSyntheticBitFieldChild(index, index, true); 2518 if (!root.get()) 2519 { 2520 *first_unparsed = expression_cstr; 2521 *reason_to_stop = ValueObject::eNoSuchChild; 2522 *final_result = ValueObject::eInvalid; 2523 return ValueObjectSP(); 2524 } 2525 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing 2526 { 2527 *first_unparsed = end+1; // skip ] 2528 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet; 2529 *final_result = ValueObject::eBitfield; 2530 return root; 2531 } 2532 } 2533 else if (root->HasSyntheticValue() && options.m_no_synthetic_children == false) 2534 { 2535 root = root->GetSyntheticValue(eUseSyntheticFilter)->GetChildAtIndex(index, true); 2536 if (!root.get()) 2537 { 2538 *first_unparsed = expression_cstr; 2539 *reason_to_stop = ValueObject::eNoSuchChild; 2540 *final_result = ValueObject::eInvalid; 2541 return ValueObjectSP(); 2542 } 2543 else 2544 { 2545 *first_unparsed = end+1; // skip ] 2546 *final_result = ValueObject::ePlain; 2547 continue; 2548 } 2549 } 2550 else 2551 { 2552 *first_unparsed = expression_cstr; 2553 *reason_to_stop = ValueObject::eNoSuchChild; 2554 *final_result = ValueObject::eInvalid; 2555 return ValueObjectSP(); 2556 } 2557 } 2558 else // we have a low and a high index 2559 { 2560 char *end = NULL; 2561 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0); 2562 if (!end || end != separator_position) // if something weird is in our way return an error 2563 { 2564 *first_unparsed = expression_cstr; 2565 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2566 *final_result = ValueObject::eInvalid; 2567 return ValueObjectSP(); 2568 } 2569 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0); 2570 if (!end || end != close_bracket_position) // if something weird is in our way return an error 2571 { 2572 *first_unparsed = expression_cstr; 2573 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2574 *final_result = ValueObject::eInvalid; 2575 return ValueObjectSP(); 2576 } 2577 if (index_lower > index_higher) // swap indices if required 2578 { 2579 unsigned long temp = index_lower; 2580 index_lower = index_higher; 2581 index_higher = temp; 2582 } 2583 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars 2584 { 2585 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true); 2586 if (!root.get()) 2587 { 2588 *first_unparsed = expression_cstr; 2589 *reason_to_stop = ValueObject::eNoSuchChild; 2590 *final_result = ValueObject::eInvalid; 2591 return ValueObjectSP(); 2592 } 2593 else 2594 { 2595 *first_unparsed = end+1; // skip ] 2596 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet; 2597 *final_result = ValueObject::eBitfield; 2598 return root; 2599 } 2600 } 2601 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield 2602 *what_next == ValueObject::eDereference && 2603 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) 2604 { 2605 Error error; 2606 root = root->Dereference(error); 2607 if (error.Fail() || !root.get()) 2608 { 2609 *first_unparsed = expression_cstr; 2610 *reason_to_stop = ValueObject::eDereferencingFailed; 2611 *final_result = ValueObject::eInvalid; 2612 return ValueObjectSP(); 2613 } 2614 else 2615 { 2616 *what_next = ValueObject::eNothing; 2617 continue; 2618 } 2619 } 2620 else 2621 { 2622 *first_unparsed = expression_cstr; 2623 *reason_to_stop = ValueObject::eArrayRangeOperatorMet; 2624 *final_result = ValueObject::eBoundedRange; 2625 return root; 2626 } 2627 } 2628 break; 2629 } 2630 default: // some non-separator is in the way 2631 { 2632 *first_unparsed = expression_cstr; 2633 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2634 *final_result = ValueObject::eInvalid; 2635 return ValueObjectSP(); 2636 break; 2637 } 2638 } 2639 } 2640} 2641 2642int 2643ValueObject::ExpandArraySliceExpression(const char* expression_cstr, 2644 const char** first_unparsed, 2645 ValueObjectSP root, 2646 ValueObjectListSP& list, 2647 ExpressionPathScanEndReason* reason_to_stop, 2648 ExpressionPathEndResultType* final_result, 2649 const GetValueForExpressionPathOptions& options, 2650 ExpressionPathAftermath* what_next) 2651{ 2652 if (!root.get()) 2653 return 0; 2654 2655 *first_unparsed = expression_cstr; 2656 2657 while (true) 2658 { 2659 2660 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr 2661 2662 clang_type_t root_clang_type = root->GetClangType(); 2663 clang_type_t pointee_clang_type; 2664 Flags root_clang_type_info,pointee_clang_type_info; 2665 2666 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type)); 2667 if (pointee_clang_type) 2668 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL)); 2669 2670 if (!expression_cstr || *expression_cstr == '\0') 2671 { 2672 *reason_to_stop = ValueObject::eEndOfString; 2673 list->Append(root); 2674 return 1; 2675 } 2676 2677 switch (*expression_cstr) 2678 { 2679 case '[': 2680 { 2681 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T* 2682 { 2683 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong! 2684 { 2685 *first_unparsed = expression_cstr; 2686 *reason_to_stop = ValueObject::eRangeOperatorInvalid; 2687 *final_result = ValueObject::eInvalid; 2688 return 0; 2689 } 2690 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields 2691 { 2692 *first_unparsed = expression_cstr; 2693 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed; 2694 *final_result = ValueObject::eInvalid; 2695 return 0; 2696 } 2697 } 2698 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays 2699 { 2700 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) 2701 { 2702 *first_unparsed = expression_cstr; 2703 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed; 2704 *final_result = ValueObject::eInvalid; 2705 return 0; 2706 } 2707 else // expand this into list 2708 { 2709 int max_index = root->GetNumChildren() - 1; 2710 for (int index = 0; index < max_index; index++) 2711 { 2712 ValueObjectSP child = 2713 root->GetChildAtIndex(index, true); 2714 list->Append(child); 2715 } 2716 *first_unparsed = expression_cstr+2; 2717 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2718 *final_result = ValueObject::eValueObjectList; 2719 return max_index; // tell me number of items I added to the VOList 2720 } 2721 } 2722 const char *separator_position = ::strchr(expression_cstr+1,'-'); 2723 const char *close_bracket_position = ::strchr(expression_cstr+1,']'); 2724 if (!close_bracket_position) // if there is no ], this is a syntax error 2725 { 2726 *first_unparsed = expression_cstr; 2727 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2728 *final_result = ValueObject::eInvalid; 2729 return 0; 2730 } 2731 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N] 2732 { 2733 char *end = NULL; 2734 unsigned long index = ::strtoul (expression_cstr+1, &end, 0); 2735 if (!end || end != close_bracket_position) // if something weird is in our way return an error 2736 { 2737 *first_unparsed = expression_cstr; 2738 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2739 *final_result = ValueObject::eInvalid; 2740 return 0; 2741 } 2742 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays 2743 { 2744 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) 2745 { 2746 int max_index = root->GetNumChildren() - 1; 2747 for (int index = 0; index < max_index; index++) 2748 { 2749 ValueObjectSP child = 2750 root->GetChildAtIndex(index, true); 2751 list->Append(child); 2752 } 2753 *first_unparsed = expression_cstr+2; 2754 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2755 *final_result = ValueObject::eValueObjectList; 2756 return max_index; // tell me number of items I added to the VOList 2757 } 2758 else 2759 { 2760 *first_unparsed = expression_cstr; 2761 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed; 2762 *final_result = ValueObject::eInvalid; 2763 return 0; 2764 } 2765 } 2766 // from here on we do have a valid index 2767 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) 2768 { 2769 root = root->GetChildAtIndex(index, true); 2770 if (!root.get()) 2771 { 2772 *first_unparsed = expression_cstr; 2773 *reason_to_stop = ValueObject::eNoSuchChild; 2774 *final_result = ValueObject::eInvalid; 2775 return 0; 2776 } 2777 else 2778 { 2779 list->Append(root); 2780 *first_unparsed = end+1; // skip ] 2781 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2782 *final_result = ValueObject::eValueObjectList; 2783 return 1; 2784 } 2785 } 2786 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) 2787 { 2788 if (*what_next == ValueObject::eDereference && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield 2789 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) 2790 { 2791 Error error; 2792 root = root->Dereference(error); 2793 if (error.Fail() || !root.get()) 2794 { 2795 *first_unparsed = expression_cstr; 2796 *reason_to_stop = ValueObject::eDereferencingFailed; 2797 *final_result = ValueObject::eInvalid; 2798 return 0; 2799 } 2800 else 2801 { 2802 *what_next = eNothing; 2803 continue; 2804 } 2805 } 2806 else 2807 { 2808 root = root->GetSyntheticArrayMemberFromPointer(index, true); 2809 if (!root.get()) 2810 { 2811 *first_unparsed = expression_cstr; 2812 *reason_to_stop = ValueObject::eNoSuchChild; 2813 *final_result = ValueObject::eInvalid; 2814 return 0; 2815 } 2816 else 2817 { 2818 list->Append(root); 2819 *first_unparsed = end+1; // skip ] 2820 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2821 *final_result = ValueObject::eValueObjectList; 2822 return 1; 2823 } 2824 } 2825 } 2826 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/ 2827 { 2828 root = root->GetSyntheticBitFieldChild(index, index, true); 2829 if (!root.get()) 2830 { 2831 *first_unparsed = expression_cstr; 2832 *reason_to_stop = ValueObject::eNoSuchChild; 2833 *final_result = ValueObject::eInvalid; 2834 return 0; 2835 } 2836 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing 2837 { 2838 list->Append(root); 2839 *first_unparsed = end+1; // skip ] 2840 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2841 *final_result = ValueObject::eValueObjectList; 2842 return 1; 2843 } 2844 } 2845 } 2846 else // we have a low and a high index 2847 { 2848 char *end = NULL; 2849 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0); 2850 if (!end || end != separator_position) // if something weird is in our way return an error 2851 { 2852 *first_unparsed = expression_cstr; 2853 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2854 *final_result = ValueObject::eInvalid; 2855 return 0; 2856 } 2857 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0); 2858 if (!end || end != close_bracket_position) // if something weird is in our way return an error 2859 { 2860 *first_unparsed = expression_cstr; 2861 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2862 *final_result = ValueObject::eInvalid; 2863 return 0; 2864 } 2865 if (index_lower > index_higher) // swap indices if required 2866 { 2867 unsigned long temp = index_lower; 2868 index_lower = index_higher; 2869 index_higher = temp; 2870 } 2871 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars 2872 { 2873 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true); 2874 if (!root.get()) 2875 { 2876 *first_unparsed = expression_cstr; 2877 *reason_to_stop = ValueObject::eNoSuchChild; 2878 *final_result = ValueObject::eInvalid; 2879 return 0; 2880 } 2881 else 2882 { 2883 list->Append(root); 2884 *first_unparsed = end+1; // skip ] 2885 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2886 *final_result = ValueObject::eValueObjectList; 2887 return 1; 2888 } 2889 } 2890 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield 2891 *what_next == ValueObject::eDereference && 2892 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) 2893 { 2894 Error error; 2895 root = root->Dereference(error); 2896 if (error.Fail() || !root.get()) 2897 { 2898 *first_unparsed = expression_cstr; 2899 *reason_to_stop = ValueObject::eDereferencingFailed; 2900 *final_result = ValueObject::eInvalid; 2901 return 0; 2902 } 2903 else 2904 { 2905 *what_next = ValueObject::eNothing; 2906 continue; 2907 } 2908 } 2909 else 2910 { 2911 for (unsigned long index = index_lower; 2912 index <= index_higher; index++) 2913 { 2914 ValueObjectSP child = 2915 root->GetChildAtIndex(index, true); 2916 list->Append(child); 2917 } 2918 *first_unparsed = end+1; 2919 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2920 *final_result = ValueObject::eValueObjectList; 2921 return index_higher-index_lower+1; // tell me number of items I added to the VOList 2922 } 2923 } 2924 break; 2925 } 2926 default: // some non-[ separator, or something entirely wrong, is in the way 2927 { 2928 *first_unparsed = expression_cstr; 2929 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2930 *final_result = ValueObject::eInvalid; 2931 return 0; 2932 break; 2933 } 2934 } 2935 } 2936} 2937 2938void 2939ValueObject::DumpValueObject 2940( 2941 Stream &s, 2942 ValueObject *valobj, 2943 const char *root_valobj_name, 2944 uint32_t ptr_depth, 2945 uint32_t curr_depth, 2946 uint32_t max_depth, 2947 bool show_types, 2948 bool show_location, 2949 bool use_objc, 2950 DynamicValueType use_dynamic, 2951 bool use_synth, 2952 bool scope_already_checked, 2953 bool flat_output, 2954 uint32_t omit_summary_depth, 2955 bool ignore_cap 2956) 2957{ 2958 if (valobj) 2959 { 2960 bool update_success = valobj->UpdateValueIfNeeded (use_dynamic, true); 2961 2962 if (update_success && use_dynamic != eNoDynamicValues) 2963 { 2964 ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get(); 2965 if (dynamic_value) 2966 valobj = dynamic_value; 2967 } 2968 2969 clang_type_t clang_type = valobj->GetClangType(); 2970 2971 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL)); 2972 const char *err_cstr = NULL; 2973 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren); 2974 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue); 2975 2976 const bool print_valobj = flat_output == false || has_value; 2977 2978 if (print_valobj) 2979 { 2980 if (show_location) 2981 { 2982 s.Printf("%s: ", valobj->GetLocationAsCString()); 2983 } 2984 2985 s.Indent(); 2986 2987 // Always show the type for the top level items. 2988 if (show_types || (curr_depth == 0 && !flat_output)) 2989 { 2990 const char* typeName = valobj->GetTypeName().AsCString("<invalid type>"); 2991 s.Printf("(%s", typeName); 2992 // only show dynamic types if the user really wants to see types 2993 if (show_types && use_dynamic != eNoDynamicValues && 2994 (/*strstr(typeName, "id") == typeName ||*/ 2995 ClangASTType::GetMinimumLanguage(valobj->GetClangAST(), valobj->GetClangType()) == eLanguageTypeObjC)) 2996 { 2997 Process* process = valobj->GetUpdatePoint().GetProcessSP().get(); 2998 if (process == NULL) 2999 s.Printf(", dynamic type: unknown) "); 3000 else 3001 { 3002 ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime(); 3003 if (runtime == NULL) 3004 s.Printf(", dynamic type: unknown) "); 3005 else 3006 { 3007 ObjCLanguageRuntime::ObjCISA isa = runtime->GetISA(*valobj); 3008 if (!runtime->IsValidISA(isa)) 3009 s.Printf(", dynamic type: unknown) "); 3010 else 3011 s.Printf(", dynamic type: %s) ", 3012 runtime->GetActualTypeName(isa).GetCString()); 3013 } 3014 } 3015 } 3016 else 3017 s.Printf(") "); 3018 } 3019 3020 3021 if (flat_output) 3022 { 3023 // If we are showing types, also qualify the C++ base classes 3024 const bool qualify_cxx_base_classes = show_types; 3025 valobj->GetExpressionPath(s, qualify_cxx_base_classes); 3026 s.PutCString(" ="); 3027 } 3028 else 3029 { 3030 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString(""); 3031 s.Printf ("%s =", name_cstr); 3032 } 3033 3034 if (!scope_already_checked && !valobj->IsInScope()) 3035 { 3036 err_cstr = "out of scope"; 3037 } 3038 } 3039 3040 const char *val_cstr = NULL; 3041 const char *sum_cstr = NULL; 3042 SummaryFormat* entry = valobj->GetSummaryFormat().get(); 3043 3044 if (omit_summary_depth > 0) 3045 entry = NULL; 3046 3047 if (err_cstr == NULL) 3048 { 3049 val_cstr = valobj->GetValueAsCString(); 3050 err_cstr = valobj->GetError().AsCString(); 3051 } 3052 3053 if (err_cstr) 3054 { 3055 s.Printf (" <%s>\n", err_cstr); 3056 } 3057 else 3058 { 3059 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference); 3060 if (print_valobj) 3061 { 3062 3063 sum_cstr = (omit_summary_depth == 0) ? valobj->GetSummaryAsCString() : NULL; 3064 3065 // We must calculate this value in realtime because entry might alter this variable's value 3066 // (e.g. by saying ${var%fmt}) and render precached values useless 3067 if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr)) 3068 s.Printf(" %s", valobj->GetValueAsCString()); 3069 3070 if (sum_cstr) 3071 { 3072 // for some reason, using %@ (ObjC description) in a summary string, makes 3073 // us believe we need to reset ourselves, thus invalidating the content of 3074 // sum_cstr. Thus, IF we had a valid sum_cstr before, but it is now empty 3075 // let us recalculate it! 3076 if (sum_cstr[0] == '\0') 3077 s.Printf(" %s", valobj->GetSummaryAsCString()); 3078 else 3079 s.Printf(" %s", sum_cstr); 3080 } 3081 3082 if (use_objc) 3083 { 3084 const char *object_desc = valobj->GetObjectDescription(); 3085 if (object_desc) 3086 s.Printf(" %s\n", object_desc); 3087 else 3088 s.Printf (" [no Objective-C description available]\n"); 3089 return; 3090 } 3091 } 3092 3093 if (curr_depth < max_depth) 3094 { 3095 // We will show children for all concrete types. We won't show 3096 // pointer contents unless a pointer depth has been specified. 3097 // We won't reference contents unless the reference is the 3098 // root object (depth of zero). 3099 bool print_children = true; 3100 3101 // Use a new temporary pointer depth in case we override the 3102 // current pointer depth below... 3103 uint32_t curr_ptr_depth = ptr_depth; 3104 3105 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer); 3106 if (is_ptr || is_ref) 3107 { 3108 // We have a pointer or reference whose value is an address. 3109 // Make sure that address is not NULL 3110 AddressType ptr_address_type; 3111 if (valobj->GetPointerValue (&ptr_address_type) == 0) 3112 print_children = false; 3113 3114 else if (is_ref && curr_depth == 0) 3115 { 3116 // If this is the root object (depth is zero) that we are showing 3117 // and it is a reference, and no pointer depth has been supplied 3118 // print out what it references. Don't do this at deeper depths 3119 // otherwise we can end up with infinite recursion... 3120 curr_ptr_depth = 1; 3121 } 3122 3123 if (curr_ptr_depth == 0) 3124 print_children = false; 3125 } 3126 3127 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr)) 3128 { 3129 ValueObjectSP synth_valobj = valobj->GetSyntheticValue(use_synth ? 3130 eUseSyntheticFilter : 3131 eNoSyntheticFilter); 3132 uint32_t num_children = synth_valobj->GetNumChildren(); 3133 bool print_dotdotdot = false; 3134 if (num_children) 3135 { 3136 if (flat_output) 3137 { 3138 if (print_valobj) 3139 s.EOL(); 3140 } 3141 else 3142 { 3143 if (print_valobj) 3144 s.PutCString(is_ref ? ": {\n" : " {\n"); 3145 s.IndentMore(); 3146 } 3147 3148 uint32_t max_num_children = valobj->GetUpdatePoint().GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 3149 3150 if (num_children > max_num_children && !ignore_cap) 3151 { 3152 num_children = max_num_children; 3153 print_dotdotdot = true; 3154 } 3155 3156 for (uint32_t idx=0; idx<num_children; ++idx) 3157 { 3158 ValueObjectSP child_sp(synth_valobj->GetChildAtIndex(idx, true)); 3159 if (child_sp.get()) 3160 { 3161 DumpValueObject (s, 3162 child_sp.get(), 3163 NULL, 3164 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth, 3165 curr_depth + 1, 3166 max_depth, 3167 show_types, 3168 show_location, 3169 false, 3170 use_dynamic, 3171 use_synth, 3172 true, 3173 flat_output, 3174 omit_summary_depth > 1 ? omit_summary_depth - 1 : 0, 3175 ignore_cap); 3176 } 3177 } 3178 3179 if (!flat_output) 3180 { 3181 if (print_dotdotdot) 3182 { 3183 valobj->GetUpdatePoint().GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated(); 3184 s.Indent("...\n"); 3185 } 3186 s.IndentLess(); 3187 s.Indent("}\n"); 3188 } 3189 } 3190 else if (has_children) 3191 { 3192 // Aggregate, no children... 3193 if (print_valobj) 3194 s.PutCString(" {}\n"); 3195 } 3196 else 3197 { 3198 if (print_valobj) 3199 s.EOL(); 3200 } 3201 3202 } 3203 else 3204 { 3205 s.EOL(); 3206 } 3207 } 3208 else 3209 { 3210 if (has_children && print_valobj) 3211 { 3212 s.PutCString("{...}\n"); 3213 } 3214 } 3215 } 3216 } 3217} 3218 3219 3220ValueObjectSP 3221ValueObject::CreateConstantValue (const ConstString &name) 3222{ 3223 ValueObjectSP valobj_sp; 3224 3225 if (UpdateValueIfNeeded(false) && m_error.Success()) 3226 { 3227 ExecutionContextScope *exe_scope = GetExecutionContextScope(); 3228 if (exe_scope) 3229 { 3230 ExecutionContext exe_ctx; 3231 exe_scope->CalculateExecutionContext(exe_ctx); 3232 3233 clang::ASTContext *ast = GetClangAST (); 3234 3235 DataExtractor data; 3236 data.SetByteOrder (m_data.GetByteOrder()); 3237 data.SetAddressByteSize(m_data.GetAddressByteSize()); 3238 3239 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule()); 3240 3241 valobj_sp = ValueObjectConstResult::Create (exe_scope, 3242 ast, 3243 GetClangType(), 3244 name, 3245 data, 3246 GetAddressOf()); 3247 } 3248 } 3249 3250 if (!valobj_sp) 3251 { 3252 valobj_sp = ValueObjectConstResult::Create (NULL, m_error); 3253 } 3254 return valobj_sp; 3255} 3256 3257ValueObjectSP 3258ValueObject::Dereference (Error &error) 3259{ 3260 if (m_deref_valobj) 3261 return m_deref_valobj->GetSP(); 3262 3263 const bool is_pointer_type = IsPointerType(); 3264 if (is_pointer_type) 3265 { 3266 bool omit_empty_base_classes = true; 3267 bool ignore_array_bounds = false; 3268 3269 std::string child_name_str; 3270 uint32_t child_byte_size = 0; 3271 int32_t child_byte_offset = 0; 3272 uint32_t child_bitfield_bit_size = 0; 3273 uint32_t child_bitfield_bit_offset = 0; 3274 bool child_is_base_class = false; 3275 bool child_is_deref_of_parent = false; 3276 const bool transparent_pointers = false; 3277 clang::ASTContext *clang_ast = GetClangAST(); 3278 clang_type_t clang_type = GetClangType(); 3279 clang_type_t child_clang_type; 3280 3281 ExecutionContext exe_ctx; 3282 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx); 3283 3284 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx, 3285 clang_ast, 3286 GetName().GetCString(), 3287 clang_type, 3288 0, 3289 transparent_pointers, 3290 omit_empty_base_classes, 3291 ignore_array_bounds, 3292 child_name_str, 3293 child_byte_size, 3294 child_byte_offset, 3295 child_bitfield_bit_size, 3296 child_bitfield_bit_offset, 3297 child_is_base_class, 3298 child_is_deref_of_parent); 3299 if (child_clang_type && child_byte_size) 3300 { 3301 ConstString child_name; 3302 if (!child_name_str.empty()) 3303 child_name.SetCString (child_name_str.c_str()); 3304 3305 m_deref_valobj = new ValueObjectChild (*this, 3306 clang_ast, 3307 child_clang_type, 3308 child_name, 3309 child_byte_size, 3310 child_byte_offset, 3311 child_bitfield_bit_size, 3312 child_bitfield_bit_offset, 3313 child_is_base_class, 3314 child_is_deref_of_parent, 3315 eAddressTypeInvalid); 3316 } 3317 } 3318 3319 if (m_deref_valobj) 3320 { 3321 error.Clear(); 3322 return m_deref_valobj->GetSP(); 3323 } 3324 else 3325 { 3326 StreamString strm; 3327 GetExpressionPath(strm, true); 3328 3329 if (is_pointer_type) 3330 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str()); 3331 else 3332 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str()); 3333 return ValueObjectSP(); 3334 } 3335} 3336 3337ValueObjectSP 3338ValueObject::AddressOf (Error &error) 3339{ 3340 if (m_addr_of_valobj_sp) 3341 return m_addr_of_valobj_sp; 3342 3343 AddressType address_type = eAddressTypeInvalid; 3344 const bool scalar_is_load_address = false; 3345 addr_t addr = GetAddressOf (scalar_is_load_address, &address_type); 3346 error.Clear(); 3347 if (addr != LLDB_INVALID_ADDRESS) 3348 { 3349 switch (address_type) 3350 { 3351 default: 3352 case eAddressTypeInvalid: 3353 { 3354 StreamString expr_path_strm; 3355 GetExpressionPath(expr_path_strm, true); 3356 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str()); 3357 } 3358 break; 3359 3360 case eAddressTypeFile: 3361 case eAddressTypeLoad: 3362 case eAddressTypeHost: 3363 { 3364 clang::ASTContext *ast = GetClangAST(); 3365 clang_type_t clang_type = GetClangType(); 3366 if (ast && clang_type) 3367 { 3368 std::string name (1, '&'); 3369 name.append (m_name.AsCString("")); 3370 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(), 3371 ast, 3372 ClangASTContext::CreatePointerType (ast, clang_type), 3373 ConstString (name.c_str()), 3374 addr, 3375 eAddressTypeInvalid, 3376 m_data.GetAddressByteSize()); 3377 } 3378 } 3379 break; 3380 } 3381 } 3382 return m_addr_of_valobj_sp; 3383} 3384 3385 3386ValueObjectSP 3387ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type) 3388{ 3389 ValueObjectSP valobj_sp; 3390 AddressType address_type; 3391 addr_t ptr_value = GetPointerValue (&address_type); 3392 3393 if (ptr_value != LLDB_INVALID_ADDRESS) 3394 { 3395 Address ptr_addr (NULL, ptr_value); 3396 3397 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(), 3398 name, 3399 ptr_addr, 3400 clang_ast_type); 3401 } 3402 return valobj_sp; 3403} 3404 3405ValueObjectSP 3406ValueObject::CastPointerType (const char *name, TypeSP &type_sp) 3407{ 3408 ValueObjectSP valobj_sp; 3409 AddressType address_type; 3410 addr_t ptr_value = GetPointerValue (&address_type); 3411 3412 if (ptr_value != LLDB_INVALID_ADDRESS) 3413 { 3414 Address ptr_addr (NULL, ptr_value); 3415 3416 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(), 3417 name, 3418 ptr_addr, 3419 type_sp); 3420 } 3421 return valobj_sp; 3422} 3423 3424ValueObject::EvaluationPoint::EvaluationPoint () : 3425 m_thread_id (LLDB_INVALID_UID), 3426 m_mod_id () 3427{ 3428} 3429 3430ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected): 3431 m_needs_update (true), 3432 m_first_update (true), 3433 m_thread_id (LLDB_INVALID_THREAD_ID), 3434 m_mod_id () 3435 3436{ 3437 ExecutionContext exe_ctx; 3438 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope, 3439 // and if so we want to cache that not the original. 3440 if (exe_scope) 3441 exe_scope->CalculateExecutionContext(exe_ctx); 3442 Target *target = exe_ctx.GetTargetPtr(); 3443 if (target != NULL) 3444 { 3445 m_target_sp = target; 3446 m_process_sp = exe_ctx.GetProcessSP(); 3447 if (!m_process_sp) 3448 m_process_sp = target->GetProcessSP(); 3449 3450 if (m_process_sp) 3451 { 3452 m_mod_id = m_process_sp->GetModID(); 3453 3454 Thread *thread = exe_ctx.GetThreadPtr(); 3455 3456 if (thread == NULL) 3457 { 3458 if (use_selected) 3459 { 3460 thread = m_process_sp->GetThreadList().GetSelectedThread().get(); 3461 if (thread) 3462 computed_exe_scope = thread; 3463 } 3464 } 3465 3466 if (thread != NULL) 3467 { 3468 m_thread_id = thread->GetIndexID(); 3469 3470 StackFrame *frame = exe_ctx.GetFramePtr(); 3471 if (frame == NULL) 3472 { 3473 if (use_selected) 3474 { 3475 frame = thread->GetSelectedFrame().get(); 3476 if (frame) 3477 { 3478 m_stack_id = frame->GetStackID(); 3479 computed_exe_scope = frame; 3480 } 3481 } 3482 } 3483 else 3484 m_stack_id = frame->GetStackID(); 3485 } 3486 } 3487 } 3488 m_exe_scope = computed_exe_scope; 3489} 3490 3491ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) : 3492 m_exe_scope (rhs.m_exe_scope), 3493 m_needs_update(true), 3494 m_first_update(true), 3495 m_target_sp (rhs.m_target_sp), 3496 m_process_sp (rhs.m_process_sp), 3497 m_thread_id (rhs.m_thread_id), 3498 m_stack_id (rhs.m_stack_id), 3499 m_mod_id () 3500{ 3501} 3502 3503ValueObject::EvaluationPoint::~EvaluationPoint () 3504{ 3505} 3506 3507ExecutionContextScope * 3508ValueObject::EvaluationPoint::GetExecutionContextScope () 3509{ 3510 // We have to update before giving out the scope, or we could be handing out stale pointers. 3511 SyncWithProcessState(); 3512 3513 return m_exe_scope; 3514} 3515 3516// This function checks the EvaluationPoint against the current process state. If the current 3517// state matches the evaluation point, or the evaluation point is already invalid, then we return 3518// false, meaning "no change". If the current state is different, we update our state, and return 3519// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so 3520// future calls to NeedsUpdate will return true. 3521 3522bool 3523ValueObject::EvaluationPoint::SyncWithProcessState() 3524{ 3525 // If we don't have a process nothing can change. 3526 if (!m_process_sp) 3527 { 3528 m_exe_scope = m_target_sp.get(); 3529 return false; 3530 } 3531 3532 // If our stop id is the current stop ID, nothing has changed: 3533 ProcessModID current_mod_id = m_process_sp->GetModID(); 3534 3535 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared. 3536 // In either case, we aren't going to be able to sync with the process state. 3537 if (current_mod_id.GetStopID() == 0) 3538 { 3539 m_exe_scope = m_target_sp.get(); 3540 return false; 3541 } 3542 3543 if (m_mod_id.IsValid()) 3544 { 3545 if (m_mod_id == current_mod_id) 3546 { 3547 // Everything is already up to date in this object, no need do 3548 // update the execution context scope. 3549 return false; 3550 } 3551 m_mod_id = current_mod_id; 3552 m_needs_update = true; 3553 } 3554 m_exe_scope = m_process_sp.get(); 3555 3556 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either 3557 // doesn't, mark ourselves as invalid. 3558 3559 if (m_thread_id != LLDB_INVALID_THREAD_ID) 3560 { 3561 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get(); 3562 if (our_thread == NULL) 3563 { 3564 SetInvalid(); 3565 } 3566 else 3567 { 3568 m_exe_scope = our_thread; 3569 3570 if (m_stack_id.IsValid()) 3571 { 3572 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get(); 3573 if (our_frame == NULL) 3574 SetInvalid(); 3575 else 3576 m_exe_scope = our_frame; 3577 } 3578 } 3579 } 3580 return true; 3581} 3582 3583void 3584ValueObject::EvaluationPoint::SetUpdated () 3585{ 3586 // this will update the execution context scope and the m_mod_id 3587 SyncWithProcessState(); 3588 m_first_update = false; 3589 m_needs_update = false; 3590} 3591 3592 3593bool 3594ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope) 3595{ 3596 if (!IsValid()) 3597 return false; 3598 3599 bool needs_update = false; 3600 m_exe_scope = NULL; 3601 3602 // The target has to be non-null, and the 3603 Target *target = exe_scope->CalculateTarget(); 3604 if (target != NULL) 3605 { 3606 Target *old_target = m_target_sp.get(); 3607 assert (target == old_target); 3608 Process *process = exe_scope->CalculateProcess(); 3609 if (process != NULL) 3610 { 3611 // FOR NOW - assume you can't update variable objects across process boundaries. 3612 Process *old_process = m_process_sp.get(); 3613 assert (process == old_process); 3614 ProcessModID current_mod_id = process->GetModID(); 3615 if (m_mod_id != current_mod_id) 3616 { 3617 needs_update = true; 3618 m_mod_id = current_mod_id; 3619 } 3620 // See if we're switching the thread or stack context. If no thread is given, this is 3621 // being evaluated in a global context. 3622 Thread *thread = exe_scope->CalculateThread(); 3623 if (thread != NULL) 3624 { 3625 user_id_t new_thread_index = thread->GetIndexID(); 3626 if (new_thread_index != m_thread_id) 3627 { 3628 needs_update = true; 3629 m_thread_id = new_thread_index; 3630 m_stack_id.Clear(); 3631 } 3632 3633 StackFrame *new_frame = exe_scope->CalculateStackFrame(); 3634 if (new_frame != NULL) 3635 { 3636 if (new_frame->GetStackID() != m_stack_id) 3637 { 3638 needs_update = true; 3639 m_stack_id = new_frame->GetStackID(); 3640 } 3641 } 3642 else 3643 { 3644 m_stack_id.Clear(); 3645 needs_update = true; 3646 } 3647 } 3648 else 3649 { 3650 // If this had been given a thread, and now there is none, we should update. 3651 // Otherwise we don't have to do anything. 3652 if (m_thread_id != LLDB_INVALID_UID) 3653 { 3654 m_thread_id = LLDB_INVALID_UID; 3655 m_stack_id.Clear(); 3656 needs_update = true; 3657 } 3658 } 3659 } 3660 else 3661 { 3662 // If there is no process, then we don't need to update anything. 3663 // But if we're switching from having a process to not, we should try to update. 3664 if (m_process_sp.get() != NULL) 3665 { 3666 needs_update = true; 3667 m_process_sp.reset(); 3668 m_thread_id = LLDB_INVALID_UID; 3669 m_stack_id.Clear(); 3670 } 3671 } 3672 } 3673 else 3674 { 3675 // If there's no target, nothing can change so we don't need to update anything. 3676 // But if we're switching from having a target to not, we should try to update. 3677 if (m_target_sp.get() != NULL) 3678 { 3679 needs_update = true; 3680 m_target_sp.reset(); 3681 m_process_sp.reset(); 3682 m_thread_id = LLDB_INVALID_UID; 3683 m_stack_id.Clear(); 3684 } 3685 } 3686 if (!m_needs_update) 3687 m_needs_update = needs_update; 3688 3689 return needs_update; 3690} 3691 3692void 3693ValueObject::ClearUserVisibleData() 3694{ 3695 m_location_str.clear(); 3696 m_value_str.clear(); 3697 m_summary_str.clear(); 3698 m_object_desc_str.clear(); 3699 m_trying_summary_already = false; 3700} 3701 3702SymbolContextScope * 3703ValueObject::GetSymbolContextScope() 3704{ 3705 if (m_parent) 3706 { 3707 if (!m_parent->IsPointerOrReferenceType()) 3708 return m_parent->GetSymbolContextScope(); 3709 } 3710 return NULL; 3711} 3712