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