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