ValueObject.cpp revision 1b42575189379cb0c1441f74a48127e9ab7335e3
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_address_type_of_ptr_or_ref_children(eAddressTypeInvalid), 89 m_value_is_valid (false), 90 m_value_did_change (false), 91 m_children_count_valid (false), 92 m_old_value_valid (false), 93 m_is_deref_of_parent (false), 94 m_is_array_item_for_pointer(false), 95 m_is_bitfield_for_scalar(false), 96 m_is_expression_path_child(false), 97 m_is_child_at_offset(false), 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_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type), 135 m_value_is_valid (false), 136 m_value_did_change (false), 137 m_children_count_valid (false), 138 m_old_value_valid (false), 139 m_is_deref_of_parent (false), 140 m_is_array_item_for_pointer(false), 141 m_is_bitfield_for_scalar(false), 142 m_is_expression_path_child(false), 143 m_is_child_at_offset(false), 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 1923ValueObjectSP 1924ValueObject::GetStaticValue() 1925{ 1926 return GetSP(); 1927} 1928 1929// GetDynamicValue() returns a NULL SharedPointer if the object is not dynamic 1930// or we do not really want a dynamic VO. this method instead returns this object 1931// itself when making it synthetic has no meaning. this makes it much simpler 1932// to replace the SyntheticValue for the ValueObject 1933ValueObjectSP 1934ValueObject::GetSyntheticValue (SyntheticValueType use_synthetic) 1935{ 1936 if (use_synthetic == eNoSyntheticFilter) 1937 return GetSP(); 1938 1939 UpdateFormatsIfNeeded(m_last_format_mgr_dynamic); 1940 1941 if (m_last_synthetic_filter.get() == NULL) 1942 return GetSP(); 1943 1944 CalculateSyntheticValue(use_synthetic); 1945 1946 if (m_synthetic_value) 1947 return m_synthetic_value->GetSP(); 1948 else 1949 return GetSP(); 1950} 1951 1952bool 1953ValueObject::HasSyntheticValue() 1954{ 1955 UpdateFormatsIfNeeded(m_last_format_mgr_dynamic); 1956 1957 if (m_last_synthetic_filter.get() == NULL) 1958 return false; 1959 1960 CalculateSyntheticValue(eUseSyntheticFilter); 1961 1962 if (m_synthetic_value) 1963 return true; 1964 else 1965 return false; 1966} 1967 1968bool 1969ValueObject::GetBaseClassPath (Stream &s) 1970{ 1971 if (IsBaseClass()) 1972 { 1973 bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s); 1974 clang_type_t clang_type = GetClangType(); 1975 std::string cxx_class_name; 1976 bool this_had_base_class = ClangASTContext::GetCXXClassName (clang_type, cxx_class_name); 1977 if (this_had_base_class) 1978 { 1979 if (parent_had_base_class) 1980 s.PutCString("::"); 1981 s.PutCString(cxx_class_name.c_str()); 1982 } 1983 return parent_had_base_class || this_had_base_class; 1984 } 1985 return false; 1986} 1987 1988 1989ValueObject * 1990ValueObject::GetNonBaseClassParent() 1991{ 1992 if (GetParent()) 1993 { 1994 if (GetParent()->IsBaseClass()) 1995 return GetParent()->GetNonBaseClassParent(); 1996 else 1997 return GetParent(); 1998 } 1999 return NULL; 2000} 2001 2002void 2003ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat) 2004{ 2005 const bool is_deref_of_parent = IsDereferenceOfParent (); 2006 2007 if (is_deref_of_parent && epformat == eDereferencePointers) 2008 { 2009 // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely 2010 // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName. 2011 // the eHonorPointers mode is meant to produce strings in this latter format 2012 s.PutCString("*("); 2013 } 2014 2015 ValueObject* parent = GetParent(); 2016 2017 if (parent) 2018 parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat); 2019 2020 // if we are a deref_of_parent just because we are synthetic array 2021 // members made up to allow ptr[%d] syntax to work in variable 2022 // printing, then add our name ([%d]) to the expression path 2023 if (m_is_array_item_for_pointer && epformat == eHonorPointers) 2024 s.PutCString(m_name.AsCString()); 2025 2026 if (!IsBaseClass()) 2027 { 2028 if (!is_deref_of_parent) 2029 { 2030 ValueObject *non_base_class_parent = GetNonBaseClassParent(); 2031 if (non_base_class_parent) 2032 { 2033 clang_type_t non_base_class_parent_clang_type = non_base_class_parent->GetClangType(); 2034 if (non_base_class_parent_clang_type) 2035 { 2036 const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL); 2037 2038 if (parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers) 2039 { 2040 s.PutCString("->"); 2041 } 2042 else 2043 { 2044 if (non_base_class_parent_type_info & ClangASTContext::eTypeIsPointer) 2045 { 2046 s.PutCString("->"); 2047 } 2048 else if ((non_base_class_parent_type_info & ClangASTContext::eTypeHasChildren) && 2049 !(non_base_class_parent_type_info & ClangASTContext::eTypeIsArray)) 2050 { 2051 s.PutChar('.'); 2052 } 2053 } 2054 } 2055 } 2056 2057 const char *name = GetName().GetCString(); 2058 if (name) 2059 { 2060 if (qualify_cxx_base_classes) 2061 { 2062 if (GetBaseClassPath (s)) 2063 s.PutCString("::"); 2064 } 2065 s.PutCString(name); 2066 } 2067 } 2068 } 2069 2070 if (is_deref_of_parent && epformat == eDereferencePointers) 2071 { 2072 s.PutChar(')'); 2073 } 2074} 2075 2076ValueObjectSP 2077ValueObject::GetValueForExpressionPath(const char* expression, 2078 const char** first_unparsed, 2079 ExpressionPathScanEndReason* reason_to_stop, 2080 ExpressionPathEndResultType* final_value_type, 2081 const GetValueForExpressionPathOptions& options, 2082 ExpressionPathAftermath* final_task_on_target) 2083{ 2084 2085 const char* dummy_first_unparsed; 2086 ExpressionPathScanEndReason dummy_reason_to_stop; 2087 ExpressionPathEndResultType dummy_final_value_type; 2088 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing; 2089 2090 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression, 2091 first_unparsed ? first_unparsed : &dummy_first_unparsed, 2092 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop, 2093 final_value_type ? final_value_type : &dummy_final_value_type, 2094 options, 2095 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target); 2096 2097 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing) 2098 { 2099 return ret_val; 2100 } 2101 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects 2102 { 2103 if (*final_task_on_target == ValueObject::eDereference) 2104 { 2105 Error error; 2106 ValueObjectSP final_value = ret_val->Dereference(error); 2107 if (error.Fail() || !final_value.get()) 2108 { 2109 *reason_to_stop = ValueObject::eDereferencingFailed; 2110 *final_value_type = ValueObject::eInvalid; 2111 return ValueObjectSP(); 2112 } 2113 else 2114 { 2115 *final_task_on_target = ValueObject::eNothing; 2116 return final_value; 2117 } 2118 } 2119 if (*final_task_on_target == ValueObject::eTakeAddress) 2120 { 2121 Error error; 2122 ValueObjectSP final_value = ret_val->AddressOf(error); 2123 if (error.Fail() || !final_value.get()) 2124 { 2125 *reason_to_stop = ValueObject::eTakingAddressFailed; 2126 *final_value_type = ValueObject::eInvalid; 2127 return ValueObjectSP(); 2128 } 2129 else 2130 { 2131 *final_task_on_target = ValueObject::eNothing; 2132 return final_value; 2133 } 2134 } 2135 } 2136 return ret_val; // final_task_on_target will still have its original value, so you know I did not do it 2137} 2138 2139int 2140ValueObject::GetValuesForExpressionPath(const char* expression, 2141 ValueObjectListSP& list, 2142 const char** first_unparsed, 2143 ExpressionPathScanEndReason* reason_to_stop, 2144 ExpressionPathEndResultType* final_value_type, 2145 const GetValueForExpressionPathOptions& options, 2146 ExpressionPathAftermath* final_task_on_target) 2147{ 2148 const char* dummy_first_unparsed; 2149 ExpressionPathScanEndReason dummy_reason_to_stop; 2150 ExpressionPathEndResultType dummy_final_value_type; 2151 ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eNothing; 2152 2153 ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression, 2154 first_unparsed ? first_unparsed : &dummy_first_unparsed, 2155 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop, 2156 final_value_type ? final_value_type : &dummy_final_value_type, 2157 options, 2158 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target); 2159 2160 if (!ret_val.get()) // if there are errors, I add nothing to the list 2161 return 0; 2162 2163 if (*reason_to_stop != eArrayRangeOperatorMet) 2164 { 2165 // I need not expand a range, just post-process the final value and return 2166 if (!final_task_on_target || *final_task_on_target == ValueObject::eNothing) 2167 { 2168 list->Append(ret_val); 2169 return 1; 2170 } 2171 if (ret_val.get() && *final_value_type == ePlain) // I can only deref and takeaddress of plain objects 2172 { 2173 if (*final_task_on_target == ValueObject::eDereference) 2174 { 2175 Error error; 2176 ValueObjectSP final_value = ret_val->Dereference(error); 2177 if (error.Fail() || !final_value.get()) 2178 { 2179 *reason_to_stop = ValueObject::eDereferencingFailed; 2180 *final_value_type = ValueObject::eInvalid; 2181 return 0; 2182 } 2183 else 2184 { 2185 *final_task_on_target = ValueObject::eNothing; 2186 list->Append(final_value); 2187 return 1; 2188 } 2189 } 2190 if (*final_task_on_target == ValueObject::eTakeAddress) 2191 { 2192 Error error; 2193 ValueObjectSP final_value = ret_val->AddressOf(error); 2194 if (error.Fail() || !final_value.get()) 2195 { 2196 *reason_to_stop = ValueObject::eTakingAddressFailed; 2197 *final_value_type = ValueObject::eInvalid; 2198 return 0; 2199 } 2200 else 2201 { 2202 *final_task_on_target = ValueObject::eNothing; 2203 list->Append(final_value); 2204 return 1; 2205 } 2206 } 2207 } 2208 } 2209 else 2210 { 2211 return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed, 2212 first_unparsed ? first_unparsed : &dummy_first_unparsed, 2213 ret_val, 2214 list, 2215 reason_to_stop ? reason_to_stop : &dummy_reason_to_stop, 2216 final_value_type ? final_value_type : &dummy_final_value_type, 2217 options, 2218 final_task_on_target ? final_task_on_target : &dummy_final_task_on_target); 2219 } 2220 // in any non-covered case, just do the obviously right thing 2221 list->Append(ret_val); 2222 return 1; 2223} 2224 2225ValueObjectSP 2226ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, 2227 const char** first_unparsed, 2228 ExpressionPathScanEndReason* reason_to_stop, 2229 ExpressionPathEndResultType* final_result, 2230 const GetValueForExpressionPathOptions& options, 2231 ExpressionPathAftermath* what_next) 2232{ 2233 ValueObjectSP root = GetSP(); 2234 2235 if (!root.get()) 2236 return ValueObjectSP(); 2237 2238 *first_unparsed = expression_cstr; 2239 2240 while (true) 2241 { 2242 2243 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr 2244 2245 clang_type_t root_clang_type = root->GetClangType(); 2246 clang_type_t pointee_clang_type; 2247 Flags root_clang_type_info,pointee_clang_type_info; 2248 2249 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type)); 2250 if (pointee_clang_type) 2251 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL)); 2252 2253 if (!expression_cstr || *expression_cstr == '\0') 2254 { 2255 *reason_to_stop = ValueObject::eEndOfString; 2256 return root; 2257 } 2258 2259 switch (*expression_cstr) 2260 { 2261 case '-': 2262 { 2263 if (options.m_check_dot_vs_arrow_syntax && 2264 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error 2265 { 2266 *first_unparsed = expression_cstr; 2267 *reason_to_stop = ValueObject::eArrowInsteadOfDot; 2268 *final_result = ValueObject::eInvalid; 2269 return ValueObjectSP(); 2270 } 2271 if (root_clang_type_info.Test(ClangASTContext::eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden 2272 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer) && 2273 options.m_no_fragile_ivar) 2274 { 2275 *first_unparsed = expression_cstr; 2276 *reason_to_stop = ValueObject::eFragileIVarNotAllowed; 2277 *final_result = ValueObject::eInvalid; 2278 return ValueObjectSP(); 2279 } 2280 if (expression_cstr[1] != '>') 2281 { 2282 *first_unparsed = expression_cstr; 2283 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2284 *final_result = ValueObject::eInvalid; 2285 return ValueObjectSP(); 2286 } 2287 expression_cstr++; // skip the - 2288 } 2289 case '.': // or fallthrough from -> 2290 { 2291 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' && 2292 root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error 2293 { 2294 *first_unparsed = expression_cstr; 2295 *reason_to_stop = ValueObject::eDotInsteadOfArrow; 2296 *final_result = ValueObject::eInvalid; 2297 return ValueObjectSP(); 2298 } 2299 expression_cstr++; // skip . 2300 const char *next_separator = strpbrk(expression_cstr+1,"-.["); 2301 ConstString child_name; 2302 if (!next_separator) // if no other separator just expand this last layer 2303 { 2304 child_name.SetCString (expression_cstr); 2305 ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true); 2306 2307 if (child_valobj_sp.get()) // we know we are done, so just return 2308 { 2309 *first_unparsed = '\0'; 2310 *reason_to_stop = ValueObject::eEndOfString; 2311 *final_result = ValueObject::ePlain; 2312 return child_valobj_sp; 2313 } 2314 else if (options.m_no_synthetic_children == false) // let's try with synthetic children 2315 { 2316 child_valobj_sp = root->GetSyntheticValue(eNoSyntheticFilter)->GetChildMemberWithName(child_name, true); 2317 } 2318 2319 // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP, 2320 // so we hit the "else" branch, and return an error 2321 if(child_valobj_sp.get()) // if it worked, just return 2322 { 2323 *first_unparsed = '\0'; 2324 *reason_to_stop = ValueObject::eEndOfString; 2325 *final_result = ValueObject::ePlain; 2326 return child_valobj_sp; 2327 } 2328 else 2329 { 2330 *first_unparsed = expression_cstr; 2331 *reason_to_stop = ValueObject::eNoSuchChild; 2332 *final_result = ValueObject::eInvalid; 2333 return ValueObjectSP(); 2334 } 2335 } 2336 else // other layers do expand 2337 { 2338 child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr); 2339 ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true); 2340 if (child_valobj_sp.get()) // store the new root and move on 2341 { 2342 root = child_valobj_sp; 2343 *first_unparsed = next_separator; 2344 *final_result = ValueObject::ePlain; 2345 continue; 2346 } 2347 else if (options.m_no_synthetic_children == false) // let's try with synthetic children 2348 { 2349 child_valobj_sp = root->GetSyntheticValue(eUseSyntheticFilter)->GetChildMemberWithName(child_name, true); 2350 } 2351 2352 // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP, 2353 // so we hit the "else" branch, and return an error 2354 if(child_valobj_sp.get()) // if it worked, move on 2355 { 2356 root = child_valobj_sp; 2357 *first_unparsed = next_separator; 2358 *final_result = ValueObject::ePlain; 2359 continue; 2360 } 2361 else 2362 { 2363 *first_unparsed = expression_cstr; 2364 *reason_to_stop = ValueObject::eNoSuchChild; 2365 *final_result = ValueObject::eInvalid; 2366 return ValueObjectSP(); 2367 } 2368 } 2369 break; 2370 } 2371 case '[': 2372 { 2373 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T* 2374 { 2375 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar... 2376 { 2377 if (options.m_no_synthetic_children) // ...only chance left is synthetic 2378 { 2379 *first_unparsed = expression_cstr; 2380 *reason_to_stop = ValueObject::eRangeOperatorInvalid; 2381 *final_result = ValueObject::eInvalid; 2382 return ValueObjectSP(); 2383 } 2384 } 2385 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields 2386 { 2387 *first_unparsed = expression_cstr; 2388 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed; 2389 *final_result = ValueObject::eInvalid; 2390 return ValueObjectSP(); 2391 } 2392 } 2393 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays 2394 { 2395 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) 2396 { 2397 *first_unparsed = expression_cstr; 2398 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed; 2399 *final_result = ValueObject::eInvalid; 2400 return ValueObjectSP(); 2401 } 2402 else // even if something follows, we cannot expand unbounded ranges, just let the caller do it 2403 { 2404 *first_unparsed = expression_cstr+2; 2405 *reason_to_stop = ValueObject::eArrayRangeOperatorMet; 2406 *final_result = ValueObject::eUnboundedRange; 2407 return root; 2408 } 2409 } 2410 const char *separator_position = ::strchr(expression_cstr+1,'-'); 2411 const char *close_bracket_position = ::strchr(expression_cstr+1,']'); 2412 if (!close_bracket_position) // if there is no ], this is a syntax error 2413 { 2414 *first_unparsed = expression_cstr; 2415 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2416 *final_result = ValueObject::eInvalid; 2417 return ValueObjectSP(); 2418 } 2419 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N] 2420 { 2421 char *end = NULL; 2422 unsigned long index = ::strtoul (expression_cstr+1, &end, 0); 2423 if (!end || end != close_bracket_position) // if something weird is in our way return an error 2424 { 2425 *first_unparsed = expression_cstr; 2426 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2427 *final_result = ValueObject::eInvalid; 2428 return ValueObjectSP(); 2429 } 2430 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays 2431 { 2432 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) 2433 { 2434 *first_unparsed = expression_cstr+2; 2435 *reason_to_stop = ValueObject::eArrayRangeOperatorMet; 2436 *final_result = ValueObject::eUnboundedRange; 2437 return root; 2438 } 2439 else 2440 { 2441 *first_unparsed = expression_cstr; 2442 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed; 2443 *final_result = ValueObject::eInvalid; 2444 return ValueObjectSP(); 2445 } 2446 } 2447 // from here on we do have a valid index 2448 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) 2449 { 2450 ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true); 2451 if (!child_valobj_sp) 2452 child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true); 2453 if (!child_valobj_sp) 2454 if (root->HasSyntheticValue() && root->GetSyntheticValue(eUseSyntheticFilter)->GetNumChildren() > index) 2455 child_valobj_sp = root->GetSyntheticValue(eUseSyntheticFilter)->GetChildAtIndex(index, true); 2456 if (child_valobj_sp) 2457 { 2458 root = child_valobj_sp; 2459 *first_unparsed = end+1; // skip ] 2460 *final_result = ValueObject::ePlain; 2461 continue; 2462 } 2463 else 2464 { 2465 *first_unparsed = expression_cstr; 2466 *reason_to_stop = ValueObject::eNoSuchChild; 2467 *final_result = ValueObject::eInvalid; 2468 return ValueObjectSP(); 2469 } 2470 } 2471 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) 2472 { 2473 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 2474 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) 2475 { 2476 Error error; 2477 root = root->Dereference(error); 2478 if (error.Fail() || !root.get()) 2479 { 2480 *first_unparsed = expression_cstr; 2481 *reason_to_stop = ValueObject::eDereferencingFailed; 2482 *final_result = ValueObject::eInvalid; 2483 return ValueObjectSP(); 2484 } 2485 else 2486 { 2487 *what_next = eNothing; 2488 continue; 2489 } 2490 } 2491 else 2492 { 2493 if (ClangASTType::GetMinimumLanguage(root->GetClangAST(), 2494 root->GetClangType()) == eLanguageTypeObjC 2495 && 2496 ClangASTContext::IsPointerType(ClangASTType::GetPointeeType(root->GetClangType())) == false 2497 && 2498 root->HasSyntheticValue() 2499 && 2500 options.m_no_synthetic_children == false) 2501 { 2502 root = root->GetSyntheticValue(eUseSyntheticFilter)->GetChildAtIndex(index, true); 2503 } 2504 else 2505 root = root->GetSyntheticArrayMemberFromPointer(index, true); 2506 if (!root.get()) 2507 { 2508 *first_unparsed = expression_cstr; 2509 *reason_to_stop = ValueObject::eNoSuchChild; 2510 *final_result = ValueObject::eInvalid; 2511 return ValueObjectSP(); 2512 } 2513 else 2514 { 2515 *first_unparsed = end+1; // skip ] 2516 *final_result = ValueObject::ePlain; 2517 continue; 2518 } 2519 } 2520 } 2521 else if (ClangASTContext::IsScalarType(root_clang_type)) 2522 { 2523 root = root->GetSyntheticBitFieldChild(index, index, true); 2524 if (!root.get()) 2525 { 2526 *first_unparsed = expression_cstr; 2527 *reason_to_stop = ValueObject::eNoSuchChild; 2528 *final_result = ValueObject::eInvalid; 2529 return ValueObjectSP(); 2530 } 2531 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing 2532 { 2533 *first_unparsed = end+1; // skip ] 2534 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet; 2535 *final_result = ValueObject::eBitfield; 2536 return root; 2537 } 2538 } 2539 else if (root->HasSyntheticValue() && options.m_no_synthetic_children == false) 2540 { 2541 root = root->GetSyntheticValue(eUseSyntheticFilter)->GetChildAtIndex(index, true); 2542 if (!root.get()) 2543 { 2544 *first_unparsed = expression_cstr; 2545 *reason_to_stop = ValueObject::eNoSuchChild; 2546 *final_result = ValueObject::eInvalid; 2547 return ValueObjectSP(); 2548 } 2549 else 2550 { 2551 *first_unparsed = end+1; // skip ] 2552 *final_result = ValueObject::ePlain; 2553 continue; 2554 } 2555 } 2556 else 2557 { 2558 *first_unparsed = expression_cstr; 2559 *reason_to_stop = ValueObject::eNoSuchChild; 2560 *final_result = ValueObject::eInvalid; 2561 return ValueObjectSP(); 2562 } 2563 } 2564 else // we have a low and a high index 2565 { 2566 char *end = NULL; 2567 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0); 2568 if (!end || end != separator_position) // if something weird is in our way return an error 2569 { 2570 *first_unparsed = expression_cstr; 2571 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2572 *final_result = ValueObject::eInvalid; 2573 return ValueObjectSP(); 2574 } 2575 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0); 2576 if (!end || end != close_bracket_position) // if something weird is in our way return an error 2577 { 2578 *first_unparsed = expression_cstr; 2579 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2580 *final_result = ValueObject::eInvalid; 2581 return ValueObjectSP(); 2582 } 2583 if (index_lower > index_higher) // swap indices if required 2584 { 2585 unsigned long temp = index_lower; 2586 index_lower = index_higher; 2587 index_higher = temp; 2588 } 2589 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars 2590 { 2591 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true); 2592 if (!root.get()) 2593 { 2594 *first_unparsed = expression_cstr; 2595 *reason_to_stop = ValueObject::eNoSuchChild; 2596 *final_result = ValueObject::eInvalid; 2597 return ValueObjectSP(); 2598 } 2599 else 2600 { 2601 *first_unparsed = end+1; // skip ] 2602 *reason_to_stop = ValueObject::eBitfieldRangeOperatorMet; 2603 *final_result = ValueObject::eBitfield; 2604 return root; 2605 } 2606 } 2607 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 2608 *what_next == ValueObject::eDereference && 2609 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) 2610 { 2611 Error error; 2612 root = root->Dereference(error); 2613 if (error.Fail() || !root.get()) 2614 { 2615 *first_unparsed = expression_cstr; 2616 *reason_to_stop = ValueObject::eDereferencingFailed; 2617 *final_result = ValueObject::eInvalid; 2618 return ValueObjectSP(); 2619 } 2620 else 2621 { 2622 *what_next = ValueObject::eNothing; 2623 continue; 2624 } 2625 } 2626 else 2627 { 2628 *first_unparsed = expression_cstr; 2629 *reason_to_stop = ValueObject::eArrayRangeOperatorMet; 2630 *final_result = ValueObject::eBoundedRange; 2631 return root; 2632 } 2633 } 2634 break; 2635 } 2636 default: // some non-separator is in the way 2637 { 2638 *first_unparsed = expression_cstr; 2639 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2640 *final_result = ValueObject::eInvalid; 2641 return ValueObjectSP(); 2642 break; 2643 } 2644 } 2645 } 2646} 2647 2648int 2649ValueObject::ExpandArraySliceExpression(const char* expression_cstr, 2650 const char** first_unparsed, 2651 ValueObjectSP root, 2652 ValueObjectListSP& list, 2653 ExpressionPathScanEndReason* reason_to_stop, 2654 ExpressionPathEndResultType* final_result, 2655 const GetValueForExpressionPathOptions& options, 2656 ExpressionPathAftermath* what_next) 2657{ 2658 if (!root.get()) 2659 return 0; 2660 2661 *first_unparsed = expression_cstr; 2662 2663 while (true) 2664 { 2665 2666 const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr 2667 2668 clang_type_t root_clang_type = root->GetClangType(); 2669 clang_type_t pointee_clang_type; 2670 Flags root_clang_type_info,pointee_clang_type_info; 2671 2672 root_clang_type_info = Flags(ClangASTContext::GetTypeInfo(root_clang_type, GetClangAST(), &pointee_clang_type)); 2673 if (pointee_clang_type) 2674 pointee_clang_type_info = Flags(ClangASTContext::GetTypeInfo(pointee_clang_type, GetClangAST(), NULL)); 2675 2676 if (!expression_cstr || *expression_cstr == '\0') 2677 { 2678 *reason_to_stop = ValueObject::eEndOfString; 2679 list->Append(root); 2680 return 1; 2681 } 2682 2683 switch (*expression_cstr) 2684 { 2685 case '[': 2686 { 2687 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray) && !root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) // if this is not a T[] nor a T* 2688 { 2689 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong! 2690 { 2691 *first_unparsed = expression_cstr; 2692 *reason_to_stop = ValueObject::eRangeOperatorInvalid; 2693 *final_result = ValueObject::eInvalid; 2694 return 0; 2695 } 2696 else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields 2697 { 2698 *first_unparsed = expression_cstr; 2699 *reason_to_stop = ValueObject::eRangeOperatorNotAllowed; 2700 *final_result = ValueObject::eInvalid; 2701 return 0; 2702 } 2703 } 2704 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays 2705 { 2706 if (!root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) 2707 { 2708 *first_unparsed = expression_cstr; 2709 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed; 2710 *final_result = ValueObject::eInvalid; 2711 return 0; 2712 } 2713 else // expand this into list 2714 { 2715 int max_index = root->GetNumChildren() - 1; 2716 for (int index = 0; index < max_index; index++) 2717 { 2718 ValueObjectSP child = 2719 root->GetChildAtIndex(index, true); 2720 list->Append(child); 2721 } 2722 *first_unparsed = expression_cstr+2; 2723 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2724 *final_result = ValueObject::eValueObjectList; 2725 return max_index; // tell me number of items I added to the VOList 2726 } 2727 } 2728 const char *separator_position = ::strchr(expression_cstr+1,'-'); 2729 const char *close_bracket_position = ::strchr(expression_cstr+1,']'); 2730 if (!close_bracket_position) // if there is no ], this is a syntax error 2731 { 2732 *first_unparsed = expression_cstr; 2733 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2734 *final_result = ValueObject::eInvalid; 2735 return 0; 2736 } 2737 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N] 2738 { 2739 char *end = NULL; 2740 unsigned long index = ::strtoul (expression_cstr+1, &end, 0); 2741 if (!end || end != close_bracket_position) // if something weird is in our way return an error 2742 { 2743 *first_unparsed = expression_cstr; 2744 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2745 *final_result = ValueObject::eInvalid; 2746 return 0; 2747 } 2748 if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays 2749 { 2750 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) 2751 { 2752 int max_index = root->GetNumChildren() - 1; 2753 for (int index = 0; index < max_index; index++) 2754 { 2755 ValueObjectSP child = 2756 root->GetChildAtIndex(index, true); 2757 list->Append(child); 2758 } 2759 *first_unparsed = expression_cstr+2; 2760 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2761 *final_result = ValueObject::eValueObjectList; 2762 return max_index; // tell me number of items I added to the VOList 2763 } 2764 else 2765 { 2766 *first_unparsed = expression_cstr; 2767 *reason_to_stop = ValueObject::eEmptyRangeNotAllowed; 2768 *final_result = ValueObject::eInvalid; 2769 return 0; 2770 } 2771 } 2772 // from here on we do have a valid index 2773 if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray)) 2774 { 2775 root = root->GetChildAtIndex(index, true); 2776 if (!root.get()) 2777 { 2778 *first_unparsed = expression_cstr; 2779 *reason_to_stop = ValueObject::eNoSuchChild; 2780 *final_result = ValueObject::eInvalid; 2781 return 0; 2782 } 2783 else 2784 { 2785 list->Append(root); 2786 *first_unparsed = end+1; // skip ] 2787 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2788 *final_result = ValueObject::eValueObjectList; 2789 return 1; 2790 } 2791 } 2792 else if (root_clang_type_info.Test(ClangASTContext::eTypeIsPointer)) 2793 { 2794 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 2795 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) 2796 { 2797 Error error; 2798 root = root->Dereference(error); 2799 if (error.Fail() || !root.get()) 2800 { 2801 *first_unparsed = expression_cstr; 2802 *reason_to_stop = ValueObject::eDereferencingFailed; 2803 *final_result = ValueObject::eInvalid; 2804 return 0; 2805 } 2806 else 2807 { 2808 *what_next = eNothing; 2809 continue; 2810 } 2811 } 2812 else 2813 { 2814 root = root->GetSyntheticArrayMemberFromPointer(index, true); 2815 if (!root.get()) 2816 { 2817 *first_unparsed = expression_cstr; 2818 *reason_to_stop = ValueObject::eNoSuchChild; 2819 *final_result = ValueObject::eInvalid; 2820 return 0; 2821 } 2822 else 2823 { 2824 list->Append(root); 2825 *first_unparsed = end+1; // skip ] 2826 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2827 *final_result = ValueObject::eValueObjectList; 2828 return 1; 2829 } 2830 } 2831 } 2832 else /*if (ClangASTContext::IsScalarType(root_clang_type))*/ 2833 { 2834 root = root->GetSyntheticBitFieldChild(index, index, true); 2835 if (!root.get()) 2836 { 2837 *first_unparsed = expression_cstr; 2838 *reason_to_stop = ValueObject::eNoSuchChild; 2839 *final_result = ValueObject::eInvalid; 2840 return 0; 2841 } 2842 else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing 2843 { 2844 list->Append(root); 2845 *first_unparsed = end+1; // skip ] 2846 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2847 *final_result = ValueObject::eValueObjectList; 2848 return 1; 2849 } 2850 } 2851 } 2852 else // we have a low and a high index 2853 { 2854 char *end = NULL; 2855 unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0); 2856 if (!end || end != separator_position) // if something weird is in our way return an error 2857 { 2858 *first_unparsed = expression_cstr; 2859 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2860 *final_result = ValueObject::eInvalid; 2861 return 0; 2862 } 2863 unsigned long index_higher = ::strtoul (separator_position+1, &end, 0); 2864 if (!end || end != close_bracket_position) // if something weird is in our way return an error 2865 { 2866 *first_unparsed = expression_cstr; 2867 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2868 *final_result = ValueObject::eInvalid; 2869 return 0; 2870 } 2871 if (index_lower > index_higher) // swap indices if required 2872 { 2873 unsigned long temp = index_lower; 2874 index_lower = index_higher; 2875 index_higher = temp; 2876 } 2877 if (root_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) // expansion only works for scalars 2878 { 2879 root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true); 2880 if (!root.get()) 2881 { 2882 *first_unparsed = expression_cstr; 2883 *reason_to_stop = ValueObject::eNoSuchChild; 2884 *final_result = ValueObject::eInvalid; 2885 return 0; 2886 } 2887 else 2888 { 2889 list->Append(root); 2890 *first_unparsed = end+1; // skip ] 2891 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2892 *final_result = ValueObject::eValueObjectList; 2893 return 1; 2894 } 2895 } 2896 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 2897 *what_next == ValueObject::eDereference && 2898 pointee_clang_type_info.Test(ClangASTContext::eTypeIsScalar)) 2899 { 2900 Error error; 2901 root = root->Dereference(error); 2902 if (error.Fail() || !root.get()) 2903 { 2904 *first_unparsed = expression_cstr; 2905 *reason_to_stop = ValueObject::eDereferencingFailed; 2906 *final_result = ValueObject::eInvalid; 2907 return 0; 2908 } 2909 else 2910 { 2911 *what_next = ValueObject::eNothing; 2912 continue; 2913 } 2914 } 2915 else 2916 { 2917 for (unsigned long index = index_lower; 2918 index <= index_higher; index++) 2919 { 2920 ValueObjectSP child = 2921 root->GetChildAtIndex(index, true); 2922 list->Append(child); 2923 } 2924 *first_unparsed = end+1; 2925 *reason_to_stop = ValueObject::eRangeOperatorExpanded; 2926 *final_result = ValueObject::eValueObjectList; 2927 return index_higher-index_lower+1; // tell me number of items I added to the VOList 2928 } 2929 } 2930 break; 2931 } 2932 default: // some non-[ separator, or something entirely wrong, is in the way 2933 { 2934 *first_unparsed = expression_cstr; 2935 *reason_to_stop = ValueObject::eUnexpectedSymbol; 2936 *final_result = ValueObject::eInvalid; 2937 return 0; 2938 break; 2939 } 2940 } 2941 } 2942} 2943 2944void 2945ValueObject::DumpValueObject 2946( 2947 Stream &s, 2948 ValueObject *valobj, 2949 const char *root_valobj_name, 2950 uint32_t ptr_depth, 2951 uint32_t curr_depth, 2952 uint32_t max_depth, 2953 bool show_types, 2954 bool show_location, 2955 bool use_objc, 2956 DynamicValueType use_dynamic, 2957 bool use_synth, 2958 bool scope_already_checked, 2959 bool flat_output, 2960 uint32_t omit_summary_depth, 2961 bool ignore_cap 2962) 2963{ 2964 if (valobj) 2965 { 2966 bool update_success = valobj->UpdateValueIfNeeded (use_dynamic, true); 2967 2968 if (update_success && use_dynamic != eNoDynamicValues) 2969 { 2970 ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get(); 2971 if (dynamic_value) 2972 valobj = dynamic_value; 2973 } 2974 2975 clang_type_t clang_type = valobj->GetClangType(); 2976 2977 const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, NULL)); 2978 const char *err_cstr = NULL; 2979 const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren); 2980 const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue); 2981 2982 const bool print_valobj = flat_output == false || has_value; 2983 2984 if (print_valobj) 2985 { 2986 if (show_location) 2987 { 2988 s.Printf("%s: ", valobj->GetLocationAsCString()); 2989 } 2990 2991 s.Indent(); 2992 2993 // Always show the type for the top level items. 2994 if (show_types || (curr_depth == 0 && !flat_output)) 2995 { 2996 const char* typeName = valobj->GetTypeName().AsCString("<invalid type>"); 2997 s.Printf("(%s", typeName); 2998 // only show dynamic types if the user really wants to see types 2999 if (show_types && use_dynamic != eNoDynamicValues && 3000 (/*strstr(typeName, "id") == typeName ||*/ 3001 ClangASTType::GetMinimumLanguage(valobj->GetClangAST(), valobj->GetClangType()) == eLanguageTypeObjC)) 3002 { 3003 Process* process = valobj->GetUpdatePoint().GetProcessSP().get(); 3004 if (process == NULL) 3005 s.Printf(", dynamic type: unknown) "); 3006 else 3007 { 3008 ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime(); 3009 if (runtime == NULL) 3010 s.Printf(", dynamic type: unknown) "); 3011 else 3012 { 3013 ObjCLanguageRuntime::ObjCISA isa = runtime->GetISA(*valobj); 3014 if (!runtime->IsValidISA(isa)) 3015 s.Printf(", dynamic type: unknown) "); 3016 else 3017 s.Printf(", dynamic type: %s) ", 3018 runtime->GetActualTypeName(isa).GetCString()); 3019 } 3020 } 3021 } 3022 else 3023 s.Printf(") "); 3024 } 3025 3026 3027 if (flat_output) 3028 { 3029 // If we are showing types, also qualify the C++ base classes 3030 const bool qualify_cxx_base_classes = show_types; 3031 valobj->GetExpressionPath(s, qualify_cxx_base_classes); 3032 s.PutCString(" ="); 3033 } 3034 else 3035 { 3036 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString(""); 3037 s.Printf ("%s =", name_cstr); 3038 } 3039 3040 if (!scope_already_checked && !valobj->IsInScope()) 3041 { 3042 err_cstr = "out of scope"; 3043 } 3044 } 3045 3046 const char *val_cstr = NULL; 3047 const char *sum_cstr = NULL; 3048 SummaryFormat* entry = valobj->GetSummaryFormat().get(); 3049 3050 if (omit_summary_depth > 0) 3051 entry = NULL; 3052 3053 if (err_cstr == NULL) 3054 { 3055 val_cstr = valobj->GetValueAsCString(); 3056 err_cstr = valobj->GetError().AsCString(); 3057 } 3058 3059 if (err_cstr) 3060 { 3061 s.Printf (" <%s>\n", err_cstr); 3062 } 3063 else 3064 { 3065 const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference); 3066 if (print_valobj) 3067 { 3068 3069 sum_cstr = (omit_summary_depth == 0) ? valobj->GetSummaryAsCString() : NULL; 3070 3071 // We must calculate this value in realtime because entry might alter this variable's value 3072 // (e.g. by saying ${var%fmt}) and render precached values useless 3073 if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr)) 3074 s.Printf(" %s", valobj->GetValueAsCString()); 3075 3076 if (sum_cstr) 3077 { 3078 // for some reason, using %@ (ObjC description) in a summary string, makes 3079 // us believe we need to reset ourselves, thus invalidating the content of 3080 // sum_cstr. Thus, IF we had a valid sum_cstr before, but it is now empty 3081 // let us recalculate it! 3082 if (sum_cstr[0] == '\0') 3083 s.Printf(" %s", valobj->GetSummaryAsCString()); 3084 else 3085 s.Printf(" %s", sum_cstr); 3086 } 3087 3088 if (use_objc) 3089 { 3090 const char *object_desc = valobj->GetObjectDescription(); 3091 if (object_desc) 3092 s.Printf(" %s\n", object_desc); 3093 else 3094 s.Printf (" [no Objective-C description available]\n"); 3095 return; 3096 } 3097 } 3098 3099 if (curr_depth < max_depth) 3100 { 3101 // We will show children for all concrete types. We won't show 3102 // pointer contents unless a pointer depth has been specified. 3103 // We won't reference contents unless the reference is the 3104 // root object (depth of zero). 3105 bool print_children = true; 3106 3107 // Use a new temporary pointer depth in case we override the 3108 // current pointer depth below... 3109 uint32_t curr_ptr_depth = ptr_depth; 3110 3111 const bool is_ptr = type_flags.Test (ClangASTContext::eTypeIsPointer); 3112 if (is_ptr || is_ref) 3113 { 3114 // We have a pointer or reference whose value is an address. 3115 // Make sure that address is not NULL 3116 AddressType ptr_address_type; 3117 if (valobj->GetPointerValue (&ptr_address_type) == 0) 3118 print_children = false; 3119 3120 else if (is_ref && curr_depth == 0) 3121 { 3122 // If this is the root object (depth is zero) that we are showing 3123 // and it is a reference, and no pointer depth has been supplied 3124 // print out what it references. Don't do this at deeper depths 3125 // otherwise we can end up with infinite recursion... 3126 curr_ptr_depth = 1; 3127 } 3128 3129 if (curr_ptr_depth == 0) 3130 print_children = false; 3131 } 3132 3133 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr)) 3134 { 3135 ValueObjectSP synth_valobj = valobj->GetSyntheticValue(use_synth ? 3136 eUseSyntheticFilter : 3137 eNoSyntheticFilter); 3138 uint32_t num_children = synth_valobj->GetNumChildren(); 3139 bool print_dotdotdot = false; 3140 if (num_children) 3141 { 3142 if (flat_output) 3143 { 3144 if (print_valobj) 3145 s.EOL(); 3146 } 3147 else 3148 { 3149 if (print_valobj) 3150 s.PutCString(is_ref ? ": {\n" : " {\n"); 3151 s.IndentMore(); 3152 } 3153 3154 uint32_t max_num_children = valobj->GetUpdatePoint().GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); 3155 3156 if (num_children > max_num_children && !ignore_cap) 3157 { 3158 num_children = max_num_children; 3159 print_dotdotdot = true; 3160 } 3161 3162 for (uint32_t idx=0; idx<num_children; ++idx) 3163 { 3164 ValueObjectSP child_sp(synth_valobj->GetChildAtIndex(idx, true)); 3165 if (child_sp.get()) 3166 { 3167 DumpValueObject (s, 3168 child_sp.get(), 3169 NULL, 3170 (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth, 3171 curr_depth + 1, 3172 max_depth, 3173 show_types, 3174 show_location, 3175 false, 3176 use_dynamic, 3177 use_synth, 3178 true, 3179 flat_output, 3180 omit_summary_depth > 1 ? omit_summary_depth - 1 : 0, 3181 ignore_cap); 3182 } 3183 } 3184 3185 if (!flat_output) 3186 { 3187 if (print_dotdotdot) 3188 { 3189 valobj->GetUpdatePoint().GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated(); 3190 s.Indent("...\n"); 3191 } 3192 s.IndentLess(); 3193 s.Indent("}\n"); 3194 } 3195 } 3196 else if (has_children) 3197 { 3198 // Aggregate, no children... 3199 if (print_valobj) 3200 s.PutCString(" {}\n"); 3201 } 3202 else 3203 { 3204 if (print_valobj) 3205 s.EOL(); 3206 } 3207 3208 } 3209 else 3210 { 3211 s.EOL(); 3212 } 3213 } 3214 else 3215 { 3216 if (has_children && print_valobj) 3217 { 3218 s.PutCString("{...}\n"); 3219 } 3220 } 3221 } 3222 } 3223} 3224 3225 3226ValueObjectSP 3227ValueObject::CreateConstantValue (const ConstString &name) 3228{ 3229 ValueObjectSP valobj_sp; 3230 3231 if (UpdateValueIfNeeded(false) && m_error.Success()) 3232 { 3233 ExecutionContextScope *exe_scope = GetExecutionContextScope(); 3234 if (exe_scope) 3235 { 3236 ExecutionContext exe_ctx; 3237 exe_scope->CalculateExecutionContext(exe_ctx); 3238 3239 clang::ASTContext *ast = GetClangAST (); 3240 3241 DataExtractor data; 3242 data.SetByteOrder (m_data.GetByteOrder()); 3243 data.SetAddressByteSize(m_data.GetAddressByteSize()); 3244 3245 m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule()); 3246 3247 valobj_sp = ValueObjectConstResult::Create (exe_scope, 3248 ast, 3249 GetClangType(), 3250 name, 3251 data, 3252 GetAddressOf()); 3253 } 3254 } 3255 3256 if (!valobj_sp) 3257 { 3258 valobj_sp = ValueObjectConstResult::Create (NULL, m_error); 3259 } 3260 return valobj_sp; 3261} 3262 3263ValueObjectSP 3264ValueObject::Dereference (Error &error) 3265{ 3266 if (m_deref_valobj) 3267 return m_deref_valobj->GetSP(); 3268 3269 const bool is_pointer_type = IsPointerType(); 3270 if (is_pointer_type) 3271 { 3272 bool omit_empty_base_classes = true; 3273 bool ignore_array_bounds = false; 3274 3275 std::string child_name_str; 3276 uint32_t child_byte_size = 0; 3277 int32_t child_byte_offset = 0; 3278 uint32_t child_bitfield_bit_size = 0; 3279 uint32_t child_bitfield_bit_offset = 0; 3280 bool child_is_base_class = false; 3281 bool child_is_deref_of_parent = false; 3282 const bool transparent_pointers = false; 3283 clang::ASTContext *clang_ast = GetClangAST(); 3284 clang_type_t clang_type = GetClangType(); 3285 clang_type_t child_clang_type; 3286 3287 ExecutionContext exe_ctx; 3288 GetExecutionContextScope()->CalculateExecutionContext (exe_ctx); 3289 3290 child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx, 3291 clang_ast, 3292 GetName().GetCString(), 3293 clang_type, 3294 0, 3295 transparent_pointers, 3296 omit_empty_base_classes, 3297 ignore_array_bounds, 3298 child_name_str, 3299 child_byte_size, 3300 child_byte_offset, 3301 child_bitfield_bit_size, 3302 child_bitfield_bit_offset, 3303 child_is_base_class, 3304 child_is_deref_of_parent); 3305 if (child_clang_type && child_byte_size) 3306 { 3307 ConstString child_name; 3308 if (!child_name_str.empty()) 3309 child_name.SetCString (child_name_str.c_str()); 3310 3311 m_deref_valobj = new ValueObjectChild (*this, 3312 clang_ast, 3313 child_clang_type, 3314 child_name, 3315 child_byte_size, 3316 child_byte_offset, 3317 child_bitfield_bit_size, 3318 child_bitfield_bit_offset, 3319 child_is_base_class, 3320 child_is_deref_of_parent, 3321 eAddressTypeInvalid); 3322 } 3323 } 3324 3325 if (m_deref_valobj) 3326 { 3327 error.Clear(); 3328 return m_deref_valobj->GetSP(); 3329 } 3330 else 3331 { 3332 StreamString strm; 3333 GetExpressionPath(strm, true); 3334 3335 if (is_pointer_type) 3336 error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str()); 3337 else 3338 error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str()); 3339 return ValueObjectSP(); 3340 } 3341} 3342 3343ValueObjectSP 3344ValueObject::AddressOf (Error &error) 3345{ 3346 if (m_addr_of_valobj_sp) 3347 return m_addr_of_valobj_sp; 3348 3349 AddressType address_type = eAddressTypeInvalid; 3350 const bool scalar_is_load_address = false; 3351 addr_t addr = GetAddressOf (scalar_is_load_address, &address_type); 3352 error.Clear(); 3353 if (addr != LLDB_INVALID_ADDRESS) 3354 { 3355 switch (address_type) 3356 { 3357 default: 3358 case eAddressTypeInvalid: 3359 { 3360 StreamString expr_path_strm; 3361 GetExpressionPath(expr_path_strm, true); 3362 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str()); 3363 } 3364 break; 3365 3366 case eAddressTypeFile: 3367 case eAddressTypeLoad: 3368 case eAddressTypeHost: 3369 { 3370 clang::ASTContext *ast = GetClangAST(); 3371 clang_type_t clang_type = GetClangType(); 3372 if (ast && clang_type) 3373 { 3374 std::string name (1, '&'); 3375 name.append (m_name.AsCString("")); 3376 m_addr_of_valobj_sp = ValueObjectConstResult::Create (GetExecutionContextScope(), 3377 ast, 3378 ClangASTContext::CreatePointerType (ast, clang_type), 3379 ConstString (name.c_str()), 3380 addr, 3381 eAddressTypeInvalid, 3382 m_data.GetAddressByteSize()); 3383 } 3384 } 3385 break; 3386 } 3387 } 3388 return m_addr_of_valobj_sp; 3389} 3390 3391 3392ValueObjectSP 3393ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type) 3394{ 3395 ValueObjectSP valobj_sp; 3396 AddressType address_type; 3397 addr_t ptr_value = GetPointerValue (&address_type); 3398 3399 if (ptr_value != LLDB_INVALID_ADDRESS) 3400 { 3401 Address ptr_addr (NULL, ptr_value); 3402 3403 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(), 3404 name, 3405 ptr_addr, 3406 clang_ast_type); 3407 } 3408 return valobj_sp; 3409} 3410 3411ValueObjectSP 3412ValueObject::CastPointerType (const char *name, TypeSP &type_sp) 3413{ 3414 ValueObjectSP valobj_sp; 3415 AddressType address_type; 3416 addr_t ptr_value = GetPointerValue (&address_type); 3417 3418 if (ptr_value != LLDB_INVALID_ADDRESS) 3419 { 3420 Address ptr_addr (NULL, ptr_value); 3421 3422 valobj_sp = ValueObjectMemory::Create (GetExecutionContextScope(), 3423 name, 3424 ptr_addr, 3425 type_sp); 3426 } 3427 return valobj_sp; 3428} 3429 3430ValueObject::EvaluationPoint::EvaluationPoint () : 3431 m_thread_id (LLDB_INVALID_UID), 3432 m_mod_id () 3433{ 3434} 3435 3436ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected): 3437 m_needs_update (true), 3438 m_first_update (true), 3439 m_thread_id (LLDB_INVALID_THREAD_ID), 3440 m_mod_id () 3441 3442{ 3443 ExecutionContext exe_ctx; 3444 ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope, 3445 // and if so we want to cache that not the original. 3446 if (exe_scope) 3447 exe_scope->CalculateExecutionContext(exe_ctx); 3448 Target *target = exe_ctx.GetTargetPtr(); 3449 if (target != NULL) 3450 { 3451 m_target_sp = target; 3452 m_process_sp = exe_ctx.GetProcessSP(); 3453 if (!m_process_sp) 3454 m_process_sp = target->GetProcessSP(); 3455 3456 if (m_process_sp) 3457 { 3458 m_mod_id = m_process_sp->GetModID(); 3459 3460 Thread *thread = exe_ctx.GetThreadPtr(); 3461 3462 if (thread == NULL) 3463 { 3464 if (use_selected) 3465 { 3466 thread = m_process_sp->GetThreadList().GetSelectedThread().get(); 3467 if (thread) 3468 computed_exe_scope = thread; 3469 } 3470 } 3471 3472 if (thread != NULL) 3473 { 3474 m_thread_id = thread->GetIndexID(); 3475 3476 StackFrame *frame = exe_ctx.GetFramePtr(); 3477 if (frame == NULL) 3478 { 3479 if (use_selected) 3480 { 3481 frame = thread->GetSelectedFrame().get(); 3482 if (frame) 3483 { 3484 m_stack_id = frame->GetStackID(); 3485 computed_exe_scope = frame; 3486 } 3487 } 3488 } 3489 else 3490 m_stack_id = frame->GetStackID(); 3491 } 3492 } 3493 } 3494 m_exe_scope = computed_exe_scope; 3495} 3496 3497ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) : 3498 m_exe_scope (rhs.m_exe_scope), 3499 m_needs_update(true), 3500 m_first_update(true), 3501 m_target_sp (rhs.m_target_sp), 3502 m_process_sp (rhs.m_process_sp), 3503 m_thread_id (rhs.m_thread_id), 3504 m_stack_id (rhs.m_stack_id), 3505 m_mod_id () 3506{ 3507} 3508 3509ValueObject::EvaluationPoint::~EvaluationPoint () 3510{ 3511} 3512 3513ExecutionContextScope * 3514ValueObject::EvaluationPoint::GetExecutionContextScope () 3515{ 3516 // We have to update before giving out the scope, or we could be handing out stale pointers. 3517 SyncWithProcessState(); 3518 3519 return m_exe_scope; 3520} 3521 3522// This function checks the EvaluationPoint against the current process state. If the current 3523// state matches the evaluation point, or the evaluation point is already invalid, then we return 3524// false, meaning "no change". If the current state is different, we update our state, and return 3525// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so 3526// future calls to NeedsUpdate will return true. 3527 3528bool 3529ValueObject::EvaluationPoint::SyncWithProcessState() 3530{ 3531 // If we don't have a process nothing can change. 3532 if (!m_process_sp) 3533 { 3534 m_exe_scope = m_target_sp.get(); 3535 return false; 3536 } 3537 3538 // If our stop id is the current stop ID, nothing has changed: 3539 ProcessModID current_mod_id = m_process_sp->GetModID(); 3540 3541 // If the current stop id is 0, either we haven't run yet, or the process state has been cleared. 3542 // In either case, we aren't going to be able to sync with the process state. 3543 if (current_mod_id.GetStopID() == 0) 3544 { 3545 m_exe_scope = m_target_sp.get(); 3546 return false; 3547 } 3548 3549 if (m_mod_id.IsValid()) 3550 { 3551 if (m_mod_id == current_mod_id) 3552 { 3553 // Everything is already up to date in this object, no need do 3554 // update the execution context scope. 3555 return false; 3556 } 3557 m_mod_id = current_mod_id; 3558 m_needs_update = true; 3559 } 3560 m_exe_scope = m_process_sp.get(); 3561 3562 // Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either 3563 // doesn't, mark ourselves as invalid. 3564 3565 if (m_thread_id != LLDB_INVALID_THREAD_ID) 3566 { 3567 Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get(); 3568 if (our_thread == NULL) 3569 { 3570 SetInvalid(); 3571 } 3572 else 3573 { 3574 m_exe_scope = our_thread; 3575 3576 if (m_stack_id.IsValid()) 3577 { 3578 StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get(); 3579 if (our_frame == NULL) 3580 SetInvalid(); 3581 else 3582 m_exe_scope = our_frame; 3583 } 3584 } 3585 } 3586 return true; 3587} 3588 3589void 3590ValueObject::EvaluationPoint::SetUpdated () 3591{ 3592 // this will update the execution context scope and the m_mod_id 3593 SyncWithProcessState(); 3594 m_first_update = false; 3595 m_needs_update = false; 3596} 3597 3598 3599bool 3600ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope) 3601{ 3602 if (!IsValid()) 3603 return false; 3604 3605 bool needs_update = false; 3606 m_exe_scope = NULL; 3607 3608 // The target has to be non-null, and the 3609 Target *target = exe_scope->CalculateTarget(); 3610 if (target != NULL) 3611 { 3612 Target *old_target = m_target_sp.get(); 3613 assert (target == old_target); 3614 Process *process = exe_scope->CalculateProcess(); 3615 if (process != NULL) 3616 { 3617 // FOR NOW - assume you can't update variable objects across process boundaries. 3618 Process *old_process = m_process_sp.get(); 3619 assert (process == old_process); 3620 ProcessModID current_mod_id = process->GetModID(); 3621 if (m_mod_id != current_mod_id) 3622 { 3623 needs_update = true; 3624 m_mod_id = current_mod_id; 3625 } 3626 // See if we're switching the thread or stack context. If no thread is given, this is 3627 // being evaluated in a global context. 3628 Thread *thread = exe_scope->CalculateThread(); 3629 if (thread != NULL) 3630 { 3631 user_id_t new_thread_index = thread->GetIndexID(); 3632 if (new_thread_index != m_thread_id) 3633 { 3634 needs_update = true; 3635 m_thread_id = new_thread_index; 3636 m_stack_id.Clear(); 3637 } 3638 3639 StackFrame *new_frame = exe_scope->CalculateStackFrame(); 3640 if (new_frame != NULL) 3641 { 3642 if (new_frame->GetStackID() != m_stack_id) 3643 { 3644 needs_update = true; 3645 m_stack_id = new_frame->GetStackID(); 3646 } 3647 } 3648 else 3649 { 3650 m_stack_id.Clear(); 3651 needs_update = true; 3652 } 3653 } 3654 else 3655 { 3656 // If this had been given a thread, and now there is none, we should update. 3657 // Otherwise we don't have to do anything. 3658 if (m_thread_id != LLDB_INVALID_UID) 3659 { 3660 m_thread_id = LLDB_INVALID_UID; 3661 m_stack_id.Clear(); 3662 needs_update = true; 3663 } 3664 } 3665 } 3666 else 3667 { 3668 // If there is no process, then we don't need to update anything. 3669 // But if we're switching from having a process to not, we should try to update. 3670 if (m_process_sp.get() != NULL) 3671 { 3672 needs_update = true; 3673 m_process_sp.reset(); 3674 m_thread_id = LLDB_INVALID_UID; 3675 m_stack_id.Clear(); 3676 } 3677 } 3678 } 3679 else 3680 { 3681 // If there's no target, nothing can change so we don't need to update anything. 3682 // But if we're switching from having a target to not, we should try to update. 3683 if (m_target_sp.get() != NULL) 3684 { 3685 needs_update = true; 3686 m_target_sp.reset(); 3687 m_process_sp.reset(); 3688 m_thread_id = LLDB_INVALID_UID; 3689 m_stack_id.Clear(); 3690 } 3691 } 3692 if (!m_needs_update) 3693 m_needs_update = needs_update; 3694 3695 return needs_update; 3696} 3697 3698void 3699ValueObject::ClearUserVisibleData() 3700{ 3701 m_location_str.clear(); 3702 m_value_str.clear(); 3703 m_summary_str.clear(); 3704 m_object_desc_str.clear(); 3705 m_trying_summary_already = false; 3706} 3707 3708SymbolContextScope * 3709ValueObject::GetSymbolContextScope() 3710{ 3711 if (m_parent) 3712 { 3713 if (!m_parent->IsPointerOrReferenceType()) 3714 return m_parent->GetSymbolContextScope(); 3715 } 3716 return NULL; 3717} 3718