1 //===-- CXXFormatterFunctions.cpp---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/DataFormatters/CXXFormatterFunctions.h"
11 #include "lldb/DataFormatters/StringPrinter.h"
12 #include "lldb/DataFormatters/TypeSummary.h"
14 #include "llvm/Support/ConvertUTF.h"
16 #include "lldb/Core/DataBufferHeap.h"
17 #include "lldb/Core/Error.h"
18 #include "lldb/Core/Stream.h"
19 #include "lldb/Core/ValueObject.h"
20 #include "lldb/Core/ValueObjectConstResult.h"
21 #include "lldb/Host/Endian.h"
22 #include "lldb/Symbol/ClangASTContext.h"
23 #include "lldb/Target/SectionLoadList.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/Thread.h"
27 #include "lldb/Utility/ProcessStructReader.h"
32 #include <sys/types.h>
35 #include "lldb/Host/Time.h"
38 using namespace lldb_private;
39 using namespace lldb_private::formatters;
42 lldb_private::formatters::GetViableFrame (ExecutionContext exe_ctx)
44 StackFrame* frame = exe_ctx.GetFramePtr();
48 Process* process = exe_ctx.GetProcessPtr();
52 ThreadSP thread_sp(process->GetThreadList().GetSelectedThread());
54 return thread_sp->GetSelectedFrame().get();
59 lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj,
60 const char* target_type,
64 if (!target_type || !*target_type)
66 if (!selector || !*selector)
69 expr.Printf("(%s)[(id)0x%" PRIx64 " %s]",target_type,valobj.GetPointerValue(),selector);
70 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
71 lldb::ValueObjectSP result_sp;
72 Target* target = exe_ctx.GetTargetPtr();
73 StackFrame* stack_frame = GetViableFrame(exe_ctx);
74 if (!target || !stack_frame)
77 EvaluateExpressionOptions options;
78 options.SetCoerceToId(false);
79 options.SetUnwindOnError(true);
80 options.SetKeepInMemory(true);
82 target->EvaluateExpression(expr.GetData(),
88 value = result_sp->GetValueAsUnsigned(0);
93 lldb_private::formatters::ExtractSummaryFromObjCExpression (ValueObject &valobj,
94 const char* target_type,
98 if (!target_type || !*target_type)
100 if (!selector || !*selector)
103 expr.Printf("(%s)[(id)0x%" PRIx64 " %s]",target_type,valobj.GetPointerValue(),selector);
104 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
105 lldb::ValueObjectSP result_sp;
106 Target* target = exe_ctx.GetTargetPtr();
107 StackFrame* stack_frame = GetViableFrame(exe_ctx);
108 if (!target || !stack_frame)
111 EvaluateExpressionOptions options;
112 options.SetCoerceToId(false);
113 options.SetUnwindOnError(true);
114 options.SetKeepInMemory(true);
115 options.SetUseDynamic(lldb::eDynamicCanRunTarget);
117 target->EvaluateExpression(expr.GetData(),
123 stream.Printf("%s",result_sp->GetSummaryAsCString());
128 lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
129 const char* return_type,
130 const char* selector,
133 lldb::ValueObjectSP valobj_sp;
134 if (!return_type || !*return_type)
136 if (!selector || !*selector)
138 StreamString expr_path_stream;
139 valobj.GetExpressionPath(expr_path_stream, false);
141 expr.Printf("(%s)[%s %s:%" PRId64 "]",return_type,expr_path_stream.GetData(),selector,index);
142 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
143 lldb::ValueObjectSP result_sp;
144 Target* target = exe_ctx.GetTargetPtr();
145 StackFrame* stack_frame = GetViableFrame(exe_ctx);
146 if (!target || !stack_frame)
149 EvaluateExpressionOptions options;
150 options.SetCoerceToId(false);
151 options.SetUnwindOnError(true);
152 options.SetKeepInMemory(true);
153 options.SetUseDynamic(lldb::eDynamicCanRunTarget);
155 target->EvaluateExpression(expr.GetData(),
163 lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
164 const char* return_type,
165 const char* selector,
168 lldb::ValueObjectSP valobj_sp;
169 if (!return_type || !*return_type)
171 if (!selector || !*selector)
175 StreamString expr_path_stream;
176 valobj.GetExpressionPath(expr_path_stream, false);
178 expr.Printf("(%s)[%s %s:%s]",return_type,expr_path_stream.GetData(),selector,key);
179 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
180 lldb::ValueObjectSP result_sp;
181 Target* target = exe_ctx.GetTargetPtr();
182 StackFrame* stack_frame = GetViableFrame(exe_ctx);
183 if (!target || !stack_frame)
186 EvaluateExpressionOptions options;
187 options.SetCoerceToId(false);
188 options.SetUnwindOnError(true);
189 options.SetKeepInMemory(true);
190 options.SetUseDynamic(lldb::eDynamicCanRunTarget);
192 target->EvaluateExpression(expr.GetData(),
200 lldb_private::formatters::FunctionPointerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
202 std::string destination;
204 AddressType func_ptr_address_type = eAddressTypeInvalid;
205 addr_t func_ptr_address = valobj.GetPointerValue (&func_ptr_address_type);
206 if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
208 switch (func_ptr_address_type)
210 case eAddressTypeInvalid:
211 case eAddressTypeFile:
212 case eAddressTypeHost:
215 case eAddressTypeLoad:
217 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
220 Target *target = exe_ctx.GetTargetPtr();
221 if (target && target->GetSectionLoadList().IsEmpty() == false)
223 if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
226 exe_ctx.GetBestExecutionContextScope(),
227 Address::DumpStyleResolvedDescription,
228 Address::DumpStyleSectionNameOffset);
235 if (sstr.GetSize() > 0)
237 stream.Printf("(%s)", sstr.GetData());
245 lldb_private::formatters::Char16StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&)
247 ProcessSP process_sp = valobj.GetProcessSP();
251 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
256 ReadStringAndDumpToStreamOptions options(valobj);
257 options.SetLocation(valobj_addr);
258 options.SetProcessSP(process_sp);
259 options.SetStream(&stream);
260 options.SetPrefixToken('u');
262 if (!ReadStringAndDumpToStream<StringElementType::UTF16>(options))
264 stream.Printf("Summary Unavailable");
272 lldb_private::formatters::Char32StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&)
274 ProcessSP process_sp = valobj.GetProcessSP();
278 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
283 ReadStringAndDumpToStreamOptions options(valobj);
284 options.SetLocation(valobj_addr);
285 options.SetProcessSP(process_sp);
286 options.SetStream(&stream);
287 options.SetPrefixToken('U');
289 if (!ReadStringAndDumpToStream<StringElementType::UTF32>(options))
291 stream.Printf("Summary Unavailable");
299 lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&)
301 ProcessSP process_sp = valobj.GetProcessSP();
305 lldb::addr_t data_addr = 0;
307 if (valobj.IsPointerType())
308 data_addr = valobj.GetValueAsUnsigned(0);
309 else if (valobj.IsArrayType())
310 data_addr = valobj.GetAddressOf();
312 if (data_addr == 0 || data_addr == LLDB_INVALID_ADDRESS)
315 clang::ASTContext* ast = valobj.GetClangType().GetASTContext();
320 ClangASTType wchar_clang_type = ClangASTContext::GetBasicType(ast, lldb::eBasicTypeWChar);
321 const uint32_t wchar_size = wchar_clang_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here
323 ReadStringAndDumpToStreamOptions options(valobj);
324 options.SetLocation(data_addr);
325 options.SetProcessSP(process_sp);
326 options.SetStream(&stream);
327 options.SetPrefixToken('L');
332 return ReadStringAndDumpToStream<StringElementType::UTF8>(options);
334 return ReadStringAndDumpToStream<StringElementType::UTF16>(options);
336 return ReadStringAndDumpToStream<StringElementType::UTF32>(options);
338 stream.Printf("size for wchar_t is not valid");
345 lldb_private::formatters::Char16SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&)
349 valobj.GetData(data, error);
355 valobj.GetValueAsCString(lldb::eFormatUnicode16, value);
357 stream.Printf("%s ", value.c_str());
359 ReadBufferAndDumpToStreamOptions options(valobj);
360 options.SetData(data);
361 options.SetStream(&stream);
362 options.SetPrefixToken('u');
363 options.SetQuote('\'');
364 options.SetSourceSize(1);
366 return ReadBufferAndDumpToStream<StringElementType::UTF16>(options);
370 lldb_private::formatters::Char32SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&)
374 valobj.GetData(data, error);
380 valobj.GetValueAsCString(lldb::eFormatUnicode32, value);
382 stream.Printf("%s ", value.c_str());
384 ReadBufferAndDumpToStreamOptions options(valobj);
385 options.SetData(data);
386 options.SetStream(&stream);
387 options.SetPrefixToken('U');
388 options.SetQuote('\'');
389 options.SetSourceSize(1);
391 return ReadBufferAndDumpToStream<StringElementType::UTF32>(options);
395 lldb_private::formatters::WCharSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&)
399 valobj.GetData(data, error);
404 ReadBufferAndDumpToStreamOptions options(valobj);
405 options.SetData(data);
406 options.SetStream(&stream);
407 options.SetPrefixToken('L');
408 options.SetQuote('\'');
409 options.SetSourceSize(1);
411 return ReadBufferAndDumpToStream<StringElementType::UTF16>(options);
414 // the field layout in a libc++ string (cap, side, data or data, size, cap)
415 enum LibcxxStringLayoutMode
417 eLibcxxStringLayoutModeCSD = 0,
418 eLibcxxStringLayoutModeDSC = 1,
419 eLibcxxStringLayoutModeInvalid = 0xffff
422 // this function abstracts away the layout and mode details of a libc++ string
423 // and returns the address of the data and the size ready for callers to consume
425 ExtractLibcxxStringInfo (ValueObject& valobj,
426 ValueObjectSP &location_sp,
429 ValueObjectSP D(valobj.GetChildAtIndexPath({0,0,0,0}));
433 ValueObjectSP layout_decider(D->GetChildAtIndexPath({0,0}));
435 // this child should exist
439 ConstString g_data_name("__data_");
440 ConstString g_size_name("__size_");
441 bool short_mode = false; // this means the string is in short-mode and the data is stored inline
442 LibcxxStringLayoutMode layout = (layout_decider->GetName() == g_data_name) ? eLibcxxStringLayoutModeDSC : eLibcxxStringLayoutModeCSD;
443 uint64_t size_mode_value = 0;
445 if (layout == eLibcxxStringLayoutModeDSC)
447 ValueObjectSP size_mode(D->GetChildAtIndexPath({1,1,0}));
451 if (size_mode->GetName() != g_size_name)
453 // we are hitting the padding structure, move along
454 size_mode = D->GetChildAtIndexPath({1,1,1});
459 size_mode_value = (size_mode->GetValueAsUnsigned(0));
460 short_mode = ((size_mode_value & 0x80) == 0);
464 ValueObjectSP size_mode(D->GetChildAtIndexPath({1,0,0}));
468 size_mode_value = (size_mode->GetValueAsUnsigned(0));
469 short_mode = ((size_mode_value & 1) == 0);
474 ValueObjectSP s(D->GetChildAtIndex(1, true));
477 location_sp = s->GetChildAtIndex((layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true);
478 size = (layout == eLibcxxStringLayoutModeDSC) ? size_mode_value : ((size_mode_value >> 1) % 256);
479 return (location_sp.get() != nullptr);
483 ValueObjectSP l(D->GetChildAtIndex(0, true));
486 // we can use the layout_decider object as the data pointer
487 location_sp = (layout == eLibcxxStringLayoutModeDSC) ? layout_decider : l->GetChildAtIndex(2, true);
488 ValueObjectSP size_vo(l->GetChildAtIndex(1, true));
489 if (!size_vo || !location_sp)
491 size = size_vo->GetValueAsUnsigned(0);
497 lldb_private::formatters::LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
500 ValueObjectSP location_sp((ValueObject*)nullptr);
501 if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
505 stream.Printf("L\"\"");
510 return WCharStringSummaryProvider(*location_sp.get(), stream, options);
514 lldb_private::formatters::LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options)
517 ValueObjectSP location_sp((ValueObject*)nullptr);
519 if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
524 stream.Printf("\"\"");
531 DataExtractor extractor;
532 if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped)
533 size = std::min<decltype(size)>(size, valobj.GetTargetSP()->GetMaximumSizeOfStringSummary());
534 location_sp->GetPointeeData(extractor, 0, size);
536 ReadBufferAndDumpToStreamOptions options(valobj);
537 options.SetData(extractor); // none of this matters for a string - pass some defaults
538 options.SetStream(&stream);
539 options.SetPrefixToken(0);
540 options.SetQuote('"');
541 options.SetSourceSize(size);
542 lldb_private::formatters::ReadBufferAndDumpToStream<lldb_private::formatters::StringElementType::ASCII>(options);
548 lldb_private::formatters::ObjCClassSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
550 ProcessSP process_sp = valobj.GetProcessSP();
554 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
559 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptorFromISA(valobj.GetValueAsUnsigned(0)));
561 if (!descriptor.get() || !descriptor->IsValid())
564 const char* class_name = descriptor->GetClassName().GetCString();
566 if (!class_name || !*class_name)
569 stream.Printf("%s",class_name);
573 class ObjCClassSyntheticChildrenFrontEnd : public SyntheticChildrenFrontEnd
576 ObjCClassSyntheticChildrenFrontEnd (lldb::ValueObjectSP valobj_sp) :
577 SyntheticChildrenFrontEnd(*valobj_sp.get())
582 CalculateNumChildren ()
587 virtual lldb::ValueObjectSP
588 GetChildAtIndex (size_t idx)
590 return lldb::ValueObjectSP();
606 GetIndexOfChildWithName (const ConstString &name)
612 ~ObjCClassSyntheticChildrenFrontEnd ()
617 SyntheticChildrenFrontEnd*
618 lldb_private::formatters::ObjCClassSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
620 return new ObjCClassSyntheticChildrenFrontEnd(valobj_sp);
623 template<bool needs_at>
625 lldb_private::formatters::NSDataSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
627 ProcessSP process_sp = valobj.GetProcessSP();
631 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
636 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
638 if (!descriptor.get() || !descriptor->IsValid())
641 bool is_64bit = (process_sp->GetAddressByteSize() == 8);
642 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
649 const char* class_name = descriptor->GetClassName().GetCString();
651 if (!class_name || !*class_name)
654 if (!strcmp(class_name,"NSConcreteData") ||
655 !strcmp(class_name,"NSConcreteMutableData") ||
656 !strcmp(class_name,"__NSCFData"))
658 uint32_t offset = (is_64bit ? 16 : 8);
660 value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, is_64bit ? 8 : 4, 0, error);
666 if (!ExtractValueFromObjCExpression(valobj, "int", "length", value))
670 stream.Printf("%s%" PRIu64 " byte%s%s",
671 (needs_at ? "@\"" : ""),
673 (value != 1 ? "s" : ""),
674 (needs_at ? "\"" : ""));
680 ReadAsciiBufferAndDumpToStream (lldb::addr_t location,
681 lldb::ProcessSP& process_sp,
685 size_t *data_read = NULL,
686 char prefix_token = '@',
691 if (!process_sp || location == 0)
695 size = process_sp->GetTarget().GetMaximumSizeOfStringSummary();
697 size = std::min(size,process_sp->GetTarget().GetMaximumSizeOfStringSummary());
699 lldb::DataBufferSP buffer_sp(new DataBufferHeap(size,0));
701 my_data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), size, my_error);
706 *data_read = my_data_read;
711 dest.Printf("%c%c",prefix_token,quote);
714 dest.Printf("%s",(char*)buffer_sp->GetBytes());
716 dest.Printf("%c",quote);
722 lldb_private::formatters::NSTaggedString_SummaryProvider (ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream)
726 uint64_t len_bits = 0, data_bits = 0;
727 if (!descriptor->GetTaggedPointerInfo(&len_bits,&data_bits,nullptr))
730 static const int g_MaxNonBitmaskedLen = 7; //TAGGED_STRING_UNPACKED_MAXLEN
731 static const int g_SixbitMaxLen = 9;
732 static const int g_fiveBitMaxLen = 11;
734 static const char *sixBitToCharLookup = "eilotrm.apdnsIc ufkMShjTRxgC4013" "bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX";
736 if (len_bits > g_fiveBitMaxLen)
739 // this is a fairly ugly trick - pretend that the numeric value is actually a char*
740 // this works under a few assumptions:
741 // little endian architecture
742 // sizeof(uint64_t) > g_MaxNonBitmaskedLen
743 if (len_bits <= g_MaxNonBitmaskedLen)
745 stream.Printf("@\"%s\"",(const char*)&data_bits);
749 // if the data is bitmasked, we need to actually process the bytes
751 uint8_t shift_offset = 0;
753 if (len_bits <= g_SixbitMaxLen)
764 std::vector<uint8_t> bytes;
765 bytes.resize(len_bits);
766 for (; len_bits > 0; data_bits >>= shift_offset, --len_bits)
768 uint8_t packed = data_bits & bitmask;
769 bytes.insert(bytes.begin(), sixBitToCharLookup[packed]);
772 stream.Printf("@\"%s\"",&bytes[0]);
777 GetNSPathStore2Type (Target &target)
779 static ConstString g_type_name("__lldb_autogen_nspathstore2");
781 ClangASTContext *ast_ctx = target.GetScratchClangASTContext();
784 return ClangASTType();
786 ClangASTType voidstar = ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType();
787 ClangASTType uint32 = ast_ctx->GetIntTypeFromBitSize(32, false);
789 return ast_ctx->GetOrCreateStructForIdentifier(g_type_name, {
791 {"lengthAndRef",uint32},
797 lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options)
799 ProcessSP process_sp = valobj.GetProcessSP();
803 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
808 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
810 if (!descriptor.get() || !descriptor->IsValid())
813 uint32_t ptr_size = process_sp->GetAddressByteSize();
815 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
820 const char* class_name = descriptor->GetClassName().GetCString();
822 if (!class_name || !*class_name)
825 bool is_tagged_ptr = (0 == strcmp(class_name,"NSTaggedPointerString")) && descriptor->GetTaggedPointerInfo();
826 // for a tagged pointer, the descriptor has everything we need
828 return NSTaggedString_SummaryProvider(descriptor, stream);
830 // if not a tagged pointer that we know about, try the normal route
831 uint64_t info_bits_location = valobj_addr + ptr_size;
832 if (process_sp->GetByteOrder() != lldb::eByteOrderLittle)
833 info_bits_location += 3;
837 uint8_t info_bits = process_sp->ReadUnsignedIntegerFromMemory(info_bits_location, 1, 0, error);
841 bool is_mutable = (info_bits & 1) == 1;
842 bool is_inline = (info_bits & 0x60) == 0;
843 bool has_explicit_length = (info_bits & (1 | 4)) != 4;
844 bool is_unicode = (info_bits & 0x10) == 0x10;
845 bool is_special = strcmp(class_name,"NSPathStore2") == 0;
846 bool has_null = (info_bits & 8) == 8;
848 size_t explicit_length = 0;
849 if (!has_null && has_explicit_length && !is_special)
851 lldb::addr_t explicit_length_offset = 2*ptr_size;
852 if (is_mutable && !is_inline)
853 explicit_length_offset = explicit_length_offset + ptr_size; // notInlineMutable.length;
855 explicit_length = explicit_length + 0; // inline1.length;
856 else if (!is_inline && !is_mutable)
857 explicit_length_offset = explicit_length_offset + ptr_size; // notInlineImmutable1.length;
859 explicit_length_offset = 0;
861 if (explicit_length_offset)
863 explicit_length_offset = valobj_addr + explicit_length_offset;
864 explicit_length = process_sp->ReadUnsignedIntegerFromMemory(explicit_length_offset, 4, 0, error);
868 if (strcmp(class_name,"NSString") &&
869 strcmp(class_name,"CFStringRef") &&
870 strcmp(class_name,"CFMutableStringRef") &&
871 strcmp(class_name,"__NSCFConstantString") &&
872 strcmp(class_name,"__NSCFString") &&
873 strcmp(class_name,"NSCFConstantString") &&
874 strcmp(class_name,"NSCFString") &&
875 strcmp(class_name,"NSPathStore2"))
877 // not one of us - but tell me class name
878 stream.Printf("class name = %s",class_name);
884 uint64_t location = 2 * ptr_size + valobj_addr;
885 location = process_sp->ReadPointerFromMemory(location, error);
888 if (has_explicit_length && is_unicode)
890 ReadStringAndDumpToStreamOptions options(valobj);
891 options.SetLocation(location);
892 options.SetProcessSP(process_sp);
893 options.SetStream(&stream);
894 options.SetPrefixToken('@');
895 options.SetQuote('"');
896 options.SetSourceSize(explicit_length);
897 options.SetNeedsZeroTermination(false);
898 options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
899 return ReadStringAndDumpToStream<StringElementType::UTF16>(options);
903 ReadStringAndDumpToStreamOptions options(valobj);
904 options.SetLocation(location+1);
905 options.SetProcessSP(process_sp);
906 options.SetStream(&stream);
907 options.SetPrefixToken('@');
908 options.SetSourceSize(explicit_length);
909 options.SetNeedsZeroTermination(false);
910 options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
911 return ReadStringAndDumpToStream<StringElementType::ASCII>(options);
914 else if (is_inline && has_explicit_length && !is_unicode && !is_special && !is_mutable)
916 uint64_t location = 3 * ptr_size + valobj_addr;
917 return ReadAsciiBufferAndDumpToStream(location,process_sp,stream,explicit_length);
921 uint64_t location = valobj_addr + 2*ptr_size;
924 if (!has_explicit_length)
926 stream.Printf("found new combo");
930 location += ptr_size;
934 location = process_sp->ReadPointerFromMemory(location, error);
938 ReadStringAndDumpToStreamOptions options(valobj);
939 options.SetLocation(location);
940 options.SetProcessSP(process_sp);
941 options.SetStream(&stream);
942 options.SetPrefixToken('@');
943 options.SetQuote('"');
944 options.SetSourceSize(explicit_length);
945 options.SetNeedsZeroTermination(has_explicit_length == false);
946 options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
947 return ReadStringAndDumpToStream<StringElementType::UTF16> (options);
951 ProcessStructReader reader(valobj.GetProcessSP().get(), valobj.GetValueAsUnsigned(0), GetNSPathStore2Type(*valobj.GetTargetSP()));
952 explicit_length = reader.GetField<uint32_t>(ConstString("lengthAndRef")) >> 20;
953 lldb::addr_t location = valobj.GetValueAsUnsigned(0) + ptr_size + 4;
955 ReadStringAndDumpToStreamOptions options(valobj);
956 options.SetLocation(location);
957 options.SetProcessSP(process_sp);
958 options.SetStream(&stream);
959 options.SetPrefixToken('@');
960 options.SetQuote('"');
961 options.SetSourceSize(explicit_length);
962 options.SetNeedsZeroTermination(has_explicit_length == false);
963 options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
964 return ReadStringAndDumpToStream<StringElementType::UTF16> (options);
968 uint64_t location = valobj_addr + 2*ptr_size;
969 if (!has_explicit_length)
971 ReadStringAndDumpToStreamOptions options(valobj);
972 options.SetLocation(location);
973 options.SetProcessSP(process_sp);
974 options.SetStream(&stream);
975 options.SetPrefixToken('@');
976 options.SetSourceSize(explicit_length);
977 options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
978 return ReadStringAndDumpToStream<StringElementType::ASCII>(options);
982 uint64_t location = valobj_addr + 2*ptr_size;
983 location = process_sp->ReadPointerFromMemory(location, error);
986 if (has_explicit_length && !has_null)
987 explicit_length++; // account for the fact that there is no NULL and we need to have one added
988 ReadStringAndDumpToStreamOptions options(valobj);
989 options.SetLocation(location);
990 options.SetProcessSP(process_sp);
991 options.SetPrefixToken('@');
992 options.SetStream(&stream);
993 options.SetSourceSize(explicit_length);
994 options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
995 return ReadStringAndDumpToStream<StringElementType::ASCII>(options);
1000 lldb_private::formatters::NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
1002 TargetSP target_sp(valobj.GetTargetSP());
1005 uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize();
1006 uint64_t pointer_value = valobj.GetValueAsUnsigned(0);
1009 pointer_value += addr_size;
1010 ClangASTType type(valobj.GetClangType());
1011 ExecutionContext exe_ctx(target_sp,false);
1012 ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress("string_ptr", pointer_value, exe_ctx, type));
1017 child_ptr_sp->GetData(data, error);
1020 ValueObjectSP child_sp(child_ptr_sp->CreateValueObjectFromData("string_data", data, exe_ctx, type));
1021 child_sp->GetValueAsUnsigned(0);
1023 return NSStringSummaryProvider(*child_sp, stream, options);
1028 lldb_private::formatters::NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
1030 return NSAttributedStringSummaryProvider(valobj, stream, options);
1034 lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
1036 stream.Printf("%s",valobj.GetObjectDescription());
1041 lldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
1043 const uint32_t type_info = valobj.GetClangType().GetTypeInfo();
1045 ValueObjectSP real_guy_sp = valobj.GetSP();
1047 if (type_info & eTypeIsPointer)
1050 real_guy_sp = valobj.Dereference(err);
1051 if (err.Fail() || !real_guy_sp)
1054 else if (type_info & eTypeIsReference)
1056 real_guy_sp = valobj.GetChildAtIndex(0, true);
1060 uint64_t value = real_guy_sp->GetValueAsUnsigned(0);
1063 stream.Printf("NO");
1066 stream.Printf("YES");
1070 template <bool is_sel_ptr>
1072 lldb_private::formatters::ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
1074 lldb::ValueObjectSP valobj_sp;
1076 ClangASTType charstar (valobj.GetClangType().GetBasicTypeFromAST(eBasicTypeChar).GetPointerType());
1081 ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
1085 lldb::addr_t data_address = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
1086 if (data_address == LLDB_INVALID_ADDRESS)
1088 valobj_sp = ValueObject::CreateValueObjectFromAddress("text", data_address, exe_ctx, charstar);
1094 valobj.GetData(data, error);
1097 valobj_sp = ValueObject::CreateValueObjectFromData("text", data, exe_ctx, charstar);
1103 stream.Printf("%s",valobj_sp->GetSummaryAsCString());
1107 // POSIX has an epoch on Jan-1-1970, but Cocoa prefers Jan-1-2001
1108 // this call gives the POSIX equivalent of the Cocoa epoch
1110 lldb_private::formatters::GetOSXEpoch ()
1112 static time_t epoch = 0;
1118 tm_epoch.tm_sec = 0;
1119 tm_epoch.tm_hour = 0;
1120 tm_epoch.tm_min = 0;
1121 tm_epoch.tm_mon = 0;
1122 tm_epoch.tm_mday = 1;
1123 tm_epoch.tm_year = 2001-1900; // for some reason, we need to subtract 1900 from this field. not sure why.
1124 tm_epoch.tm_isdst = -1;
1125 tm_epoch.tm_gmtoff = 0;
1126 tm_epoch.tm_zone = NULL;
1127 epoch = timegm(&tm_epoch);
1134 lldb_private::formatters::ExtractIndexFromString (const char* item_name)
1136 if (!item_name || !*item_name)
1138 if (*item_name != '[')
1141 char* endptr = NULL;
1142 unsigned long int idx = ::strtoul(item_name, &endptr, 0);
1143 if (idx == 0 && endptr == item_name)
1145 if (idx == ULONG_MAX)
1150 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::VectorIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp,
1151 ConstString item_name) :
1152 SyntheticChildrenFrontEnd(*valobj_sp.get()),
1154 m_item_name(item_name),
1162 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::Update()
1166 ValueObjectSP valobj_sp = m_backend.GetSP();
1173 ValueObjectSP item_ptr(valobj_sp->GetChildMemberWithName(m_item_name,true));
1176 if (item_ptr->GetValueAsUnsigned(0) == 0)
1179 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
1180 m_item_sp = CreateValueObjectFromAddress("item", item_ptr->GetValueAsUnsigned(0), m_exe_ctx_ref, item_ptr->GetClangType().GetPointeeType());
1187 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::CalculateNumChildren ()
1193 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
1197 return lldb::ValueObjectSP();
1201 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::MightHaveChildren ()
1207 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
1209 if (name == ConstString("item"))
1214 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::~VectorIteratorSyntheticFrontEnd ()
1219 lldb_private::formatters::NSDataSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
1222 lldb_private::formatters::NSDataSummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
1225 lldb_private::formatters::ObjCSELSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
1228 lldb_private::formatters::ObjCSELSummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&) ;