NSSet.cpp revision 292932
1362679Sdim//===-- NSSet.cpp -----------------------------------------------*- C++ -*-===// 2362679Sdim// 3362679Sdim// The LLVM Compiler Infrastructure 4362679Sdim// 5362679Sdim// This file is distributed under the University of Illinois Open Source 6362679Sdim// License. See LICENSE.TXT for details. 7362679Sdim// 8362679Sdim//===----------------------------------------------------------------------===// 9362679Sdim 10362679Sdim// C Includes 11362679Sdim// C++ Includes 12362679Sdim// Other libraries and framework includes 13362679Sdim// Project includes 14362679Sdim#include "NSSet.h" 15362679Sdim 16362679Sdim#include "lldb/Core/DataBufferHeap.h" 17362679Sdim#include "lldb/Core/Error.h" 18362679Sdim#include "lldb/Core/Stream.h" 19362679Sdim#include "lldb/Core/ValueObject.h" 20362679Sdim#include "lldb/Core/ValueObjectConstResult.h" 21362679Sdim#include "lldb/DataFormatters/FormattersHelpers.h" 22362679Sdim#include "lldb/Host/Endian.h" 23362679Sdim#include "lldb/Symbol/ClangASTContext.h" 24362679Sdim#include "lldb/Target/Language.h" 25362679Sdim#include "lldb/Target/ObjCLanguageRuntime.h" 26362679Sdim#include "lldb/Target/Target.h" 27362679Sdim 28362679Sdimusing namespace lldb; 29362679Sdimusing namespace lldb_private; 30362679Sdimusing namespace lldb_private::formatters; 31362679Sdim 32362679Sdimstd::map<ConstString, CXXFunctionSummaryFormat::Callback>& 33362679SdimNSSet_Additionals::GetAdditionalSummaries () 34362679Sdim{ 35362679Sdim static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map; 36362679Sdim return g_map; 37362679Sdim} 38362679Sdim 39362679Sdimstd::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>& 40362679SdimNSSet_Additionals::GetAdditionalSynthetics () 41362679Sdim{ 42362679Sdim static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> g_map; 43362679Sdim return g_map; 44362679Sdim} 45362679Sdim 46362679Sdimnamespace lldb_private { 47362679Sdim namespace formatters { 48362679Sdim class NSSetISyntheticFrontEnd : public SyntheticChildrenFrontEnd 49362679Sdim { 50362679Sdim public: 51362679Sdim NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); 52362679Sdim 53362679Sdim ~NSSetISyntheticFrontEnd() override; 54362679Sdim 55362679Sdim size_t 56362679Sdim CalculateNumChildren() override; 57362679Sdim 58362679Sdim lldb::ValueObjectSP 59362679Sdim GetChildAtIndex(size_t idx) override; 60362679Sdim 61362679Sdim bool 62362679Sdim Update() override; 63362679Sdim 64362679Sdim bool 65362679Sdim MightHaveChildren() override; 66362679Sdim 67362679Sdim size_t 68362679Sdim GetIndexOfChildWithName(const ConstString &name) override; 69362679Sdim 70362679Sdim private: 71362679Sdim struct DataDescriptor_32 72362679Sdim { 73362679Sdim uint32_t _used : 26; 74362679Sdim uint32_t _szidx : 6; 75362679Sdim }; 76362679Sdim 77362679Sdim struct DataDescriptor_64 78362679Sdim { 79362679Sdim uint64_t _used : 58; 80362679Sdim uint32_t _szidx : 6; 81362679Sdim }; 82362679Sdim 83362679Sdim struct SetItemDescriptor 84362679Sdim { 85362679Sdim lldb::addr_t item_ptr; 86362679Sdim lldb::ValueObjectSP valobj_sp; 87362679Sdim }; 88362679Sdim 89362679Sdim ExecutionContextRef m_exe_ctx_ref; 90362679Sdim uint8_t m_ptr_size; 91362679Sdim DataDescriptor_32 *m_data_32; 92362679Sdim DataDescriptor_64 *m_data_64; 93362679Sdim lldb::addr_t m_data_ptr; 94362679Sdim std::vector<SetItemDescriptor> m_children; 95362679Sdim }; 96362679Sdim 97362679Sdim class NSOrderedSetSyntheticFrontEnd : public SyntheticChildrenFrontEnd 98362679Sdim { 99362679Sdim public: 100362679Sdim NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); 101362679Sdim 102362679Sdim ~NSOrderedSetSyntheticFrontEnd() override = default; 103362679Sdim 104362679Sdim size_t 105362679Sdim CalculateNumChildren() override; 106362679Sdim 107362679Sdim lldb::ValueObjectSP 108362679Sdim GetChildAtIndex(size_t idx) override; 109362679Sdim 110362679Sdim bool 111362679Sdim Update() override; 112362679Sdim 113362679Sdim bool 114362679Sdim MightHaveChildren() override; 115362679Sdim 116362679Sdim size_t 117362679Sdim 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 201template<bool cf_style> 202bool 203lldb_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 303SyntheticChildrenFrontEnd* 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 356lldb_private::formatters::NSSetISyntheticFrontEnd::NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : 357SyntheticChildrenFrontEnd(*valobj_sp.get()), 358m_exe_ctx_ref(), 359m_ptr_size(8), 360m_data_32(NULL), 361m_data_64(NULL) 362{ 363 if (valobj_sp) 364 Update(); 365} 366 367lldb_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 375size_t 376lldb_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 385size_t 386lldb_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 393bool 394lldb_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 437bool 438lldb_private::formatters::NSSetISyntheticFrontEnd::MightHaveChildren () 439{ 440 return true; 441} 442 443lldb::ValueObjectSP 444lldb_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 523lldb_private::formatters::NSSetMSyntheticFrontEnd::NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : 524SyntheticChildrenFrontEnd(*valobj_sp.get()), 525m_exe_ctx_ref(), 526m_ptr_size(8), 527m_data_32(NULL), 528m_data_64(NULL) 529{ 530 if (valobj_sp) 531 Update (); 532} 533 534lldb_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 542size_t 543lldb_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 552size_t 553lldb_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 560bool 561lldb_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 603bool 604lldb_private::formatters::NSSetMSyntheticFrontEnd::MightHaveChildren () 605{ 606 return true; 607} 608 609lldb::ValueObjectSP 610lldb_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 691lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : 692SyntheticChildrenFrontEnd(*valobj_sp.get()), 693m_count(UINT32_MAX), 694m_children() 695{} 696 697size_t 698lldb_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 708lldb::ValueObjectSP 709lldb_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 732bool 733lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::Update() 734{ 735 return false; 736} 737 738bool 739lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::MightHaveChildren () 740{ 741 return true; 742} 743 744size_t 745lldb_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 754template bool 755lldb_private::formatters::NSSetSummaryProvider<true> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); 756 757template bool 758lldb_private::formatters::NSSetSummaryProvider<false> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); 759