blob: d5466ed4c8d7a9d0144ca2e47e4b4910013ad4ba [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"
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"
Jason Molenda705b1802014-06-13 02:37:02 +000021#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
Enrico Granataf615b802013-02-15 23:38:37 +000022#include "lldb/Target/Target.h"
23
Jason Molenda705b1802014-06-13 02:37:02 +000024#include "clang/AST/ASTContext.h"
25
Enrico Granataf615b802013-02-15 23:38:37 +000026using namespace lldb;
27using namespace lldb_private;
28using namespace lldb_private::formatters;
29
Jason Molenda705b1802014-06-13 02:37:02 +000030namespace lldb_private {
31 namespace formatters {
32 class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
33 {
34 public:
35 NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
36
37 virtual size_t
38 CalculateNumChildren ();
39
40 virtual lldb::ValueObjectSP
41 GetChildAtIndex (size_t idx);
42
43 virtual bool
44 Update() = 0;
45
46 virtual bool
47 MightHaveChildren ();
48
49 virtual size_t
50 GetIndexOfChildWithName (const ConstString &name);
51
52 virtual
53 ~NSArrayMSyntheticFrontEnd () {}
54
55 protected:
56 virtual lldb::addr_t
57 GetDataAddress () = 0;
58
59 virtual uint64_t
60 GetUsedCount () = 0;
61
62 virtual uint64_t
63 GetOffset () = 0;
64
65 virtual uint64_t
66 GetSize () = 0;
67
68 ExecutionContextRef m_exe_ctx_ref;
69 uint8_t m_ptr_size;
Greg Claytona1e5dc82015-08-11 22:53:00 +000070 CompilerType m_id_type;
Jason Molenda705b1802014-06-13 02:37:02 +000071 std::vector<lldb::ValueObjectSP> m_children;
72 };
73
74 class NSArrayMSyntheticFrontEnd_109 : public NSArrayMSyntheticFrontEnd
75 {
76 private:
77 struct DataDescriptor_32
78 {
79 uint32_t _used;
80 uint32_t _priv1 : 2 ;
81 uint32_t _size : 30;
82 uint32_t _priv2 : 2;
83 uint32_t _offset : 30;
84 uint32_t _priv3;
85 uint32_t _data;
86 };
87 struct DataDescriptor_64
88 {
89 uint64_t _used;
90 uint64_t _priv1 : 2 ;
91 uint64_t _size : 62;
92 uint64_t _priv2 : 2;
93 uint64_t _offset : 62;
94 uint32_t _priv3;
95 uint64_t _data;
96 };
97 public:
98 NSArrayMSyntheticFrontEnd_109 (lldb::ValueObjectSP valobj_sp);
99
100 virtual bool
101 Update();
102
103 virtual
104 ~NSArrayMSyntheticFrontEnd_109 ();
105
106 protected:
107 virtual lldb::addr_t
108 GetDataAddress ();
109
110 virtual uint64_t
111 GetUsedCount ();
112
113 virtual uint64_t
114 GetOffset ();
115
116 virtual uint64_t
117 GetSize ();
118
119 private:
120 DataDescriptor_32 *m_data_32;
121 DataDescriptor_64 *m_data_64;
122 };
123
124 class NSArrayMSyntheticFrontEnd_1010 : public NSArrayMSyntheticFrontEnd
125 {
126 private:
127 struct DataDescriptor_32
128 {
129 uint32_t _used;
130 uint32_t _offset;
131 uint32_t _size : 28;
132 uint64_t _priv1 : 4;
133 uint32_t _priv2;
134 uint32_t _data;
135 };
136 struct DataDescriptor_64
137 {
138 uint64_t _used;
139 uint64_t _offset;
140 uint64_t _size : 60;
141 uint64_t _priv1 : 4;
142 uint32_t _priv2;
143 uint64_t _data;
144 };
145 public:
146 NSArrayMSyntheticFrontEnd_1010 (lldb::ValueObjectSP valobj_sp);
147
148 virtual bool
149 Update();
150
151 virtual
152 ~NSArrayMSyntheticFrontEnd_1010 ();
153
154 protected:
155 virtual lldb::addr_t
156 GetDataAddress ();
157
158 virtual uint64_t
159 GetUsedCount ();
160
161 virtual uint64_t
162 GetOffset ();
163
164 virtual uint64_t
165 GetSize ();
166
167 private:
168 DataDescriptor_32 *m_data_32;
169 DataDescriptor_64 *m_data_64;
170 };
171
172 class NSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd
173 {
174 public:
175 NSArrayISyntheticFrontEnd (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 ~NSArrayISyntheticFrontEnd ();
194 private:
195 ExecutionContextRef m_exe_ctx_ref;
196 uint8_t m_ptr_size;
197 uint64_t m_items;
198 lldb::addr_t m_data_ptr;
Greg Claytona1e5dc82015-08-11 22:53:00 +0000199 CompilerType m_id_type;
Jason Molenda705b1802014-06-13 02:37:02 +0000200 std::vector<lldb::ValueObjectSP> m_children;
201 };
202
203 class NSArrayCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
204 {
205 public:
206 NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
207
208 virtual size_t
209 CalculateNumChildren ();
210
211 virtual lldb::ValueObjectSP
212 GetChildAtIndex (size_t idx);
213
214 virtual bool
215 Update();
216
217 virtual bool
218 MightHaveChildren ();
219
220 virtual size_t
221 GetIndexOfChildWithName (const ConstString &name);
222
223 virtual
224 ~NSArrayCodeRunningSyntheticFrontEnd ();
225 };
226 }
227}
228
Enrico Granataf615b802013-02-15 23:38:37 +0000229bool
Enrico Granataf35bc632014-11-06 21:55:30 +0000230lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
Enrico Granataf615b802013-02-15 23:38:37 +0000231{
232 ProcessSP process_sp = valobj.GetProcessSP();
233 if (!process_sp)
234 return false;
235
236 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
237
238 if (!runtime)
239 return false;
240
241 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
242
243 if (!descriptor.get() || !descriptor->IsValid())
244 return false;
245
246 uint32_t ptr_size = process_sp->GetAddressByteSize();
247
248 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
249
250 if (!valobj_addr)
251 return false;
252
253 uint64_t value = 0;
254
255 const char* class_name = descriptor->GetClassName().GetCString();
256
257 if (!class_name || !*class_name)
258 return false;
259
260 if (!strcmp(class_name,"__NSArrayI"))
261 {
262 Error error;
263 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
264 if (error.Fail())
265 return false;
266 }
267 else if (!strcmp(class_name,"__NSArrayM"))
268 {
269 Error error;
270 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
271 if (error.Fail())
272 return false;
273 }
274 else if (!strcmp(class_name,"__NSCFArray"))
275 {
276 Error error;
277 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + 2 * ptr_size, ptr_size, 0, error);
278 if (error.Fail())
279 return false;
280 }
281 else
282 {
283 if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
284 return false;
285 }
286
287 stream.Printf("@\"%" PRIu64 " object%s\"",
288 value,
289 value == 1 ? "" : "s");
290 return true;
291}
292
293lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
Jason Molenda705b1802014-06-13 02:37:02 +0000294SyntheticChildrenFrontEnd(*valobj_sp),
Greg Clayton57ee3062013-07-11 22:46:58 +0000295 m_exe_ctx_ref(),
296 m_ptr_size(8),
Jason Molenda705b1802014-06-13 02:37:02 +0000297m_id_type(),
298m_children()
Enrico Granataf615b802013-02-15 23:38:37 +0000299{
300 if (valobj_sp)
Greg Clayton57ee3062013-07-11 22:46:58 +0000301 {
Jason Molenda705b1802014-06-13 02:37:02 +0000302 clang::ASTContext *ast = valobj_sp->GetExecutionContextRef().GetTargetSP()->GetScratchClangASTContext()->getASTContext();
Greg Clayton57ee3062013-07-11 22:46:58 +0000303 if (ast)
Greg Claytona1e5dc82015-08-11 22:53:00 +0000304 m_id_type = CompilerType(ast, ast->ObjCBuiltinIdTy);
Jason Molenda705b1802014-06-13 02:37:02 +0000305 if (valobj_sp->GetProcessSP())
306 m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize();
Greg Clayton57ee3062013-07-11 22:46:58 +0000307 }
Enrico Granataf615b802013-02-15 23:38:37 +0000308}
309
Jason Molenda705b1802014-06-13 02:37:02 +0000310lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::NSArrayMSyntheticFrontEnd_109 (lldb::ValueObjectSP valobj_sp) :
311NSArrayMSyntheticFrontEnd(valobj_sp),
312m_data_32(NULL),
313m_data_64(NULL)
314{
315}
316
317lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::NSArrayMSyntheticFrontEnd_1010 (lldb::ValueObjectSP valobj_sp) :
318NSArrayMSyntheticFrontEnd(valobj_sp),
319m_data_32(NULL),
320m_data_64(NULL)
321{
322}
323
Enrico Granataf615b802013-02-15 23:38:37 +0000324size_t
325lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren ()
326{
Jason Molenda705b1802014-06-13 02:37:02 +0000327 return GetUsedCount();
Enrico Granataf615b802013-02-15 23:38:37 +0000328}
329
330lldb::ValueObjectSP
331lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
332{
Enrico Granataf615b802013-02-15 23:38:37 +0000333 if (idx >= CalculateNumChildren())
334 return lldb::ValueObjectSP();
Jason Molenda705b1802014-06-13 02:37:02 +0000335 lldb::addr_t object_at_idx = GetDataAddress();
Enrico Granatab65b3032013-03-26 21:44:13 +0000336 size_t pyhs_idx = idx;
Jason Molenda705b1802014-06-13 02:37:02 +0000337 pyhs_idx += GetOffset();
338 if (GetSize() <= pyhs_idx)
339 pyhs_idx -= GetSize();
Enrico Granatab65b3032013-03-26 21:44:13 +0000340 object_at_idx += (pyhs_idx * m_ptr_size);
Enrico Granataf615b802013-02-15 23:38:37 +0000341 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000342 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granatae29df232014-12-09 19:51:20 +0000343 lldb::ValueObjectSP retval_sp = CreateValueObjectFromAddress(idx_name.GetData(),
344 object_at_idx,
345 m_exe_ctx_ref,
346 m_id_type);
Enrico Granataf615b802013-02-15 23:38:37 +0000347 m_children.push_back(retval_sp);
348 return retval_sp;
349}
350
351bool
Jason Molenda705b1802014-06-13 02:37:02 +0000352lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::Update()
353{
354 m_children.clear();
355 ValueObjectSP valobj_sp = m_backend.GetSP();
356 m_ptr_size = 0;
357 delete m_data_32;
358 m_data_32 = NULL;
359 delete m_data_64;
360 m_data_64 = NULL;
361 if (!valobj_sp)
362 return false;
363 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
364 Error error;
365 error.Clear();
366 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
367 if (!process_sp)
368 return false;
369 m_ptr_size = process_sp->GetAddressByteSize();
370 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
371 if (m_ptr_size == 4)
372 {
373 m_data_32 = new DataDescriptor_32();
374 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
375 }
376 else
377 {
378 m_data_64 = new DataDescriptor_64();
379 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
380 }
381 if (error.Fail())
382 return false;
383 return false;
384}
385
386bool
387lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::Update()
Enrico Granataf615b802013-02-15 23:38:37 +0000388{
389 m_children.clear();
390 ValueObjectSP valobj_sp = m_backend.GetSP();
391 m_ptr_size = 0;
392 delete m_data_32;
393 m_data_32 = NULL;
394 delete m_data_64;
395 m_data_64 = NULL;
Enrico Granataf615b802013-02-15 23:38:37 +0000396 if (!valobj_sp)
397 return false;
398 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
399 Error error;
Enrico Granataf615b802013-02-15 23:38:37 +0000400 error.Clear();
401 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
402 if (!process_sp)
403 return false;
404 m_ptr_size = process_sp->GetAddressByteSize();
Enrico Granata723e1292013-04-23 01:13:50 +0000405 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
Enrico Granataf615b802013-02-15 23:38:37 +0000406 if (m_ptr_size == 4)
407 {
408 m_data_32 = new DataDescriptor_32();
409 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
410 }
411 else
412 {
413 m_data_64 = new DataDescriptor_64();
414 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
415 }
416 if (error.Fail())
417 return false;
418 return false;
419}
420
421bool
422lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren ()
423{
424 return true;
425}
426
427size_t
428lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
429{
Enrico Granataf615b802013-02-15 23:38:37 +0000430 const char* item_name = name.GetCString();
431 uint32_t idx = ExtractIndexFromString(item_name);
432 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
433 return UINT32_MAX;
434 return idx;
435}
436
Jason Molenda705b1802014-06-13 02:37:02 +0000437lldb::addr_t
438lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetDataAddress ()
439{
440 if (!m_data_32 && !m_data_64)
441 return LLDB_INVALID_ADDRESS;
442 return m_data_32 ? m_data_32->_data :
443 m_data_64->_data;
444}
445
446uint64_t
447lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetUsedCount ()
448{
449 if (!m_data_32 && !m_data_64)
450 return 0;
451 return m_data_32 ? m_data_32->_used :
452 m_data_64->_used;
453}
454
455uint64_t
456lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetOffset ()
457{
458 if (!m_data_32 && !m_data_64)
459 return 0;
460 return m_data_32 ? m_data_32->_offset :
461 m_data_64->_offset;
462}
463
464uint64_t
465lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::GetSize ()
466{
467 if (!m_data_32 && !m_data_64)
468 return 0;
469 return m_data_32 ? m_data_32->_size :
470 m_data_64->_size;
471}
472
473lldb_private::formatters::NSArrayMSyntheticFrontEnd_109::~NSArrayMSyntheticFrontEnd_109 ()
474{
475 delete m_data_32;
476 m_data_32 = NULL;
477 delete m_data_64;
478 m_data_64 = NULL;
479}
480
481lldb::addr_t
482lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetDataAddress ()
483{
484 if (!m_data_32 && !m_data_64)
485 return LLDB_INVALID_ADDRESS;
486 return m_data_32 ? m_data_32->_data :
487 m_data_64->_data;
488}
489
490uint64_t
491lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetUsedCount ()
492{
493 if (!m_data_32 && !m_data_64)
494 return 0;
495 return m_data_32 ? m_data_32->_used :
496 m_data_64->_used;
497}
498
499uint64_t
500lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetOffset ()
501{
502 if (!m_data_32 && !m_data_64)
503 return 0;
504 return m_data_32 ? m_data_32->_offset :
505 m_data_64->_offset;
506}
507
508uint64_t
509lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::GetSize ()
510{
511 if (!m_data_32 && !m_data_64)
512 return 0;
513 return m_data_32 ? m_data_32->_size :
514 m_data_64->_size;
515}
516
517lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::~NSArrayMSyntheticFrontEnd_1010 ()
Enrico Granataf615b802013-02-15 23:38:37 +0000518{
519 delete m_data_32;
520 m_data_32 = NULL;
521 delete m_data_64;
522 m_data_64 = NULL;
523}
524
525lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
Greg Clayton57ee3062013-07-11 22:46:58 +0000526 SyntheticChildrenFrontEnd (*valobj_sp.get()),
527 m_exe_ctx_ref (),
528 m_ptr_size (8),
529 m_items (0),
530 m_data_ptr (0)
Enrico Granataf615b802013-02-15 23:38:37 +0000531{
Greg Claytonf73034f2015-09-08 18:15:05 +0000532 if (valobj_sp)
Greg Clayton57ee3062013-07-11 22:46:58 +0000533 {
Greg Claytonf73034f2015-09-08 18:15:05 +0000534 CompilerType type = valobj_sp->GetCompilerType();
535 if (type)
536 {
537 ClangASTContext *ast = valobj_sp->GetExecutionContextRef().GetTargetSP()->GetScratchClangASTContext();
538 if (ast)
539 m_id_type = CompilerType(ast->getASTContext(), ast->getASTContext()->ObjCBuiltinIdTy);
540 }
Greg Clayton57ee3062013-07-11 22:46:58 +0000541 }
Enrico Granataf615b802013-02-15 23:38:37 +0000542}
543
544lldb_private::formatters::NSArrayISyntheticFrontEnd::~NSArrayISyntheticFrontEnd ()
545{
546}
547
548size_t
549lldb_private::formatters::NSArrayISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
550{
551 const char* item_name = name.GetCString();
552 uint32_t idx = ExtractIndexFromString(item_name);
553 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
554 return UINT32_MAX;
555 return idx;
556}
557
558size_t
559lldb_private::formatters::NSArrayISyntheticFrontEnd::CalculateNumChildren ()
560{
561 return m_items;
562}
563
564bool
565lldb_private::formatters::NSArrayISyntheticFrontEnd::Update()
566{
567 m_ptr_size = 0;
568 m_items = 0;
569 m_data_ptr = 0;
570 m_children.clear();
571 ValueObjectSP valobj_sp = m_backend.GetSP();
Enrico Granataf615b802013-02-15 23:38:37 +0000572 if (!valobj_sp)
573 return false;
574 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
575 Error error;
Enrico Granataf615b802013-02-15 23:38:37 +0000576 error.Clear();
577 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
578 if (!process_sp)
579 return false;
580 m_ptr_size = process_sp->GetAddressByteSize();
Enrico Granata723e1292013-04-23 01:13:50 +0000581 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
Enrico Granataf615b802013-02-15 23:38:37 +0000582 m_items = process_sp->ReadPointerFromMemory(data_location, error);
583 if (error.Fail())
584 return false;
585 m_data_ptr = data_location+m_ptr_size;
586 return false;
587}
588
589bool
590lldb_private::formatters::NSArrayISyntheticFrontEnd::MightHaveChildren ()
591{
592 return true;
593}
594
595lldb::ValueObjectSP
596lldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex (size_t idx)
597{
598 if (idx >= CalculateNumChildren())
599 return lldb::ValueObjectSP();
600 lldb::addr_t object_at_idx = m_data_ptr;
601 object_at_idx += (idx * m_ptr_size);
602 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
603 if (!process_sp)
604 return lldb::ValueObjectSP();
605 Error error;
Enrico Granataf615b802013-02-15 23:38:37 +0000606 if (error.Fail())
607 return lldb::ValueObjectSP();
Enrico Granataf615b802013-02-15 23:38:37 +0000608 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000609 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granatae29df232014-12-09 19:51:20 +0000610 lldb::ValueObjectSP retval_sp = CreateValueObjectFromAddress(idx_name.GetData(),
611 object_at_idx,
612 m_exe_ctx_ref,
613 m_id_type);
Enrico Granataf615b802013-02-15 23:38:37 +0000614 m_children.push_back(retval_sp);
615 return retval_sp;
616}
617
618SyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
619{
Jason Molenda705b1802014-06-13 02:37:02 +0000620 if (!valobj_sp)
621 return nullptr;
622
Enrico Granataf615b802013-02-15 23:38:37 +0000623 lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
624 if (!process_sp)
625 return NULL;
Jason Molenda705b1802014-06-13 02:37:02 +0000626 AppleObjCRuntime *runtime = (AppleObjCRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
Enrico Granataf615b802013-02-15 23:38:37 +0000627 if (!runtime)
628 return NULL;
629
Greg Clayton99558cc42015-08-24 23:46:31 +0000630 CompilerType valobj_type(valobj_sp->GetCompilerType());
Jason Molenda705b1802014-06-13 02:37:02 +0000631 Flags flags(valobj_type.GetTypeInfo());
632
Enrico Granata622be232014-10-21 20:52:14 +0000633 if (flags.IsClear(eTypeIsPointer))
Enrico Granataf615b802013-02-15 23:38:37 +0000634 {
635 Error error;
636 valobj_sp = valobj_sp->AddressOf(error);
637 if (error.Fail() || !valobj_sp)
638 return NULL;
639 }
640
641 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
642
643 if (!descriptor.get() || !descriptor->IsValid())
644 return NULL;
645
646 const char* class_name = descriptor->GetClassName().GetCString();
647
648 if (!class_name || !*class_name)
649 return NULL;
650
651 if (!strcmp(class_name,"__NSArrayI"))
652 {
653 return (new NSArrayISyntheticFrontEnd(valobj_sp));
654 }
655 else if (!strcmp(class_name,"__NSArrayM"))
656 {
Jason Molenda705b1802014-06-13 02:37:02 +0000657 if (runtime->GetFoundationVersion() >= 1100)
658 return (new NSArrayMSyntheticFrontEnd_1010(valobj_sp));
659 else
660 return (new NSArrayMSyntheticFrontEnd_109(valobj_sp));
Enrico Granataf615b802013-02-15 23:38:37 +0000661 }
662 else
663 {
664 return (new NSArrayCodeRunningSyntheticFrontEnd(valobj_sp));
665 }
666}
667
668lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
669SyntheticChildrenFrontEnd(*valobj_sp.get())
670{}
671
672size_t
673lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
674{
675 uint64_t count = 0;
676 if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
677 return count;
678 return 0;
679}
680
681lldb::ValueObjectSP
682lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetChildAtIndex (size_t idx)
683{
684 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000685 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granataf615b802013-02-15 23:38:37 +0000686 lldb::ValueObjectSP valobj_sp = CallSelectorOnObject(m_backend,"id","objectAtIndex:",idx);
687 if (valobj_sp)
688 valobj_sp->SetName(ConstString(idx_name.GetData()));
689 return valobj_sp;
690}
691
692bool
693lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::Update()
694{
695 return false;
696}
697
698bool
699lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::MightHaveChildren ()
700{
701 return true;
702}
703
704size_t
705lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
706{
707 return 0;
708}
709
710lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::~NSArrayCodeRunningSyntheticFrontEnd ()
711{}