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