blob: 919ffaab0a6c5181496b1810c03caaf76c8aa148 [file] [log] [blame]
Enrico Granataf615b802013-02-15 23:38:37 +00001//===-- NSDictionary.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"
22#include "lldb/Target/Target.h"
23
Jason Molendac01e1b72013-04-03 20:32:17 +000024#include "clang/AST/DeclCXX.h"
25
Enrico Granataf615b802013-02-15 23:38:37 +000026using namespace lldb;
27using namespace lldb_private;
28using namespace lldb_private::formatters;
29
Enrico Granataeb8bd922013-04-03 01:25:29 +000030static ClangASTType
31GetLLDBNSPairType (TargetSP target_sp)
32{
Greg Clayton57ee3062013-07-11 22:46:58 +000033 ClangASTType clang_type;
Enrico Granataeb8bd922013-04-03 01:25:29 +000034
35 ClangASTContext *target_ast_context = target_sp->GetScratchClangASTContext();
36
Greg Clayton57ee3062013-07-11 22:46:58 +000037 if (target_ast_context)
Enrico Granataeb8bd922013-04-03 01:25:29 +000038 {
Enrico Granata0e478f52014-10-17 17:56:59 +000039 ConstString g___lldb_autogen_nspair("__lldb_autogen_nspair");
Greg Clayton57ee3062013-07-11 22:46:58 +000040
Enrico Granata0e478f52014-10-17 17:56:59 +000041 clang_type = target_ast_context->GetTypeForIdentifier<clang::CXXRecordDecl>(g___lldb_autogen_nspair);
42
43 if (!clang_type)
Enrico Granataeb8bd922013-04-03 01:25:29 +000044 {
Enrico Granata0e478f52014-10-17 17:56:59 +000045 clang_type = target_ast_context->CreateRecordType(NULL, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC);
Greg Clayton57ee3062013-07-11 22:46:58 +000046
Enrico Granata0e478f52014-10-17 17:56:59 +000047 if (clang_type)
Greg Clayton57ee3062013-07-11 22:46:58 +000048 {
Enrico Granata0e478f52014-10-17 17:56:59 +000049 clang_type.StartTagDeclarationDefinition();
50 ClangASTType id_clang_type = target_ast_context->GetBasicType (eBasicTypeObjCID);
51 clang_type.AddFieldToRecordType("key", id_clang_type, lldb::eAccessPublic, 0);
52 clang_type.AddFieldToRecordType("value", id_clang_type, lldb::eAccessPublic, 0);
53 clang_type.CompleteTagDeclarationDefinition();
Greg Clayton57ee3062013-07-11 22:46:58 +000054 }
Enrico Granataeb8bd922013-04-03 01:25:29 +000055 }
56 }
Enrico Granataeb8bd922013-04-03 01:25:29 +000057 return clang_type;
58}
59
Enrico Granataf615b802013-02-15 23:38:37 +000060template<bool name_entries>
61bool
62lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream)
63{
64 ProcessSP process_sp = valobj.GetProcessSP();
65 if (!process_sp)
66 return false;
67
68 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
69
70 if (!runtime)
71 return false;
72
73 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
74
75 if (!descriptor.get() || !descriptor->IsValid())
76 return false;
77
78 uint32_t ptr_size = process_sp->GetAddressByteSize();
79 bool is_64bit = (ptr_size == 8);
80
81 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
82
83 if (!valobj_addr)
84 return false;
85
86 uint64_t value = 0;
87
88 const char* class_name = descriptor->GetClassName().GetCString();
89
90 if (!class_name || !*class_name)
91 return false;
92
93 if (!strcmp(class_name,"__NSDictionaryI"))
94 {
95 Error error;
96 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
97 if (error.Fail())
98 return false;
99 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
100 }
101 else if (!strcmp(class_name,"__NSDictionaryM"))
102 {
103 Error error;
104 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
105 if (error.Fail())
106 return false;
107 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
108 }
Enrico Granataf68f7322013-03-15 18:44:08 +0000109 /*else if (!strcmp(class_name,"__NSCFDictionary"))
Enrico Granataf615b802013-02-15 23:38:37 +0000110 {
111 Error error;
Enrico Granataf68f7322013-03-15 18:44:08 +0000112 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error);
Enrico Granataf615b802013-02-15 23:38:37 +0000113 if (error.Fail())
114 return false;
115 if (is_64bit)
116 value &= ~0x0f1f000000000000UL;
Enrico Granataf68f7322013-03-15 18:44:08 +0000117 }*/
Enrico Granataf615b802013-02-15 23:38:37 +0000118 else
119 {
120 if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
121 return false;
122 }
123
124 stream.Printf("%s%" PRIu64 " %s%s",
125 (name_entries ? "@\"" : ""),
126 value,
127 (name_entries ? (value == 1 ? "entry" : "entries") : (value == 1 ? "key/value pair" : "key/value pairs")),
128 (name_entries ? "\"" : ""));
129 return true;
130}
131
132SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
133{
134
135 lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
136 if (!process_sp)
137 return NULL;
138 ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
139 if (!runtime)
140 return NULL;
141
142 if (!valobj_sp->IsPointerType())
143 {
144 Error error;
145 valobj_sp = valobj_sp->AddressOf(error);
146 if (error.Fail() || !valobj_sp)
147 return NULL;
148 }
149
150 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
151
152 if (!descriptor.get() || !descriptor->IsValid())
153 return NULL;
154
155 const char* class_name = descriptor->GetClassName().GetCString();
156
157 if (!class_name || !*class_name)
158 return NULL;
159
160 if (!strcmp(class_name,"__NSDictionaryI"))
161 {
162 return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
163 }
164 else if (!strcmp(class_name,"__NSDictionaryM"))
165 {
166 return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
167 }
168 else
169 {
170 return (new NSDictionaryCodeRunningSyntheticFrontEnd(valobj_sp));
171 }
172}
173
174lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
175SyntheticChildrenFrontEnd(*valobj_sp.get())
176{}
177
178size_t
179lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
180{
181 uint64_t count = 0;
182 if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
183 return count;
184 return 0;
185}
186
187lldb::ValueObjectSP
188lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetChildAtIndex (size_t idx)
189{
190 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000191 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granataf615b802013-02-15 23:38:37 +0000192 StreamString key_fetcher_expr;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000193 key_fetcher_expr.Printf("(id)[(NSArray*)[(id)0x%" PRIx64 " allKeys] objectAtIndex:%" PRIu64 "]", m_backend.GetPointerValue(), (uint64_t)idx);
Enrico Granataf615b802013-02-15 23:38:37 +0000194 StreamString value_fetcher_expr;
Enrico Granataa221e4e2013-02-25 19:44:39 +0000195 value_fetcher_expr.Printf("(id)[(id)0x%" PRIx64 " objectForKey:(%s)]",m_backend.GetPointerValue(),key_fetcher_expr.GetData());
Enrico Granataf615b802013-02-15 23:38:37 +0000196 StreamString object_fetcher_expr;
197 object_fetcher_expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = %s; _lldb_valgen_item.value = %s; _lldb_valgen_item;",key_fetcher_expr.GetData(),value_fetcher_expr.GetData());
198 lldb::ValueObjectSP child_sp;
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000199 EvaluateExpressionOptions options;
200 options.SetKeepInMemory(true);
Enrico Granataba8eb122014-07-30 21:07:50 +0000201 m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(),
202 GetViableFrame(m_backend.GetTargetSP().get()),
203 child_sp,
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000204 options);
Enrico Granataf615b802013-02-15 23:38:37 +0000205 if (child_sp)
206 child_sp->SetName(ConstString(idx_name.GetData()));
207 return child_sp;
208}
209
210bool
211lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::Update()
212{
213 return false;
214}
215
216bool
217lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::MightHaveChildren ()
218{
219 return true;
220}
221
222size_t
223lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
224{
225 return 0;
226}
227
228lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::~NSDictionaryCodeRunningSyntheticFrontEnd ()
229{}
230
231lldb_private::formatters::NSDictionaryISyntheticFrontEnd::NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
232SyntheticChildrenFrontEnd(*valobj_sp.get()),
233m_exe_ctx_ref(),
234m_ptr_size(8),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000235m_order(lldb::eByteOrderInvalid),
Enrico Granataf615b802013-02-15 23:38:37 +0000236m_data_32(NULL),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000237m_data_64(NULL),
238m_pair_type()
Enrico Granataf615b802013-02-15 23:38:37 +0000239{
Enrico Granataf615b802013-02-15 23:38:37 +0000240}
241
242lldb_private::formatters::NSDictionaryISyntheticFrontEnd::~NSDictionaryISyntheticFrontEnd ()
243{
244 delete m_data_32;
245 m_data_32 = NULL;
246 delete m_data_64;
247 m_data_64 = NULL;
248}
249
250size_t
251lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
252{
253 const char* item_name = name.GetCString();
254 uint32_t idx = ExtractIndexFromString(item_name);
255 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
256 return UINT32_MAX;
257 return idx;
258}
259
260size_t
261lldb_private::formatters::NSDictionaryISyntheticFrontEnd::CalculateNumChildren ()
262{
263 if (!m_data_32 && !m_data_64)
264 return 0;
265 return (m_data_32 ? m_data_32->_used : m_data_64->_used);
266}
267
268bool
269lldb_private::formatters::NSDictionaryISyntheticFrontEnd::Update()
270{
271 m_children.clear();
272 delete m_data_32;
273 m_data_32 = NULL;
274 delete m_data_64;
275 m_data_64 = NULL;
276 m_ptr_size = 0;
277 ValueObjectSP valobj_sp = m_backend.GetSP();
278 if (!valobj_sp)
279 return false;
Enrico Granataf615b802013-02-15 23:38:37 +0000280 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
281 Error error;
Enrico Granataf615b802013-02-15 23:38:37 +0000282 error.Clear();
283 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
284 if (!process_sp)
285 return false;
286 m_ptr_size = process_sp->GetAddressByteSize();
Enrico Granataeb8bd922013-04-03 01:25:29 +0000287 m_order = process_sp->GetByteOrder();
Enrico Granata723e1292013-04-23 01:13:50 +0000288 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
Enrico Granataf615b802013-02-15 23:38:37 +0000289 if (m_ptr_size == 4)
290 {
291 m_data_32 = new DataDescriptor_32();
292 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
293 }
294 else
295 {
296 m_data_64 = new DataDescriptor_64();
297 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
298 }
299 if (error.Fail())
300 return false;
301 m_data_ptr = data_location + m_ptr_size;
302 return false;
303}
304
305bool
306lldb_private::formatters::NSDictionaryISyntheticFrontEnd::MightHaveChildren ()
307{
308 return true;
309}
310
311lldb::ValueObjectSP
312lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex (size_t idx)
313{
314 uint32_t num_children = CalculateNumChildren();
315
316 if (idx >= num_children)
317 return lldb::ValueObjectSP();
318
319 if (m_children.empty())
320 {
321 // do the scan phase
322 lldb::addr_t key_at_idx = 0, val_at_idx = 0;
323
324 uint32_t tries = 0;
325 uint32_t test_idx = 0;
326
327 while(tries < num_children)
328 {
329 key_at_idx = m_data_ptr + (2*test_idx * m_ptr_size);
330 val_at_idx = key_at_idx + m_ptr_size;
331 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
332 if (!process_sp)
333 return lldb::ValueObjectSP();
334 Error error;
335 key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
336 if (error.Fail())
337 return lldb::ValueObjectSP();
338 val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
339 if (error.Fail())
340 return lldb::ValueObjectSP();
341
342 test_idx++;
343
344 if (!key_at_idx || !val_at_idx)
345 continue;
346 tries++;
347
348 DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
349
350 m_children.push_back(descriptor);
351 }
352 }
353
354 if (idx >= m_children.size()) // should never happen
355 return lldb::ValueObjectSP();
356
357 DictionaryItemDescriptor &dict_item = m_children[idx];
358 if (!dict_item.valobj_sp)
359 {
Enrico Granataeb8bd922013-04-03 01:25:29 +0000360 if (!m_pair_type.IsValid())
361 {
362 TargetSP target_sp(m_backend.GetTargetSP());
363 if (!target_sp)
364 return ValueObjectSP();
365 m_pair_type = GetLLDBNSPairType(target_sp);
366 }
367 if (!m_pair_type.IsValid())
368 return ValueObjectSP();
369
370 DataBufferSP buffer_sp(new DataBufferHeap(2*m_ptr_size,0));
371
372 if (m_ptr_size == 8)
373 {
374 uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
375 *data_ptr = dict_item.key_ptr;
376 *(data_ptr+1) = dict_item.val_ptr;
377 }
378 else
379 {
380 uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
381 *data_ptr = dict_item.key_ptr;
382 *(data_ptr+1) = dict_item.val_ptr;
383 }
384
Enrico Granataf615b802013-02-15 23:38:37 +0000385 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000386 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granataeb8bd922013-04-03 01:25:29 +0000387 DataExtractor data(buffer_sp, m_order, m_ptr_size);
388 dict_item.valobj_sp = ValueObject::CreateValueObjectFromData(idx_name.GetData(), data, m_exe_ctx_ref, m_pair_type);
Enrico Granataf615b802013-02-15 23:38:37 +0000389 }
390 return dict_item.valobj_sp;
391}
392
393lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
394SyntheticChildrenFrontEnd(*valobj_sp.get()),
395m_exe_ctx_ref(),
396m_ptr_size(8),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000397m_order(lldb::eByteOrderInvalid),
Enrico Granataf615b802013-02-15 23:38:37 +0000398m_data_32(NULL),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000399m_data_64(NULL),
400m_pair_type()
Enrico Granataf615b802013-02-15 23:38:37 +0000401{
Enrico Granataf615b802013-02-15 23:38:37 +0000402}
403
404lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd ()
405{
406 delete m_data_32;
407 m_data_32 = NULL;
408 delete m_data_64;
409 m_data_64 = NULL;
410}
411
412size_t
413lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
414{
415 const char* item_name = name.GetCString();
416 uint32_t idx = ExtractIndexFromString(item_name);
417 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
418 return UINT32_MAX;
419 return idx;
420}
421
422size_t
423lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::CalculateNumChildren ()
424{
425 if (!m_data_32 && !m_data_64)
426 return 0;
427 return (m_data_32 ? m_data_32->_used : m_data_64->_used);
428}
429
430bool
431lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update()
432{
433 m_children.clear();
434 ValueObjectSP valobj_sp = m_backend.GetSP();
435 m_ptr_size = 0;
436 delete m_data_32;
437 m_data_32 = NULL;
438 delete m_data_64;
439 m_data_64 = NULL;
440 if (!valobj_sp)
441 return false;
Enrico Granataf615b802013-02-15 23:38:37 +0000442 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
443 Error error;
Enrico Granataf615b802013-02-15 23:38:37 +0000444 error.Clear();
445 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
446 if (!process_sp)
447 return false;
448 m_ptr_size = process_sp->GetAddressByteSize();
Enrico Granataeb8bd922013-04-03 01:25:29 +0000449 m_order = process_sp->GetByteOrder();
Enrico Granata723e1292013-04-23 01:13:50 +0000450 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
Enrico Granataf615b802013-02-15 23:38:37 +0000451 if (m_ptr_size == 4)
452 {
453 m_data_32 = new DataDescriptor_32();
454 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
455 }
456 else
457 {
458 m_data_64 = new DataDescriptor_64();
459 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
460 }
461 if (error.Fail())
462 return false;
463 return false;
464}
465
466bool
467lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::MightHaveChildren ()
468{
469 return true;
470}
471
472lldb::ValueObjectSP
473lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
474{
475 lldb::addr_t m_keys_ptr = (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
476 lldb::addr_t m_values_ptr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
477
478 uint32_t num_children = CalculateNumChildren();
479
480 if (idx >= num_children)
481 return lldb::ValueObjectSP();
482
483 if (m_children.empty())
484 {
485 // do the scan phase
486 lldb::addr_t key_at_idx = 0, val_at_idx = 0;
487
488 uint32_t tries = 0;
489 uint32_t test_idx = 0;
490
491 while(tries < num_children)
492 {
493 key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
494 val_at_idx = m_values_ptr + (test_idx * m_ptr_size);;
495 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
496 if (!process_sp)
497 return lldb::ValueObjectSP();
498 Error error;
499 key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
500 if (error.Fail())
501 return lldb::ValueObjectSP();
502 val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
503 if (error.Fail())
504 return lldb::ValueObjectSP();
505
506 test_idx++;
507
508 if (!key_at_idx || !val_at_idx)
509 continue;
510 tries++;
511
512 DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
513
514 m_children.push_back(descriptor);
515 }
516 }
517
518 if (idx >= m_children.size()) // should never happen
519 return lldb::ValueObjectSP();
520
521 DictionaryItemDescriptor &dict_item = m_children[idx];
522 if (!dict_item.valobj_sp)
523 {
Enrico Granataeb8bd922013-04-03 01:25:29 +0000524 if (!m_pair_type.IsValid())
525 {
526 TargetSP target_sp(m_backend.GetTargetSP());
527 if (!target_sp)
528 return ValueObjectSP();
529 m_pair_type = GetLLDBNSPairType(target_sp);
530 }
531 if (!m_pair_type.IsValid())
532 return ValueObjectSP();
533
534 DataBufferSP buffer_sp(new DataBufferHeap(2*m_ptr_size,0));
535
536 if (m_ptr_size == 8)
537 {
538 uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
539 *data_ptr = dict_item.key_ptr;
540 *(data_ptr+1) = dict_item.val_ptr;
541 }
542 else
543 {
544 uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
545 *data_ptr = dict_item.key_ptr;
546 *(data_ptr+1) = dict_item.val_ptr;
547 }
548
Enrico Granataf615b802013-02-15 23:38:37 +0000549 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000550 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granataeb8bd922013-04-03 01:25:29 +0000551 DataExtractor data(buffer_sp, m_order, m_ptr_size);
552 dict_item.valobj_sp = ValueObject::CreateValueObjectFromData(idx_name.GetData(), data, m_exe_ctx_ref, m_pair_type);
Enrico Granataf615b802013-02-15 23:38:37 +0000553 }
554 return dict_item.valobj_sp;
555}
556
557template bool
558lldb_private::formatters::NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
559
560template bool
561lldb_private::formatters::NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;