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