blob: 16635381f94fd7c7804aebb38126363dec72d6f8 [file] [log] [blame]
Enrico Granataf615b802013-02-15 23:38:37 +00001//===-- NSArray.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
Matt Kopec676a4872013-02-21 23:55:31 +000010#include "lldb/lldb-python.h"
11
Enrico Granataf615b802013-02-15 23:38:37 +000012#include "lldb/DataFormatters/CXXFormatterFunctions.h"
13
Enrico Granataf615b802013-02-15 23:38:37 +000014#include "lldb/Core/DataBufferHeap.h"
15#include "lldb/Core/Error.h"
16#include "lldb/Core/Stream.h"
17#include "lldb/Core/ValueObject.h"
18#include "lldb/Core/ValueObjectConstResult.h"
19#include "lldb/Host/Endian.h"
20#include "lldb/Symbol/ClangASTContext.h"
21#include "lldb/Target/ObjCLanguageRuntime.h"
Jason Molenda705b1802014-06-13 02:37:02 +000022#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
Enrico Granataf615b802013-02-15 23:38:37 +000023#include "lldb/Target/Target.h"
24
Jason Molenda705b1802014-06-13 02:37:02 +000025#include "clang/AST/ASTContext.h"
26
Enrico Granataf615b802013-02-15 23:38:37 +000027using namespace lldb;
28using namespace lldb_private;
29using namespace lldb_private::formatters;
30
Jason Molenda705b1802014-06-13 02:37:02 +000031namespace lldb_private {
32 namespace formatters {
33 class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
34 {
35 public:
36 NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
37
38 virtual size_t
39 CalculateNumChildren ();
40
41 virtual lldb::ValueObjectSP
42 GetChildAtIndex (size_t idx);
43
44 virtual bool
45 Update() = 0;
46
47 virtual bool
48 MightHaveChildren ();
49
50 virtual size_t
51 GetIndexOfChildWithName (const ConstString &name);
52
53 virtual
54 ~NSArrayMSyntheticFrontEnd () {}
55
56 protected:
57 virtual lldb::addr_t
58 GetDataAddress () = 0;
59
60 virtual uint64_t
61 GetUsedCount () = 0;
62
63 virtual uint64_t
64 GetOffset () = 0;
65
66 virtual uint64_t
67 GetSize () = 0;
68
69 ExecutionContextRef m_exe_ctx_ref;
70 uint8_t m_ptr_size;
71 ClangASTType m_id_type;
72 std::vector<lldb::ValueObjectSP> m_children;
73 };
74
75 class NSArrayMSyntheticFrontEnd_109 : public NSArrayMSyntheticFrontEnd
76 {
77 private:
78 struct DataDescriptor_32
79 {
80 uint32_t _used;
81 uint32_t _priv1 : 2 ;
82 uint32_t _size : 30;
83 uint32_t _priv2 : 2;
84 uint32_t _offset : 30;
85 uint32_t _priv3;
86 uint32_t _data;
87 };
88 struct DataDescriptor_64
89 {
90 uint64_t _used;
91 uint64_t _priv1 : 2 ;
92 uint64_t _size : 62;
93 uint64_t _priv2 : 2;
94 uint64_t _offset : 62;
95 uint32_t _priv3;
96 uint64_t _data;
97 };
98 public:
99 NSArrayMSyntheticFrontEnd_109 (lldb::ValueObjectSP valobj_sp);
100
101 virtual bool
102 Update();
103
104 virtual
105 ~NSArrayMSyntheticFrontEnd_109 ();
106
107 protected:
108 virtual lldb::addr_t
109 GetDataAddress ();
110
111 virtual uint64_t
112 GetUsedCount ();
113
114 virtual uint64_t
115 GetOffset ();
116
117 virtual uint64_t
118 GetSize ();
119
120 private:
121 DataDescriptor_32 *m_data_32;
122 DataDescriptor_64 *m_data_64;
123 };
124
125 class NSArrayMSyntheticFrontEnd_1010 : public NSArrayMSyntheticFrontEnd
126 {
127 private:
128 struct DataDescriptor_32
129 {
130 uint32_t _used;
131 uint32_t _offset;
132 uint32_t _size : 28;
133 uint64_t _priv1 : 4;
134 uint32_t _priv2;
135 uint32_t _data;
136 };
137 struct DataDescriptor_64
138 {
139 uint64_t _used;
140 uint64_t _offset;
141 uint64_t _size : 60;
142 uint64_t _priv1 : 4;
143 uint32_t _priv2;
144 uint64_t _data;
145 };
146 public:
147 NSArrayMSyntheticFrontEnd_1010 (lldb::ValueObjectSP valobj_sp);
148
149 virtual bool
150 Update();
151
152 virtual
153 ~NSArrayMSyntheticFrontEnd_1010 ();
154
155 protected:
156 virtual lldb::addr_t
157 GetDataAddress ();
158
159 virtual uint64_t
160 GetUsedCount ();
161
162 virtual uint64_t
163 GetOffset ();
164
165 virtual uint64_t
166 GetSize ();
167
168 private:
169 DataDescriptor_32 *m_data_32;
170 DataDescriptor_64 *m_data_64;
171 };
172
173 class NSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd
174 {
175 public:
176 NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
177
178 virtual size_t
179 CalculateNumChildren ();
180
181 virtual lldb::ValueObjectSP
182 GetChildAtIndex (size_t idx);
183
184 virtual bool
185 Update();
186
187 virtual bool
188 MightHaveChildren ();
189
190 virtual size_t
191 GetIndexOfChildWithName (const ConstString &name);
192
193 virtual
194 ~NSArrayISyntheticFrontEnd ();
195 private:
196 ExecutionContextRef m_exe_ctx_ref;
197 uint8_t m_ptr_size;
198 uint64_t m_items;
199 lldb::addr_t m_data_ptr;
200 ClangASTType m_id_type;
201 std::vector<lldb::ValueObjectSP> m_children;
202 };
203
204 class NSArrayCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
205 {
206 public:
207 NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
208
209 virtual size_t
210 CalculateNumChildren ();
211
212 virtual lldb::ValueObjectSP
213 GetChildAtIndex (size_t idx);
214
215 virtual bool
216 Update();
217
218 virtual bool
219 MightHaveChildren ();
220
221 virtual size_t
222 GetIndexOfChildWithName (const ConstString &name);
223
224 virtual
225 ~NSArrayCodeRunningSyntheticFrontEnd ();
226 };
227 }
228}
229
Enrico Granataf615b802013-02-15 23:38:37 +0000230bool
231lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& stream)
232{
233 ProcessSP process_sp = valobj.GetProcessSP();
234 if (!process_sp)
235 return false;
236
237 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
238
239 if (!runtime)
240 return false;
241
242 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
243
244 if (!descriptor.get() || !descriptor->IsValid())
245 return false;
246
247 uint32_t ptr_size = process_sp->GetAddressByteSize();
248
249 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
250
251 if (!valobj_addr)
252 return false;
253
254 uint64_t value = 0;
255
256 const char* class_name = descriptor->GetClassName().GetCString();
257
258 if (!class_name || !*class_name)
259 return false;
260
261 if (!strcmp(class_name,"__NSArrayI"))
262 {
263 Error error;
264 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
265 if (error.Fail())
266 return false;
267 }
268 else if (!strcmp(class_name,"__NSArrayM"))
269 {
270 Error error;
271 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
272 if (error.Fail())
273 return false;
274 }
275 else if (!strcmp(class_name,"__NSCFArray"))
276 {
277 Error error;
278 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + 2 * ptr_size, ptr_size, 0, error);
279 if (error.Fail())
280 return false;
281 }
282 else
283 {
284 if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
285 return false;
286 }
287
288 stream.Printf("@\"%" PRIu64 " object%s\"",
289 value,
290 value == 1 ? "" : "s");
291 return true;
292}
293
294lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
Jason Molenda705b1802014-06-13 02:37:02 +0000295SyntheticChildrenFrontEnd(*valobj_sp),
Greg Clayton57ee3062013-07-11 22:46:58 +0000296 m_exe_ctx_ref(),
297 m_ptr_size(8),
Jason Molenda705b1802014-06-13 02:37:02 +0000298m_id_type(),
299m_children()
Enrico Granataf615b802013-02-15 23:38:37 +0000300{
301 if (valobj_sp)
Greg Clayton57ee3062013-07-11 22:46:58 +0000302 {
Jason Molenda705b1802014-06-13 02:37:02 +0000303 clang::ASTContext *ast = valobj_sp->GetExecutionContextRef().GetTargetSP()->GetScratchClangASTContext()->getASTContext();
Greg Clayton57ee3062013-07-11 22:46:58 +0000304 if (ast)
305 m_id_type = ClangASTType(ast, ast->ObjCBuiltinIdTy);
Jason Molenda705b1802014-06-13 02:37:02 +0000306 if (valobj_sp->GetProcessSP())
307 m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize();
Greg Clayton57ee3062013-07-11 22:46:58 +0000308 }
Enrico Granataf615b802013-02-15 23:38:37 +0000309}
310
Jason Molenda705b1802014-06-13 02:37:02 +0000311lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::NSArrayMSyntheticFrontEnd_109 (lldb::ValueObjectSP valobj_sp) :
312NSArrayMSyntheticFrontEnd(valobj_sp),
313m_data_32(NULL),
314m_data_64(NULL)
315{
316}
317
318lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::NSArrayMSyntheticFrontEnd_1010 (lldb::ValueObjectSP valobj_sp) :
319NSArrayMSyntheticFrontEnd(valobj_sp),
320m_data_32(NULL),
321m_data_64(NULL)
322{
323}
324
Enrico Granataf615b802013-02-15 23:38:37 +0000325size_t
326lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren ()
327{
Jason Molenda705b1802014-06-13 02:37:02 +0000328 return GetUsedCount();
Enrico Granataf615b802013-02-15 23:38:37 +0000329}
330
331lldb::ValueObjectSP
332lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
333{
Enrico Granataf615b802013-02-15 23:38:37 +0000334 if (idx >= CalculateNumChildren())
335 return lldb::ValueObjectSP();
Jason Molenda705b1802014-06-13 02:37:02 +0000336 lldb::addr_t object_at_idx = GetDataAddress();
Enrico Granatab65b3032013-03-26 21:44:13 +0000337 size_t pyhs_idx = idx;
Jason Molenda705b1802014-06-13 02:37:02 +0000338 pyhs_idx += GetOffset();
339 if (GetSize() <= pyhs_idx)
340 pyhs_idx -= GetSize();
Enrico Granatab65b3032013-03-26 21:44:13 +0000341 object_at_idx += (pyhs_idx * m_ptr_size);
Enrico Granataf615b802013-02-15 23:38:37 +0000342 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000343 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granataf615b802013-02-15 23:38:37 +0000344 lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromAddress(idx_name.GetData(),
345 object_at_idx,
346 m_exe_ctx_ref,
347 m_id_type);
348 m_children.push_back(retval_sp);
349 return retval_sp;
350}
351
352bool
Jason Molenda705b1802014-06-13 02:37:02 +0000353lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::Update()
354{
355 m_children.clear();
356 ValueObjectSP valobj_sp = m_backend.GetSP();
357 m_ptr_size = 0;
358 delete m_data_32;
359 m_data_32 = NULL;
360 delete m_data_64;
361 m_data_64 = NULL;
362 if (!valobj_sp)
363 return false;
364 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
365 Error error;
366 error.Clear();
367 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
368 if (!process_sp)
369 return false;
370 m_ptr_size = process_sp->GetAddressByteSize();
371 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
372 if (m_ptr_size == 4)
373 {
374 m_data_32 = new DataDescriptor_32();
375 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
376 }
377 else
378 {
379 m_data_64 = new DataDescriptor_64();
380 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
381 }
382 if (error.Fail())
383 return false;
384 return false;
385}
386
387bool
388lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::Update()
Enrico Granataf615b802013-02-15 23:38:37 +0000389{
390 m_children.clear();
391 ValueObjectSP valobj_sp = m_backend.GetSP();
392 m_ptr_size = 0;
393 delete m_data_32;
394 m_data_32 = NULL;
395 delete m_data_64;
396 m_data_64 = NULL;
Enrico Granataf615b802013-02-15 23:38:37 +0000397 if (!valobj_sp)
398 return false;
399 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
400 Error error;
Enrico Granataf615b802013-02-15 23:38:37 +0000401 error.Clear();
402 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
403 if (!process_sp)
404 return false;
405 m_ptr_size = process_sp->GetAddressByteSize();
Enrico Granata723e1292013-04-23 01:13:50 +0000406 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
Enrico Granataf615b802013-02-15 23:38:37 +0000407 if (m_ptr_size == 4)
408 {
409 m_data_32 = new DataDescriptor_32();
410 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
411 }
412 else
413 {
414 m_data_64 = new DataDescriptor_64();
415 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
416 }
417 if (error.Fail())
418 return false;
419 return false;
420}
421
422bool
423lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren ()
424{
425 return true;
426}
427
428size_t
429lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
430{
Enrico Granataf615b802013-02-15 23:38:37 +0000431 const char* item_name = name.GetCString();
432 uint32_t idx = ExtractIndexFromString(item_name);
433 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
434 return UINT32_MAX;
435 return idx;
436}
437
Jason Molenda705b1802014-06-13 02:37:02 +0000438lldb::addr_t
439lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetDataAddress ()
440{
441 if (!m_data_32 && !m_data_64)
442 return LLDB_INVALID_ADDRESS;
443 return m_data_32 ? m_data_32->_data :
444 m_data_64->_data;
445}
446
447uint64_t
448lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetUsedCount ()
449{
450 if (!m_data_32 && !m_data_64)
451 return 0;
452 return m_data_32 ? m_data_32->_used :
453 m_data_64->_used;
454}
455
456uint64_t
457lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetOffset ()
458{
459 if (!m_data_32 && !m_data_64)
460 return 0;
461 return m_data_32 ? m_data_32->_offset :
462 m_data_64->_offset;
463}
464
465uint64_t
466lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetSize ()
467{
468 if (!m_data_32 && !m_data_64)
469 return 0;
470 return m_data_32 ? m_data_32->_size :
471 m_data_64->_size;
472}
473
474lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::~NSArrayMSyntheticFrontEnd_109 ()
475{
476 delete m_data_32;
477 m_data_32 = NULL;
478 delete m_data_64;
479 m_data_64 = NULL;
480}
481
482lldb::addr_t
483lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetDataAddress ()
484{
485 if (!m_data_32 && !m_data_64)
486 return LLDB_INVALID_ADDRESS;
487 return m_data_32 ? m_data_32->_data :
488 m_data_64->_data;
489}
490
491uint64_t
492lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetUsedCount ()
493{
494 if (!m_data_32 && !m_data_64)
495 return 0;
496 return m_data_32 ? m_data_32->_used :
497 m_data_64->_used;
498}
499
500uint64_t
501lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetOffset ()
502{
503 if (!m_data_32 && !m_data_64)
504 return 0;
505 return m_data_32 ? m_data_32->_offset :
506 m_data_64->_offset;
507}
508
509uint64_t
510lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetSize ()
511{
512 if (!m_data_32 && !m_data_64)
513 return 0;
514 return m_data_32 ? m_data_32->_size :
515 m_data_64->_size;
516}
517
518lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::~NSArrayMSyntheticFrontEnd_1010 ()
Enrico Granataf615b802013-02-15 23:38:37 +0000519{
520 delete m_data_32;
521 m_data_32 = NULL;
522 delete m_data_64;
523 m_data_64 = NULL;
524}
525
526lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
Greg Clayton57ee3062013-07-11 22:46:58 +0000527 SyntheticChildrenFrontEnd (*valobj_sp.get()),
528 m_exe_ctx_ref (),
529 m_ptr_size (8),
530 m_items (0),
531 m_data_ptr (0)
Enrico Granataf615b802013-02-15 23:38:37 +0000532{
533 if (valobj_sp)
Greg Clayton57ee3062013-07-11 22:46:58 +0000534 {
535 clang::ASTContext *ast = valobj_sp->GetClangType().GetASTContext();
536 if (ast)
537 m_id_type = ClangASTType(ast, ast->ObjCBuiltinIdTy);
538 }
Enrico Granataf615b802013-02-15 23:38:37 +0000539}
540
541lldb_private::formatters::NSArrayISyntheticFrontEnd::~NSArrayISyntheticFrontEnd ()
542{
543}
544
545size_t
546lldb_private::formatters::NSArrayISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
547{
548 const char* item_name = name.GetCString();
549 uint32_t idx = ExtractIndexFromString(item_name);
550 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
551 return UINT32_MAX;
552 return idx;
553}
554
555size_t
556lldb_private::formatters::NSArrayISyntheticFrontEnd::CalculateNumChildren ()
557{
558 return m_items;
559}
560
561bool
562lldb_private::formatters::NSArrayISyntheticFrontEnd::Update()
563{
564 m_ptr_size = 0;
565 m_items = 0;
566 m_data_ptr = 0;
567 m_children.clear();
568 ValueObjectSP valobj_sp = m_backend.GetSP();
Enrico Granataf615b802013-02-15 23:38:37 +0000569 if (!valobj_sp)
570 return false;
571 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
572 Error error;
Enrico Granataf615b802013-02-15 23:38:37 +0000573 error.Clear();
574 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
575 if (!process_sp)
576 return false;
577 m_ptr_size = process_sp->GetAddressByteSize();
Enrico Granata723e1292013-04-23 01:13:50 +0000578 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
Enrico Granataf615b802013-02-15 23:38:37 +0000579 m_items = process_sp->ReadPointerFromMemory(data_location, error);
580 if (error.Fail())
581 return false;
582 m_data_ptr = data_location+m_ptr_size;
583 return false;
584}
585
586bool
587lldb_private::formatters::NSArrayISyntheticFrontEnd::MightHaveChildren ()
588{
589 return true;
590}
591
592lldb::ValueObjectSP
593lldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex (size_t idx)
594{
595 if (idx >= CalculateNumChildren())
596 return lldb::ValueObjectSP();
597 lldb::addr_t object_at_idx = m_data_ptr;
598 object_at_idx += (idx * m_ptr_size);
599 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
600 if (!process_sp)
601 return lldb::ValueObjectSP();
602 Error error;
Enrico Granataf615b802013-02-15 23:38:37 +0000603 if (error.Fail())
604 return lldb::ValueObjectSP();
Enrico Granataf615b802013-02-15 23:38:37 +0000605 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000606 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granatae9818432013-04-04 01:12:12 +0000607 lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromAddress(idx_name.GetData(), object_at_idx, m_exe_ctx_ref, m_id_type);
Enrico Granataf615b802013-02-15 23:38:37 +0000608 m_children.push_back(retval_sp);
609 return retval_sp;
610}
611
612SyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
613{
Jason Molenda705b1802014-06-13 02:37:02 +0000614 if (!valobj_sp)
615 return nullptr;
616
Enrico Granataf615b802013-02-15 23:38:37 +0000617 lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
618 if (!process_sp)
619 return NULL;
Jason Molenda705b1802014-06-13 02:37:02 +0000620 AppleObjCRuntime *runtime = (AppleObjCRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Enrico Granataf615b802013-02-15 23:38:37 +0000621 if (!runtime)
622 return NULL;
623
Jason Molenda705b1802014-06-13 02:37:02 +0000624 ClangASTType valobj_type(valobj_sp->GetClangType());
625 Flags flags(valobj_type.GetTypeInfo());
626
627 if (flags.IsClear(ClangASTType::eTypeIsPointer))
Enrico Granataf615b802013-02-15 23:38:37 +0000628 {
629 Error error;
630 valobj_sp = valobj_sp->AddressOf(error);
631 if (error.Fail() || !valobj_sp)
632 return NULL;
633 }
634
635 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
636
637 if (!descriptor.get() || !descriptor->IsValid())
638 return NULL;
639
640 const char* class_name = descriptor->GetClassName().GetCString();
641
642 if (!class_name || !*class_name)
643 return NULL;
644
645 if (!strcmp(class_name,"__NSArrayI"))
646 {
647 return (new NSArrayISyntheticFrontEnd(valobj_sp));
648 }
649 else if (!strcmp(class_name,"__NSArrayM"))
650 {
Jason Molenda705b1802014-06-13 02:37:02 +0000651 if (runtime->GetFoundationVersion() >= 1100)
652 return (new NSArrayMSyntheticFrontEnd_1010(valobj_sp));
653 else
654 return (new NSArrayMSyntheticFrontEnd_109(valobj_sp));
Enrico Granataf615b802013-02-15 23:38:37 +0000655 }
656 else
657 {
658 return (new NSArrayCodeRunningSyntheticFrontEnd(valobj_sp));
659 }
660}
661
662lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
663SyntheticChildrenFrontEnd(*valobj_sp.get())
664{}
665
666size_t
667lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
668{
669 uint64_t count = 0;
670 if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
671 return count;
672 return 0;
673}
674
675lldb::ValueObjectSP
676lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetChildAtIndex (size_t idx)
677{
678 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000679 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granataf615b802013-02-15 23:38:37 +0000680 lldb::ValueObjectSP valobj_sp = CallSelectorOnObject(m_backend,"id","objectAtIndex:",idx);
681 if (valobj_sp)
682 valobj_sp->SetName(ConstString(idx_name.GetData()));
683 return valobj_sp;
684}
685
686bool
687lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::Update()
688{
689 return false;
690}
691
692bool
693lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::MightHaveChildren ()
694{
695 return true;
696}
697
698size_t
699lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
700{
701 return 0;
702}
703
704lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::~NSArrayCodeRunningSyntheticFrontEnd ()
705{}