1 //===-- NSSet.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 "NSSet.h" 11 12 #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" 13 #include "lldb/Core/ValueObject.h" 14 #include "lldb/Core/ValueObjectConstResult.h" 15 #include "lldb/DataFormatters/FormattersHelpers.h" 16 #include "lldb/Symbol/ClangASTContext.h" 17 #include "lldb/Target/Language.h" 18 #include "lldb/Target/ObjCLanguageRuntime.h" 19 #include "lldb/Target/Target.h" 20 #include "lldb/Utility/DataBufferHeap.h" 21 #include "lldb/Utility/Endian.h" 22 #include "lldb/Utility/Status.h" 23 #include "lldb/Utility/Stream.h" 24 25 using namespace lldb; 26 using namespace lldb_private; 27 using namespace lldb_private::formatters; 28 29 std::map<ConstString, CXXFunctionSummaryFormat::Callback> & 30 NSSet_Additionals::GetAdditionalSummaries() { 31 static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map; 32 return g_map; 33 } 34 35 std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> & 36 NSSet_Additionals::GetAdditionalSynthetics() { 37 static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> 38 g_map; 39 return g_map; 40 } 41 42 namespace lldb_private { 43 namespace formatters { 44 class NSSetISyntheticFrontEnd : public SyntheticChildrenFrontEnd { 45 public: 46 NSSetISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); 47 48 ~NSSetISyntheticFrontEnd() override; 49 50 size_t CalculateNumChildren() override; 51 52 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; 53 54 bool Update() override; 55 56 bool MightHaveChildren() override; 57 58 size_t GetIndexOfChildWithName(const ConstString &name) override; 59 60 private: 61 struct DataDescriptor_32 { 62 uint32_t _used : 26; 63 uint32_t _szidx : 6; 64 }; 65 66 struct DataDescriptor_64 { 67 uint64_t _used : 58; 68 uint32_t _szidx : 6; 69 }; 70 71 struct SetItemDescriptor { 72 lldb::addr_t item_ptr; 73 lldb::ValueObjectSP valobj_sp; 74 }; 75 76 ExecutionContextRef m_exe_ctx_ref; 77 uint8_t m_ptr_size; 78 DataDescriptor_32 *m_data_32; 79 DataDescriptor_64 *m_data_64; 80 lldb::addr_t m_data_ptr; 81 std::vector<SetItemDescriptor> m_children; 82 }; 83 84 template <typename D32, typename D64> 85 class GenericNSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd { 86 public: 87 GenericNSSetMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); 88 89 ~GenericNSSetMSyntheticFrontEnd() override; 90 91 size_t CalculateNumChildren() override; 92 93 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; 94 95 bool Update() override; 96 97 bool MightHaveChildren() override; 98 99 size_t GetIndexOfChildWithName(const ConstString &name) override; 100 101 private: 102 103 struct SetItemDescriptor { 104 lldb::addr_t item_ptr; 105 lldb::ValueObjectSP valobj_sp; 106 }; 107 108 ExecutionContextRef m_exe_ctx_ref; 109 uint8_t m_ptr_size; 110 D32 *m_data_32; 111 D64 *m_data_64; 112 std::vector<SetItemDescriptor> m_children; 113 }; 114 115 namespace Foundation1300 { 116 struct DataDescriptor_32 { 117 uint32_t _used : 26; 118 uint32_t _size; 119 uint32_t _mutations; 120 uint32_t _objs_addr; 121 }; 122 123 struct DataDescriptor_64 { 124 uint64_t _used : 58; 125 uint64_t _size; 126 uint64_t _mutations; 127 uint64_t _objs_addr; 128 }; 129 130 using NSSetMSyntheticFrontEnd = 131 GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>; 132 } 133 134 namespace Foundation1428 { 135 struct DataDescriptor_32 { 136 uint32_t _used : 26; 137 uint32_t _size; 138 uint32_t _objs_addr; 139 uint32_t _mutations; 140 }; 141 142 struct DataDescriptor_64 { 143 uint64_t _used : 58; 144 uint64_t _size; 145 uint64_t _objs_addr; 146 uint64_t _mutations; 147 }; 148 149 using NSSetMSyntheticFrontEnd = 150 GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>; 151 } 152 153 namespace Foundation1437 { 154 struct DataDescriptor_32 { 155 uint32_t _cow; 156 // __table storage 157 uint32_t _objs_addr; 158 union { 159 uint32_t _mutations; 160 struct { 161 uint32_t _muts; 162 uint32_t _used : 26; 163 uint32_t _szidx : 6; 164 }; 165 }; 166 }; 167 168 struct DataDescriptor_64 { 169 uint64_t _cow; 170 // __Table storage 171 uint64_t _objs_addr; 172 union { 173 uint64_t _mutations; 174 struct { 175 uint32_t _muts; 176 uint32_t _used : 26; 177 uint32_t _szidx : 6; 178 }; 179 }; 180 }; 181 182 using NSSetMSyntheticFrontEnd = 183 GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>; 184 185 template <typename DD> 186 uint64_t 187 __NSSetMSize_Impl(lldb_private::Process &process, lldb::addr_t valobj_addr, 188 Status &error) { 189 const lldb::addr_t start_of_descriptor = 190 valobj_addr + process.GetAddressByteSize(); 191 DD descriptor = DD(); 192 process.ReadMemory(start_of_descriptor, &descriptor, sizeof(descriptor), 193 error); 194 if (error.Fail()) { 195 return 0; 196 } 197 return descriptor._used; 198 } 199 200 uint64_t 201 __NSSetMSize(lldb_private::Process &process, lldb::addr_t valobj_addr, 202 Status &error) { 203 if (process.GetAddressByteSize() == 4) { 204 return __NSSetMSize_Impl<DataDescriptor_32>(process, valobj_addr, error); 205 } else { 206 return __NSSetMSize_Impl<DataDescriptor_64>(process, valobj_addr, error); 207 } 208 } 209 } 210 211 class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd { 212 public: 213 NSSetCodeRunningSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); 214 215 ~NSSetCodeRunningSyntheticFrontEnd() override; 216 217 size_t CalculateNumChildren() override; 218 219 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; 220 221 bool Update() override; 222 223 bool MightHaveChildren() override; 224 225 size_t GetIndexOfChildWithName(const ConstString &name) override; 226 }; 227 } // namespace formatters 228 } // namespace lldb_private 229 230 template <bool cf_style> 231 bool lldb_private::formatters::NSSetSummaryProvider( 232 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { 233 static ConstString g_TypeHint("NSSet"); 234 235 ProcessSP process_sp = valobj.GetProcessSP(); 236 if (!process_sp) 237 return false; 238 239 ObjCLanguageRuntime *runtime = 240 (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime( 241 lldb::eLanguageTypeObjC); 242 243 if (!runtime) 244 return false; 245 246 ObjCLanguageRuntime::ClassDescriptorSP descriptor( 247 runtime->GetClassDescriptor(valobj)); 248 249 if (!descriptor || !descriptor->IsValid()) 250 return false; 251 252 uint32_t ptr_size = process_sp->GetAddressByteSize(); 253 bool is_64bit = (ptr_size == 8); 254 255 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); 256 257 if (!valobj_addr) 258 return false; 259 260 uint64_t value = 0; 261 262 ConstString class_name_cs = descriptor->GetClassName(); 263 const char *class_name = class_name_cs.GetCString(); 264 265 if (!class_name || !*class_name) 266 return false; 267 268 if (!strcmp(class_name, "__NSSetI") || 269 !strcmp(class_name, "__NSOrderedSetI")) { 270 Status error; 271 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 272 ptr_size, 0, error); 273 if (error.Fail()) 274 return false; 275 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); 276 } else if (!strcmp(class_name, "__NSSetM")) { 277 AppleObjCRuntime *apple_runtime = 278 llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime); 279 Status error; 280 if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1437) { 281 value = Foundation1437::__NSSetMSize(*process_sp, valobj_addr, error); 282 } else { 283 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 284 ptr_size, 0, error); 285 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); 286 } 287 if (error.Fail()) 288 return false; 289 } else { 290 auto &map(NSSet_Additionals::GetAdditionalSummaries()); 291 auto iter = map.find(class_name_cs), end = map.end(); 292 if (iter != end) 293 return iter->second(valobj, stream, options); 294 else 295 return false; 296 } 297 298 std::string prefix, suffix; 299 if (Language *language = Language::FindPlugin(options.GetLanguage())) { 300 if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, 301 suffix)) { 302 prefix.clear(); 303 suffix.clear(); 304 } 305 } 306 307 stream.Printf("%s%" PRIu64 " %s%s%s", prefix.c_str(), value, "element", 308 value == 1 ? "" : "s", suffix.c_str()); 309 return true; 310 } 311 312 SyntheticChildrenFrontEnd * 313 lldb_private::formatters::NSSetSyntheticFrontEndCreator( 314 CXXSyntheticChildren *synth, lldb::ValueObjectSP valobj_sp) { 315 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); 316 if (!process_sp) 317 return nullptr; 318 ObjCLanguageRuntime *runtime = 319 (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime( 320 lldb::eLanguageTypeObjC); 321 if (!runtime) 322 return nullptr; 323 324 CompilerType valobj_type(valobj_sp->GetCompilerType()); 325 Flags flags(valobj_type.GetTypeInfo()); 326 327 if (flags.IsClear(eTypeIsPointer)) { 328 Status error; 329 valobj_sp = valobj_sp->AddressOf(error); 330 if (error.Fail() || !valobj_sp) 331 return nullptr; 332 } 333 334 ObjCLanguageRuntime::ClassDescriptorSP descriptor( 335 runtime->GetClassDescriptor(*valobj_sp)); 336 337 if (!descriptor || !descriptor->IsValid()) 338 return nullptr; 339 340 ConstString class_name_cs = descriptor->GetClassName(); 341 const char *class_name = class_name_cs.GetCString(); 342 343 if (!class_name || !*class_name) 344 return nullptr; 345 346 if (!strcmp(class_name, "__NSSetI") || 347 !strcmp(class_name, "__NSOrderedSetI")) { 348 return (new NSSetISyntheticFrontEnd(valobj_sp)); 349 } else if (!strcmp(class_name, "__NSSetM")) { 350 AppleObjCRuntime *apple_runtime = 351 llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime); 352 if (apple_runtime) { 353 if (apple_runtime->GetFoundationVersion() >= 1437) 354 return (new Foundation1437::NSSetMSyntheticFrontEnd(valobj_sp)); 355 else if (apple_runtime->GetFoundationVersion() >= 1428) 356 return (new Foundation1428::NSSetMSyntheticFrontEnd(valobj_sp)); 357 else 358 return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp)); 359 } else { 360 return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp)); 361 } 362 } else { 363 auto &map(NSSet_Additionals::GetAdditionalSynthetics()); 364 auto iter = map.find(class_name_cs), end = map.end(); 365 if (iter != end) 366 return iter->second(synth, valobj_sp); 367 return nullptr; 368 } 369 } 370 371 lldb_private::formatters::NSSetISyntheticFrontEnd::NSSetISyntheticFrontEnd( 372 lldb::ValueObjectSP valobj_sp) 373 : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), 374 m_data_32(nullptr), m_data_64(nullptr) { 375 if (valobj_sp) 376 Update(); 377 } 378 379 lldb_private::formatters::NSSetISyntheticFrontEnd::~NSSetISyntheticFrontEnd() { 380 delete m_data_32; 381 m_data_32 = nullptr; 382 delete m_data_64; 383 m_data_64 = nullptr; 384 } 385 386 size_t 387 lldb_private::formatters::NSSetISyntheticFrontEnd::GetIndexOfChildWithName( 388 const ConstString &name) { 389 const char *item_name = name.GetCString(); 390 uint32_t idx = ExtractIndexFromString(item_name); 391 if (idx < UINT32_MAX && idx >= CalculateNumChildren()) 392 return UINT32_MAX; 393 return idx; 394 } 395 396 size_t 397 lldb_private::formatters::NSSetISyntheticFrontEnd::CalculateNumChildren() { 398 if (!m_data_32 && !m_data_64) 399 return 0; 400 return (m_data_32 ? m_data_32->_used : m_data_64->_used); 401 } 402 403 bool lldb_private::formatters::NSSetISyntheticFrontEnd::Update() { 404 m_children.clear(); 405 delete m_data_32; 406 m_data_32 = nullptr; 407 delete m_data_64; 408 m_data_64 = nullptr; 409 m_ptr_size = 0; 410 ValueObjectSP valobj_sp = m_backend.GetSP(); 411 if (!valobj_sp) 412 return false; 413 if (!valobj_sp) 414 return false; 415 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); 416 Status error; 417 if (valobj_sp->IsPointerType()) { 418 valobj_sp = valobj_sp->Dereference(error); 419 if (error.Fail() || !valobj_sp) 420 return false; 421 } 422 error.Clear(); 423 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); 424 if (!process_sp) 425 return false; 426 m_ptr_size = process_sp->GetAddressByteSize(); 427 uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size; 428 if (m_ptr_size == 4) { 429 m_data_32 = new DataDescriptor_32(); 430 process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32), 431 error); 432 } else { 433 m_data_64 = new DataDescriptor_64(); 434 process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64), 435 error); 436 } 437 if (error.Fail()) 438 return false; 439 m_data_ptr = data_location + m_ptr_size; 440 return false; 441 } 442 443 bool lldb_private::formatters::NSSetISyntheticFrontEnd::MightHaveChildren() { 444 return true; 445 } 446 447 lldb::ValueObjectSP 448 lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex(size_t idx) { 449 uint32_t num_children = CalculateNumChildren(); 450 451 if (idx >= num_children) 452 return lldb::ValueObjectSP(); 453 454 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP(); 455 if (!process_sp) 456 return lldb::ValueObjectSP(); 457 458 if (m_children.empty()) { 459 // do the scan phase 460 lldb::addr_t obj_at_idx = 0; 461 462 uint32_t tries = 0; 463 uint32_t test_idx = 0; 464 465 while (tries < num_children) { 466 obj_at_idx = m_data_ptr + (test_idx * m_ptr_size); 467 if (!process_sp) 468 return lldb::ValueObjectSP(); 469 Status error; 470 obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error); 471 if (error.Fail()) 472 return lldb::ValueObjectSP(); 473 474 test_idx++; 475 476 if (!obj_at_idx) 477 continue; 478 tries++; 479 480 SetItemDescriptor descriptor = {obj_at_idx, lldb::ValueObjectSP()}; 481 482 m_children.push_back(descriptor); 483 } 484 } 485 486 if (idx >= m_children.size()) // should never happen 487 return lldb::ValueObjectSP(); 488 489 SetItemDescriptor &set_item = m_children[idx]; 490 if (!set_item.valobj_sp) { 491 auto ptr_size = process_sp->GetAddressByteSize(); 492 DataBufferHeap buffer(ptr_size, 0); 493 switch (ptr_size) { 494 case 0: // architecture has no clue?? - fail 495 return lldb::ValueObjectSP(); 496 case 4: 497 *((uint32_t *)buffer.GetBytes()) = (uint32_t)set_item.item_ptr; 498 break; 499 case 8: 500 *((uint64_t *)buffer.GetBytes()) = (uint64_t)set_item.item_ptr; 501 break; 502 default: 503 assert(false && "pointer size is not 4 nor 8 - get out of here ASAP"); 504 } 505 StreamString idx_name; 506 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); 507 508 DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(), 509 process_sp->GetByteOrder(), 510 process_sp->GetAddressByteSize()); 511 512 set_item.valobj_sp = CreateValueObjectFromData( 513 idx_name.GetString(), data, m_exe_ctx_ref, 514 m_backend.GetCompilerType().GetBasicTypeFromAST( 515 lldb::eBasicTypeObjCID)); 516 } 517 return set_item.valobj_sp; 518 } 519 520 template <typename D32, typename D64> 521 lldb_private::formatters:: 522 GenericNSSetMSyntheticFrontEnd<D32, D64>::GenericNSSetMSyntheticFrontEnd( 523 lldb::ValueObjectSP valobj_sp) 524 : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), 525 m_data_32(nullptr), m_data_64(nullptr) { 526 if (valobj_sp) 527 Update(); 528 } 529 530 template <typename D32, typename D64> 531 lldb_private::formatters:: 532 GenericNSSetMSyntheticFrontEnd<D32, D64>::~GenericNSSetMSyntheticFrontEnd() { 533 delete m_data_32; 534 m_data_32 = nullptr; 535 delete m_data_64; 536 m_data_64 = nullptr; 537 } 538 539 template <typename D32, typename D64> 540 size_t 541 lldb_private::formatters:: 542 GenericNSSetMSyntheticFrontEnd<D32, D64>::GetIndexOfChildWithName( 543 const ConstString &name) { 544 const char *item_name = name.GetCString(); 545 uint32_t idx = ExtractIndexFromString(item_name); 546 if (idx < UINT32_MAX && idx >= CalculateNumChildren()) 547 return UINT32_MAX; 548 return idx; 549 } 550 551 template <typename D32, typename D64> 552 size_t 553 lldb_private::formatters:: 554 GenericNSSetMSyntheticFrontEnd<D32, D64>::CalculateNumChildren() { 555 if (!m_data_32 && !m_data_64) 556 return 0; 557 return (m_data_32 ? m_data_32->_used : m_data_64->_used); 558 } 559 560 template <typename D32, typename D64> 561 bool 562 lldb_private::formatters:: 563 GenericNSSetMSyntheticFrontEnd<D32, D64>::Update() { 564 m_children.clear(); 565 ValueObjectSP valobj_sp = m_backend.GetSP(); 566 m_ptr_size = 0; 567 delete m_data_32; 568 m_data_32 = nullptr; 569 delete m_data_64; 570 m_data_64 = nullptr; 571 if (!valobj_sp) 572 return false; 573 if (!valobj_sp) 574 return false; 575 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); 576 Status error; 577 if (valobj_sp->IsPointerType()) { 578 valobj_sp = valobj_sp->Dereference(error); 579 if (error.Fail() || !valobj_sp) 580 return false; 581 } 582 error.Clear(); 583 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); 584 if (!process_sp) 585 return false; 586 m_ptr_size = process_sp->GetAddressByteSize(); 587 uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size; 588 if (m_ptr_size == 4) { 589 m_data_32 = new D32(); 590 process_sp->ReadMemory(data_location, m_data_32, sizeof(D32), 591 error); 592 } else { 593 m_data_64 = new D64(); 594 process_sp->ReadMemory(data_location, m_data_64, sizeof(D64), 595 error); 596 } 597 if (error.Fail()) 598 return false; 599 return false; 600 } 601 602 template <typename D32, typename D64> 603 bool 604 lldb_private::formatters:: 605 GenericNSSetMSyntheticFrontEnd<D32, D64>::MightHaveChildren() { 606 return true; 607 } 608 609 template <typename D32, typename D64> 610 lldb::ValueObjectSP 611 lldb_private::formatters:: 612 GenericNSSetMSyntheticFrontEnd<D32, D64>::GetChildAtIndex(size_t idx) { 613 lldb::addr_t m_objs_addr = 614 (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr); 615 616 uint32_t num_children = CalculateNumChildren(); 617 618 if (idx >= num_children) 619 return lldb::ValueObjectSP(); 620 621 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP(); 622 if (!process_sp) 623 return lldb::ValueObjectSP(); 624 625 if (m_children.empty()) { 626 // do the scan phase 627 lldb::addr_t obj_at_idx = 0; 628 629 uint32_t tries = 0; 630 uint32_t test_idx = 0; 631 632 while (tries < num_children) { 633 obj_at_idx = m_objs_addr + (test_idx * m_ptr_size); 634 if (!process_sp) 635 return lldb::ValueObjectSP(); 636 Status error; 637 obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error); 638 if (error.Fail()) 639 return lldb::ValueObjectSP(); 640 641 test_idx++; 642 643 if (!obj_at_idx) 644 continue; 645 tries++; 646 647 SetItemDescriptor descriptor = {obj_at_idx, lldb::ValueObjectSP()}; 648 649 m_children.push_back(descriptor); 650 } 651 } 652 653 if (idx >= m_children.size()) // should never happen 654 return lldb::ValueObjectSP(); 655 656 SetItemDescriptor &set_item = m_children[idx]; 657 if (!set_item.valobj_sp) { 658 auto ptr_size = process_sp->GetAddressByteSize(); 659 DataBufferHeap buffer(ptr_size, 0); 660 switch (ptr_size) { 661 case 0: // architecture has no clue?? - fail 662 return lldb::ValueObjectSP(); 663 case 4: 664 *((uint32_t *)buffer.GetBytes()) = (uint32_t)set_item.item_ptr; 665 break; 666 case 8: 667 *((uint64_t *)buffer.GetBytes()) = (uint64_t)set_item.item_ptr; 668 break; 669 default: 670 assert(false && "pointer size is not 4 nor 8 - get out of here ASAP"); 671 } 672 StreamString idx_name; 673 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); 674 675 DataExtractor data(buffer.GetBytes(), buffer.GetByteSize(), 676 process_sp->GetByteOrder(), 677 process_sp->GetAddressByteSize()); 678 679 set_item.valobj_sp = CreateValueObjectFromData( 680 idx_name.GetString(), data, m_exe_ctx_ref, 681 m_backend.GetCompilerType().GetBasicTypeFromAST( 682 lldb::eBasicTypeObjCID)); 683 } 684 return set_item.valobj_sp; 685 } 686 687 template bool lldb_private::formatters::NSSetSummaryProvider<true>( 688 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); 689 690 template bool lldb_private::formatters::NSSetSummaryProvider<false>( 691 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); 692