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