blob: 54d6652c1fcdd650cf7a892f149e8ba089b04a66 [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{
33 ClangASTType clang_type = ClangASTType();
34
35 ClangASTContext *target_ast_context = target_sp->GetScratchClangASTContext();
36
37 if (!target_ast_context)
38 return clang_type;
39
40 const char* type_name = "__lldb_autogen_nspair";
41
42 clang::IdentifierInfo &myIdent = target_ast_context->getASTContext()->Idents.get(type_name);
43 clang::DeclarationName myName = target_ast_context->getASTContext()->DeclarationNames.getIdentifier(&myIdent);
44
45 clang::DeclContext::lookup_const_result result = target_ast_context->getASTContext()->getTranslationUnitDecl()->lookup(myName);
46
47 clang_type_t opaque_type = NULL;
48
49 for (clang::NamedDecl *named_decl : result)
50 {
51 if (const clang::CXXRecordDecl *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(named_decl))
52 {
53 opaque_type = clang::QualType(record_decl->getTypeForDecl(), 0).getAsOpaquePtr();
54 break;
55 }
56 else
57 {
58 // somebody else (the user?) has defined a type with the magic name already - fail!!!
59 return clang_type;
60 }
61 }
62
63 if (!opaque_type)
64 {
65 opaque_type = target_ast_context->CreateRecordType(NULL, lldb::eAccessPublic, type_name, clang::TTK_Struct, lldb::eLanguageTypeC);
66
67 if (!opaque_type)
68 return clang_type;
69
70 target_ast_context->StartTagDeclarationDefinition(opaque_type);
71
72 target_ast_context->AddFieldToRecordType(opaque_type, "key", target_ast_context->GetBuiltInType_objc_id(), lldb::eAccessPublic, 0);
73 target_ast_context->AddFieldToRecordType(opaque_type, "value", target_ast_context->GetBuiltInType_objc_id(), lldb::eAccessPublic, 0);
74
75 target_ast_context->CompleteTagDeclarationDefinition(opaque_type);
76 }
77
78 clang_type.SetClangType(target_ast_context->getASTContext(), opaque_type);
79 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;
213 idx_name.Printf("[%zu]",idx);
Enrico Granataf615b802013-02-15 23:38:37 +0000214 StreamString key_fetcher_expr;
Enrico Granataa221e4e2013-02-25 19:44:39 +0000215 key_fetcher_expr.Printf("(id)[(NSArray*)[(id)0x%" PRIx64 " allKeys] objectAtIndex:%zu]",m_backend.GetPointerValue(),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;
221 m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(), m_backend.GetFrameSP().get(), child_sp,
222 EvaluateExpressionOptions().SetKeepInMemory(true));
223 if (child_sp)
224 child_sp->SetName(ConstString(idx_name.GetData()));
225 return child_sp;
226}
227
228bool
229lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::Update()
230{
231 return false;
232}
233
234bool
235lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::MightHaveChildren ()
236{
237 return true;
238}
239
240size_t
241lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
242{
243 return 0;
244}
245
246lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::~NSDictionaryCodeRunningSyntheticFrontEnd ()
247{}
248
249lldb_private::formatters::NSDictionaryISyntheticFrontEnd::NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
250SyntheticChildrenFrontEnd(*valobj_sp.get()),
251m_exe_ctx_ref(),
252m_ptr_size(8),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000253m_order(lldb::eByteOrderInvalid),
Enrico Granataf615b802013-02-15 23:38:37 +0000254m_data_32(NULL),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000255m_data_64(NULL),
256m_pair_type()
Enrico Granataf615b802013-02-15 23:38:37 +0000257{
258 if (valobj_sp)
259 Update();
260}
261
262lldb_private::formatters::NSDictionaryISyntheticFrontEnd::~NSDictionaryISyntheticFrontEnd ()
263{
264 delete m_data_32;
265 m_data_32 = NULL;
266 delete m_data_64;
267 m_data_64 = NULL;
268}
269
270size_t
271lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
272{
273 const char* item_name = name.GetCString();
274 uint32_t idx = ExtractIndexFromString(item_name);
275 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
276 return UINT32_MAX;
277 return idx;
278}
279
280size_t
281lldb_private::formatters::NSDictionaryISyntheticFrontEnd::CalculateNumChildren ()
282{
283 if (!m_data_32 && !m_data_64)
284 return 0;
285 return (m_data_32 ? m_data_32->_used : m_data_64->_used);
286}
287
288bool
289lldb_private::formatters::NSDictionaryISyntheticFrontEnd::Update()
290{
291 m_children.clear();
292 delete m_data_32;
293 m_data_32 = NULL;
294 delete m_data_64;
295 m_data_64 = NULL;
296 m_ptr_size = 0;
297 ValueObjectSP valobj_sp = m_backend.GetSP();
298 if (!valobj_sp)
299 return false;
Enrico Granataf615b802013-02-15 23:38:37 +0000300 if (!valobj_sp)
301 return false;
302 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
303 Error error;
304 if (valobj_sp->IsPointerType())
305 {
306 valobj_sp = valobj_sp->Dereference(error);
307 if (error.Fail() || !valobj_sp)
308 return false;
309 }
310 error.Clear();
311 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
312 if (!process_sp)
313 return false;
314 m_ptr_size = process_sp->GetAddressByteSize();
Enrico Granataeb8bd922013-04-03 01:25:29 +0000315 m_order = process_sp->GetByteOrder();
Enrico Granataf615b802013-02-15 23:38:37 +0000316 uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
317 if (m_ptr_size == 4)
318 {
319 m_data_32 = new DataDescriptor_32();
320 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
321 }
322 else
323 {
324 m_data_64 = new DataDescriptor_64();
325 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
326 }
327 if (error.Fail())
328 return false;
329 m_data_ptr = data_location + m_ptr_size;
330 return false;
331}
332
333bool
334lldb_private::formatters::NSDictionaryISyntheticFrontEnd::MightHaveChildren ()
335{
336 return true;
337}
338
339lldb::ValueObjectSP
340lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex (size_t idx)
341{
342 uint32_t num_children = CalculateNumChildren();
343
344 if (idx >= num_children)
345 return lldb::ValueObjectSP();
346
347 if (m_children.empty())
348 {
349 // do the scan phase
350 lldb::addr_t key_at_idx = 0, val_at_idx = 0;
351
352 uint32_t tries = 0;
353 uint32_t test_idx = 0;
354
355 while(tries < num_children)
356 {
357 key_at_idx = m_data_ptr + (2*test_idx * m_ptr_size);
358 val_at_idx = key_at_idx + m_ptr_size;
359 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
360 if (!process_sp)
361 return lldb::ValueObjectSP();
362 Error error;
363 key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
364 if (error.Fail())
365 return lldb::ValueObjectSP();
366 val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
367 if (error.Fail())
368 return lldb::ValueObjectSP();
369
370 test_idx++;
371
372 if (!key_at_idx || !val_at_idx)
373 continue;
374 tries++;
375
376 DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
377
378 m_children.push_back(descriptor);
379 }
380 }
381
382 if (idx >= m_children.size()) // should never happen
383 return lldb::ValueObjectSP();
384
385 DictionaryItemDescriptor &dict_item = m_children[idx];
386 if (!dict_item.valobj_sp)
387 {
Enrico Granataeb8bd922013-04-03 01:25:29 +0000388 if (!m_pair_type.IsValid())
389 {
390 TargetSP target_sp(m_backend.GetTargetSP());
391 if (!target_sp)
392 return ValueObjectSP();
393 m_pair_type = GetLLDBNSPairType(target_sp);
394 }
395 if (!m_pair_type.IsValid())
396 return ValueObjectSP();
397
398 DataBufferSP buffer_sp(new DataBufferHeap(2*m_ptr_size,0));
399
400 if (m_ptr_size == 8)
401 {
402 uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
403 *data_ptr = dict_item.key_ptr;
404 *(data_ptr+1) = dict_item.val_ptr;
405 }
406 else
407 {
408 uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
409 *data_ptr = dict_item.key_ptr;
410 *(data_ptr+1) = dict_item.val_ptr;
411 }
412
Enrico Granataf615b802013-02-15 23:38:37 +0000413 StreamString idx_name;
414 idx_name.Printf("[%zu]",idx);
Enrico Granataeb8bd922013-04-03 01:25:29 +0000415 DataExtractor data(buffer_sp, m_order, m_ptr_size);
416 dict_item.valobj_sp = ValueObject::CreateValueObjectFromData(idx_name.GetData(), data, m_exe_ctx_ref, m_pair_type);
Enrico Granataf615b802013-02-15 23:38:37 +0000417 }
418 return dict_item.valobj_sp;
419}
420
421lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
422SyntheticChildrenFrontEnd(*valobj_sp.get()),
423m_exe_ctx_ref(),
424m_ptr_size(8),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000425m_order(lldb::eByteOrderInvalid),
Enrico Granataf615b802013-02-15 23:38:37 +0000426m_data_32(NULL),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000427m_data_64(NULL),
428m_pair_type()
Enrico Granataf615b802013-02-15 23:38:37 +0000429{
430 if (valobj_sp)
431 Update ();
432}
433
434lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd ()
435{
436 delete m_data_32;
437 m_data_32 = NULL;
438 delete m_data_64;
439 m_data_64 = NULL;
440}
441
442size_t
443lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
444{
445 const char* item_name = name.GetCString();
446 uint32_t idx = ExtractIndexFromString(item_name);
447 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
448 return UINT32_MAX;
449 return idx;
450}
451
452size_t
453lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::CalculateNumChildren ()
454{
455 if (!m_data_32 && !m_data_64)
456 return 0;
457 return (m_data_32 ? m_data_32->_used : m_data_64->_used);
458}
459
460bool
461lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update()
462{
463 m_children.clear();
464 ValueObjectSP valobj_sp = m_backend.GetSP();
465 m_ptr_size = 0;
466 delete m_data_32;
467 m_data_32 = NULL;
468 delete m_data_64;
469 m_data_64 = NULL;
470 if (!valobj_sp)
471 return false;
Enrico Granataf615b802013-02-15 23:38:37 +0000472 if (!valobj_sp)
473 return false;
474 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
475 Error error;
476 if (valobj_sp->IsPointerType())
477 {
478 valobj_sp = valobj_sp->Dereference(error);
479 if (error.Fail() || !valobj_sp)
480 return false;
481 }
482 error.Clear();
483 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
484 if (!process_sp)
485 return false;
486 m_ptr_size = process_sp->GetAddressByteSize();
Enrico Granataeb8bd922013-04-03 01:25:29 +0000487 m_order = process_sp->GetByteOrder();
Enrico Granataf615b802013-02-15 23:38:37 +0000488 uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
489 if (m_ptr_size == 4)
490 {
491 m_data_32 = new DataDescriptor_32();
492 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
493 }
494 else
495 {
496 m_data_64 = new DataDescriptor_64();
497 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
498 }
499 if (error.Fail())
500 return false;
501 return false;
502}
503
504bool
505lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::MightHaveChildren ()
506{
507 return true;
508}
509
510lldb::ValueObjectSP
511lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
512{
513 lldb::addr_t m_keys_ptr = (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
514 lldb::addr_t m_values_ptr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
515
516 uint32_t num_children = CalculateNumChildren();
517
518 if (idx >= num_children)
519 return lldb::ValueObjectSP();
520
521 if (m_children.empty())
522 {
523 // do the scan phase
524 lldb::addr_t key_at_idx = 0, val_at_idx = 0;
525
526 uint32_t tries = 0;
527 uint32_t test_idx = 0;
528
529 while(tries < num_children)
530 {
531 key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
532 val_at_idx = m_values_ptr + (test_idx * m_ptr_size);;
533 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
534 if (!process_sp)
535 return lldb::ValueObjectSP();
536 Error error;
537 key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
538 if (error.Fail())
539 return lldb::ValueObjectSP();
540 val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
541 if (error.Fail())
542 return lldb::ValueObjectSP();
543
544 test_idx++;
545
546 if (!key_at_idx || !val_at_idx)
547 continue;
548 tries++;
549
550 DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
551
552 m_children.push_back(descriptor);
553 }
554 }
555
556 if (idx >= m_children.size()) // should never happen
557 return lldb::ValueObjectSP();
558
559 DictionaryItemDescriptor &dict_item = m_children[idx];
560 if (!dict_item.valobj_sp)
561 {
Enrico Granataeb8bd922013-04-03 01:25:29 +0000562 if (!m_pair_type.IsValid())
563 {
564 TargetSP target_sp(m_backend.GetTargetSP());
565 if (!target_sp)
566 return ValueObjectSP();
567 m_pair_type = GetLLDBNSPairType(target_sp);
568 }
569 if (!m_pair_type.IsValid())
570 return ValueObjectSP();
571
572 DataBufferSP buffer_sp(new DataBufferHeap(2*m_ptr_size,0));
573
574 if (m_ptr_size == 8)
575 {
576 uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
577 *data_ptr = dict_item.key_ptr;
578 *(data_ptr+1) = dict_item.val_ptr;
579 }
580 else
581 {
582 uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
583 *data_ptr = dict_item.key_ptr;
584 *(data_ptr+1) = dict_item.val_ptr;
585 }
586
Enrico Granataf615b802013-02-15 23:38:37 +0000587 StreamString idx_name;
588 idx_name.Printf("[%zu]",idx);
Enrico Granataeb8bd922013-04-03 01:25:29 +0000589 DataExtractor data(buffer_sp, m_order, m_ptr_size);
590 dict_item.valobj_sp = ValueObject::CreateValueObjectFromData(idx_name.GetData(), data, m_exe_ctx_ref, m_pair_type);
Enrico Granataf615b802013-02-15 23:38:37 +0000591 }
592 return dict_item.valobj_sp;
593}
594
595template bool
596lldb_private::formatters::NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
597
598template bool
599lldb_private::formatters::NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;