blob: c6db27e93d4adbcef10a08de2989d7663c3a87cd [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
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"
Jim Ingham151c0322015-09-15 21:13:50 +000018#include "lldb/Expression/FunctionCaller.h"
Enrico Granataf615b802013-02-15 23:38:37 +000019#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;
Greg Claytona1e5dc82015-08-11 22:53:00 +000071 CompilerType m_id_type;
Jason Molenda705b1802014-06-13 02:37:02 +000072 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;
Greg Claytona1e5dc82015-08-11 22:53:00 +0000200 CompilerType m_id_type;
Jason Molenda705b1802014-06-13 02:37:02 +0000201 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
Enrico Granataf35bc632014-11-06 21:55:30 +0000231lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
Enrico Granataf615b802013-02-15 23:38:37 +0000232{
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)
Greg Claytona1e5dc82015-08-11 22:53:00 +0000305 m_id_type = CompilerType(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 Granatae29df232014-12-09 19:51:20 +0000344 lldb::ValueObjectSP retval_sp = CreateValueObjectFromAddress(idx_name.GetData(),
345 object_at_idx,
346 m_exe_ctx_ref,
347 m_id_type);
Enrico Granataf615b802013-02-15 23:38:37 +0000348 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{
Greg Claytonf73034f2015-09-08 18:15:05 +0000533 if (valobj_sp)
Greg Clayton57ee3062013-07-11 22:46:58 +0000534 {
Greg Claytonf73034f2015-09-08 18:15:05 +0000535 CompilerType type = valobj_sp->GetCompilerType();
536 if (type)
537 {
538 ClangASTContext *ast = valobj_sp->GetExecutionContextRef().GetTargetSP()->GetScratchClangASTContext();
539 if (ast)
540 m_id_type = CompilerType(ast->getASTContext(), ast->getASTContext()->ObjCBuiltinIdTy);
541 }
Greg Clayton57ee3062013-07-11 22:46:58 +0000542 }
Enrico Granataf615b802013-02-15 23:38:37 +0000543}
544
545lldb_private::formatters::NSArrayISyntheticFrontEnd::~NSArrayISyntheticFrontEnd ()
546{
547}
548
549size_t
550lldb_private::formatters::NSArrayISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
551{
552 const char* item_name = name.GetCString();
553 uint32_t idx = ExtractIndexFromString(item_name);
554 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
555 return UINT32_MAX;
556 return idx;
557}
558
559size_t
560lldb_private::formatters::NSArrayISyntheticFrontEnd::CalculateNumChildren ()
561{
562 return m_items;
563}
564
565bool
566lldb_private::formatters::NSArrayISyntheticFrontEnd::Update()
567{
568 m_ptr_size = 0;
569 m_items = 0;
570 m_data_ptr = 0;
571 m_children.clear();
572 ValueObjectSP valobj_sp = m_backend.GetSP();
Enrico Granataf615b802013-02-15 23:38:37 +0000573 if (!valobj_sp)
574 return false;
575 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
576 Error error;
Enrico Granataf615b802013-02-15 23:38:37 +0000577 error.Clear();
578 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
579 if (!process_sp)
580 return false;
581 m_ptr_size = process_sp->GetAddressByteSize();
Enrico Granata723e1292013-04-23 01:13:50 +0000582 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
Enrico Granataf615b802013-02-15 23:38:37 +0000583 m_items = process_sp->ReadPointerFromMemory(data_location, error);
584 if (error.Fail())
585 return false;
586 m_data_ptr = data_location+m_ptr_size;
587 return false;
588}
589
590bool
591lldb_private::formatters::NSArrayISyntheticFrontEnd::MightHaveChildren ()
592{
593 return true;
594}
595
596lldb::ValueObjectSP
597lldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex (size_t idx)
598{
599 if (idx >= CalculateNumChildren())
600 return lldb::ValueObjectSP();
601 lldb::addr_t object_at_idx = m_data_ptr;
602 object_at_idx += (idx * m_ptr_size);
603 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
604 if (!process_sp)
605 return lldb::ValueObjectSP();
606 Error error;
Enrico Granataf615b802013-02-15 23:38:37 +0000607 if (error.Fail())
608 return lldb::ValueObjectSP();
Enrico Granataf615b802013-02-15 23:38:37 +0000609 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000610 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granatae29df232014-12-09 19:51:20 +0000611 lldb::ValueObjectSP retval_sp = CreateValueObjectFromAddress(idx_name.GetData(),
612 object_at_idx,
613 m_exe_ctx_ref,
614 m_id_type);
Enrico Granataf615b802013-02-15 23:38:37 +0000615 m_children.push_back(retval_sp);
616 return retval_sp;
617}
618
619SyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
620{
Jason Molenda705b1802014-06-13 02:37:02 +0000621 if (!valobj_sp)
622 return nullptr;
623
Enrico Granataf615b802013-02-15 23:38:37 +0000624 lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
625 if (!process_sp)
626 return NULL;
Jason Molenda705b1802014-06-13 02:37:02 +0000627 AppleObjCRuntime *runtime = (AppleObjCRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Enrico Granataf615b802013-02-15 23:38:37 +0000628 if (!runtime)
629 return NULL;
630
Greg Clayton99558cc42015-08-24 23:46:31 +0000631 CompilerType valobj_type(valobj_sp->GetCompilerType());
Jason Molenda705b1802014-06-13 02:37:02 +0000632 Flags flags(valobj_type.GetTypeInfo());
633
Enrico Granata622be232014-10-21 20:52:14 +0000634 if (flags.IsClear(eTypeIsPointer))
Enrico Granataf615b802013-02-15 23:38:37 +0000635 {
636 Error error;
637 valobj_sp = valobj_sp->AddressOf(error);
638 if (error.Fail() || !valobj_sp)
639 return NULL;
640 }
641
642 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
643
644 if (!descriptor.get() || !descriptor->IsValid())
645 return NULL;
646
647 const char* class_name = descriptor->GetClassName().GetCString();
648
649 if (!class_name || !*class_name)
650 return NULL;
651
652 if (!strcmp(class_name,"__NSArrayI"))
653 {
654 return (new NSArrayISyntheticFrontEnd(valobj_sp));
655 }
656 else if (!strcmp(class_name,"__NSArrayM"))
657 {
Jason Molenda705b1802014-06-13 02:37:02 +0000658 if (runtime->GetFoundationVersion() >= 1100)
659 return (new NSArrayMSyntheticFrontEnd_1010(valobj_sp));
660 else
661 return (new NSArrayMSyntheticFrontEnd_109(valobj_sp));
Enrico Granataf615b802013-02-15 23:38:37 +0000662 }
663 else
664 {
665 return (new NSArrayCodeRunningSyntheticFrontEnd(valobj_sp));
666 }
667}
668
669lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
670SyntheticChildrenFrontEnd(*valobj_sp.get())
671{}
672
673size_t
674lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
675{
676 uint64_t count = 0;
677 if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
678 return count;
679 return 0;
680}
681
682lldb::ValueObjectSP
683lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetChildAtIndex (size_t idx)
684{
685 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000686 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granataf615b802013-02-15 23:38:37 +0000687 lldb::ValueObjectSP valobj_sp = CallSelectorOnObject(m_backend,"id","objectAtIndex:",idx);
688 if (valobj_sp)
689 valobj_sp->SetName(ConstString(idx_name.GetData()));
690 return valobj_sp;
691}
692
693bool
694lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::Update()
695{
696 return false;
697}
698
699bool
700lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::MightHaveChildren ()
701{
702 return true;
703}
704
705size_t
706lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
707{
708 return 0;
709}
710
711lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::~NSArrayCodeRunningSyntheticFrontEnd ()
712{}