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