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