blob: bcc3e0c471c9523d7c35077a21aabb5307098173 [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
24using namespace lldb;
25using namespace lldb_private;
26using namespace lldb_private::formatters;
27
Enrico Granataeb8bd922013-04-03 01:25:29 +000028static ClangASTType
29GetLLDBNSPairType (TargetSP target_sp)
30{
31 ClangASTType clang_type = ClangASTType();
32
33 ClangASTContext *target_ast_context = target_sp->GetScratchClangASTContext();
34
35 if (!target_ast_context)
36 return clang_type;
37
38 const char* type_name = "__lldb_autogen_nspair";
39
40 clang::IdentifierInfo &myIdent = target_ast_context->getASTContext()->Idents.get(type_name);
41 clang::DeclarationName myName = target_ast_context->getASTContext()->DeclarationNames.getIdentifier(&myIdent);
42
43 clang::DeclContext::lookup_const_result result = target_ast_context->getASTContext()->getTranslationUnitDecl()->lookup(myName);
44
45 clang_type_t opaque_type = NULL;
46
47 for (clang::NamedDecl *named_decl : result)
48 {
49 if (const clang::CXXRecordDecl *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(named_decl))
50 {
51 opaque_type = clang::QualType(record_decl->getTypeForDecl(), 0).getAsOpaquePtr();
52 break;
53 }
54 else
55 {
56 // somebody else (the user?) has defined a type with the magic name already - fail!!!
57 return clang_type;
58 }
59 }
60
61 if (!opaque_type)
62 {
63 opaque_type = target_ast_context->CreateRecordType(NULL, lldb::eAccessPublic, type_name, clang::TTK_Struct, lldb::eLanguageTypeC);
64
65 if (!opaque_type)
66 return clang_type;
67
68 target_ast_context->StartTagDeclarationDefinition(opaque_type);
69
70 target_ast_context->AddFieldToRecordType(opaque_type, "key", target_ast_context->GetBuiltInType_objc_id(), lldb::eAccessPublic, 0);
71 target_ast_context->AddFieldToRecordType(opaque_type, "value", target_ast_context->GetBuiltInType_objc_id(), lldb::eAccessPublic, 0);
72
73 target_ast_context->CompleteTagDeclarationDefinition(opaque_type);
74 }
75
76 clang_type.SetClangType(target_ast_context->getASTContext(), opaque_type);
77 return clang_type;
78}
79
Enrico Granataf615b802013-02-15 23:38:37 +000080template<bool name_entries>
81bool
82lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream)
83{
84 ProcessSP process_sp = valobj.GetProcessSP();
85 if (!process_sp)
86 return false;
87
88 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
89
90 if (!runtime)
91 return false;
92
93 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
94
95 if (!descriptor.get() || !descriptor->IsValid())
96 return false;
97
98 uint32_t ptr_size = process_sp->GetAddressByteSize();
99 bool is_64bit = (ptr_size == 8);
100
101 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
102
103 if (!valobj_addr)
104 return false;
105
106 uint64_t value = 0;
107
108 const char* class_name = descriptor->GetClassName().GetCString();
109
110 if (!class_name || !*class_name)
111 return false;
112
113 if (!strcmp(class_name,"__NSDictionaryI"))
114 {
115 Error error;
116 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
117 if (error.Fail())
118 return false;
119 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
120 }
121 else if (!strcmp(class_name,"__NSDictionaryM"))
122 {
123 Error error;
124 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
125 if (error.Fail())
126 return false;
127 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
128 }
Enrico Granataf68f7322013-03-15 18:44:08 +0000129 /*else if (!strcmp(class_name,"__NSCFDictionary"))
Enrico Granataf615b802013-02-15 23:38:37 +0000130 {
131 Error error;
Enrico Granataf68f7322013-03-15 18:44:08 +0000132 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error);
Enrico Granataf615b802013-02-15 23:38:37 +0000133 if (error.Fail())
134 return false;
135 if (is_64bit)
136 value &= ~0x0f1f000000000000UL;
Enrico Granataf68f7322013-03-15 18:44:08 +0000137 }*/
Enrico Granataf615b802013-02-15 23:38:37 +0000138 else
139 {
140 if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
141 return false;
142 }
143
144 stream.Printf("%s%" PRIu64 " %s%s",
145 (name_entries ? "@\"" : ""),
146 value,
147 (name_entries ? (value == 1 ? "entry" : "entries") : (value == 1 ? "key/value pair" : "key/value pairs")),
148 (name_entries ? "\"" : ""));
149 return true;
150}
151
152SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
153{
154
155 lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
156 if (!process_sp)
157 return NULL;
158 ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
159 if (!runtime)
160 return NULL;
161
162 if (!valobj_sp->IsPointerType())
163 {
164 Error error;
165 valobj_sp = valobj_sp->AddressOf(error);
166 if (error.Fail() || !valobj_sp)
167 return NULL;
168 }
169
170 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
171
172 if (!descriptor.get() || !descriptor->IsValid())
173 return NULL;
174
175 const char* class_name = descriptor->GetClassName().GetCString();
176
177 if (!class_name || !*class_name)
178 return NULL;
179
180 if (!strcmp(class_name,"__NSDictionaryI"))
181 {
182 return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
183 }
184 else if (!strcmp(class_name,"__NSDictionaryM"))
185 {
186 return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
187 }
188 else
189 {
190 return (new NSDictionaryCodeRunningSyntheticFrontEnd(valobj_sp));
191 }
192}
193
194lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
195SyntheticChildrenFrontEnd(*valobj_sp.get())
196{}
197
198size_t
199lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
200{
201 uint64_t count = 0;
202 if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
203 return count;
204 return 0;
205}
206
207lldb::ValueObjectSP
208lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetChildAtIndex (size_t idx)
209{
210 StreamString idx_name;
211 idx_name.Printf("[%zu]",idx);
Enrico Granataf615b802013-02-15 23:38:37 +0000212 StreamString key_fetcher_expr;
Enrico Granataa221e4e2013-02-25 19:44:39 +0000213 key_fetcher_expr.Printf("(id)[(NSArray*)[(id)0x%" PRIx64 " allKeys] objectAtIndex:%zu]",m_backend.GetPointerValue(),idx);
Enrico Granataf615b802013-02-15 23:38:37 +0000214 StreamString value_fetcher_expr;
Enrico Granataa221e4e2013-02-25 19:44:39 +0000215 value_fetcher_expr.Printf("(id)[(id)0x%" PRIx64 " objectForKey:(%s)]",m_backend.GetPointerValue(),key_fetcher_expr.GetData());
Enrico Granataf615b802013-02-15 23:38:37 +0000216 StreamString object_fetcher_expr;
217 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());
218 lldb::ValueObjectSP child_sp;
219 m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(), m_backend.GetFrameSP().get(), child_sp,
220 EvaluateExpressionOptions().SetKeepInMemory(true));
221 if (child_sp)
222 child_sp->SetName(ConstString(idx_name.GetData()));
223 return child_sp;
224}
225
226bool
227lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::Update()
228{
229 return false;
230}
231
232bool
233lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::MightHaveChildren ()
234{
235 return true;
236}
237
238size_t
239lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
240{
241 return 0;
242}
243
244lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::~NSDictionaryCodeRunningSyntheticFrontEnd ()
245{}
246
247lldb_private::formatters::NSDictionaryISyntheticFrontEnd::NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
248SyntheticChildrenFrontEnd(*valobj_sp.get()),
249m_exe_ctx_ref(),
250m_ptr_size(8),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000251m_order(lldb::eByteOrderInvalid),
Enrico Granataf615b802013-02-15 23:38:37 +0000252m_data_32(NULL),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000253m_data_64(NULL),
254m_pair_type()
Enrico Granataf615b802013-02-15 23:38:37 +0000255{
256 if (valobj_sp)
257 Update();
258}
259
260lldb_private::formatters::NSDictionaryISyntheticFrontEnd::~NSDictionaryISyntheticFrontEnd ()
261{
262 delete m_data_32;
263 m_data_32 = NULL;
264 delete m_data_64;
265 m_data_64 = NULL;
266}
267
268size_t
269lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
270{
271 const char* item_name = name.GetCString();
272 uint32_t idx = ExtractIndexFromString(item_name);
273 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
274 return UINT32_MAX;
275 return idx;
276}
277
278size_t
279lldb_private::formatters::NSDictionaryISyntheticFrontEnd::CalculateNumChildren ()
280{
281 if (!m_data_32 && !m_data_64)
282 return 0;
283 return (m_data_32 ? m_data_32->_used : m_data_64->_used);
284}
285
286bool
287lldb_private::formatters::NSDictionaryISyntheticFrontEnd::Update()
288{
289 m_children.clear();
290 delete m_data_32;
291 m_data_32 = NULL;
292 delete m_data_64;
293 m_data_64 = NULL;
294 m_ptr_size = 0;
295 ValueObjectSP valobj_sp = m_backend.GetSP();
296 if (!valobj_sp)
297 return false;
Enrico Granataf615b802013-02-15 23:38:37 +0000298 if (!valobj_sp)
299 return false;
300 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
301 Error error;
302 if (valobj_sp->IsPointerType())
303 {
304 valobj_sp = valobj_sp->Dereference(error);
305 if (error.Fail() || !valobj_sp)
306 return false;
307 }
308 error.Clear();
309 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
310 if (!process_sp)
311 return false;
312 m_ptr_size = process_sp->GetAddressByteSize();
Enrico Granataeb8bd922013-04-03 01:25:29 +0000313 m_order = process_sp->GetByteOrder();
Enrico Granataf615b802013-02-15 23:38:37 +0000314 uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
315 if (m_ptr_size == 4)
316 {
317 m_data_32 = new DataDescriptor_32();
318 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
319 }
320 else
321 {
322 m_data_64 = new DataDescriptor_64();
323 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
324 }
325 if (error.Fail())
326 return false;
327 m_data_ptr = data_location + m_ptr_size;
328 return false;
329}
330
331bool
332lldb_private::formatters::NSDictionaryISyntheticFrontEnd::MightHaveChildren ()
333{
334 return true;
335}
336
337lldb::ValueObjectSP
338lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex (size_t idx)
339{
340 uint32_t num_children = CalculateNumChildren();
341
342 if (idx >= num_children)
343 return lldb::ValueObjectSP();
344
345 if (m_children.empty())
346 {
347 // do the scan phase
348 lldb::addr_t key_at_idx = 0, val_at_idx = 0;
349
350 uint32_t tries = 0;
351 uint32_t test_idx = 0;
352
353 while(tries < num_children)
354 {
355 key_at_idx = m_data_ptr + (2*test_idx * m_ptr_size);
356 val_at_idx = key_at_idx + m_ptr_size;
357 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
358 if (!process_sp)
359 return lldb::ValueObjectSP();
360 Error error;
361 key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
362 if (error.Fail())
363 return lldb::ValueObjectSP();
364 val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
365 if (error.Fail())
366 return lldb::ValueObjectSP();
367
368 test_idx++;
369
370 if (!key_at_idx || !val_at_idx)
371 continue;
372 tries++;
373
374 DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
375
376 m_children.push_back(descriptor);
377 }
378 }
379
380 if (idx >= m_children.size()) // should never happen
381 return lldb::ValueObjectSP();
382
383 DictionaryItemDescriptor &dict_item = m_children[idx];
384 if (!dict_item.valobj_sp)
385 {
Enrico Granataeb8bd922013-04-03 01:25:29 +0000386 if (!m_pair_type.IsValid())
387 {
388 TargetSP target_sp(m_backend.GetTargetSP());
389 if (!target_sp)
390 return ValueObjectSP();
391 m_pair_type = GetLLDBNSPairType(target_sp);
392 }
393 if (!m_pair_type.IsValid())
394 return ValueObjectSP();
395
396 DataBufferSP buffer_sp(new DataBufferHeap(2*m_ptr_size,0));
397
398 if (m_ptr_size == 8)
399 {
400 uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
401 *data_ptr = dict_item.key_ptr;
402 *(data_ptr+1) = dict_item.val_ptr;
403 }
404 else
405 {
406 uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
407 *data_ptr = dict_item.key_ptr;
408 *(data_ptr+1) = dict_item.val_ptr;
409 }
410
Enrico Granataf615b802013-02-15 23:38:37 +0000411 StreamString idx_name;
412 idx_name.Printf("[%zu]",idx);
Enrico Granataeb8bd922013-04-03 01:25:29 +0000413 DataExtractor data(buffer_sp, m_order, m_ptr_size);
414 dict_item.valobj_sp = ValueObject::CreateValueObjectFromData(idx_name.GetData(), data, m_exe_ctx_ref, m_pair_type);
Enrico Granataf615b802013-02-15 23:38:37 +0000415 }
416 return dict_item.valobj_sp;
417}
418
419lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
420SyntheticChildrenFrontEnd(*valobj_sp.get()),
421m_exe_ctx_ref(),
422m_ptr_size(8),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000423m_order(lldb::eByteOrderInvalid),
Enrico Granataf615b802013-02-15 23:38:37 +0000424m_data_32(NULL),
Enrico Granataeb8bd922013-04-03 01:25:29 +0000425m_data_64(NULL),
426m_pair_type()
Enrico Granataf615b802013-02-15 23:38:37 +0000427{
428 if (valobj_sp)
429 Update ();
430}
431
432lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd ()
433{
434 delete m_data_32;
435 m_data_32 = NULL;
436 delete m_data_64;
437 m_data_64 = NULL;
438}
439
440size_t
441lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
442{
443 const char* item_name = name.GetCString();
444 uint32_t idx = ExtractIndexFromString(item_name);
445 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
446 return UINT32_MAX;
447 return idx;
448}
449
450size_t
451lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::CalculateNumChildren ()
452{
453 if (!m_data_32 && !m_data_64)
454 return 0;
455 return (m_data_32 ? m_data_32->_used : m_data_64->_used);
456}
457
458bool
459lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update()
460{
461 m_children.clear();
462 ValueObjectSP valobj_sp = m_backend.GetSP();
463 m_ptr_size = 0;
464 delete m_data_32;
465 m_data_32 = NULL;
466 delete m_data_64;
467 m_data_64 = NULL;
468 if (!valobj_sp)
469 return false;
Enrico Granataf615b802013-02-15 23:38:37 +0000470 if (!valobj_sp)
471 return false;
472 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
473 Error error;
474 if (valobj_sp->IsPointerType())
475 {
476 valobj_sp = valobj_sp->Dereference(error);
477 if (error.Fail() || !valobj_sp)
478 return false;
479 }
480 error.Clear();
481 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
482 if (!process_sp)
483 return false;
484 m_ptr_size = process_sp->GetAddressByteSize();
Enrico Granataeb8bd922013-04-03 01:25:29 +0000485 m_order = process_sp->GetByteOrder();
Enrico Granataf615b802013-02-15 23:38:37 +0000486 uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
487 if (m_ptr_size == 4)
488 {
489 m_data_32 = new DataDescriptor_32();
490 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
491 }
492 else
493 {
494 m_data_64 = new DataDescriptor_64();
495 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
496 }
497 if (error.Fail())
498 return false;
499 return false;
500}
501
502bool
503lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::MightHaveChildren ()
504{
505 return true;
506}
507
508lldb::ValueObjectSP
509lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
510{
511 lldb::addr_t m_keys_ptr = (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
512 lldb::addr_t m_values_ptr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
513
514 uint32_t num_children = CalculateNumChildren();
515
516 if (idx >= num_children)
517 return lldb::ValueObjectSP();
518
519 if (m_children.empty())
520 {
521 // do the scan phase
522 lldb::addr_t key_at_idx = 0, val_at_idx = 0;
523
524 uint32_t tries = 0;
525 uint32_t test_idx = 0;
526
527 while(tries < num_children)
528 {
529 key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
530 val_at_idx = m_values_ptr + (test_idx * m_ptr_size);;
531 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
532 if (!process_sp)
533 return lldb::ValueObjectSP();
534 Error error;
535 key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
536 if (error.Fail())
537 return lldb::ValueObjectSP();
538 val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
539 if (error.Fail())
540 return lldb::ValueObjectSP();
541
542 test_idx++;
543
544 if (!key_at_idx || !val_at_idx)
545 continue;
546 tries++;
547
548 DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
549
550 m_children.push_back(descriptor);
551 }
552 }
553
554 if (idx >= m_children.size()) // should never happen
555 return lldb::ValueObjectSP();
556
557 DictionaryItemDescriptor &dict_item = m_children[idx];
558 if (!dict_item.valobj_sp)
559 {
Enrico Granataeb8bd922013-04-03 01:25:29 +0000560 if (!m_pair_type.IsValid())
561 {
562 TargetSP target_sp(m_backend.GetTargetSP());
563 if (!target_sp)
564 return ValueObjectSP();
565 m_pair_type = GetLLDBNSPairType(target_sp);
566 }
567 if (!m_pair_type.IsValid())
568 return ValueObjectSP();
569
570 DataBufferSP buffer_sp(new DataBufferHeap(2*m_ptr_size,0));
571
572 if (m_ptr_size == 8)
573 {
574 uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
575 *data_ptr = dict_item.key_ptr;
576 *(data_ptr+1) = dict_item.val_ptr;
577 }
578 else
579 {
580 uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
581 *data_ptr = dict_item.key_ptr;
582 *(data_ptr+1) = dict_item.val_ptr;
583 }
584
Enrico Granataf615b802013-02-15 23:38:37 +0000585 StreamString idx_name;
586 idx_name.Printf("[%zu]",idx);
Enrico Granataeb8bd922013-04-03 01:25:29 +0000587 DataExtractor data(buffer_sp, m_order, m_ptr_size);
588 dict_item.valobj_sp = ValueObject::CreateValueObjectFromData(idx_name.GetData(), data, m_exe_ctx_ref, m_pair_type);
Enrico Granataf615b802013-02-15 23:38:37 +0000589 }
590 return dict_item.valobj_sp;
591}
592
593template bool
594lldb_private::formatters::NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
595
596template bool
597lldb_private::formatters::NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;