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