blob: ddd1e2e7ca90c1bd2f9664c7129914c05a5a4909 [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 {
Greg Clayton57ee3062013-07-11 22:46:58 +000039 clang::ASTContext *ast = target_ast_context->getASTContext();
40
41 if (ast)
Enrico Granataeb8bd922013-04-03 01:25:29 +000042 {
Greg Clayton57ee3062013-07-11 22:46:58 +000043 const char* type_name = "__lldb_autogen_nspair";
44
45 clang::IdentifierInfo &myIdent = ast->Idents.get(type_name);
46 clang::DeclarationName myName = ast->DeclarationNames.getIdentifier(&myIdent);
47
48 clang::DeclContext::lookup_const_result result = ast->getTranslationUnitDecl()->lookup(myName);
49
50 for (clang::NamedDecl *named_decl : result)
51 {
52 if (const clang::CXXRecordDecl *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(named_decl))
53 {
54 clang_type.SetClangType(ast, clang::QualType(record_decl->getTypeForDecl(), 0));
55 break;
56 }
57 else
58 {
59 // somebody else (the user?) has defined a type with the magic name already - fail!!!
60 return clang_type;
61 }
62 }
63
64 if (!clang_type)
65 {
66 clang_type = target_ast_context->CreateRecordType(NULL, lldb::eAccessPublic, type_name, clang::TTK_Struct, lldb::eLanguageTypeC);
67
68 if (clang_type)
69 {
70 clang_type.StartTagDeclarationDefinition();
71 ClangASTType id_clang_type = target_ast_context->GetBasicType (eBasicTypeObjCID);
72 clang_type.AddFieldToRecordType("key", id_clang_type, lldb::eAccessPublic, 0);
73 clang_type.AddFieldToRecordType("value", id_clang_type, lldb::eAccessPublic, 0);
74 clang_type.CompleteTagDeclarationDefinition();
75 }
76 }
Enrico Granataeb8bd922013-04-03 01:25:29 +000077 }
78 }
Enrico Granataeb8bd922013-04-03 01:25:29 +000079 return clang_type;
80}
81
Enrico Granataf615b802013-02-15 23:38:37 +000082template<bool name_entries>
83bool
84lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream)
85{
86 ProcessSP process_sp = valobj.GetProcessSP();
87 if (!process_sp)
88 return false;
89
90 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
91
92 if (!runtime)
93 return false;
94
95 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
96
97 if (!descriptor.get() || !descriptor->IsValid())
98 return false;
99
100 uint32_t ptr_size = process_sp->GetAddressByteSize();
101 bool is_64bit = (ptr_size == 8);
102
103 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
104
105 if (!valobj_addr)
106 return false;
107
108 uint64_t value = 0;
109
110 const char* class_name = descriptor->GetClassName().GetCString();
111
112 if (!class_name || !*class_name)
113 return false;
114
115 if (!strcmp(class_name,"__NSDictionaryI"))
116 {
117 Error error;
118 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
119 if (error.Fail())
120 return false;
121 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
122 }
123 else if (!strcmp(class_name,"__NSDictionaryM"))
124 {
125 Error error;
126 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
127 if (error.Fail())
128 return false;
129 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
130 }
Enrico Granataf68f7322013-03-15 18:44:08 +0000131 /*else if (!strcmp(class_name,"__NSCFDictionary"))
Enrico Granataf615b802013-02-15 23:38:37 +0000132 {
133 Error error;
Enrico Granataf68f7322013-03-15 18:44:08 +0000134 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error);
Enrico Granataf615b802013-02-15 23:38:37 +0000135 if (error.Fail())
136 return false;
137 if (is_64bit)
138 value &= ~0x0f1f000000000000UL;
Enrico Granataf68f7322013-03-15 18:44:08 +0000139 }*/
Enrico Granataf615b802013-02-15 23:38:37 +0000140 else
141 {
142 if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
143 return false;
144 }
145
146 stream.Printf("%s%" PRIu64 " %s%s",
147 (name_entries ? "@\"" : ""),
148 value,
149 (name_entries ? (value == 1 ? "entry" : "entries") : (value == 1 ? "key/value pair" : "key/value pairs")),
150 (name_entries ? "\"" : ""));
151 return true;
152}
153
154SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
155{
156
157 lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
158 if (!process_sp)
159 return NULL;
160 ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
161 if (!runtime)
162 return NULL;
163
164 if (!valobj_sp->IsPointerType())
165 {
166 Error error;
167 valobj_sp = valobj_sp->AddressOf(error);
168 if (error.Fail() || !valobj_sp)
169 return NULL;
170 }
171
172 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
173
174 if (!descriptor.get() || !descriptor->IsValid())
175 return NULL;
176
177 const char* class_name = descriptor->GetClassName().GetCString();
178
179 if (!class_name || !*class_name)
180 return NULL;
181
182 if (!strcmp(class_name,"__NSDictionaryI"))
183 {
184 return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
185 }
186 else if (!strcmp(class_name,"__NSDictionaryM"))
187 {
188 return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
189 }
190 else
191 {
192 return (new NSDictionaryCodeRunningSyntheticFrontEnd(valobj_sp));
193 }
194}
195
196lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
197SyntheticChildrenFrontEnd(*valobj_sp.get())
198{}
199
200size_t
201lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
202{
203 uint64_t count = 0;
204 if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
205 return count;
206 return 0;
207}
208
209lldb::ValueObjectSP
210lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetChildAtIndex (size_t idx)
211{
212 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000213 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granataf615b802013-02-15 23:38:37 +0000214 StreamString key_fetcher_expr;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000215 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 +0000216 StreamString value_fetcher_expr;
Enrico Granataa221e4e2013-02-25 19:44:39 +0000217 value_fetcher_expr.Printf("(id)[(id)0x%" PRIx64 " objectForKey:(%s)]",m_backend.GetPointerValue(),key_fetcher_expr.GetData());
Enrico Granataf615b802013-02-15 23:38:37 +0000218 StreamString object_fetcher_expr;
219 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());
220 lldb::ValueObjectSP child_sp;
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000221 EvaluateExpressionOptions options;
222 options.SetKeepInMemory(true);
Enrico Granataba8eb122014-07-30 21:07:50 +0000223 m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(),
224 GetViableFrame(m_backend.GetTargetSP().get()),
225 child_sp,
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000226 options);
Enrico Granataf615b802013-02-15 23:38:37 +0000227 if (child_sp)
228 child_sp->SetName(ConstString(idx_name.GetData()));
229 return child_sp;
230}
231
232bool
233lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::Update()
234{
235 return false;
236}
237
238bool
239lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::MightHaveChildren ()
240{
241 return true;
242}
243
244size_t
245lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
246{
247 return 0;
248}
249
250lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::~NSDictionaryCodeRunningSyntheticFrontEnd ()
251{}
252
253lldb_private::formatters::NSDictionaryISyntheticFrontEnd::NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
254SyntheticChildrenFrontEnd(*valobj_sp.get()),
255m_exe_ctx_ref(),
256m_ptr_size(8),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000257m_order(lldb::eByteOrderInvalid),
Enrico Granataf615b802013-02-15 23:38:37 +0000258m_data_32(NULL),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000259m_data_64(NULL),
260m_pair_type()
Enrico Granataf615b802013-02-15 23:38:37 +0000261{
Enrico Granataf615b802013-02-15 23:38:37 +0000262}
263
264lldb_private::formatters::NSDictionaryISyntheticFrontEnd::~NSDictionaryISyntheticFrontEnd ()
265{
266 delete m_data_32;
267 m_data_32 = NULL;
268 delete m_data_64;
269 m_data_64 = NULL;
270}
271
272size_t
273lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
274{
275 const char* item_name = name.GetCString();
276 uint32_t idx = ExtractIndexFromString(item_name);
277 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
278 return UINT32_MAX;
279 return idx;
280}
281
282size_t
283lldb_private::formatters::NSDictionaryISyntheticFrontEnd::CalculateNumChildren ()
284{
285 if (!m_data_32 && !m_data_64)
286 return 0;
287 return (m_data_32 ? m_data_32->_used : m_data_64->_used);
288}
289
290bool
291lldb_private::formatters::NSDictionaryISyntheticFrontEnd::Update()
292{
293 m_children.clear();
294 delete m_data_32;
295 m_data_32 = NULL;
296 delete m_data_64;
297 m_data_64 = NULL;
298 m_ptr_size = 0;
299 ValueObjectSP valobj_sp = m_backend.GetSP();
300 if (!valobj_sp)
301 return false;
Enrico Granataf615b802013-02-15 23:38:37 +0000302 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
303 Error error;
Enrico Granataf615b802013-02-15 23:38:37 +0000304 error.Clear();
305 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
306 if (!process_sp)
307 return false;
308 m_ptr_size = process_sp->GetAddressByteSize();
Enrico Granataeb8bd922013-04-03 01:25:29 +0000309 m_order = process_sp->GetByteOrder();
Enrico Granata723e1292013-04-23 01:13:50 +0000310 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
Enrico Granataf615b802013-02-15 23:38:37 +0000311 if (m_ptr_size == 4)
312 {
313 m_data_32 = new DataDescriptor_32();
314 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
315 }
316 else
317 {
318 m_data_64 = new DataDescriptor_64();
319 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
320 }
321 if (error.Fail())
322 return false;
323 m_data_ptr = data_location + m_ptr_size;
324 return false;
325}
326
327bool
328lldb_private::formatters::NSDictionaryISyntheticFrontEnd::MightHaveChildren ()
329{
330 return true;
331}
332
333lldb::ValueObjectSP
334lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex (size_t idx)
335{
336 uint32_t num_children = CalculateNumChildren();
337
338 if (idx >= num_children)
339 return lldb::ValueObjectSP();
340
341 if (m_children.empty())
342 {
343 // do the scan phase
344 lldb::addr_t key_at_idx = 0, val_at_idx = 0;
345
346 uint32_t tries = 0;
347 uint32_t test_idx = 0;
348
349 while(tries < num_children)
350 {
351 key_at_idx = m_data_ptr + (2*test_idx * m_ptr_size);
352 val_at_idx = key_at_idx + m_ptr_size;
353 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
354 if (!process_sp)
355 return lldb::ValueObjectSP();
356 Error error;
357 key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
358 if (error.Fail())
359 return lldb::ValueObjectSP();
360 val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
361 if (error.Fail())
362 return lldb::ValueObjectSP();
363
364 test_idx++;
365
366 if (!key_at_idx || !val_at_idx)
367 continue;
368 tries++;
369
370 DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
371
372 m_children.push_back(descriptor);
373 }
374 }
375
376 if (idx >= m_children.size()) // should never happen
377 return lldb::ValueObjectSP();
378
379 DictionaryItemDescriptor &dict_item = m_children[idx];
380 if (!dict_item.valobj_sp)
381 {
Enrico Granataeb8bd922013-04-03 01:25:29 +0000382 if (!m_pair_type.IsValid())
383 {
384 TargetSP target_sp(m_backend.GetTargetSP());
385 if (!target_sp)
386 return ValueObjectSP();
387 m_pair_type = GetLLDBNSPairType(target_sp);
388 }
389 if (!m_pair_type.IsValid())
390 return ValueObjectSP();
391
392 DataBufferSP buffer_sp(new DataBufferHeap(2*m_ptr_size,0));
393
394 if (m_ptr_size == 8)
395 {
396 uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
397 *data_ptr = dict_item.key_ptr;
398 *(data_ptr+1) = dict_item.val_ptr;
399 }
400 else
401 {
402 uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
403 *data_ptr = dict_item.key_ptr;
404 *(data_ptr+1) = dict_item.val_ptr;
405 }
406
Enrico Granataf615b802013-02-15 23:38:37 +0000407 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000408 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granataeb8bd922013-04-03 01:25:29 +0000409 DataExtractor data(buffer_sp, m_order, m_ptr_size);
410 dict_item.valobj_sp = ValueObject::CreateValueObjectFromData(idx_name.GetData(), data, m_exe_ctx_ref, m_pair_type);
Enrico Granataf615b802013-02-15 23:38:37 +0000411 }
412 return dict_item.valobj_sp;
413}
414
415lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
416SyntheticChildrenFrontEnd(*valobj_sp.get()),
417m_exe_ctx_ref(),
418m_ptr_size(8),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000419m_order(lldb::eByteOrderInvalid),
Enrico Granataf615b802013-02-15 23:38:37 +0000420m_data_32(NULL),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000421m_data_64(NULL),
422m_pair_type()
Enrico Granataf615b802013-02-15 23:38:37 +0000423{
Enrico Granataf615b802013-02-15 23:38:37 +0000424}
425
426lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd ()
427{
428 delete m_data_32;
429 m_data_32 = NULL;
430 delete m_data_64;
431 m_data_64 = NULL;
432}
433
434size_t
435lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
436{
437 const char* item_name = name.GetCString();
438 uint32_t idx = ExtractIndexFromString(item_name);
439 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
440 return UINT32_MAX;
441 return idx;
442}
443
444size_t
445lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::CalculateNumChildren ()
446{
447 if (!m_data_32 && !m_data_64)
448 return 0;
449 return (m_data_32 ? m_data_32->_used : m_data_64->_used);
450}
451
452bool
453lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update()
454{
455 m_children.clear();
456 ValueObjectSP valobj_sp = m_backend.GetSP();
457 m_ptr_size = 0;
458 delete m_data_32;
459 m_data_32 = NULL;
460 delete m_data_64;
461 m_data_64 = NULL;
462 if (!valobj_sp)
463 return false;
Enrico Granataf615b802013-02-15 23:38:37 +0000464 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
465 Error error;
Enrico Granataf615b802013-02-15 23:38:37 +0000466 error.Clear();
467 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
468 if (!process_sp)
469 return false;
470 m_ptr_size = process_sp->GetAddressByteSize();
Enrico Granataeb8bd922013-04-03 01:25:29 +0000471 m_order = process_sp->GetByteOrder();
Enrico Granata723e1292013-04-23 01:13:50 +0000472 uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
Enrico Granataf615b802013-02-15 23:38:37 +0000473 if (m_ptr_size == 4)
474 {
475 m_data_32 = new DataDescriptor_32();
476 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
477 }
478 else
479 {
480 m_data_64 = new DataDescriptor_64();
481 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
482 }
483 if (error.Fail())
484 return false;
485 return false;
486}
487
488bool
489lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::MightHaveChildren ()
490{
491 return true;
492}
493
494lldb::ValueObjectSP
495lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
496{
497 lldb::addr_t m_keys_ptr = (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
498 lldb::addr_t m_values_ptr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
499
500 uint32_t num_children = CalculateNumChildren();
501
502 if (idx >= num_children)
503 return lldb::ValueObjectSP();
504
505 if (m_children.empty())
506 {
507 // do the scan phase
508 lldb::addr_t key_at_idx = 0, val_at_idx = 0;
509
510 uint32_t tries = 0;
511 uint32_t test_idx = 0;
512
513 while(tries < num_children)
514 {
515 key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
516 val_at_idx = m_values_ptr + (test_idx * m_ptr_size);;
517 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
518 if (!process_sp)
519 return lldb::ValueObjectSP();
520 Error error;
521 key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
522 if (error.Fail())
523 return lldb::ValueObjectSP();
524 val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
525 if (error.Fail())
526 return lldb::ValueObjectSP();
527
528 test_idx++;
529
530 if (!key_at_idx || !val_at_idx)
531 continue;
532 tries++;
533
534 DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
535
536 m_children.push_back(descriptor);
537 }
538 }
539
540 if (idx >= m_children.size()) // should never happen
541 return lldb::ValueObjectSP();
542
543 DictionaryItemDescriptor &dict_item = m_children[idx];
544 if (!dict_item.valobj_sp)
545 {
Enrico Granataeb8bd922013-04-03 01:25:29 +0000546 if (!m_pair_type.IsValid())
547 {
548 TargetSP target_sp(m_backend.GetTargetSP());
549 if (!target_sp)
550 return ValueObjectSP();
551 m_pair_type = GetLLDBNSPairType(target_sp);
552 }
553 if (!m_pair_type.IsValid())
554 return ValueObjectSP();
555
556 DataBufferSP buffer_sp(new DataBufferHeap(2*m_ptr_size,0));
557
558 if (m_ptr_size == 8)
559 {
560 uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
561 *data_ptr = dict_item.key_ptr;
562 *(data_ptr+1) = dict_item.val_ptr;
563 }
564 else
565 {
566 uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
567 *data_ptr = dict_item.key_ptr;
568 *(data_ptr+1) = dict_item.val_ptr;
569 }
570
Enrico Granataf615b802013-02-15 23:38:37 +0000571 StreamString idx_name;
Deepak Panickal99fbc072014-03-03 15:39:47 +0000572 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
Enrico Granataeb8bd922013-04-03 01:25:29 +0000573 DataExtractor data(buffer_sp, m_order, m_ptr_size);
574 dict_item.valobj_sp = ValueObject::CreateValueObjectFromData(idx_name.GetData(), data, m_exe_ctx_ref, m_pair_type);
Enrico Granataf615b802013-02-15 23:38:37 +0000575 }
576 return dict_item.valobj_sp;
577}
578
579template bool
580lldb_private::formatters::NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
581
582template bool
583lldb_private::formatters::NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;