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