blob: 77e33490ced73153970774cf6f1b5b0ef26b7def [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 Granataf615b802013-02-15 23:38:37 +000010#include "lldb/DataFormatters/CXXFormatterFunctions.h"
11
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"
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
22using namespace lldb;
23using namespace lldb_private;
24using namespace lldb_private::formatters;
25
Enrico Granata6714a0f2014-10-22 21:47:27 +000026namespace 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
Enrico Granataf615b802013-02-15 23:38:37 +0000182template<bool cf_style>
183bool
Enrico Granataf35bc632014-11-06 21:55:30 +0000184lldb_private::formatters::NSSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
Enrico Granataf615b802013-02-15 23:38:37 +0000185{
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 }
Enrico Granataea9f9e82013-07-15 23:17:32 +0000231 /*else if (!strcmp(class_name,"__NSCFSet"))
Enrico Granataf615b802013-02-15 23:38:37 +0000232 {
233 Error error;
Enrico Granataf68f7322013-03-15 18:44:08 +0000234 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error);
Enrico Granataf615b802013-02-15 23:38:37 +0000235 if (error.Fail())
236 return false;
237 if (is_64bit)
238 value &= ~0x1fff000000000000UL;
239 }
Enrico Granataea9f9e82013-07-15 23:17:32 +0000240 else if (!strcmp(class_name,"NSCountedSet"))
Enrico Granataf615b802013-02-15 23:38:37 +0000241 {
242 Error error;
243 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
244 if (error.Fail())
245 return false;
Enrico Granataf68f7322013-03-15 18:44:08 +0000246 value = process_sp->ReadUnsignedIntegerFromMemory(value + (is_64bit ? 20 : 12), 4, 0, error);
Enrico Granataf615b802013-02-15 23:38:37 +0000247 if (error.Fail())
248 return false;
249 if (is_64bit)
250 value &= ~0x1fff000000000000UL;
Enrico Granataf68f7322013-03-15 18:44:08 +0000251 }*/
Enrico Granataf615b802013-02-15 23:38:37 +0000252 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
Enrico Granata9f02e092013-02-18 23:16:23 +0000266SyntheticChildrenFrontEnd* 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 }
Enrico Granatacd67f972013-04-27 00:27:20 +0000301 else if ((!strcmp(class_name,"__NSOrderedSetI")) || (!strcmp(class_name,"__NSOrderedSetM")))
302 {
303 return new NSOrderedSetSyntheticFrontEnd(valobj_sp); // this runs code
304 }
Enrico Granata9f02e092013-02-18 23:16:23 +0000305 else
306 {
307 return /*(new NSSetCodeRunningSyntheticFrontEnd(valobj_sp))*/ NULL;
308 }
309}
310
311lldb_private::formatters::NSSetISyntheticFrontEnd::NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
312SyntheticChildrenFrontEnd(*valobj_sp.get()),
313m_exe_ctx_ref(),
314m_ptr_size(8),
315m_data_32(NULL),
316m_data_64(NULL)
317{
318 if (valobj_sp)
319 Update();
320}
321
322lldb_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
330size_t
331lldb_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
340size_t
341lldb_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
348bool
349lldb_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;
Enrico Granata9f02e092013-02-18 23:16:23 +0000360 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
392bool
393lldb_private::formatters::NSSetISyntheticFrontEnd::MightHaveChildren ()
394{
395 return true;
396}
397
398lldb::ValueObjectSP
399lldb_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
Enrico Granata5383e812013-11-21 01:08:05 +0000406 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
407 if (!process_sp)
408 return lldb::ValueObjectSP();
409
Enrico Granata9f02e092013-02-18 23:16:23 +0000410 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);
Enrico Granata9f02e092013-02-18 23:16:23 +0000421 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 {
Enrico Granata5383e812013-11-21 01:08:05 +0000446 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 }
Enrico Granata9f02e092013-02-18 23:16:23 +0000461 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000462 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granata5383e812013-11-21 01:08:05 +0000463
464 DataExtractor data(buffer.GetBytes(),
465 buffer.GetByteSize(),
466 process_sp->GetByteOrder(),
467 process_sp->GetAddressByteSize());
468
469 set_item.valobj_sp =
Enrico Granatae29df232014-12-09 19:51:20 +0000470 CreateValueObjectFromData(idx_name.GetData(),
471 data,
472 m_exe_ctx_ref,
Greg Clayton99558cc42015-08-24 23:46:31 +0000473 m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID));
Enrico Granata9f02e092013-02-18 23:16:23 +0000474 }
475 return set_item.valobj_sp;
476}
477
478lldb_private::formatters::NSSetMSyntheticFrontEnd::NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
479SyntheticChildrenFrontEnd(*valobj_sp.get()),
480m_exe_ctx_ref(),
481m_ptr_size(8),
482m_data_32(NULL),
483m_data_64(NULL)
484{
485 if (valobj_sp)
486 Update ();
487}
488
489lldb_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
497size_t
498lldb_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
507size_t
508lldb_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
515bool
516lldb_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;
Enrico Granata9f02e092013-02-18 23:16:23 +0000527 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
558bool
559lldb_private::formatters::NSSetMSyntheticFrontEnd::MightHaveChildren ()
560{
561 return true;
562}
563
564lldb::ValueObjectSP
565lldb_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
Enrico Granata5383e812013-11-21 01:08:05 +0000574 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
575 if (!process_sp)
576 return lldb::ValueObjectSP();
577
Enrico Granata9f02e092013-02-18 23:16:23 +0000578 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);
Enrico Granata9f02e092013-02-18 23:16:23 +0000589 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 {
Enrico Granata5383e812013-11-21 01:08:05 +0000614 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 }
Enrico Granata9f02e092013-02-18 23:16:23 +0000629 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000630 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granata5383e812013-11-21 01:08:05 +0000631
632 DataExtractor data(buffer.GetBytes(),
633 buffer.GetByteSize(),
634 process_sp->GetByteOrder(),
635 process_sp->GetAddressByteSize());
636
637 set_item.valobj_sp =
Enrico Granatae29df232014-12-09 19:51:20 +0000638 CreateValueObjectFromData(idx_name.GetData(),
639 data,
640 m_exe_ctx_ref,
Greg Clayton99558cc42015-08-24 23:46:31 +0000641 m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID));
Enrico Granata9f02e092013-02-18 23:16:23 +0000642 }
643 return set_item.valobj_sp;
644}
645
Enrico Granatacd67f972013-04-27 00:27:20 +0000646lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
647SyntheticChildrenFrontEnd(*valobj_sp.get()),
648m_count(UINT32_MAX),
649m_children()
650{}
651
652size_t
653lldb_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
663lldb::ValueObjectSP
664lldb_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;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000676 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granatacd67f972013-04-27 00:27:20 +0000677 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
687bool
688lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::Update()
689{
690 return false;
691}
692
693bool
694lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::MightHaveChildren ()
695{
696 return true;
697}
698
699size_t
700lldb_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
709lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::~NSOrderedSetSyntheticFrontEnd ()
710{
711}
712
Enrico Granataf615b802013-02-15 23:38:37 +0000713template bool
Enrico Granataf35bc632014-11-06 21:55:30 +0000714lldb_private::formatters::NSSetSummaryProvider<true> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
Enrico Granataf615b802013-02-15 23:38:37 +0000715
716template bool
Enrico Granataf35bc632014-11-06 21:55:30 +0000717lldb_private::formatters::NSSetSummaryProvider<false> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);