blob: 78b63e9188f151f1b2c818d0bbe64cb1a16a57c9 [file] [log] [blame]
Enrico Granatacaaf0102012-09-04 18:48:21 +00001//===-- CXXFormatterFunctions.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
Daniel Malead891f9b2012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Enrico Granataf509c5e2013-01-28 23:47:25 +000012#include "lldb/DataFormatters/CXXFormatterFunctions.h"
Enrico Granatacaaf0102012-09-04 18:48:21 +000013
Dmitri Gribenko2a64f9a2013-01-30 15:05:59 +000014#include "llvm/Support/ConvertUTF.h"
Enrico Granatacaaf0102012-09-04 18:48:21 +000015
Enrico Granataf91e78f2012-09-13 18:27:09 +000016#include "lldb/Core/DataBufferHeap.h"
17#include "lldb/Core/Error.h"
Enrico Granatacaaf0102012-09-04 18:48:21 +000018#include "lldb/Core/Stream.h"
19#include "lldb/Core/ValueObject.h"
Enrico Granataf91e78f2012-09-13 18:27:09 +000020#include "lldb/Core/ValueObjectConstResult.h"
21#include "lldb/Host/Endian.h"
Enrico Granatadb054912012-10-29 21:18:03 +000022#include "lldb/Symbol/ClangASTContext.h"
Enrico Granatacaaf0102012-09-04 18:48:21 +000023#include "lldb/Target/ObjCLanguageRuntime.h"
24#include "lldb/Target/Target.h"
25
26using namespace lldb;
27using namespace lldb_private;
28using namespace lldb_private::formatters;
29
30bool
Enrico Granataf91e78f2012-09-13 18:27:09 +000031lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj,
32 const char* target_type,
33 const char* selector,
34 uint64_t &value)
Enrico Granatacaaf0102012-09-04 18:48:21 +000035{
36 if (!target_type || !*target_type)
37 return false;
38 if (!selector || !*selector)
39 return false;
Enrico Granatacaaf0102012-09-04 18:48:21 +000040 StreamString expr;
Daniel Maleab9db9d52012-12-07 22:21:08 +000041 expr.Printf("(%s)[(id)0x%" PRIx64 " %s]",target_type,valobj.GetPointerValue(),selector);
Enrico Granatacaaf0102012-09-04 18:48:21 +000042 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
43 lldb::ValueObjectSP result_sp;
44 Target* target = exe_ctx.GetTargetPtr();
45 StackFrame* stack_frame = exe_ctx.GetFramePtr();
46 if (!target || !stack_frame)
47 return false;
Enrico Granatad27026e2012-09-05 20:41:26 +000048
Jim Ingham47beabb2012-10-16 21:41:58 +000049 EvaluateExpressionOptions options;
Enrico Granatad27026e2012-09-05 20:41:26 +000050 options.SetCoerceToId(false)
51 .SetUnwindOnError(true)
Sean Callanan99611fe2012-12-04 20:56:04 +000052 .SetKeepInMemory(true);
Enrico Granatad27026e2012-09-05 20:41:26 +000053
Enrico Granatacaaf0102012-09-04 18:48:21 +000054 target->EvaluateExpression(expr.GetData(),
55 stack_frame,
Enrico Granatad27026e2012-09-05 20:41:26 +000056 result_sp,
57 options);
Enrico Granatacaaf0102012-09-04 18:48:21 +000058 if (!result_sp)
59 return false;
60 value = result_sp->GetValueAsUnsigned(0);
61 return true;
62}
63
Enrico Granataf91e78f2012-09-13 18:27:09 +000064lldb::ValueObjectSP
65lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
66 const char* return_type,
67 const char* selector,
68 uint64_t index)
69{
70 lldb::ValueObjectSP valobj_sp;
71 if (!return_type || !*return_type)
72 return valobj_sp;
73 if (!selector || !*selector)
74 return valobj_sp;
75 StreamString expr_path_stream;
76 valobj.GetExpressionPath(expr_path_stream, false);
77 StreamString expr;
Daniel Malea5f35a4b2012-11-29 21:49:15 +000078 expr.Printf("(%s)[%s %s:%" PRId64 "]",return_type,expr_path_stream.GetData(),selector,index);
Enrico Granataf91e78f2012-09-13 18:27:09 +000079 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
80 lldb::ValueObjectSP result_sp;
81 Target* target = exe_ctx.GetTargetPtr();
82 StackFrame* stack_frame = exe_ctx.GetFramePtr();
83 if (!target || !stack_frame)
84 return valobj_sp;
85
Jim Ingham47beabb2012-10-16 21:41:58 +000086 EvaluateExpressionOptions options;
Enrico Granataf91e78f2012-09-13 18:27:09 +000087 options.SetCoerceToId(false)
88 .SetUnwindOnError(true)
89 .SetKeepInMemory(true)
90 .SetUseDynamic(lldb::eDynamicCanRunTarget);
91
92 target->EvaluateExpression(expr.GetData(),
93 stack_frame,
94 valobj_sp,
95 options);
96 return valobj_sp;
97}
98
99lldb::ValueObjectSP
100lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
101 const char* return_type,
102 const char* selector,
103 const char* key)
104{
105 lldb::ValueObjectSP valobj_sp;
106 if (!return_type || !*return_type)
107 return valobj_sp;
108 if (!selector || !*selector)
109 return valobj_sp;
110 if (!key || !*key)
111 return valobj_sp;
112 StreamString expr_path_stream;
113 valobj.GetExpressionPath(expr_path_stream, false);
114 StreamString expr;
115 expr.Printf("(%s)[%s %s:%s]",return_type,expr_path_stream.GetData(),selector,key);
116 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
117 lldb::ValueObjectSP result_sp;
118 Target* target = exe_ctx.GetTargetPtr();
119 StackFrame* stack_frame = exe_ctx.GetFramePtr();
120 if (!target || !stack_frame)
121 return valobj_sp;
122
Jim Ingham47beabb2012-10-16 21:41:58 +0000123 EvaluateExpressionOptions options;
Enrico Granataf91e78f2012-09-13 18:27:09 +0000124 options.SetCoerceToId(false)
125 .SetUnwindOnError(true)
126 .SetKeepInMemory(true)
127 .SetUseDynamic(lldb::eDynamicCanRunTarget);
128
129 target->EvaluateExpression(expr.GetData(),
130 stack_frame,
131 valobj_sp,
132 options);
133 return valobj_sp;
134}
135
Enrico Granatacd8cd612013-01-14 23:53:26 +0000136// use this call if you already have an LLDB-side buffer for the data
137template<typename SourceDataType>
Enrico Granataf5545f92013-01-10 22:08:35 +0000138static bool
Enrico Granatacd8cd612013-01-14 23:53:26 +0000139DumpUTFBufferToStream (ConversionResult (*ConvertFunction) (const SourceDataType**,
140 const SourceDataType*,
141 UTF8**,
142 UTF8*,
143 ConversionFlags),
144 DataExtractor& data,
145 Stream& stream,
146 char prefix_token = '@',
147 char quote = '"',
148 int sourceSize = 0)
Enrico Granataf5545f92013-01-10 22:08:35 +0000149{
Enrico Granatacd8cd612013-01-14 23:53:26 +0000150 if (prefix_token != 0)
151 stream.Printf("%c",prefix_token);
152 if (quote != 0)
153 stream.Printf("%c",quote);
154 if (data.GetByteSize() && data.GetDataStart() && data.GetDataEnd())
Enrico Granataf5545f92013-01-10 22:08:35 +0000155 {
Enrico Granatacd8cd612013-01-14 23:53:26 +0000156 const int bufferSPSize = data.GetByteSize();
157 if (sourceSize == 0)
158 {
159 const int origin_encoding = 8*sizeof(SourceDataType);
160 sourceSize = bufferSPSize/(origin_encoding >> 2);
161 }
162
163 SourceDataType *data_ptr = (SourceDataType*)data.GetDataStart();
Enrico Granataf5545f92013-01-10 22:08:35 +0000164 SourceDataType *data_end_ptr = data_ptr + sourceSize;
165
166 while (data_ptr < data_end_ptr)
167 {
168 if (!*data_ptr)
169 {
170 data_end_ptr = data_ptr;
171 break;
172 }
173 data_ptr++;
174 }
175
176 *data_ptr = 0;
Enrico Granatacd8cd612013-01-14 23:53:26 +0000177 data_ptr = (SourceDataType*)data.GetDataStart();
Enrico Granataf5545f92013-01-10 22:08:35 +0000178
Enrico Granata06d58b02013-01-11 02:44:00 +0000179 lldb::DataBufferSP utf8_data_buffer_sp;
180 UTF8* utf8_data_ptr = nullptr;
181 UTF8* utf8_data_end_ptr = nullptr;
Enrico Granatacd8cd612013-01-14 23:53:26 +0000182
Enrico Granataf5545f92013-01-10 22:08:35 +0000183 if (ConvertFunction)
Enrico Granata06d58b02013-01-11 02:44:00 +0000184 {
185 utf8_data_buffer_sp.reset(new DataBufferHeap(bufferSPSize,0));
186 utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes();
187 utf8_data_end_ptr = utf8_data_ptr + bufferSPSize;
Enrico Granataf5545f92013-01-10 22:08:35 +0000188 ConvertFunction ( (const SourceDataType**)&data_ptr, data_end_ptr, &utf8_data_ptr, utf8_data_end_ptr, lenientConversion );
Enrico Granata06d58b02013-01-11 02:44:00 +0000189 utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes(); // needed because the ConvertFunction will change the value of the data_ptr
190 }
Enrico Granataf5545f92013-01-10 22:08:35 +0000191 else
192 {
193 // just copy the pointers - the cast is necessary to make the compiler happy
194 // but this should only happen if we are reading UTF8 data
195 utf8_data_ptr = (UTF8*)data_ptr;
196 utf8_data_end_ptr = (UTF8*)data_end_ptr;
197 }
198
Enrico Granatab6985792013-01-12 01:00:22 +0000199 // since we tend to accept partial data (and even partially malformed data)
200 // we might end up with no NULL terminator before the end_ptr
201 // hence we need to take a slower route and ensure we stay within boundaries
Enrico Granataf5545f92013-01-10 22:08:35 +0000202 for (;utf8_data_ptr != utf8_data_end_ptr; utf8_data_ptr++)
203 {
204 if (!*utf8_data_ptr)
205 break;
206 stream.Printf("%c",*utf8_data_ptr);
207 }
Enrico Granatacd8cd612013-01-14 23:53:26 +0000208 }
209 if (quote != 0)
210 stream.Printf("%c",quote);
211 return true;
212}
213
214template<typename SourceDataType>
215static bool
216ReadUTFBufferAndDumpToStream (ConversionResult (*ConvertFunction) (const SourceDataType**,
217 const SourceDataType*,
218 UTF8**,
219 UTF8*,
220 ConversionFlags),
221 uint64_t location,
222 const ProcessSP& process_sp,
223 Stream& stream,
224 char prefix_token = '@',
225 char quote = '"',
226 int sourceSize = 0)
227{
228 if (location == 0 || location == LLDB_INVALID_ADDRESS)
229 return false;
230 if (!process_sp)
231 return false;
232
233 const int origin_encoding = 8*sizeof(SourceDataType);
234 if (origin_encoding != 8 && origin_encoding != 16 && origin_encoding != 32)
235 return false;
236 // if not UTF8, I need a conversion function to return proper UTF8
237 if (origin_encoding != 8 && !ConvertFunction)
238 return false;
239
240 if (sourceSize == 0)
241 sourceSize = process_sp->GetTarget().GetMaximumSizeOfStringSummary();
242 const int bufferSPSize = sourceSize * (origin_encoding >> 2);
243
244 Error error;
245 lldb::DataBufferSP buffer_sp(new DataBufferHeap(bufferSPSize,0));
246
247 if (!buffer_sp->GetBytes())
248 return false;
249
250 size_t data_read = process_sp->ReadMemoryFromInferior(location, (char*)buffer_sp->GetBytes(), bufferSPSize, error);
251 if (error.Fail() || data_read == 0)
252 {
253 stream.Printf("unable to read data");
Enrico Granataf5545f92013-01-10 22:08:35 +0000254 return true;
255 }
Enrico Granatacd8cd612013-01-14 23:53:26 +0000256
257 DataExtractor data(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize());
258
259 return DumpUTFBufferToStream(ConvertFunction, data, stream, prefix_token, quote, sourceSize);
Enrico Granataf5545f92013-01-10 22:08:35 +0000260}
261
262bool
263lldb_private::formatters::Char16StringSummaryProvider (ValueObject& valobj, Stream& stream)
264{
265 ProcessSP process_sp = valobj.GetProcessSP();
266 if (!process_sp)
267 return false;
268
269 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
270
271 if (!valobj_addr)
272 return false;
273
Enrico Granatacd8cd612013-01-14 23:53:26 +0000274 if (!ReadUTFBufferAndDumpToStream<UTF16>(ConvertUTF16toUTF8,valobj_addr,
Enrico Granataf5545f92013-01-10 22:08:35 +0000275 process_sp,
276 stream,
Enrico Granatacd8cd612013-01-14 23:53:26 +0000277 'u'))
Enrico Granataf5545f92013-01-10 22:08:35 +0000278 {
279 stream.Printf("Summary Unavailable");
280 return true;
281 }
282
283 return true;
284}
285
286bool
287lldb_private::formatters::Char32StringSummaryProvider (ValueObject& valobj, Stream& stream)
288{
289 ProcessSP process_sp = valobj.GetProcessSP();
290 if (!process_sp)
291 return false;
292
293 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
294
295 if (!valobj_addr)
296 return false;
297
Enrico Granatacd8cd612013-01-14 23:53:26 +0000298 if (!ReadUTFBufferAndDumpToStream<UTF32>(ConvertUTF32toUTF8,valobj_addr,
Enrico Granataf5545f92013-01-10 22:08:35 +0000299 process_sp,
300 stream,
Enrico Granatacd8cd612013-01-14 23:53:26 +0000301 'U'))
Enrico Granataf5545f92013-01-10 22:08:35 +0000302 {
303 stream.Printf("Summary Unavailable");
304 return true;
305 }
306
307 return true;
308}
309
310bool
311lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Stream& stream)
312{
Enrico Granata06d58b02013-01-11 02:44:00 +0000313 ProcessSP process_sp = valobj.GetProcessSP();
314 if (!process_sp)
315 return false;
316
Enrico Granatab6985792013-01-12 01:00:22 +0000317 lldb::addr_t data_addr = 0;
318
319 if (valobj.IsPointerType())
320 data_addr = valobj.GetValueAsUnsigned(0);
321 else if (valobj.IsArrayType())
322 data_addr = valobj.GetAddressOf();
Enrico Granata06d58b02013-01-11 02:44:00 +0000323
Enrico Granatab6985792013-01-12 01:00:22 +0000324 if (data_addr == 0 || data_addr == LLDB_INVALID_ADDRESS)
Enrico Granata06d58b02013-01-11 02:44:00 +0000325 return false;
326
327 clang::ASTContext* ast = valobj.GetClangAST();
328
329 if (!ast)
330 return false;
331
332 uint32_t wchar_size = ClangASTType::GetClangTypeBitWidth(ast, ClangASTType::GetBasicType(ast, lldb::eBasicTypeWChar).GetOpaqueQualType());
333
334 switch (wchar_size)
335 {
336 case 8:
337 // utf 8
Enrico Granatacd8cd612013-01-14 23:53:26 +0000338 return ReadUTFBufferAndDumpToStream<UTF8>(nullptr, data_addr,
Enrico Granata06d58b02013-01-11 02:44:00 +0000339 process_sp,
340 stream,
Enrico Granatacd8cd612013-01-14 23:53:26 +0000341 'L');
Enrico Granata06d58b02013-01-11 02:44:00 +0000342 case 16:
343 // utf 16
Enrico Granatacd8cd612013-01-14 23:53:26 +0000344 return ReadUTFBufferAndDumpToStream<UTF16>(ConvertUTF16toUTF8, data_addr,
Enrico Granata06d58b02013-01-11 02:44:00 +0000345 process_sp,
346 stream,
Enrico Granatacd8cd612013-01-14 23:53:26 +0000347 'L');
Enrico Granata06d58b02013-01-11 02:44:00 +0000348 case 32:
349 // utf 32
Enrico Granatacd8cd612013-01-14 23:53:26 +0000350 return ReadUTFBufferAndDumpToStream<UTF32>(ConvertUTF32toUTF8, data_addr,
Enrico Granata06d58b02013-01-11 02:44:00 +0000351 process_sp,
352 stream,
Enrico Granatacd8cd612013-01-14 23:53:26 +0000353 'L');
354 default:
355 stream.Printf("size for wchar_t is not valid");
356 return true;
357 }
358 return true;
359}
360
361bool
362lldb_private::formatters::Char16SummaryProvider (ValueObject& valobj, Stream& stream)
363{
364 DataExtractor data;
365 valobj.GetData(data);
366
367 std::string value;
368 valobj.GetValueAsCString(lldb::eFormatUnicode16, value);
369 if (!value.empty())
370 stream.Printf("%s ", value.c_str());
371
372 return DumpUTFBufferToStream<UTF16>(ConvertUTF16toUTF8,data,stream, 'u','\'',1);
373}
374
375bool
376lldb_private::formatters::Char32SummaryProvider (ValueObject& valobj, Stream& stream)
377{
378 DataExtractor data;
379 valobj.GetData(data);
380
381 std::string value;
382 valobj.GetValueAsCString(lldb::eFormatUnicode32, value);
383 if (!value.empty())
384 stream.Printf("%s ", value.c_str());
385
386 return DumpUTFBufferToStream<UTF32>(ConvertUTF32toUTF8,data,stream, 'U','\'',1);
387}
388
389bool
390lldb_private::formatters::WCharSummaryProvider (ValueObject& valobj, Stream& stream)
391{
392 DataExtractor data;
393 valobj.GetData(data);
394
395 clang::ASTContext* ast = valobj.GetClangAST();
396
397 if (!ast)
398 return false;
399
400 std::string value;
401
402 uint32_t wchar_size = ClangASTType::GetClangTypeBitWidth(ast, ClangASTType::GetBasicType(ast, lldb::eBasicTypeWChar).GetOpaqueQualType());
403
404 switch (wchar_size)
405 {
406 case 8:
407 // utf 8
408 valobj.GetValueAsCString(lldb::eFormatChar, value);
409 if (!value.empty())
410 stream.Printf("%s ", value.c_str());
411 return DumpUTFBufferToStream<UTF8>(nullptr,
412 data,
413 stream,
414 'L',
415 '\'',
416 1);
417 case 16:
418 // utf 16
419 valobj.GetValueAsCString(lldb::eFormatUnicode16, value);
420 if (!value.empty())
421 stream.Printf("%s ", value.c_str());
422 return DumpUTFBufferToStream<UTF16>(ConvertUTF16toUTF8,
423 data,
424 stream,
425 'L',
426 '\'',
427 1);
428 case 32:
429 // utf 32
430 valobj.GetValueAsCString(lldb::eFormatUnicode32, value);
431 if (!value.empty())
432 stream.Printf("%s ", value.c_str());
433 return DumpUTFBufferToStream<UTF32>(ConvertUTF32toUTF8,
434 data,
435 stream,
436 'L',
437 '\'',
438 1);
Enrico Granata06d58b02013-01-11 02:44:00 +0000439 default:
440 stream.Printf("size for wchar_t is not valid");
441 return true;
442 }
443 return true;
Enrico Granataf5545f92013-01-10 22:08:35 +0000444}
445
Enrico Granatab6985792013-01-12 01:00:22 +0000446// this function extracts information from a libcxx std::basic_string<>
447// irregardless of template arguments. it reports the size (in item count not bytes)
448// and the location in memory where the string data can be found
449static bool
450ExtractLibcxxStringInfo (ValueObject& valobj,
451 ValueObjectSP &location_sp,
452 uint64_t& size)
453{
454 ValueObjectSP D(valobj.GetChildAtIndexPath({0,0,0,0}));
455 if (!D)
456 return false;
457
458 ValueObjectSP size_mode(D->GetChildAtIndexPath({1,0,0}));
459 if (!size_mode)
460 return false;
461
462 uint64_t size_mode_value(size_mode->GetValueAsUnsigned(0));
463
464 if ((size_mode_value & 1) == 0) // this means the string is in short-mode and the data is stored inline
465 {
466 ValueObjectSP s(D->GetChildAtIndex(1, true));
467 if (!s)
468 return false;
469 size = ((size_mode_value >> 1) % 256);
470 location_sp = s->GetChildAtIndex(1, true);
471 return (location_sp.get() != nullptr);
472 }
473 else
474 {
475 ValueObjectSP l(D->GetChildAtIndex(0, true));
476 if (!l)
477 return false;
478 location_sp = l->GetChildAtIndex(2, true);
479 ValueObjectSP size_vo(l->GetChildAtIndex(1, true));
480 if (!size_vo || !location_sp)
481 return false;
482 size = size_vo->GetValueAsUnsigned(0);
483 return true;
484 }
485}
486
487bool
488lldb_private::formatters::LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream)
489{
490 uint64_t size = 0;
491 ValueObjectSP location_sp((ValueObject*)nullptr);
492 if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
493 return false;
494 if (size == 0)
495 {
496 stream.Printf("L\"\"");
497 return true;
498 }
499 if (!location_sp)
500 return false;
501 return WCharStringSummaryProvider(*location_sp.get(), stream);
502}
503
504bool
505lldb_private::formatters::LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream)
506{
507 uint64_t size = 0;
508 ValueObjectSP location_sp((ValueObject*)nullptr);
509 if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
510 return false;
511 if (size == 0)
512 {
513 stream.Printf("\"\"");
514 return true;
515 }
516 if (!location_sp)
517 return false;
518 Error error;
519 location_sp->ReadPointedString(stream,
520 error,
521 0, // max length is decided by the settings
522 false); // do not honor array (terminates on first 0 byte even for a char[])
523 return error.Success();
524}
525
Enrico Granatacaaf0102012-09-04 18:48:21 +0000526template<bool name_entries>
527bool
Enrico Granataf91e78f2012-09-13 18:27:09 +0000528lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream)
Enrico Granatacaaf0102012-09-04 18:48:21 +0000529{
530 ProcessSP process_sp = valobj.GetProcessSP();
531 if (!process_sp)
532 return false;
533
534 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
535
536 if (!runtime)
537 return false;
538
539 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
540
541 if (!descriptor.get() || !descriptor->IsValid())
542 return false;
543
544 uint32_t ptr_size = process_sp->GetAddressByteSize();
545 bool is_64bit = (ptr_size == 8);
546
547 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
548
549 if (!valobj_addr)
550 return false;
551
552 uint64_t value = 0;
553
554 const char* class_name = descriptor->GetClassName().GetCString();
Enrico Granata7685a562012-09-29 00:47:43 +0000555
556 if (!class_name || !*class_name)
557 return false;
558
Enrico Granatacaaf0102012-09-04 18:48:21 +0000559 if (!strcmp(class_name,"__NSDictionaryI"))
560 {
561 Error error;
562 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
563 if (error.Fail())
564 return false;
565 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
566 }
567 else if (!strcmp(class_name,"__NSDictionaryM"))
568 {
569 Error error;
570 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
571 if (error.Fail())
572 return false;
573 value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
574 }
575 else if (!strcmp(class_name,"__NSCFDictionary"))
576 {
577 Error error;
578 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), ptr_size, 0, error);
579 if (error.Fail())
580 return false;
581 if (is_64bit)
582 value &= ~0x0f1f000000000000UL;
Enrico Granata06d58b02013-01-11 02:44:00 +0000583 }
Enrico Granatacaaf0102012-09-04 18:48:21 +0000584 else
585 {
Enrico Granataf91e78f2012-09-13 18:27:09 +0000586 if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
Enrico Granatacaaf0102012-09-04 18:48:21 +0000587 return false;
588 }
589
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000590 stream.Printf("%s%" PRIu64 " %s%s",
Enrico Granatacaaf0102012-09-04 18:48:21 +0000591 (name_entries ? "@\"" : ""),
592 value,
593 (name_entries ? (value == 1 ? "entry" : "entries") : (value == 1 ? "key/value pair" : "key/value pairs")),
594 (name_entries ? "\"" : ""));
595 return true;
596}
597
598bool
Enrico Granataf91e78f2012-09-13 18:27:09 +0000599lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& stream)
Enrico Granatacaaf0102012-09-04 18:48:21 +0000600{
601 ProcessSP process_sp = valobj.GetProcessSP();
602 if (!process_sp)
603 return false;
604
605 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
606
607 if (!runtime)
608 return false;
609
610 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
611
612 if (!descriptor.get() || !descriptor->IsValid())
613 return false;
614
615 uint32_t ptr_size = process_sp->GetAddressByteSize();
616
617 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
618
619 if (!valobj_addr)
620 return false;
621
622 uint64_t value = 0;
623
624 const char* class_name = descriptor->GetClassName().GetCString();
Enrico Granata7685a562012-09-29 00:47:43 +0000625
626 if (!class_name || !*class_name)
627 return false;
628
Enrico Granatacaaf0102012-09-04 18:48:21 +0000629 if (!strcmp(class_name,"__NSArrayI"))
630 {
631 Error error;
632 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
633 if (error.Fail())
634 return false;
635 }
636 else if (!strcmp(class_name,"__NSArrayM"))
637 {
638 Error error;
639 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
640 if (error.Fail())
641 return false;
642 }
643 else if (!strcmp(class_name,"__NSCFArray"))
644 {
645 Error error;
646 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + 2 * ptr_size, ptr_size, 0, error);
647 if (error.Fail())
648 return false;
649 }
650 else
651 {
Enrico Granataf91e78f2012-09-13 18:27:09 +0000652 if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
Enrico Granatacaaf0102012-09-04 18:48:21 +0000653 return false;
654 }
655
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000656 stream.Printf("@\"%" PRIu64 " object%s\"",
Enrico Granatacaaf0102012-09-04 18:48:21 +0000657 value,
658 value == 1 ? "" : "s");
659 return true;
660}
661
662template<bool needs_at>
663bool
Enrico Granataf91e78f2012-09-13 18:27:09 +0000664lldb_private::formatters::NSDataSummaryProvider (ValueObject& valobj, Stream& stream)
Enrico Granatacaaf0102012-09-04 18:48:21 +0000665{
666 ProcessSP process_sp = valobj.GetProcessSP();
667 if (!process_sp)
668 return false;
669
670 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
671
672 if (!runtime)
673 return false;
674
675 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
676
677 if (!descriptor.get() || !descriptor->IsValid())
678 return false;
679
680 bool is_64bit = (process_sp->GetAddressByteSize() == 8);
681 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
682
683 if (!valobj_addr)
684 return false;
685
686 uint64_t value = 0;
687
688 const char* class_name = descriptor->GetClassName().GetCString();
Enrico Granata7685a562012-09-29 00:47:43 +0000689
690 if (!class_name || !*class_name)
691 return false;
692
Enrico Granatacaaf0102012-09-04 18:48:21 +0000693 if (!strcmp(class_name,"NSConcreteData") ||
694 !strcmp(class_name,"NSConcreteMutableData") ||
695 !strcmp(class_name,"__NSCFData"))
696 {
697 uint32_t offset = (is_64bit ? 16 : 8);
698 Error error;
699 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, is_64bit ? 8 : 4, 0, error);
700 if (error.Fail())
701 return false;
702 }
703 else
704 {
Enrico Granataf91e78f2012-09-13 18:27:09 +0000705 if (!ExtractValueFromObjCExpression(valobj, "int", "length", value))
Enrico Granatacaaf0102012-09-04 18:48:21 +0000706 return false;
707 }
708
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000709 stream.Printf("%s%" PRIu64 " byte%s%s",
Enrico Granatacaaf0102012-09-04 18:48:21 +0000710 (needs_at ? "@\"" : ""),
711 value,
712 (value > 1 ? "s" : ""),
713 (needs_at ? "\"" : ""));
714
715 return true;
716}
717
718bool
Enrico Granataf91e78f2012-09-13 18:27:09 +0000719lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream)
Enrico Granatacaaf0102012-09-04 18:48:21 +0000720{
721 ProcessSP process_sp = valobj.GetProcessSP();
722 if (!process_sp)
723 return false;
724
725 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
726
727 if (!runtime)
728 return false;
729
730 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
731
732 if (!descriptor.get() || !descriptor->IsValid())
733 return false;
734
735 uint32_t ptr_size = process_sp->GetAddressByteSize();
736
737 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
738
739 if (!valobj_addr)
740 return false;
741
742 const char* class_name = descriptor->GetClassName().GetCString();
743
Enrico Granata7685a562012-09-29 00:47:43 +0000744 if (!class_name || !*class_name)
745 return false;
746
Enrico Granatacaaf0102012-09-04 18:48:21 +0000747 if (!strcmp(class_name,"NSNumber") || !strcmp(class_name,"__NSCFNumber"))
748 {
749 if (descriptor->IsTagged())
750 {
751 // we have a call to get info and value bits in the tagged descriptor. but we prefer not to cast and replicate them
752 int64_t value = (valobj_addr & ~0x0000000000000000FFL) >> 8;
753 uint64_t i_bits = (valobj_addr & 0xF0) >> 4;
754
755 switch (i_bits)
756 {
757 case 0:
758 stream.Printf("(char)%hhd",(char)value);
759 break;
760 case 4:
761 stream.Printf("(short)%hd",(short)value);
762 break;
763 case 8:
764 stream.Printf("(int)%d",(int)value);
765 break;
766 case 12:
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000767 stream.Printf("(long)%" PRId64,value);
Enrico Granatacaaf0102012-09-04 18:48:21 +0000768 break;
769 default:
Enrico Granata3ca24b42012-12-10 19:23:00 +0000770 stream.Printf("unexpected value:(info=%" PRIu64 ", value=%" PRIu64,i_bits,value);
Enrico Granatacaaf0102012-09-04 18:48:21 +0000771 break;
772 }
773 return true;
774 }
775 else
776 {
777 Error error;
778 uint8_t data_type = (process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 1, 0, error) & 0x1F);
779 uint64_t data_location = valobj_addr + 2*ptr_size;
780 uint64_t value = 0;
781 if (error.Fail())
782 return false;
783 switch (data_type)
784 {
785 case 1: // 0B00001
786 value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0, error);
787 if (error.Fail())
788 return false;
789 stream.Printf("(char)%hhd",(char)value);
790 break;
791 case 2: // 0B0010
792 value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0, error);
793 if (error.Fail())
794 return false;
795 stream.Printf("(short)%hd",(short)value);
796 break;
797 case 3: // 0B0011
798 value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
799 if (error.Fail())
800 return false;
801 stream.Printf("(int)%d",(int)value);
802 break;
803 case 17: // 0B10001
804 data_location += 8;
805 case 4: // 0B0100
806 value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
807 if (error.Fail())
808 return false;
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000809 stream.Printf("(long)%" PRId64,value);
Enrico Granatacaaf0102012-09-04 18:48:21 +0000810 break;
811 case 5: // 0B0101
812 {
813 uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
814 if (error.Fail())
815 return false;
816 float flt_value = *((float*)&flt_as_int);
817 stream.Printf("(float)%f",flt_value);
818 break;
819 }
820 case 6: // 0B0110
821 {
822 uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
823 if (error.Fail())
824 return false;
825 double dbl_value = *((double*)&dbl_as_lng);
826 stream.Printf("(double)%g",dbl_value);
827 break;
828 }
829 default:
830 stream.Printf("absurd: dt=%d",data_type);
831 break;
832 }
833 return true;
834 }
835 }
836 else
837 {
Enrico Granataf91e78f2012-09-13 18:27:09 +0000838 // similar to ExtractValueFromObjCExpression but uses summary instead of value
Enrico Granatacaaf0102012-09-04 18:48:21 +0000839 StreamString expr_path_stream;
840 valobj.GetExpressionPath(expr_path_stream, false);
841 StreamString expr;
842 expr.Printf("(NSString*)[%s stringValue]",expr_path_stream.GetData());
843 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
844 lldb::ValueObjectSP result_sp;
845 Target* target = exe_ctx.GetTargetPtr();
846 StackFrame* stack_frame = exe_ctx.GetFramePtr();
847 if (!target || !stack_frame)
848 return false;
Enrico Granatad27026e2012-09-05 20:41:26 +0000849
Jim Ingham47beabb2012-10-16 21:41:58 +0000850 EvaluateExpressionOptions options;
Enrico Granatad27026e2012-09-05 20:41:26 +0000851 options.SetCoerceToId(false)
852 .SetUnwindOnError(true)
853 .SetKeepInMemory(true)
854 .SetUseDynamic(lldb::eDynamicCanRunTarget);
855
Enrico Granatacaaf0102012-09-04 18:48:21 +0000856 target->EvaluateExpression(expr.GetData(),
857 stack_frame,
Enrico Granatad27026e2012-09-05 20:41:26 +0000858 result_sp,
859 options);
Enrico Granatacaaf0102012-09-04 18:48:21 +0000860 if (!result_sp)
861 return false;
862 stream.Printf("%s",result_sp->GetSummaryAsCString());
863 return true;
864 }
865}
866
867bool
Enrico Granataf91e78f2012-09-13 18:27:09 +0000868lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream)
Enrico Granatacaaf0102012-09-04 18:48:21 +0000869{
870 ProcessSP process_sp = valobj.GetProcessSP();
871 if (!process_sp)
872 return false;
873
874 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
875
876 if (!runtime)
877 return false;
878
879 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
880
881 if (!descriptor.get() || !descriptor->IsValid())
882 return false;
883
884 uint32_t ptr_size = process_sp->GetAddressByteSize();
885
886 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
887
888 if (!valobj_addr)
889 return false;
890
891 const char* class_name = descriptor->GetClassName().GetCString();
892
Enrico Granata25c9ade2012-09-29 00:45:53 +0000893 if (!class_name || !*class_name)
894 return false;
895
Enrico Granatacaaf0102012-09-04 18:48:21 +0000896 uint64_t info_bits_location = valobj_addr + ptr_size;
897 if (process_sp->GetByteOrder() != lldb::eByteOrderLittle)
898 info_bits_location += 3;
899
900 Error error;
901
902 uint8_t info_bits = process_sp->ReadUnsignedIntegerFromMemory(info_bits_location, 1, 0, error);
903 if (error.Fail())
904 return false;
905
906 bool is_mutable = (info_bits & 1) == 1;
907 bool is_inline = (info_bits & 0x60) == 0;
908 bool has_explicit_length = (info_bits & (1 | 4)) != 4;
909 bool is_unicode = (info_bits & 0x10) == 0x10;
910 bool is_special = strcmp(class_name,"NSPathStore2") == 0;
911
912 if (strcmp(class_name,"NSString") &&
913 strcmp(class_name,"CFStringRef") &&
914 strcmp(class_name,"CFMutableStringRef") &&
915 strcmp(class_name,"__NSCFConstantString") &&
916 strcmp(class_name,"__NSCFString") &&
917 strcmp(class_name,"NSCFConstantString") &&
918 strcmp(class_name,"NSCFString") &&
919 strcmp(class_name,"NSPathStore2"))
920 {
921 // probably not one of us - bail out
922 return false;
923 }
924
925 if (is_mutable)
926 {
927 uint64_t location = 2 * ptr_size + valobj_addr;
928 location = process_sp->ReadPointerFromMemory(location, error);
929 if (error.Fail())
930 return false;
931 if (has_explicit_length and is_unicode)
Enrico Granatacd8cd612013-01-14 23:53:26 +0000932 return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8,location, process_sp, stream, '@');
Enrico Granatacaaf0102012-09-04 18:48:21 +0000933 else
934 {
935 location++;
936 lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
937 size_t data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), 1024, error);
938 if (error.Fail())
939 return false;
940 if (data_read)
941 stream.Printf("@\"%s\"",(char*)buffer_sp->GetBytes());
942 return true;
943 }
944 }
945 else if (is_inline && has_explicit_length && !is_unicode && !is_special && !is_mutable)
946 {
947 uint64_t location = 3 * ptr_size + valobj_addr;
948 lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
949 size_t data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), 1024, error);
950 if (error.Fail())
951 return false;
952 if (data_read)
953 stream.Printf("@\"%s\"",(char*)buffer_sp->GetBytes());
954 return true;
955 }
956 else if (is_unicode)
957 {
958 uint64_t location = valobj_addr + ptr_size + 4 + (ptr_size == 8 ? 4 : 0);
959 if (is_inline)
960 {
961 if (!has_explicit_length)
962 {
963 stream.Printf("found new combo");
964 return true;
965 }
966 else
967 location += ptr_size;
968 }
969 else
970 {
971 location = process_sp->ReadPointerFromMemory(location, error);
972 if (error.Fail())
973 return false;
974 }
Enrico Granatacd8cd612013-01-14 23:53:26 +0000975 return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8, location, process_sp, stream, '@');
Enrico Granatacaaf0102012-09-04 18:48:21 +0000976 }
977 else if (is_special)
978 {
979 uint64_t location = valobj_addr + (ptr_size == 8 ? 12 : 8);
Enrico Granatacd8cd612013-01-14 23:53:26 +0000980 return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8, location, process_sp, stream, '@');
Enrico Granatacaaf0102012-09-04 18:48:21 +0000981 }
982 else if (is_inline)
983 {
984 uint64_t location = valobj_addr + ptr_size + 4 + (ptr_size == 8 ? 4 : 0);
985 if (!has_explicit_length)
986 location++;
987 lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
988 size_t data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), 1024, error);
989 if (error.Fail())
990 return false;
991 if (data_read)
992 stream.Printf("@\"%s\"",(char*)buffer_sp->GetBytes());
993 return true;
994 }
995 else
996 {
997 uint64_t location = valobj_addr + ptr_size + 4 + (ptr_size == 8 ? 4 : 0);
998 location = process_sp->ReadPointerFromMemory(location, error);
999 if (error.Fail())
1000 return false;
1001 lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
1002 size_t data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), 1024, error);
1003 if (error.Fail())
1004 return false;
1005 if (data_read)
1006 stream.Printf("@\"%s\"",(char*)buffer_sp->GetBytes());
1007 return true;
1008 }
1009
1010 stream.Printf("class name = %s",class_name);
1011 return true;
1012
1013}
1014
Enrico Granata9abbfba2012-10-03 23:53:45 +00001015bool
Enrico Granatadcffc1a2013-02-08 01:55:46 +00001016lldb_private::formatters::NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream)
1017{
1018 TargetSP target_sp(valobj.GetTargetSP());
1019 if (!target_sp)
1020 return false;
1021 uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize();
1022 uint64_t pointee = valobj.GetValueAsUnsigned(0);
1023 if (!pointee)
1024 return false;
1025 pointee += addr_size;
1026 ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
1027 ExecutionContext exe_ctx(target_sp,false);
1028 ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress("string_ptr", pointee, exe_ctx, type));
1029 if (!child_ptr_sp)
1030 return false;
1031 DataExtractor data;
1032 child_ptr_sp->GetData(data);
1033 ValueObjectSP child_sp(child_ptr_sp->CreateValueObjectFromData("string_data", data, exe_ctx, type));
1034 child_sp->GetValueAsUnsigned(0);
1035 if (child_sp)
1036 return NSStringSummaryProvider(*child_sp, stream);
1037 return false;
1038}
1039
1040bool
1041lldb_private::formatters::NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream)
1042{
1043 return NSAttributedStringSummaryProvider(valobj, stream);
1044}
1045
1046bool
Enrico Granata9abbfba2012-10-03 23:53:45 +00001047lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider (ValueObject& valobj, Stream& stream)
1048{
1049 stream.Printf("%s",valobj.GetObjectDescription());
1050 return true;
1051}
1052
Enrico Granatadb054912012-10-29 21:18:03 +00001053bool
Enrico Granata979c4b52013-02-08 19:28:04 +00001054lldb_private::formatters::NSURLSummaryProvider (ValueObject& valobj, Stream& stream)
1055{
1056 ProcessSP process_sp = valobj.GetProcessSP();
1057 if (!process_sp)
1058 return false;
1059
1060 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
1061
1062 if (!runtime)
1063 return false;
1064
1065 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
1066
1067 if (!descriptor.get() || !descriptor->IsValid())
1068 return false;
1069
1070 uint32_t ptr_size = process_sp->GetAddressByteSize();
1071
1072 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
1073
1074 if (!valobj_addr)
1075 return false;
1076
1077 const char* class_name = descriptor->GetClassName().GetCString();
1078
1079 if (!class_name || !*class_name)
1080 return false;
1081
1082 if (strcmp(class_name, "NSURL") == 0)
1083 {
1084 uint64_t offset_text = ptr_size + ptr_size + 8; // ISA + pointer + 8 bytes of data (even on 32bit)
1085 uint64_t offset_base = offset_text + ptr_size;
1086 ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
1087 ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset_text, type, true));
1088 ValueObjectSP base(valobj.GetSyntheticChildAtOffset(offset_base, type, true));
1089 if (!text || !base)
1090 return false;
1091 if (text->GetValueAsUnsigned(0) == 0)
1092 return false;
1093 StreamString summary;
1094 if (!NSStringSummaryProvider(*text, summary))
1095 return false;
1096 if (base->GetValueAsUnsigned(0))
1097 {
1098 if (summary.GetSize() > 0)
1099 summary.GetString().resize(summary.GetSize()-1);
1100 summary.Printf(" -- ");
1101 StreamString base_summary;
1102 if (NSStringSummaryProvider(*base, base_summary) && base_summary.GetSize() > 0)
1103 summary.Printf("%s",base_summary.GetSize() > 2 ? base_summary.GetData() + 2 : base_summary.GetData());
1104 }
1105 if (summary.GetSize())
1106 {
1107 stream.Printf("%s",summary.GetData());
1108 return true;
1109 }
1110 }
1111 else
1112 {
1113 // similar to ExtractValueFromObjCExpression but uses summary instead of value
1114 StreamString expr_path_stream;
1115 valobj.GetExpressionPath(expr_path_stream, false);
1116 StreamString expr;
1117 expr.Printf("(NSString*)[%s description]",expr_path_stream.GetData());
1118 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
1119 lldb::ValueObjectSP result_sp;
1120 Target* target = exe_ctx.GetTargetPtr();
1121 StackFrame* stack_frame = exe_ctx.GetFramePtr();
1122 if (!target || !stack_frame)
1123 return false;
1124
1125 EvaluateExpressionOptions options;
1126 options.SetCoerceToId(false)
1127 .SetUnwindOnError(true)
1128 .SetKeepInMemory(true)
1129 .SetUseDynamic(lldb::eDynamicCanRunTarget);
1130
1131 target->EvaluateExpression(expr.GetData(),
1132 stack_frame,
1133 result_sp,
1134 options);
1135 if (!result_sp)
1136 return false;
1137 stream.Printf("%s",result_sp->GetSummaryAsCString());
1138 return true;
1139 }
1140 return false;
1141}
1142
1143bool
Enrico Granatadb054912012-10-29 21:18:03 +00001144lldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream)
1145{
1146 const uint32_t type_info = ClangASTContext::GetTypeInfo(valobj.GetClangType(),
1147 valobj.GetClangAST(),
1148 NULL);
1149
1150 ValueObjectSP real_guy_sp = valobj.GetSP();
1151
1152 if (type_info & ClangASTContext::eTypeIsPointer)
1153 {
1154 Error err;
1155 real_guy_sp = valobj.Dereference(err);
1156 if (err.Fail() || !real_guy_sp)
1157 return false;
1158 }
1159 else if (type_info & ClangASTContext::eTypeIsReference)
1160 {
1161 real_guy_sp = valobj.GetChildAtIndex(0, true);
1162 if (!real_guy_sp)
1163 return false;
1164 }
1165 uint64_t value = real_guy_sp->GetValueAsUnsigned(0);
1166 if (value == 0)
1167 {
1168 stream.Printf("NO");
1169 return true;
1170 }
1171 stream.Printf("YES");
1172 return true;
1173}
1174
1175template <bool is_sel_ptr>
1176bool
1177lldb_private::formatters::ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream)
1178{
1179 lldb::addr_t data_address = LLDB_INVALID_ADDRESS;
1180
1181 if (is_sel_ptr)
1182 data_address = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
1183 else
1184 data_address = valobj.GetAddressOf();
1185
1186 if (data_address == LLDB_INVALID_ADDRESS)
1187 return false;
1188
1189 ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
1190
1191 void* char_opaque_type = valobj.GetClangAST()->CharTy.getAsOpaquePtr();
1192 ClangASTType charstar(valobj.GetClangAST(),ClangASTType::GetPointerType(valobj.GetClangAST(), char_opaque_type));
1193
1194 ValueObjectSP valobj_sp(ValueObject::CreateValueObjectFromAddress("text", data_address, exe_ctx, charstar));
1195
1196 stream.Printf("%s",valobj_sp->GetSummaryAsCString());
1197 return true;
1198}
1199
Enrico Granataf91e78f2012-09-13 18:27:09 +00001200lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
1201SyntheticChildrenFrontEnd(*valobj_sp.get()),
1202m_exe_ctx_ref(),
1203m_ptr_size(8),
1204m_data_32(NULL),
1205m_data_64(NULL)
1206{
Enrico Granata247da332012-10-04 21:04:46 +00001207 if (valobj_sp)
Enrico Granataf91e78f2012-09-13 18:27:09 +00001208 {
Enrico Granata247da332012-10-04 21:04:46 +00001209 m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
1210 Update();
Enrico Granataf91e78f2012-09-13 18:27:09 +00001211 }
Enrico Granataf91e78f2012-09-13 18:27:09 +00001212}
1213
Greg Clayton36da2aa2013-01-25 18:06:21 +00001214size_t
Enrico Granataf91e78f2012-09-13 18:27:09 +00001215lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren ()
1216{
1217 if (m_data_32)
1218 return m_data_32->_used;
1219 if (m_data_64)
1220 return m_data_64->_used;
1221 return 0;
1222}
1223
1224lldb::ValueObjectSP
Greg Clayton36da2aa2013-01-25 18:06:21 +00001225lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
Enrico Granataf91e78f2012-09-13 18:27:09 +00001226{
1227 if (!m_data_32 && !m_data_64)
1228 return lldb::ValueObjectSP();
1229 if (idx >= CalculateNumChildren())
1230 return lldb::ValueObjectSP();
1231 lldb::addr_t object_at_idx = (m_data_32 ? m_data_32->_data : m_data_64->_data);
1232 object_at_idx += (idx * m_ptr_size);
1233 StreamString idx_name;
Greg Clayton36da2aa2013-01-25 18:06:21 +00001234 idx_name.Printf("[%zu]",idx);
Enrico Granataf91e78f2012-09-13 18:27:09 +00001235 lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromAddress(idx_name.GetData(),
1236 object_at_idx,
1237 m_exe_ctx_ref,
1238 m_id_type);
1239 m_children.push_back(retval_sp);
1240 return retval_sp;
1241}
1242
1243bool
1244lldb_private::formatters::NSArrayMSyntheticFrontEnd::Update()
1245{
1246 m_children.clear();
Enrico Granata247da332012-10-04 21:04:46 +00001247 ValueObjectSP valobj_sp = m_backend.GetSP();
1248 m_ptr_size = 0;
1249 delete m_data_32;
1250 m_data_32 = NULL;
1251 delete m_data_64;
1252 m_data_64 = NULL;
1253 if (valobj_sp->IsDynamic())
1254 valobj_sp = valobj_sp->GetStaticValue();
1255 if (!valobj_sp)
1256 return false;
1257 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
1258 Error error;
1259 if (valobj_sp->IsPointerType())
1260 {
1261 valobj_sp = valobj_sp->Dereference(error);
1262 if (error.Fail() || !valobj_sp)
1263 return false;
1264 }
1265 error.Clear();
1266 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
1267 if (!process_sp)
1268 return false;
1269 m_ptr_size = process_sp->GetAddressByteSize();
1270 uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
1271 if (m_ptr_size == 4)
1272 {
1273 m_data_32 = new DataDescriptor_32();
1274 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
1275 }
1276 else
1277 {
1278 m_data_64 = new DataDescriptor_64();
1279 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
1280 }
1281 if (error.Fail())
1282 return false;
Enrico Granataf91e78f2012-09-13 18:27:09 +00001283 return false;
1284}
1285
Enrico Granata800332c2012-10-23 19:54:09 +00001286bool
1287lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren ()
1288{
Enrico Granataf3c10482012-12-10 19:55:53 +00001289 return true;
Enrico Granata800332c2012-10-23 19:54:09 +00001290}
1291
Enrico Granataf91e78f2012-09-13 18:27:09 +00001292static uint32_t
1293ExtractIndexFromString (const char* item_name)
1294{
1295 if (!item_name || !*item_name)
1296 return UINT32_MAX;
1297 if (*item_name != '[')
1298 return UINT32_MAX;
1299 item_name++;
1300 uint32_t idx = 0;
1301 while(*item_name)
1302 {
1303 char x = *item_name;
1304 if (x == ']')
1305 break;
1306 if (x < '0' || x > '9')
1307 return UINT32_MAX;
1308 idx = 10*idx + (x-'0');
1309 item_name++;
1310 }
1311 return idx;
1312}
1313
Enrico Granataf509c5e2013-01-28 23:47:25 +00001314size_t
Enrico Granataf91e78f2012-09-13 18:27:09 +00001315lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
1316{
1317 if (!m_data_32 && !m_data_64)
1318 return UINT32_MAX;
1319 const char* item_name = name.GetCString();
1320 uint32_t idx = ExtractIndexFromString(item_name);
1321 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
1322 return UINT32_MAX;
1323 return idx;
1324}
1325
1326lldb_private::formatters::NSArrayMSyntheticFrontEnd::~NSArrayMSyntheticFrontEnd ()
1327{
1328 delete m_data_32;
1329 m_data_32 = NULL;
1330 delete m_data_64;
1331 m_data_64 = NULL;
1332}
1333
1334lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
1335SyntheticChildrenFrontEnd(*valobj_sp.get()),
1336m_exe_ctx_ref(),
1337m_ptr_size(8),
1338m_items(0),
1339m_data_ptr(0)
1340{
Enrico Granata247da332012-10-04 21:04:46 +00001341 if (valobj_sp)
Enrico Granataf91e78f2012-09-13 18:27:09 +00001342 {
Enrico Granata247da332012-10-04 21:04:46 +00001343 m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
1344 Update();
Enrico Granataf91e78f2012-09-13 18:27:09 +00001345 }
Enrico Granataf91e78f2012-09-13 18:27:09 +00001346}
1347
1348lldb_private::formatters::NSArrayISyntheticFrontEnd::~NSArrayISyntheticFrontEnd ()
1349{
1350}
1351
Enrico Granataf509c5e2013-01-28 23:47:25 +00001352size_t
Enrico Granataf91e78f2012-09-13 18:27:09 +00001353lldb_private::formatters::NSArrayISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
1354{
1355 const char* item_name = name.GetCString();
1356 uint32_t idx = ExtractIndexFromString(item_name);
1357 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
1358 return UINT32_MAX;
1359 return idx;
1360}
1361
Greg Clayton36da2aa2013-01-25 18:06:21 +00001362size_t
Enrico Granataf91e78f2012-09-13 18:27:09 +00001363lldb_private::formatters::NSArrayISyntheticFrontEnd::CalculateNumChildren ()
1364{
1365 return m_items;
1366}
1367
1368bool
1369lldb_private::formatters::NSArrayISyntheticFrontEnd::Update()
1370{
Enrico Granata247da332012-10-04 21:04:46 +00001371 m_ptr_size = 0;
1372 m_items = 0;
1373 m_data_ptr = 0;
Enrico Granataf91e78f2012-09-13 18:27:09 +00001374 m_children.clear();
Enrico Granata247da332012-10-04 21:04:46 +00001375 ValueObjectSP valobj_sp = m_backend.GetSP();
1376 if (valobj_sp->IsDynamic())
1377 valobj_sp = valobj_sp->GetStaticValue();
1378 if (!valobj_sp)
1379 return false;
1380 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
1381 Error error;
1382 if (valobj_sp->IsPointerType())
1383 {
1384 valobj_sp = valobj_sp->Dereference(error);
1385 if (error.Fail() || !valobj_sp)
1386 return false;
1387 }
1388 error.Clear();
1389 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
1390 if (!process_sp)
1391 return false;
1392 m_ptr_size = process_sp->GetAddressByteSize();
1393 uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
1394 m_items = process_sp->ReadPointerFromMemory(data_location, error);
1395 if (error.Fail())
1396 return false;
1397 m_data_ptr = data_location+m_ptr_size;
Enrico Granataf91e78f2012-09-13 18:27:09 +00001398 return false;
1399}
1400
Enrico Granata800332c2012-10-23 19:54:09 +00001401bool
1402lldb_private::formatters::NSArrayISyntheticFrontEnd::MightHaveChildren ()
1403{
Enrico Granataf3c10482012-12-10 19:55:53 +00001404 return true;
Enrico Granata800332c2012-10-23 19:54:09 +00001405}
1406
Enrico Granataf91e78f2012-09-13 18:27:09 +00001407lldb::ValueObjectSP
Greg Clayton36da2aa2013-01-25 18:06:21 +00001408lldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex (size_t idx)
Enrico Granataf91e78f2012-09-13 18:27:09 +00001409{
1410 if (idx >= CalculateNumChildren())
1411 return lldb::ValueObjectSP();
1412 lldb::addr_t object_at_idx = m_data_ptr;
1413 object_at_idx += (idx * m_ptr_size);
1414 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
1415 if (!process_sp)
1416 return lldb::ValueObjectSP();
1417 Error error;
1418 object_at_idx = process_sp->ReadPointerFromMemory(object_at_idx, error);
1419 if (error.Fail())
1420 return lldb::ValueObjectSP();
1421 StreamString expr;
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001422 expr.Printf("(id)%" PRIu64,object_at_idx);
Enrico Granataf91e78f2012-09-13 18:27:09 +00001423 StreamString idx_name;
Greg Clayton36da2aa2013-01-25 18:06:21 +00001424 idx_name.Printf("[%zu]",idx);
Enrico Granataf91e78f2012-09-13 18:27:09 +00001425 lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
1426 m_children.push_back(retval_sp);
1427 return retval_sp;
1428}
1429
1430SyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
1431{
1432 lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
1433 if (!process_sp)
1434 return NULL;
1435 ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
1436 if (!runtime)
1437 return NULL;
1438
1439 if (!valobj_sp->IsPointerType())
1440 {
1441 Error error;
1442 valobj_sp = valobj_sp->AddressOf(error);
1443 if (error.Fail() || !valobj_sp)
1444 return NULL;
1445 }
1446
1447 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
1448
1449 if (!descriptor.get() || !descriptor->IsValid())
1450 return NULL;
1451
1452 const char* class_name = descriptor->GetClassName().GetCString();
Enrico Granata7685a562012-09-29 00:47:43 +00001453
1454 if (!class_name || !*class_name)
1455 return NULL;
1456
Enrico Granataf91e78f2012-09-13 18:27:09 +00001457 if (!strcmp(class_name,"__NSArrayI"))
1458 {
1459 return (new NSArrayISyntheticFrontEnd(valobj_sp));
1460 }
1461 else if (!strcmp(class_name,"__NSArrayM"))
1462 {
1463 return (new NSArrayMSyntheticFrontEnd(valobj_sp));
1464 }
1465 else
1466 {
1467 return (new NSArrayCodeRunningSyntheticFrontEnd(valobj_sp));
1468 }
1469}
1470
1471lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
1472SyntheticChildrenFrontEnd(*valobj_sp.get())
1473{}
1474
Greg Clayton36da2aa2013-01-25 18:06:21 +00001475size_t
Enrico Granataf91e78f2012-09-13 18:27:09 +00001476lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
1477{
Enrico Granataf91e78f2012-09-13 18:27:09 +00001478 uint64_t count = 0;
1479 if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
1480 return count;
1481 return 0;
1482}
1483
1484lldb::ValueObjectSP
Greg Clayton36da2aa2013-01-25 18:06:21 +00001485lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetChildAtIndex (size_t idx)
Enrico Granataf91e78f2012-09-13 18:27:09 +00001486{
1487 StreamString idx_name;
Greg Clayton36da2aa2013-01-25 18:06:21 +00001488 idx_name.Printf("[%zu]",idx);
Enrico Granataf91e78f2012-09-13 18:27:09 +00001489 lldb::ValueObjectSP valobj_sp = CallSelectorOnObject(m_backend,"id","objectAtIndex:",idx);
1490 if (valobj_sp)
1491 valobj_sp->SetName(ConstString(idx_name.GetData()));
1492 return valobj_sp;
1493}
1494
1495bool
1496lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::Update()
1497{
1498 return false;
1499}
1500
Enrico Granata800332c2012-10-23 19:54:09 +00001501bool
1502lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::MightHaveChildren ()
1503{
Enrico Granataf3c10482012-12-10 19:55:53 +00001504 return true;
Enrico Granata800332c2012-10-23 19:54:09 +00001505}
1506
Enrico Granataf509c5e2013-01-28 23:47:25 +00001507size_t
Enrico Granataf91e78f2012-09-13 18:27:09 +00001508lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
1509{
1510 return 0;
1511}
1512
1513lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::~NSArrayCodeRunningSyntheticFrontEnd ()
1514{}
1515
Enrico Granata3a08fd12012-09-18 17:43:16 +00001516SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
1517{
1518
1519 lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
1520 if (!process_sp)
1521 return NULL;
1522 ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
1523 if (!runtime)
1524 return NULL;
1525
1526 if (!valobj_sp->IsPointerType())
1527 {
1528 Error error;
1529 valobj_sp = valobj_sp->AddressOf(error);
1530 if (error.Fail() || !valobj_sp)
1531 return NULL;
1532 }
1533
1534 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
1535
1536 if (!descriptor.get() || !descriptor->IsValid())
1537 return NULL;
1538
1539 const char* class_name = descriptor->GetClassName().GetCString();
Enrico Granata7685a562012-09-29 00:47:43 +00001540
1541 if (!class_name || !*class_name)
1542 return NULL;
1543
Enrico Granata3a08fd12012-09-18 17:43:16 +00001544 if (!strcmp(class_name,"__NSDictionaryI"))
1545 {
1546 return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
1547 }
1548 else if (!strcmp(class_name,"__NSDictionaryM"))
1549 {
1550 return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
1551 }
1552 else
1553 {
1554 return (new NSDictionaryCodeRunningSyntheticFrontEnd(valobj_sp));
1555 }
1556}
1557
1558lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
1559SyntheticChildrenFrontEnd(*valobj_sp.get())
1560{}
1561
Greg Clayton36da2aa2013-01-25 18:06:21 +00001562size_t
Enrico Granata3a08fd12012-09-18 17:43:16 +00001563lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
1564{
1565 uint64_t count = 0;
1566 if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
1567 return count;
1568 return 0;
1569}
1570
1571lldb::ValueObjectSP
Greg Clayton36da2aa2013-01-25 18:06:21 +00001572lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetChildAtIndex (size_t idx)
Enrico Granata3a08fd12012-09-18 17:43:16 +00001573{
1574 StreamString idx_name;
Greg Clayton36da2aa2013-01-25 18:06:21 +00001575 idx_name.Printf("[%zu]",idx);
Enrico Granata3a08fd12012-09-18 17:43:16 +00001576 StreamString valobj_expr_path;
1577 m_backend.GetExpressionPath(valobj_expr_path, false);
1578 StreamString key_fetcher_expr;
Greg Clayton36da2aa2013-01-25 18:06:21 +00001579 key_fetcher_expr.Printf("(id)[(NSArray*)[%s allKeys] objectAtIndex:%zu]",valobj_expr_path.GetData(),idx);
Enrico Granata3a08fd12012-09-18 17:43:16 +00001580 StreamString value_fetcher_expr;
1581 value_fetcher_expr.Printf("(id)[%s objectForKey:%s]",valobj_expr_path.GetData(),key_fetcher_expr.GetData());
1582 StreamString object_fetcher_expr;
Enrico Granatafd3d28d2012-10-01 21:49:10 +00001583 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());
Enrico Granata3a08fd12012-09-18 17:43:16 +00001584 lldb::ValueObjectSP child_sp;
1585 m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(), m_backend.GetFrameSP().get(), child_sp,
Jim Ingham47beabb2012-10-16 21:41:58 +00001586 EvaluateExpressionOptions().SetKeepInMemory(true));
Enrico Granata3a08fd12012-09-18 17:43:16 +00001587 if (child_sp)
1588 child_sp->SetName(ConstString(idx_name.GetData()));
1589 return child_sp;
1590}
1591
1592bool
1593lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::Update()
1594{
1595 return false;
1596}
1597
Enrico Granata800332c2012-10-23 19:54:09 +00001598bool
1599lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::MightHaveChildren ()
1600{
Enrico Granataf3c10482012-12-10 19:55:53 +00001601 return true;
Enrico Granata800332c2012-10-23 19:54:09 +00001602}
1603
Enrico Granataf509c5e2013-01-28 23:47:25 +00001604size_t
Enrico Granata3a08fd12012-09-18 17:43:16 +00001605lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
1606{
1607 return 0;
1608}
1609
1610lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::~NSDictionaryCodeRunningSyntheticFrontEnd ()
1611{}
1612
1613lldb_private::formatters::NSDictionaryISyntheticFrontEnd::NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
1614 SyntheticChildrenFrontEnd(*valobj_sp.get()),
1615 m_exe_ctx_ref(),
1616 m_ptr_size(8),
1617 m_data_32(NULL),
1618 m_data_64(NULL)
1619{
Enrico Granataa787c1a2012-10-04 21:46:06 +00001620 if (valobj_sp)
1621 Update();
Enrico Granata3a08fd12012-09-18 17:43:16 +00001622}
1623
1624lldb_private::formatters::NSDictionaryISyntheticFrontEnd::~NSDictionaryISyntheticFrontEnd ()
1625{
1626 delete m_data_32;
1627 m_data_32 = NULL;
1628 delete m_data_64;
1629 m_data_64 = NULL;
1630}
1631
Enrico Granataf509c5e2013-01-28 23:47:25 +00001632size_t
Enrico Granata3a08fd12012-09-18 17:43:16 +00001633lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
1634{
1635 const char* item_name = name.GetCString();
1636 uint32_t idx = ExtractIndexFromString(item_name);
1637 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
1638 return UINT32_MAX;
1639 return idx;
1640}
1641
Greg Clayton36da2aa2013-01-25 18:06:21 +00001642size_t
Enrico Granata3a08fd12012-09-18 17:43:16 +00001643lldb_private::formatters::NSDictionaryISyntheticFrontEnd::CalculateNumChildren ()
1644{
1645 if (!m_data_32 && !m_data_64)
1646 return 0;
1647 return (m_data_32 ? m_data_32->_used : m_data_64->_used);
1648}
1649
1650bool
1651lldb_private::formatters::NSDictionaryISyntheticFrontEnd::Update()
1652{
1653 m_children.clear();
Enrico Granataa787c1a2012-10-04 21:46:06 +00001654 delete m_data_32;
1655 m_data_32 = NULL;
1656 delete m_data_64;
1657 m_data_64 = NULL;
1658 m_ptr_size = 0;
1659 ValueObjectSP valobj_sp = m_backend.GetSP();
1660 if (!valobj_sp)
1661 return false;
1662 if (valobj_sp->IsDynamic())
1663 valobj_sp = valobj_sp->GetStaticValue();
1664 if (!valobj_sp)
1665 return false;
1666 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
1667 Error error;
1668 if (valobj_sp->IsPointerType())
1669 {
1670 valobj_sp = valobj_sp->Dereference(error);
1671 if (error.Fail() || !valobj_sp)
1672 return false;
1673 }
1674 error.Clear();
1675 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
1676 if (!process_sp)
1677 return false;
1678 m_ptr_size = process_sp->GetAddressByteSize();
1679 uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
1680 if (m_ptr_size == 4)
1681 {
1682 m_data_32 = new DataDescriptor_32();
1683 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
1684 }
1685 else
1686 {
1687 m_data_64 = new DataDescriptor_64();
1688 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
1689 }
1690 if (error.Fail())
1691 return false;
1692 m_data_ptr = data_location + m_ptr_size;
Enrico Granata3a08fd12012-09-18 17:43:16 +00001693 return false;
1694}
1695
Enrico Granata800332c2012-10-23 19:54:09 +00001696bool
1697lldb_private::formatters::NSDictionaryISyntheticFrontEnd::MightHaveChildren ()
1698{
Enrico Granataf3c10482012-12-10 19:55:53 +00001699 return true;
Enrico Granata800332c2012-10-23 19:54:09 +00001700}
1701
Enrico Granata3a08fd12012-09-18 17:43:16 +00001702lldb::ValueObjectSP
Greg Clayton36da2aa2013-01-25 18:06:21 +00001703lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex (size_t idx)
Enrico Granata3a08fd12012-09-18 17:43:16 +00001704{
1705 uint32_t num_children = CalculateNumChildren();
1706
1707 if (idx >= num_children)
1708 return lldb::ValueObjectSP();
1709
1710 if (m_children.empty())
1711 {
1712 // do the scan phase
1713 lldb::addr_t key_at_idx = 0, val_at_idx = 0;
1714
1715 uint32_t tries = 0;
1716 uint32_t test_idx = 0;
1717
1718 while(tries < num_children)
1719 {
1720 key_at_idx = m_data_ptr + (2*test_idx * m_ptr_size);
1721 val_at_idx = key_at_idx + m_ptr_size;
1722 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
1723 if (!process_sp)
1724 return lldb::ValueObjectSP();
1725 Error error;
1726 key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
1727 if (error.Fail())
1728 return lldb::ValueObjectSP();
1729 val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
1730 if (error.Fail())
1731 return lldb::ValueObjectSP();
1732
1733 test_idx++;
1734
1735 if (!key_at_idx || !val_at_idx)
1736 continue;
1737 tries++;
1738
1739 DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
1740
1741 m_children.push_back(descriptor);
1742 }
1743 }
1744
1745 if (idx >= m_children.size()) // should never happen
1746 return lldb::ValueObjectSP();
1747
1748 DictionaryItemDescriptor &dict_item = m_children[idx];
1749 if (!dict_item.valobj_sp)
1750 {
1751 // make the new ValueObject
1752 StreamString expr;
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001753 expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = (id)%" PRIu64 " ; _lldb_valgen_item.value = (id)%" PRIu64 "; _lldb_valgen_item;",dict_item.key_ptr,dict_item.val_ptr);
Enrico Granata3a08fd12012-09-18 17:43:16 +00001754 StreamString idx_name;
Greg Clayton36da2aa2013-01-25 18:06:21 +00001755 idx_name.Printf("[%zu]",idx);
Enrico Granata3a08fd12012-09-18 17:43:16 +00001756 dict_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
1757 }
1758 return dict_item.valobj_sp;
1759}
1760
1761lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
1762 SyntheticChildrenFrontEnd(*valobj_sp.get()),
1763 m_exe_ctx_ref(),
1764 m_ptr_size(8),
1765 m_data_32(NULL),
1766 m_data_64(NULL)
1767{
Enrico Granataa787c1a2012-10-04 21:46:06 +00001768 if (valobj_sp)
1769 Update ();
Enrico Granata3a08fd12012-09-18 17:43:16 +00001770}
1771
1772lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd ()
1773{
1774 delete m_data_32;
1775 m_data_32 = NULL;
1776 delete m_data_64;
1777 m_data_64 = NULL;
1778}
1779
Enrico Granataf509c5e2013-01-28 23:47:25 +00001780size_t
Enrico Granata3a08fd12012-09-18 17:43:16 +00001781lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
1782{
1783 const char* item_name = name.GetCString();
1784 uint32_t idx = ExtractIndexFromString(item_name);
1785 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
1786 return UINT32_MAX;
1787 return idx;
1788}
1789
Greg Clayton36da2aa2013-01-25 18:06:21 +00001790size_t
Enrico Granata3a08fd12012-09-18 17:43:16 +00001791lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::CalculateNumChildren ()
1792{
1793 if (!m_data_32 && !m_data_64)
1794 return 0;
1795 return (m_data_32 ? m_data_32->_used : m_data_64->_used);
1796}
1797
1798bool
1799lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update()
1800{
1801 m_children.clear();
Enrico Granataa787c1a2012-10-04 21:46:06 +00001802 ValueObjectSP valobj_sp = m_backend.GetSP();
1803 m_ptr_size = 0;
1804 delete m_data_32;
1805 m_data_32 = NULL;
1806 delete m_data_64;
1807 m_data_64 = NULL;
1808 if (!valobj_sp)
1809 return false;
1810 if (valobj_sp->IsDynamic())
1811 valobj_sp = valobj_sp->GetStaticValue();
1812 if (!valobj_sp)
1813 return false;
1814 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
1815 Error error;
1816 if (valobj_sp->IsPointerType())
1817 {
1818 valobj_sp = valobj_sp->Dereference(error);
1819 if (error.Fail() || !valobj_sp)
1820 return false;
1821 }
1822 error.Clear();
1823 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
1824 if (!process_sp)
1825 return false;
1826 m_ptr_size = process_sp->GetAddressByteSize();
1827 uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
1828 if (m_ptr_size == 4)
1829 {
1830 m_data_32 = new DataDescriptor_32();
1831 process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
1832 }
1833 else
1834 {
1835 m_data_64 = new DataDescriptor_64();
1836 process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
1837 }
1838 if (error.Fail())
1839 return false;
Enrico Granata3a08fd12012-09-18 17:43:16 +00001840 return false;
1841}
1842
Enrico Granata800332c2012-10-23 19:54:09 +00001843bool
1844lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::MightHaveChildren ()
1845{
Enrico Granataf3c10482012-12-10 19:55:53 +00001846 return true;
Enrico Granata800332c2012-10-23 19:54:09 +00001847}
1848
Enrico Granata3a08fd12012-09-18 17:43:16 +00001849lldb::ValueObjectSP
Greg Clayton36da2aa2013-01-25 18:06:21 +00001850lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
Enrico Granata3a08fd12012-09-18 17:43:16 +00001851{
1852 lldb::addr_t m_keys_ptr = (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
1853 lldb::addr_t m_values_ptr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
1854
1855 uint32_t num_children = CalculateNumChildren();
1856
1857 if (idx >= num_children)
1858 return lldb::ValueObjectSP();
1859
1860 if (m_children.empty())
1861 {
1862 // do the scan phase
1863 lldb::addr_t key_at_idx = 0, val_at_idx = 0;
1864
1865 uint32_t tries = 0;
1866 uint32_t test_idx = 0;
1867
1868 while(tries < num_children)
1869 {
1870 key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
1871 val_at_idx = m_values_ptr + (test_idx * m_ptr_size);;
1872 ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
1873 if (!process_sp)
1874 return lldb::ValueObjectSP();
1875 Error error;
1876 key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
1877 if (error.Fail())
1878 return lldb::ValueObjectSP();
1879 val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
1880 if (error.Fail())
1881 return lldb::ValueObjectSP();
1882
1883 test_idx++;
1884
1885 if (!key_at_idx || !val_at_idx)
1886 continue;
1887 tries++;
1888
1889 DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
1890
1891 m_children.push_back(descriptor);
1892 }
1893 }
1894
1895 if (idx >= m_children.size()) // should never happen
1896 return lldb::ValueObjectSP();
1897
1898 DictionaryItemDescriptor &dict_item = m_children[idx];
1899 if (!dict_item.valobj_sp)
1900 {
1901 // make the new ValueObject
1902 StreamString expr;
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001903 expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = (id)%" PRIu64 " ; _lldb_valgen_item.value = (id)%" PRIu64 "; _lldb_valgen_item;",dict_item.key_ptr,dict_item.val_ptr);
Enrico Granata3a08fd12012-09-18 17:43:16 +00001904 StreamString idx_name;
Greg Clayton36da2aa2013-01-25 18:06:21 +00001905 idx_name.Printf("[%zu]",idx);
Enrico Granata3a08fd12012-09-18 17:43:16 +00001906 dict_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
1907 }
1908 return dict_item.valobj_sp;
1909}
Enrico Granatacaaf0102012-09-04 18:48:21 +00001910
Enrico Granata689696c2013-02-04 22:54:42 +00001911lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::LibcxxVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
1912 SyntheticChildrenFrontEnd(*valobj_sp.get()),
1913 m_exe_ctx_ref(),
1914 m_count(0),
1915 m_base_data_address(0),
1916 m_options()
1917 {
1918 if (valobj_sp)
1919 Update();
1920 m_options.SetCoerceToId(false)
1921 .SetUnwindOnError(true)
1922 .SetKeepInMemory(true)
1923 .SetUseDynamic(lldb::eDynamicCanRunTarget);
1924 }
1925
1926size_t
1927lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::CalculateNumChildren ()
1928{
1929 return m_count;
1930}
1931
1932lldb::ValueObjectSP
1933lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex (size_t idx)
1934{
1935 if (idx >= m_count)
1936 return ValueObjectSP();
1937 if (m_base_data_address == 0 || m_count == 0)
1938 return ValueObjectSP();
1939 size_t byte_idx = (idx >> 3); // divide by 8 to get byte index
1940 size_t bit_index = (idx & 7); // efficient idx % 8 for bit index
1941 lldb::addr_t byte_location = m_base_data_address + byte_idx;
1942 ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
1943 if (!process_sp)
1944 return ValueObjectSP();
1945 uint8_t byte = 0;
1946 uint8_t mask = 0;
1947 Error err;
1948 size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err);
1949 if (err.Fail() || bytes_read == 0)
1950 return ValueObjectSP();
1951 switch (bit_index)
1952 {
1953 case 0:
1954 mask = 1; break;
1955 case 1:
1956 mask = 2; break;
1957 case 2:
1958 mask = 4; break;
1959 case 3:
1960 mask = 8; break;
1961 case 4:
1962 mask = 16; break;
1963 case 5:
1964 mask = 32; break;
1965 case 6:
1966 mask = 64; break;
1967 case 7:
1968 mask = 128; break;
1969 default:
1970 return ValueObjectSP();
1971 }
1972 bool bit_set = ((byte & mask) != 0);
1973 Target& target(process_sp->GetTarget());
1974 ValueObjectSP retval_sp;
1975 if (bit_set)
1976 target.EvaluateExpression("(bool)true", NULL, retval_sp);
1977 else
1978 target.EvaluateExpression("(bool)false", NULL, retval_sp);
1979 StreamString name; name.Printf("[%zu]",idx);
1980 if (retval_sp)
1981 retval_sp->SetName(ConstString(name.GetData()));
1982 return retval_sp;
1983}
1984
1985/*(std::__1::vector<std::__1::allocator<bool> >) vBool = {
1986 __begin_ = 0x00000001001000e0
1987 __size_ = 56
1988 __cap_alloc_ = {
1989 std::__1::__libcpp_compressed_pair_imp<unsigned long, std::__1::allocator<unsigned long> > = {
1990 __first_ = 1
1991 }
1992 }
1993}*/
1994
1995bool
1996lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::Update()
1997{
1998 ValueObjectSP valobj_sp = m_backend.GetSP();
1999 if (!valobj_sp)
2000 return false;
2001 if (valobj_sp->IsDynamic())
2002 valobj_sp = valobj_sp->GetStaticValue();
2003 if (!valobj_sp)
2004 return false;
2005 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
2006 ValueObjectSP size_sp(valobj_sp->GetChildMemberWithName(ConstString("__size_"), true));
2007 if (!size_sp)
2008 return false;
2009 m_count = size_sp->GetValueAsUnsigned(0);
2010 if (!m_count)
2011 return true;
2012 ValueObjectSP begin_sp(valobj_sp->GetChildMemberWithName(ConstString("__begin_"), true));
2013 if (!begin_sp)
2014 {
2015 m_count = 0;
2016 return false;
2017 }
2018 m_base_data_address = begin_sp->GetValueAsUnsigned(0);
2019 if (!m_base_data_address)
2020 {
2021 m_count = 0;
2022 return false;
2023 }
2024 return true;
2025}
2026
2027bool
2028lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::MightHaveChildren ()
2029{
2030 return true;
2031}
2032
2033size_t
2034lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
2035{
2036 if (!m_count || !m_base_data_address)
2037 return UINT32_MAX;
2038 const char* item_name = name.GetCString();
2039 uint32_t idx = ExtractIndexFromString(item_name);
2040 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
2041 return UINT32_MAX;
2042 return idx;
2043}
2044
2045lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::~LibcxxVectorBoolSyntheticFrontEnd ()
2046{}
2047
2048SyntheticChildrenFrontEnd*
2049lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
2050{
2051 if (!valobj_sp)
2052 return NULL;
2053 return (new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp));
2054}
2055
2056lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::LibstdcppVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
2057SyntheticChildrenFrontEnd(*valobj_sp.get()),
2058m_exe_ctx_ref(),
2059m_count(0),
2060m_base_data_address(0),
2061m_options()
2062{
2063 if (valobj_sp)
2064 Update();
2065 m_options.SetCoerceToId(false)
2066 .SetUnwindOnError(true)
2067 .SetKeepInMemory(true)
2068 .SetUseDynamic(lldb::eDynamicCanRunTarget);
2069}
2070
2071size_t
2072lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::CalculateNumChildren ()
2073{
2074 return m_count;
2075}
2076
2077lldb::ValueObjectSP
2078lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::GetChildAtIndex (size_t idx)
2079{
2080 if (idx >= m_count)
2081 return ValueObjectSP();
2082 if (m_base_data_address == 0 || m_count == 0)
2083 return ValueObjectSP();
2084 size_t byte_idx = (idx >> 3); // divide by 8 to get byte index
2085 size_t bit_index = (idx & 7); // efficient idx % 8 for bit index
2086 lldb::addr_t byte_location = m_base_data_address + byte_idx;
2087 ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
2088 if (!process_sp)
2089 return ValueObjectSP();
2090 uint8_t byte = 0;
2091 uint8_t mask = 0;
2092 Error err;
2093 size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err);
2094 if (err.Fail() || bytes_read == 0)
2095 return ValueObjectSP();
2096 switch (bit_index)
2097 {
2098 case 0:
2099 mask = 1; break;
2100 case 1:
2101 mask = 2; break;
2102 case 2:
2103 mask = 4; break;
2104 case 3:
2105 mask = 8; break;
2106 case 4:
2107 mask = 16; break;
2108 case 5:
2109 mask = 32; break;
2110 case 6:
2111 mask = 64; break;
2112 case 7:
2113 mask = 128; break;
2114 default:
2115 return ValueObjectSP();
2116 }
2117 bool bit_set = ((byte & mask) != 0);
2118 Target& target(process_sp->GetTarget());
2119 ValueObjectSP retval_sp;
2120 if (bit_set)
2121 target.EvaluateExpression("(bool)true", NULL, retval_sp);
2122 else
2123 target.EvaluateExpression("(bool)false", NULL, retval_sp);
2124 StreamString name; name.Printf("[%zu]",idx);
2125 if (retval_sp)
2126 retval_sp->SetName(ConstString(name.GetData()));
2127 return retval_sp;
2128}
2129
2130/*((std::vector<std::allocator<bool> >) vBool = {
2131 (std::_Bvector_base<std::allocator<bool> >) std::_Bvector_base<std::allocator<bool> > = {
2132 (std::_Bvector_base<std::allocator<bool> >::_Bvector_impl) _M_impl = {
2133 (std::_Bit_iterator) _M_start = {
2134 (std::_Bit_iterator_base) std::_Bit_iterator_base = {
2135 (_Bit_type *) _M_p = 0x0016b160
2136 (unsigned int) _M_offset = 0
2137 }
2138 }
2139 (std::_Bit_iterator) _M_finish = {
2140 (std::_Bit_iterator_base) std::_Bit_iterator_base = {
2141 (_Bit_type *) _M_p = 0x0016b16c
2142 (unsigned int) _M_offset = 16
2143 }
2144 }
2145 (_Bit_type *) _M_end_of_storage = 0x0016b170
2146 }
2147 }
2148 }
2149*/
2150
2151bool
2152lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::Update()
2153{
2154 ValueObjectSP valobj_sp = m_backend.GetSP();
2155 if (!valobj_sp)
2156 return false;
2157 if (valobj_sp->IsDynamic())
2158 valobj_sp = valobj_sp->GetStaticValue();
2159 if (!valobj_sp)
2160 return false;
2161 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
2162
2163 ValueObjectSP m_impl_sp(valobj_sp->GetChildMemberWithName(ConstString("_M_impl"), true));
2164 if (!m_impl_sp)
2165 return false;
2166
2167 ValueObjectSP m_start_sp(m_impl_sp->GetChildMemberWithName(ConstString("_M_start"), true));
2168 ValueObjectSP m_finish_sp(m_impl_sp->GetChildMemberWithName(ConstString("_M_finish"), true));
2169
2170 ValueObjectSP start_p_sp, finish_p_sp, finish_offset_sp;
2171
2172 if (!m_start_sp || !m_finish_sp)
2173 return false;
2174
2175 start_p_sp = m_start_sp->GetChildMemberWithName(ConstString("_M_p"), true);
2176 finish_p_sp = m_finish_sp->GetChildMemberWithName(ConstString("_M_p"), true);
2177 finish_offset_sp = m_finish_sp->GetChildMemberWithName(ConstString("_M_offset"), true);
2178
2179 if (!start_p_sp || !finish_offset_sp || !finish_p_sp)
2180 return false;
2181
2182 m_base_data_address = start_p_sp->GetValueAsUnsigned(0);
2183 if (!m_base_data_address)
2184 return false;
2185
2186 lldb::addr_t end_data_address(finish_p_sp->GetValueAsUnsigned(0));
2187 if (!end_data_address)
2188 return false;
2189
2190 if (end_data_address < m_base_data_address)
2191 return false;
2192 else
2193 m_count = finish_offset_sp->GetValueAsUnsigned(0) + (end_data_address-m_base_data_address)*8;
2194
2195 return true;
2196}
2197
2198bool
2199lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::MightHaveChildren ()
2200{
2201 return true;
2202}
2203
2204size_t
2205lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
2206{
2207 if (!m_count || !m_base_data_address)
2208 return UINT32_MAX;
2209 const char* item_name = name.GetCString();
2210 uint32_t idx = ExtractIndexFromString(item_name);
2211 if (idx < UINT32_MAX && idx >= CalculateNumChildren())
2212 return UINT32_MAX;
2213 return idx;
2214}
2215
2216lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::~LibstdcppVectorBoolSyntheticFrontEnd ()
2217{}
2218
2219SyntheticChildrenFrontEnd*
2220lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
2221{
2222 if (!valobj_sp)
2223 return NULL;
2224 return (new LibstdcppVectorBoolSyntheticFrontEnd(valobj_sp));
2225}
2226
Enrico Granatacaaf0102012-09-04 18:48:21 +00002227template bool
Enrico Granataf91e78f2012-09-13 18:27:09 +00002228lldb_private::formatters::NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
Enrico Granatacaaf0102012-09-04 18:48:21 +00002229
2230template bool
Enrico Granataf91e78f2012-09-13 18:27:09 +00002231lldb_private::formatters::NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;
Enrico Granatacaaf0102012-09-04 18:48:21 +00002232
2233template bool
Enrico Granataf91e78f2012-09-13 18:27:09 +00002234lldb_private::formatters::NSDataSummaryProvider<true> (ValueObject&, Stream&) ;
2235
2236template bool
2237lldb_private::formatters::NSDataSummaryProvider<false> (ValueObject&, Stream&) ;
Enrico Granatadb054912012-10-29 21:18:03 +00002238
2239template bool
2240lldb_private::formatters::ObjCSELSummaryProvider<true> (ValueObject&, Stream&) ;
2241
2242template bool
2243lldb_private::formatters::ObjCSELSummaryProvider<false> (ValueObject&, Stream&) ;