blob: 602db12faea5e879265958bb44b873f5dfd8531d [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 Granata7de855c2015-10-02 20:59:58 +000010#include "NSSet.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"
Enrico Granata675f49b2015-10-07 18:36:53 +000020#include "lldb/Target/Language.h"
Enrico Granataf615b802013-02-15 23:38:37 +000021#include "lldb/Target/ObjCLanguageRuntime.h"
22#include "lldb/Target/Target.h"
23
24using namespace lldb;
25using namespace lldb_private;
26using namespace lldb_private::formatters;
27
Enrico Granata7de855c2015-10-02 20:59:58 +000028std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
29NSSet_Additionals::GetAdditionalSummaries ()
30{
31 static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
32 return g_map;
33}
34
35std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
36NSSet_Additionals::GetAdditionalSynthetics ()
37{
38 static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> g_map;
39 return g_map;
40}
41
Enrico Granata6714a0f2014-10-22 21:47:27 +000042namespace lldb_private {
43 namespace formatters {
44 class NSSetISyntheticFrontEnd : public SyntheticChildrenFrontEnd
45 {
46 private:
47 struct DataDescriptor_32
48 {
49 uint32_t _used : 26;
50 uint32_t _szidx : 6;
51 };
52 struct DataDescriptor_64
53 {
54 uint64_t _used : 58;
55 uint32_t _szidx : 6;
56 };
57
58 struct SetItemDescriptor
59 {
60 lldb::addr_t item_ptr;
61 lldb::ValueObjectSP valobj_sp;
62 };
63
64 public:
65 NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
66
67 virtual size_t
68 CalculateNumChildren ();
69
70 virtual lldb::ValueObjectSP
71 GetChildAtIndex (size_t idx);
72
73 virtual bool
74 Update();
75
76 virtual bool
77 MightHaveChildren ();
78
79 virtual size_t
80 GetIndexOfChildWithName (const ConstString &name);
81
82 virtual
83 ~NSSetISyntheticFrontEnd ();
84 private:
85 ExecutionContextRef m_exe_ctx_ref;
86 uint8_t m_ptr_size;
87 DataDescriptor_32 *m_data_32;
88 DataDescriptor_64 *m_data_64;
89 lldb::addr_t m_data_ptr;
90 std::vector<SetItemDescriptor> m_children;
91 };
92
93 class NSOrderedSetSyntheticFrontEnd : public SyntheticChildrenFrontEnd
94 {
95 private:
96
97 public:
98 NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
99
100 virtual size_t
101 CalculateNumChildren ();
102
103 virtual lldb::ValueObjectSP
104 GetChildAtIndex (size_t idx);
105
106 virtual bool
107 Update();
108
109 virtual bool
110 MightHaveChildren ();
111
112 virtual size_t
113 GetIndexOfChildWithName (const ConstString &name);
114
115 virtual
116 ~NSOrderedSetSyntheticFrontEnd ();
117 private:
118 uint32_t m_count;
119 std::map<uint32_t,lldb::ValueObjectSP> m_children;
120 };
121
122 class NSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
123 {
124 private:
125 struct DataDescriptor_32
126 {
127 uint32_t _used : 26;
128 uint32_t _size;
129 uint32_t _mutations;
130 uint32_t _objs_addr;
131 };
132 struct DataDescriptor_64
133 {
134 uint64_t _used : 58;
135 uint64_t _size;
136 uint64_t _mutations;
137 uint64_t _objs_addr;
138 };
139 struct SetItemDescriptor
140 {
141 lldb::addr_t item_ptr;
142 lldb::ValueObjectSP valobj_sp;
143 };
144 public:
145 NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
146
147 virtual size_t
148 CalculateNumChildren ();
149
150 virtual lldb::ValueObjectSP
151 GetChildAtIndex (size_t idx);
152
153 virtual bool
154 Update();
155
156 virtual bool
157 MightHaveChildren ();
158
159 virtual size_t
160 GetIndexOfChildWithName (const ConstString &name);
161
162 virtual
163 ~NSSetMSyntheticFrontEnd ();
164 private:
165 ExecutionContextRef m_exe_ctx_ref;
166 uint8_t m_ptr_size;
167 DataDescriptor_32 *m_data_32;
168 DataDescriptor_64 *m_data_64;
169 std::vector<SetItemDescriptor> m_children;
170 };
171
172 class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
173 {
174 public:
175 NSSetCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
176
177 virtual size_t
178 CalculateNumChildren ();
179
180 virtual lldb::ValueObjectSP
181 GetChildAtIndex (size_t idx);
182
183 virtual bool
184 Update();
185
186 virtual bool
187 MightHaveChildren ();
188
189 virtual size_t
190 GetIndexOfChildWithName (const ConstString &name);
191
192 virtual
193 ~NSSetCodeRunningSyntheticFrontEnd ();
194 };
195 }
196}
197
Enrico Granataf615b802013-02-15 23:38:37 +0000198template<bool cf_style>
199bool
Enrico Granataf35bc632014-11-06 21:55:30 +0000200lldb_private::formatters::NSSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
Enrico Granataf615b802013-02-15 23:38:37 +0000201{
Enrico Granata675f49b2015-10-07 18:36:53 +0000202 static ConstString g_TypeHint("NSSet");
203
Enrico Granataf615b802013-02-15 23:38:37 +0000204 ProcessSP process_sp = valobj.GetProcessSP();
205 if (!process_sp)
206 return false;
207
208 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
209
210 if (!runtime)
211 return false;
212
213 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
214
215 if (!descriptor.get() || !descriptor->IsValid())
216 return false;
217
218 uint32_t ptr_size = process_sp->GetAddressByteSize();
219 bool is_64bit = (ptr_size == 8);
220
221 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
222
223 if (!valobj_addr)
224 return false;
225
226 uint64_t value = 0;
227
Enrico Granata7de855c2015-10-02 20:59:58 +0000228 ConstString class_name_cs = descriptor->GetClassName();
229 const char* class_name = class_name_cs.GetCString();
Enrico Granataf615b802013-02-15 23:38:37 +0000230
231 if (!class_name || !*class_name)
232 return false;
233
234 if (!strcmp(class_name,"__NSSetI"))
235 {
236 Error error;
237 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
238 if (error.Fail())
239 return false;
240 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
241 }
242 else if (!strcmp(class_name,"__NSSetM"))
243 {
244 Error error;
245 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
246 if (error.Fail())
247 return false;
248 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
249 }
Enrico Granataea9f9e82013-07-15 23:17:32 +0000250 /*else if (!strcmp(class_name,"__NSCFSet"))
Enrico Granata675f49b2015-10-07 18:36:53 +0000251 {
252 Error error;
253 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error);
254 if (error.Fail())
255 return false;
256 if (is_64bit)
257 value &= ~0x1fff000000000000UL;
258 }
259 else if (!strcmp(class_name,"NSCountedSet"))
260 {
261 Error error;
262 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
263 if (error.Fail())
264 return false;
265 value = process_sp->ReadUnsignedIntegerFromMemory(value + (is_64bit ? 20 : 12), 4, 0, error);
266 if (error.Fail())
267 return false;
268 if (is_64bit)
269 value &= ~0x1fff000000000000UL;
270 }*/
Enrico Granataf615b802013-02-15 23:38:37 +0000271 else
272 {
Enrico Granata7de855c2015-10-02 20:59:58 +0000273 auto& map(NSSet_Additionals::GetAdditionalSummaries());
274 auto iter = map.find(class_name_cs), end = map.end();
275 if (iter != end)
276 return iter->second(valobj, stream, options);
Enrico Granataf615b802013-02-15 23:38:37 +0000277 if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
278 return false;
279 }
280
Enrico Granata675f49b2015-10-07 18:36:53 +0000281 std::string prefix,suffix;
282 if (Language* language = Language::FindPlugin(options.GetLanguage()))
283 {
284 if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
285 {
286 prefix.clear();
287 suffix.clear();
288 }
289 }
290
291 stream.Printf("%s%" PRIu64 " %s%s%s",
292 prefix.c_str(),
Enrico Granataf615b802013-02-15 23:38:37 +0000293 value,
Enrico Granata675f49b2015-10-07 18:36:53 +0000294 "element",
295 value == 1 ? "" : "s",
296 suffix.c_str());
Enrico Granataf615b802013-02-15 23:38:37 +0000297 return true;
298}
299
Enrico Granata7de855c2015-10-02 20:59:58 +0000300SyntheticChildrenFrontEnd* lldb_private::formatters::NSSetSyntheticFrontEndCreator (CXXSyntheticChildren* synth, lldb::ValueObjectSP valobj_sp)
Enrico Granata9f02e092013-02-18 23:16:23 +0000301{
302 lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
303 if (!process_sp)
304 return NULL;
305 ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
306 if (!runtime)
307 return NULL;
308
Enrico Granata675f49b2015-10-07 18:36:53 +0000309 CompilerType valobj_type(valobj_sp->GetCompilerType());
310 Flags flags(valobj_type.GetTypeInfo());
311
312 if (flags.IsClear(eTypeIsPointer))
Enrico Granata9f02e092013-02-18 23:16:23 +0000313 {
314 Error error;
315 valobj_sp = valobj_sp->AddressOf(error);
316 if (error.Fail() || !valobj_sp)
317 return NULL;
318 }
319
320 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
321
322 if (!descriptor.get() || !descriptor->IsValid())
323 return NULL;
324
Enrico Granata7de855c2015-10-02 20:59:58 +0000325 ConstString class_name_cs = descriptor->GetClassName();
326 const char* class_name = class_name_cs.GetCString();
Enrico Granata9f02e092013-02-18 23:16:23 +0000327
328 if (!class_name || !*class_name)
329 return NULL;
330
331 if (!strcmp(class_name,"__NSSetI"))
332 {
333 return (new NSSetISyntheticFrontEnd(valobj_sp));
334 }
335 else if (!strcmp(class_name,"__NSSetM"))
336 {
337 return (new NSSetMSyntheticFrontEnd(valobj_sp));
338 }
Enrico Granatacd67f972013-04-27 00:27:20 +0000339 else if ((!strcmp(class_name,"__NSOrderedSetI")) || (!strcmp(class_name,"__NSOrderedSetM")))
340 {
341 return new NSOrderedSetSyntheticFrontEnd(valobj_sp); // this runs code
342 }
Enrico Granata9f02e092013-02-18 23:16:23 +0000343 else
344 {
Enrico Granata7de855c2015-10-02 20:59:58 +0000345 auto& map(NSSet_Additionals::GetAdditionalSynthetics());
346 auto iter = map.find(class_name_cs), end = map.end();
347 if (iter != end)
348 return iter->second(synth, valobj_sp);
Enrico Granata9f02e092013-02-18 23:16:23 +0000349 return /*(new NSSetCodeRunningSyntheticFrontEnd(valobj_sp))*/ NULL;
350 }
351}
352
353lldb_private::formatters::NSSetISyntheticFrontEnd::NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
354SyntheticChildrenFrontEnd(*valobj_sp.get()),
355m_exe_ctx_ref(),
356m_ptr_size(8),
357m_data_32(NULL),
358m_data_64(NULL)
359{
360 if (valobj_sp)
361 Update();
362}
363
364lldb_private::formatters::NSSetISyntheticFrontEnd::~NSSetISyntheticFrontEnd ()
365{
366 delete m_data_32;
367 m_data_32 = NULL;
368 delete m_data_64;
369 m_data_64 = NULL;
370}
371
372size_t
373lldb_private::formatters::NSSetISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
374{
375 const char* item_name = name.GetCString();
376 uint32_t idx = ExtractIndexFromString(item_name);
377 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
378 return UINT32_MAX;
379 return idx;
380}
381
382size_t
383lldb_private::formatters::NSSetISyntheticFrontEnd::CalculateNumChildren ()
384{
385 if (!m_data_32 && !m_data_64)
386 return 0;
387 return (m_data_32 ? m_data_32->_used : m_data_64->_used);
388}
389
390bool
391lldb_private::formatters::NSSetISyntheticFrontEnd::Update()
392{
393 m_children.clear();
394 delete m_data_32;
395 m_data_32 = NULL;
396 delete m_data_64;
397 m_data_64 = NULL;
398 m_ptr_size = 0;
399 ValueObjectSP valobj_sp = m_backend.GetSP();
400 if (!valobj_sp)
401 return false;
Enrico Granata9f02e092013-02-18 23:16:23 +0000402 if (!valobj_sp)
403 return false;
404 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
405 Error error;
406 if (valobj_sp->IsPointerType())
407 {
408 valobj_sp = valobj_sp->Dereference(error);
409 if (error.Fail() || !valobj_sp)
410 return false;
411 }
412 error.Clear();
413 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
414 if (!process_sp)
415 return false;
416 m_ptr_size = process_sp->GetAddressByteSize();
417 uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
418 if (m_ptr_size == 4)
419 {
420 m_data_32 = new DataDescriptor_32();
421 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
422 }
423 else
424 {
425 m_data_64 = new DataDescriptor_64();
426 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
427 }
428 if (error.Fail())
429 return false;
430 m_data_ptr = data_location + m_ptr_size;
431 return false;
432}
433
434bool
435lldb_private::formatters::NSSetISyntheticFrontEnd::MightHaveChildren ()
436{
437 return true;
438}
439
440lldb::ValueObjectSP
441lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex (size_t idx)
442{
443 uint32_t num_children = CalculateNumChildren();
444
445 if (idx >= num_children)
446 return lldb::ValueObjectSP();
447
Enrico Granata5383e812013-11-21 01:08:05 +0000448 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
449 if (!process_sp)
450 return lldb::ValueObjectSP();
451
Enrico Granata9f02e092013-02-18 23:16:23 +0000452 if (m_children.empty())
453 {
454 // do the scan phase
455 lldb::addr_t obj_at_idx = 0;
456
457 uint32_t tries = 0;
458 uint32_t test_idx = 0;
459
460 while(tries < num_children)
461 {
462 obj_at_idx = m_data_ptr + (test_idx * m_ptr_size);
Enrico Granata9f02e092013-02-18 23:16:23 +0000463 if (!process_sp)
464 return lldb::ValueObjectSP();
465 Error error;
466 obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
467 if (error.Fail())
468 return lldb::ValueObjectSP();
469
470 test_idx++;
471
472 if (!obj_at_idx)
473 continue;
474 tries++;
475
476 SetItemDescriptor descriptor = {obj_at_idx,lldb::ValueObjectSP()};
477
478 m_children.push_back(descriptor);
479 }
480 }
481
482 if (idx >= m_children.size()) // should never happen
483 return lldb::ValueObjectSP();
484
485 SetItemDescriptor &set_item = m_children[idx];
486 if (!set_item.valobj_sp)
487 {
Enrico Granata5383e812013-11-21 01:08:05 +0000488 auto ptr_size = process_sp->GetAddressByteSize();
489 DataBufferHeap buffer(ptr_size,0);
490 switch (ptr_size)
491 {
492 case 0: // architecture has no clue?? - fail
493 return lldb::ValueObjectSP();
494 case 4:
495 *((uint32_t*)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
496 break;
497 case 8:
498 *((uint64_t*)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
499 break;
500 default:
501 assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
502 }
Enrico Granata9f02e092013-02-18 23:16:23 +0000503 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000504 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granata5383e812013-11-21 01:08:05 +0000505
506 DataExtractor data(buffer.GetBytes(),
507 buffer.GetByteSize(),
508 process_sp->GetByteOrder(),
509 process_sp->GetAddressByteSize());
510
511 set_item.valobj_sp =
Enrico Granata675f49b2015-10-07 18:36:53 +0000512 CreateValueObjectFromData(idx_name.GetData(),
513 data,
514 m_exe_ctx_ref,
515 m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID));
Enrico Granata9f02e092013-02-18 23:16:23 +0000516 }
517 return set_item.valobj_sp;
518}
519
520lldb_private::formatters::NSSetMSyntheticFrontEnd::NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
521SyntheticChildrenFrontEnd(*valobj_sp.get()),
522m_exe_ctx_ref(),
523m_ptr_size(8),
524m_data_32(NULL),
525m_data_64(NULL)
526{
527 if (valobj_sp)
528 Update ();
529}
530
531lldb_private::formatters::NSSetMSyntheticFrontEnd::~NSSetMSyntheticFrontEnd ()
532{
533 delete m_data_32;
534 m_data_32 = NULL;
535 delete m_data_64;
536 m_data_64 = NULL;
537}
538
539size_t
540lldb_private::formatters::NSSetMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
541{
542 const char* item_name = name.GetCString();
543 uint32_t idx = ExtractIndexFromString(item_name);
544 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
545 return UINT32_MAX;
546 return idx;
547}
548
549size_t
550lldb_private::formatters::NSSetMSyntheticFrontEnd::CalculateNumChildren ()
551{
552 if (!m_data_32 && !m_data_64)
553 return 0;
554 return (m_data_32 ? m_data_32->_used : m_data_64->_used);
555}
556
557bool
558lldb_private::formatters::NSSetMSyntheticFrontEnd::Update()
559{
560 m_children.clear();
561 ValueObjectSP valobj_sp = m_backend.GetSP();
562 m_ptr_size = 0;
563 delete m_data_32;
564 m_data_32 = NULL;
565 delete m_data_64;
566 m_data_64 = NULL;
567 if (!valobj_sp)
568 return false;
Enrico Granata9f02e092013-02-18 23:16:23 +0000569 if (!valobj_sp)
570 return false;
571 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
572 Error error;
573 if (valobj_sp->IsPointerType())
574 {
575 valobj_sp = valobj_sp->Dereference(error);
576 if (error.Fail() || !valobj_sp)
577 return false;
578 }
579 error.Clear();
580 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
581 if (!process_sp)
582 return false;
583 m_ptr_size = process_sp->GetAddressByteSize();
584 uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
585 if (m_ptr_size == 4)
586 {
587 m_data_32 = new DataDescriptor_32();
588 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
589 }
590 else
591 {
592 m_data_64 = new DataDescriptor_64();
593 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
594 }
595 if (error.Fail())
596 return false;
597 return false;
598}
599
600bool
601lldb_private::formatters::NSSetMSyntheticFrontEnd::MightHaveChildren ()
602{
603 return true;
604}
605
606lldb::ValueObjectSP
607lldb_private::formatters::NSSetMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
608{
609 lldb::addr_t m_objs_addr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
Enrico Granata675f49b2015-10-07 18:36:53 +0000610
Enrico Granata9f02e092013-02-18 23:16:23 +0000611 uint32_t num_children = CalculateNumChildren();
612
613 if (idx >= num_children)
614 return lldb::ValueObjectSP();
615
Enrico Granata5383e812013-11-21 01:08:05 +0000616 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
617 if (!process_sp)
618 return lldb::ValueObjectSP();
619
Enrico Granata9f02e092013-02-18 23:16:23 +0000620 if (m_children.empty())
621 {
622 // do the scan phase
623 lldb::addr_t obj_at_idx = 0;
624
625 uint32_t tries = 0;
626 uint32_t test_idx = 0;
627
628 while(tries < num_children)
629 {
630 obj_at_idx = m_objs_addr + (test_idx * m_ptr_size);
Enrico Granata9f02e092013-02-18 23:16:23 +0000631 if (!process_sp)
632 return lldb::ValueObjectSP();
633 Error error;
634 obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
635 if (error.Fail())
636 return lldb::ValueObjectSP();
637
638 test_idx++;
639
640 if (!obj_at_idx)
641 continue;
642 tries++;
643
644 SetItemDescriptor descriptor = {obj_at_idx,lldb::ValueObjectSP()};
645
646 m_children.push_back(descriptor);
647 }
648 }
649
650 if (idx >= m_children.size()) // should never happen
651 return lldb::ValueObjectSP();
652
653 SetItemDescriptor &set_item = m_children[idx];
654 if (!set_item.valobj_sp)
655 {
Enrico Granata5383e812013-11-21 01:08:05 +0000656 auto ptr_size = process_sp->GetAddressByteSize();
657 DataBufferHeap buffer(ptr_size,0);
658 switch (ptr_size)
659 {
660 case 0: // architecture has no clue?? - fail
661 return lldb::ValueObjectSP();
662 case 4:
663 *((uint32_t*)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
664 break;
665 case 8:
666 *((uint64_t*)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
667 break;
668 default:
669 assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
670 }
Enrico Granata9f02e092013-02-18 23:16:23 +0000671 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000672 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granata5383e812013-11-21 01:08:05 +0000673
674 DataExtractor data(buffer.GetBytes(),
675 buffer.GetByteSize(),
676 process_sp->GetByteOrder(),
677 process_sp->GetAddressByteSize());
678
679 set_item.valobj_sp =
Enrico Granata675f49b2015-10-07 18:36:53 +0000680 CreateValueObjectFromData(idx_name.GetData(),
681 data,
682 m_exe_ctx_ref,
683 m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID));
Enrico Granata9f02e092013-02-18 23:16:23 +0000684 }
685 return set_item.valobj_sp;
686}
687
Enrico Granatacd67f972013-04-27 00:27:20 +0000688lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
689SyntheticChildrenFrontEnd(*valobj_sp.get()),
690m_count(UINT32_MAX),
691m_children()
692{}
693
694size_t
695lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::CalculateNumChildren ()
696{
697 if (m_count != UINT32_MAX)
698 return m_count;
699 uint64_t count_temp;
700 if (ExtractValueFromObjCExpression(m_backend,"unsigned int","count",count_temp))
701 return (m_count = count_temp);
702 return (m_count = 0);
703}
704
705lldb::ValueObjectSP
706lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::GetChildAtIndex (size_t idx)
707{
708 auto iter = m_children.find(idx);
709 if (iter == m_children.end())
710 {
711 lldb::ValueObjectSP retval_sp;
712 if (idx <= m_count)
713 {
714 retval_sp = CallSelectorOnObject(m_backend, "id", "objectAtIndex", idx);
715 if (retval_sp)
716 {
717 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000718 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granatacd67f972013-04-27 00:27:20 +0000719 retval_sp->SetName(ConstString(idx_name.GetData()));
720 }
721 m_children[idx] = retval_sp;
722 }
723 return retval_sp;
724 }
725 else
726 return iter->second;
727}
728
729bool
730lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::Update()
731{
732 return false;
733}
734
735bool
736lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::MightHaveChildren ()
737{
738 return true;
739}
740
741size_t
742lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
743{
744 const char* item_name = name.GetCString();
745 uint32_t idx = ExtractIndexFromString(item_name);
746 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
747 return UINT32_MAX;
748 return idx;
749}
750
751lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::~NSOrderedSetSyntheticFrontEnd ()
752{
753}
754
Enrico Granataf615b802013-02-15 23:38:37 +0000755template bool
Enrico Granataf35bc632014-11-06 21:55:30 +0000756lldb_private::formatters::NSSetSummaryProvider<true> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
Enrico Granataf615b802013-02-15 23:38:37 +0000757
758template bool
Enrico Granataf35bc632014-11-06 21:55:30 +0000759lldb_private::formatters::NSSetSummaryProvider<false> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
Enrico Granata675f49b2015-10-07 18:36:53 +0000760