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