[Lldb-commits] [lldb] r249185 - Add hooks that enable NSSet, NSDictionary and NSString formatting to apply to other types beyond the well-known ones
Enrico Granata via lldb-commits
lldb-commits at lists.llvm.org
Fri Oct 2 13:59:59 PDT 2015
Author: enrico
Date: Fri Oct 2 15:59:58 2015
New Revision: 249185
URL: http://llvm.org/viewvc/llvm-project?rev=249185&view=rev
Log:
Add hooks that enable NSSet, NSDictionary and NSString formatting to apply to other types beyond the well-known ones
This is meant to support languages that can do some sort of bridging from<-->to these ObjC types via types that statically vend themselves as Cocoa types, but dynamically have an implementation that does not match any of our well-known types, but where an introspecting formatter can be vended by the bridged language
Added:
lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.h
lldb/trunk/source/Plugins/Language/ObjC/NSSet.h
lldb/trunk/source/Plugins/Language/ObjC/NSString.cpp
lldb/trunk/source/Plugins/Language/ObjC/NSString.h
Modified:
lldb/trunk/lldb.xcodeproj/project.pbxproj
lldb/trunk/source/Plugins/Language/ObjC/Cocoa.cpp
lldb/trunk/source/Plugins/Language/ObjC/Cocoa.h
lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.cpp
lldb/trunk/source/Plugins/Language/ObjC/NSSet.cpp
lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.cpp
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=249185&r1=249184&r2=249185&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Oct 2 15:59:58 2015
@@ -780,6 +780,7 @@
94B6385D1B8FB178004FE1E4 /* CPlusPlusLanguage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94B6385B1B8FB174004FE1E4 /* CPlusPlusLanguage.cpp */; };
94B638631B8FB7F1004FE1E4 /* ObjCPlusPlusLanguage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94B638621B8FB7F1004FE1E4 /* ObjCPlusPlusLanguage.cpp */; };
94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */; };
+ 94B9E5121BBF20F4000A48DC /* NSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94B9E5111BBF20F4000A48DC /* NSString.cpp */; };
94BA8B6D176F8C9B005A91B5 /* Range.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94BA8B6C176F8C9B005A91B5 /* Range.cpp */; };
94BA8B70176F97CE005A91B5 /* CommandHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94BA8B6F176F97CE005A91B5 /* CommandHistory.cpp */; };
94CB255C16B069770059775D /* DataVisualization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB255816B069770059775D /* DataVisualization.cpp */; };
@@ -2523,6 +2524,10 @@
94B638621B8FB7F1004FE1E4 /* ObjCPlusPlusLanguage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjCPlusPlusLanguage.cpp; path = Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp; sourceTree = "<group>"; };
94B6E76013D8833C005F417F /* ValueObjectSyntheticFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectSyntheticFilter.h; path = include/lldb/Core/ValueObjectSyntheticFilter.h; sourceTree = "<group>"; };
94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectSyntheticFilter.cpp; path = source/Core/ValueObjectSyntheticFilter.cpp; sourceTree = "<group>"; };
+ 94B9E50E1BBEFDFE000A48DC /* NSDictionary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NSDictionary.h; path = Language/ObjC/NSDictionary.h; sourceTree = "<group>"; };
+ 94B9E50F1BBF0069000A48DC /* NSSet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NSSet.h; path = Language/ObjC/NSSet.h; sourceTree = "<group>"; };
+ 94B9E5101BBF20B7000A48DC /* NSString.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NSString.h; path = Language/ObjC/NSString.h; sourceTree = "<group>"; };
+ 94B9E5111BBF20F4000A48DC /* NSString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NSString.cpp; path = Language/ObjC/NSString.cpp; sourceTree = "<group>"; };
94BA8B6C176F8C9B005A91B5 /* Range.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Range.cpp; path = source/Utility/Range.cpp; sourceTree = "<group>"; };
94BA8B6E176F8CA0005A91B5 /* Range.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Range.h; path = include/lldb/Utility/Range.h; sourceTree = "<group>"; };
94BA8B6F176F97CE005A91B5 /* CommandHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandHistory.cpp; path = source/Interpreter/CommandHistory.cpp; sourceTree = "<group>"; };
@@ -5342,9 +5347,13 @@
949EED9F1BA74B64008C63CF /* CoreMedia.h */,
949EED9E1BA74B64008C63CF /* CoreMedia.cpp */,
949EEDA41BA765B5008C63CF /* NSArray.cpp */,
+ 94B9E50E1BBEFDFE000A48DC /* NSDictionary.h */,
949EEDA51BA765B5008C63CF /* NSDictionary.cpp */,
949EEDA61BA765B5008C63CF /* NSIndexPath.cpp */,
+ 94B9E50F1BBF0069000A48DC /* NSSet.h */,
949EEDA71BA765B5008C63CF /* NSSet.cpp */,
+ 94B9E5101BBF20B7000A48DC /* NSString.h */,
+ 94B9E5111BBF20F4000A48DC /* NSString.cpp */,
);
name = Formatters;
sourceTree = "<group>";
@@ -6297,6 +6306,7 @@
6D99A3631BBC2F3200979793 /* ArmUnwindInfo.cpp in Sources */,
4984BA131B978C55008658D4 /* ClangExpressionVariable.cpp in Sources */,
3F81691A1ABA2419001DA9DF /* NameMatches.cpp in Sources */,
+ 94B9E5121BBF20F4000A48DC /* NSString.cpp in Sources */,
AF0E22F018A09FB20009B7D1 /* AppleGetItemInfoHandler.cpp in Sources */,
2689004E13353E0400698AC0 /* Stream.cpp in Sources */,
2689004F13353E0400698AC0 /* StreamFile.cpp in Sources */,
Modified: lldb/trunk/source/Plugins/Language/ObjC/Cocoa.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/Cocoa.cpp?rev=249185&r1=249184&r2=249185&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/Cocoa.cpp (original)
+++ lldb/trunk/source/Plugins/Language/ObjC/Cocoa.cpp Fri Oct 2 15:59:58 2015
@@ -11,6 +11,7 @@
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
+#include "lldb/Core/Mangled.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
@@ -24,6 +25,8 @@
#include "lldb/Target/Process.h"
#include "lldb/Utility/ProcessStructReader.h"
+#include "NSString.h"
+
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
@@ -582,12 +585,15 @@ lldb_private::formatters::ObjCClassSumma
if (!descriptor.get() || !descriptor->IsValid())
return false;
- const char* class_name = descriptor->GetClassName().GetCString();
+ ConstString class_name = descriptor->GetClassName();
- if (!class_name || !*class_name)
+ if (class_name.IsEmpty())
return false;
- stream.Printf("%s",class_name);
+ if (ConstString cs = Mangled(class_name).GetDemangledName(lldb::eLanguageTypeUnknown))
+ class_name = cs;
+
+ stream.Printf("%s",class_name.AsCString("<unknown class>"));
return true;
}
@@ -698,353 +704,6 @@ lldb_private::formatters::NSDataSummaryP
}
bool
-lldb_private::formatters::NSTaggedString_SummaryProvider (ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream)
-{
- if (!descriptor)
- return false;
- uint64_t len_bits = 0, data_bits = 0;
- if (!descriptor->GetTaggedPointerInfo(&len_bits,&data_bits,nullptr))
- return false;
-
- static const int g_MaxNonBitmaskedLen = 7; //TAGGED_STRING_UNPACKED_MAXLEN
- static const int g_SixbitMaxLen = 9;
- static const int g_fiveBitMaxLen = 11;
-
- static const char *sixBitToCharLookup = "eilotrm.apdnsIc ufkMShjTRxgC4013" "bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX";
-
- if (len_bits > g_fiveBitMaxLen)
- return false;
-
- // this is a fairly ugly trick - pretend that the numeric value is actually a char*
- // this works under a few assumptions:
- // little endian architecture
- // sizeof(uint64_t) > g_MaxNonBitmaskedLen
- if (len_bits <= g_MaxNonBitmaskedLen)
- {
- stream.Printf("@\"%s\"",(const char*)&data_bits);
- return true;
- }
-
- // if the data is bitmasked, we need to actually process the bytes
- uint8_t bitmask = 0;
- uint8_t shift_offset = 0;
-
- if (len_bits <= g_SixbitMaxLen)
- {
- bitmask = 0x03f;
- shift_offset = 6;
- }
- else
- {
- bitmask = 0x01f;
- shift_offset = 5;
- }
-
- std::vector<uint8_t> bytes;
- bytes.resize(len_bits);
- for (; len_bits > 0; data_bits >>= shift_offset, --len_bits)
- {
- uint8_t packed = data_bits & bitmask;
- bytes.insert(bytes.begin(), sixBitToCharLookup[packed]);
- }
-
- stream.Printf("@\"%s\"",&bytes[0]);
- return true;
-}
-
-static CompilerType
-GetNSPathStore2Type (Target &target)
-{
- static ConstString g_type_name("__lldb_autogen_nspathstore2");
-
- ClangASTContext *ast_ctx = target.GetScratchClangASTContext();
-
- if (!ast_ctx)
- return CompilerType();
-
- CompilerType voidstar = ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType();
- CompilerType uint32 = ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
-
- return ast_ctx->GetOrCreateStructForIdentifier(g_type_name, {
- {"isa",voidstar},
- {"lengthAndRef",uint32},
- {"buffer",voidstar}
- });
-}
-
-bool
-lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- bool is_tagged_ptr = (0 == strcmp(class_name,"NSTaggedPointerString")) && descriptor->GetTaggedPointerInfo();
- // for a tagged pointer, the descriptor has everything we need
- if (is_tagged_ptr)
- return NSTaggedString_SummaryProvider(descriptor, stream);
-
- // if not a tagged pointer that we know about, try the normal route
- uint64_t info_bits_location = valobj_addr + ptr_size;
- if (process_sp->GetByteOrder() != lldb::eByteOrderLittle)
- info_bits_location += 3;
-
- Error error;
-
- uint8_t info_bits = process_sp->ReadUnsignedIntegerFromMemory(info_bits_location, 1, 0, error);
- if (error.Fail())
- return false;
-
- bool is_mutable = (info_bits & 1) == 1;
- bool is_inline = (info_bits & 0x60) == 0;
- bool has_explicit_length = (info_bits & (1 | 4)) != 4;
- bool is_unicode = (info_bits & 0x10) == 0x10;
- bool is_path_store = strcmp(class_name,"NSPathStore2") == 0;
- bool has_null = (info_bits & 8) == 8;
-
- size_t explicit_length = 0;
- if (!has_null && has_explicit_length && !is_path_store)
- {
- lldb::addr_t explicit_length_offset = 2*ptr_size;
- if (is_mutable && !is_inline)
- explicit_length_offset = explicit_length_offset + ptr_size; // notInlineMutable.length;
- else if (is_inline)
- explicit_length = explicit_length + 0; // inline1.length;
- else if (!is_inline && !is_mutable)
- explicit_length_offset = explicit_length_offset + ptr_size; // notInlineImmutable1.length;
- else
- explicit_length_offset = 0;
-
- if (explicit_length_offset)
- {
- explicit_length_offset = valobj_addr + explicit_length_offset;
- explicit_length = process_sp->ReadUnsignedIntegerFromMemory(explicit_length_offset, 4, 0, error);
- }
- }
-
- if (strcmp(class_name,"NSString") &&
- strcmp(class_name,"CFStringRef") &&
- strcmp(class_name,"CFMutableStringRef") &&
- strcmp(class_name,"__NSCFConstantString") &&
- strcmp(class_name,"__NSCFString") &&
- strcmp(class_name,"NSCFConstantString") &&
- strcmp(class_name,"NSCFString") &&
- strcmp(class_name,"NSPathStore2"))
- {
- // not one of us - but tell me class name
- stream.Printf("class name = %s",class_name);
- return true;
- }
-
- if (is_mutable)
- {
- uint64_t location = 2 * ptr_size + valobj_addr;
- location = process_sp->ReadPointerFromMemory(location, error);
- if (error.Fail())
- return false;
- if (has_explicit_length && is_unicode)
- {
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- options.SetLocation(location);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetPrefixToken('@');
- options.SetQuote('"');
- options.SetSourceSize(explicit_length);
- options.SetNeedsZeroTermination(false);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(false);
- options.SetLanguage(summary_options.GetLanguage());
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
- }
- else
- {
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- options.SetLocation(location+1);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetPrefixToken('@');
- options.SetSourceSize(explicit_length);
- options.SetNeedsZeroTermination(false);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(false);
- options.SetLanguage(summary_options.GetLanguage());
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options);
- }
- }
- else if (is_inline && has_explicit_length && !is_unicode && !is_path_store && !is_mutable)
- {
- uint64_t location = 3 * ptr_size + valobj_addr;
-
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- options.SetLocation(location);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetPrefixToken('@');
- options.SetQuote('"');
- options.SetSourceSize(explicit_length);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetLanguage(summary_options.GetLanguage());
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII> (options);
- }
- else if (is_unicode)
- {
- uint64_t location = valobj_addr + 2*ptr_size;
- if (is_inline)
- {
- if (!has_explicit_length)
- {
- stream.Printf("found new combo");
- return true;
- }
- else
- location += ptr_size;
- }
- else
- {
- location = process_sp->ReadPointerFromMemory(location, error);
- if (error.Fail())
- return false;
- }
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- options.SetLocation(location);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetPrefixToken('@');
- options.SetQuote('"');
- options.SetSourceSize(explicit_length);
- options.SetNeedsZeroTermination(has_explicit_length == false);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(has_explicit_length == false);
- options.SetLanguage(summary_options.GetLanguage());
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16> (options);
- }
- else if (is_path_store)
- {
- ProcessStructReader reader(valobj.GetProcessSP().get(), valobj.GetValueAsUnsigned(0), GetNSPathStore2Type(*valobj.GetTargetSP()));
- explicit_length = reader.GetField<uint32_t>(ConstString("lengthAndRef")) >> 20;
- lldb::addr_t location = valobj.GetValueAsUnsigned(0) + ptr_size + 4;
-
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- options.SetLocation(location);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetPrefixToken('@');
- options.SetQuote('"');
- options.SetSourceSize(explicit_length);
- options.SetNeedsZeroTermination(has_explicit_length == false);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(has_explicit_length == false);
- options.SetLanguage(summary_options.GetLanguage());
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16> (options);
- }
- else if (is_inline)
- {
- uint64_t location = valobj_addr + 2*ptr_size;
- if (!has_explicit_length)
- {
- // in this kind of string, the byte before the string content is a length byte
- // so let's try and use it to handle the embedded NUL case
- Error error;
- explicit_length = process_sp->ReadUnsignedIntegerFromMemory(location, 1, 0, error);
- if (error.Fail() || explicit_length == 0)
- has_explicit_length = false;
- else
- has_explicit_length = true;
- location++;
- }
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- options.SetLocation(location);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetPrefixToken('@');
- options.SetSourceSize(explicit_length);
- options.SetNeedsZeroTermination(!has_explicit_length);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(!has_explicit_length);
- options.SetLanguage(summary_options.GetLanguage());
- if (has_explicit_length)
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options);
- else
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options);
- }
- else
- {
- uint64_t location = valobj_addr + 2*ptr_size;
- location = process_sp->ReadPointerFromMemory(location, error);
- if (error.Fail())
- return false;
- if (has_explicit_length && !has_null)
- explicit_length++; // account for the fact that there is no NULL and we need to have one added
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- options.SetLocation(location);
- options.SetProcessSP(process_sp);
- options.SetPrefixToken('@');
- options.SetStream(&stream);
- options.SetSourceSize(explicit_length);
- options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetLanguage(summary_options.GetLanguage());
- return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options);
- }
-}
-
-bool
-lldb_private::formatters::NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- TargetSP target_sp(valobj.GetTargetSP());
- if (!target_sp)
- return false;
- uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize();
- uint64_t pointer_value = valobj.GetValueAsUnsigned(0);
- if (!pointer_value)
- return false;
- pointer_value += addr_size;
- CompilerType type(valobj.GetCompilerType());
- ExecutionContext exe_ctx(target_sp,false);
- ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress("string_ptr", pointer_value, exe_ctx, type));
- if (!child_ptr_sp)
- return false;
- DataExtractor data;
- Error error;
- child_ptr_sp->GetData(data, error);
- if (error.Fail())
- return false;
- ValueObjectSP child_sp(child_ptr_sp->CreateValueObjectFromData("string_data", data, exe_ctx, type));
- child_sp->GetValueAsUnsigned(0);
- if (child_sp)
- return NSStringSummaryProvider(*child_sp, stream, options);
- return false;
-}
-
-bool
-lldb_private::formatters::NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
-{
- return NSAttributedStringSummaryProvider(valobj, stream, options);
-}
-
-bool
lldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
{
const uint32_t type_info = valobj.GetCompilerType().GetTypeInfo();
Modified: lldb/trunk/source/Plugins/Language/ObjC/Cocoa.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/Cocoa.h?rev=249185&r1=249184&r2=249185&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/Cocoa.h (original)
+++ lldb/trunk/source/Plugins/Language/ObjC/Cocoa.h Fri Oct 2 15:59:58 2015
@@ -18,20 +18,12 @@
namespace lldb_private {
namespace formatters
{
- template<bool name_entries>
- bool
- NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
bool
NSIndexSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
bool
NSArraySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
- template<bool cf_style>
- bool
- NSSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
template<bool needs_at>
bool
NSDataSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
@@ -55,27 +47,9 @@ namespace lldb_private {
NSBundleSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
bool
- NSStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- NSTaggedString_SummaryProvider (ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream);
-
- bool
- NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
- NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
-
- bool
NSURLSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
extern template bool
- NSDictionarySummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
-
- extern template bool
- NSDictionarySummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
-
- extern template bool
NSDataSummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
extern template bool
@@ -83,10 +57,6 @@ namespace lldb_private {
SyntheticChildrenFrontEnd* NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
- SyntheticChildrenFrontEnd* NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- SyntheticChildrenFrontEnd* NSSetSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
SyntheticChildrenFrontEnd* NSIndexPathSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
bool
Modified: lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.cpp?rev=249185&r1=249184&r2=249185&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.cpp (original)
+++ lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.cpp Fri Oct 2 15:59:58 2015
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "Cocoa.h"
+#include "NSDictionary.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
@@ -22,10 +22,26 @@
#include "clang/AST/DeclCXX.h"
+#include <mutex>
+
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
+std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
+NSDictionary_Additionals::GetAdditionalSummaries ()
+{
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
+ return g_map;
+}
+
+std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
+NSDictionary_Additionals::GetAdditionalSynthetics ()
+{
+ static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> g_map;
+ return g_map;
+}
+
static CompilerType
GetLLDBNSPairType (TargetSP target_sp)
{
@@ -221,7 +237,8 @@ lldb_private::formatters::NSDictionarySu
uint64_t value = 0;
- const char* class_name = descriptor->GetClassName().GetCString();
+ ConstString class_name_cs = descriptor->GetClassName();
+ const char* class_name = class_name_cs.GetCString();
if (!class_name || !*class_name)
return false;
@@ -253,6 +270,10 @@ lldb_private::formatters::NSDictionarySu
}*/
else
{
+ auto& map(NSDictionary_Additionals::GetAdditionalSummaries());
+ auto iter = map.find(class_name_cs), end = map.end();
+ if (iter != end)
+ return iter->second(valobj, stream, options);
if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
return false;
}
@@ -265,9 +286,8 @@ lldb_private::formatters::NSDictionarySu
return true;
}
-SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren* synth, lldb::ValueObjectSP valobj_sp)
{
-
lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
if (!process_sp)
return NULL;
@@ -288,7 +308,8 @@ SyntheticChildrenFrontEnd* lldb_private:
if (!descriptor.get() || !descriptor->IsValid())
return NULL;
- const char* class_name = descriptor->GetClassName().GetCString();
+ ConstString class_name_cs = descriptor->GetClassName();
+ const char* class_name = class_name_cs.GetCString();
if (!class_name || !*class_name)
return NULL;
@@ -303,6 +324,10 @@ SyntheticChildrenFrontEnd* lldb_private:
}
else
{
+ auto& map(NSDictionary_Additionals::GetAdditionalSynthetics());
+ auto iter = map.find(class_name_cs), end = map.end();
+ if (iter != end)
+ return iter->second(synth, valobj_sp);
return (new NSDictionaryCodeRunningSyntheticFrontEnd(valobj_sp));
}
}
Added: lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.h?rev=249185&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.h (added)
+++ lldb/trunk/source/Plugins/Language/ObjC/NSDictionary.h Fri Oct 2 15:59:58 2015
@@ -0,0 +1,48 @@
+//===-- NSDictionary.h ---------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_NSDictionary_h_
+#define liblldb_NSDictionary_h_
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/TypeSummary.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
+
+#include <map>
+
+namespace lldb_private {
+ namespace formatters
+ {
+ template<bool name_entries>
+ bool
+ NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
+
+ extern template bool
+ NSDictionarySummaryProvider<true> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
+
+ extern template bool
+ NSDictionarySummaryProvider<false> (ValueObject&, Stream&, const TypeSummaryOptions&) ;
+
+ SyntheticChildrenFrontEnd* NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class NSDictionary_Additionals
+ {
+ public:
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
+ GetAdditionalSummaries ();
+
+ static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
+ GetAdditionalSynthetics ();
+ };
+ } // namespace formatters
+} // namespace lldb_private
+
+#endif // liblldb_NSDictionary_h_
Modified: lldb/trunk/source/Plugins/Language/ObjC/NSSet.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/NSSet.cpp?rev=249185&r1=249184&r2=249185&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/NSSet.cpp (original)
+++ lldb/trunk/source/Plugins/Language/ObjC/NSSet.cpp Fri Oct 2 15:59:58 2015
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "Cocoa.h"
+#include "NSSet.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
@@ -24,6 +24,20 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
+std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
+NSSet_Additionals::GetAdditionalSummaries ()
+{
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
+ return g_map;
+}
+
+std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
+NSSet_Additionals::GetAdditionalSynthetics ()
+{
+ static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback> g_map;
+ return g_map;
+}
+
namespace lldb_private {
namespace formatters {
class NSSetISyntheticFrontEnd : public SyntheticChildrenFrontEnd
@@ -208,7 +222,8 @@ lldb_private::formatters::NSSetSummaryPr
uint64_t value = 0;
- const char* class_name = descriptor->GetClassName().GetCString();
+ ConstString class_name_cs = descriptor->GetClassName();
+ const char* class_name = class_name_cs.GetCString();
if (!class_name || !*class_name)
return false;
@@ -252,6 +267,10 @@ lldb_private::formatters::NSSetSummaryPr
}*/
else
{
+ auto& map(NSSet_Additionals::GetAdditionalSummaries());
+ auto iter = map.find(class_name_cs), end = map.end();
+ if (iter != end)
+ return iter->second(valobj, stream, options);
if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
return false;
}
@@ -264,7 +283,7 @@ lldb_private::formatters::NSSetSummaryPr
return true;
}
-SyntheticChildrenFrontEnd* lldb_private::formatters::NSSetSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+SyntheticChildrenFrontEnd* lldb_private::formatters::NSSetSyntheticFrontEndCreator (CXXSyntheticChildren* synth, lldb::ValueObjectSP valobj_sp)
{
lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
if (!process_sp)
@@ -286,7 +305,8 @@ SyntheticChildrenFrontEnd* lldb_private:
if (!descriptor.get() || !descriptor->IsValid())
return NULL;
- const char* class_name = descriptor->GetClassName().GetCString();
+ ConstString class_name_cs = descriptor->GetClassName();
+ const char* class_name = class_name_cs.GetCString();
if (!class_name || !*class_name)
return NULL;
@@ -305,6 +325,10 @@ SyntheticChildrenFrontEnd* lldb_private:
}
else
{
+ auto& map(NSSet_Additionals::GetAdditionalSynthetics());
+ auto iter = map.find(class_name_cs), end = map.end();
+ if (iter != end)
+ return iter->second(synth, valobj_sp);
return /*(new NSSetCodeRunningSyntheticFrontEnd(valobj_sp))*/ NULL;
}
}
Added: lldb/trunk/source/Plugins/Language/ObjC/NSSet.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/NSSet.h?rev=249185&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/NSSet.h (added)
+++ lldb/trunk/source/Plugins/Language/ObjC/NSSet.h Fri Oct 2 15:59:58 2015
@@ -0,0 +1,40 @@
+//===-- NSSet.h ---------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_NSSet_h_
+#define liblldb_NSSet_h_
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/TypeSummary.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
+
+namespace lldb_private {
+ namespace formatters
+ {
+ template<bool cf_style>
+ bool
+ NSSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
+
+ SyntheticChildrenFrontEnd* NSSetSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class NSSet_Additionals
+ {
+ public:
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
+ GetAdditionalSummaries ();
+
+ static std::map<ConstString, CXXSyntheticChildren::CreateFrontEndCallback>&
+ GetAdditionalSynthetics ();
+ };
+ } // namespace formatters
+} // namespace lldb_private
+
+#endif // liblldb_NSSet_h_
Added: lldb/trunk/source/Plugins/Language/ObjC/NSString.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/NSString.cpp?rev=249185&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/NSString.cpp (added)
+++ lldb/trunk/source/Plugins/Language/ObjC/NSString.cpp Fri Oct 2 15:59:58 2015
@@ -0,0 +1,386 @@
+//===-- NSString.cpp ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NSString.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/DataFormatters/StringPrinter.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/ProcessStructReader.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
+NSString_Additionals::GetAdditionalSummaries ()
+{
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback> g_map;
+ return g_map;
+}
+
+static CompilerType
+GetNSPathStore2Type (Target &target)
+{
+ static ConstString g_type_name("__lldb_autogen_nspathstore2");
+
+ ClangASTContext *ast_ctx = target.GetScratchClangASTContext();
+
+ if (!ast_ctx)
+ return CompilerType();
+
+ CompilerType voidstar = ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType();
+ CompilerType uint32 = ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+
+ return ast_ctx->GetOrCreateStructForIdentifier(g_type_name, {
+ {"isa",voidstar},
+ {"lengthAndRef",uint32},
+ {"buffer",voidstar}
+ });
+}
+
+bool
+lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ ConstString class_name_cs = descriptor->GetClassName();
+ const char* class_name = class_name_cs.GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ bool is_tagged_ptr = (0 == strcmp(class_name,"NSTaggedPointerString")) && descriptor->GetTaggedPointerInfo();
+ // for a tagged pointer, the descriptor has everything we need
+ if (is_tagged_ptr)
+ return NSTaggedString_SummaryProvider(descriptor, stream);
+
+ auto& additionals_map(NSString_Additionals::GetAdditionalSummaries());
+ auto iter = additionals_map.find(class_name_cs), end = additionals_map.end();
+ if (iter != end)
+ return iter->second(valobj, stream, summary_options);
+
+ // if not a tagged pointer that we know about, try the normal route
+ uint64_t info_bits_location = valobj_addr + ptr_size;
+ if (process_sp->GetByteOrder() != lldb::eByteOrderLittle)
+ info_bits_location += 3;
+
+ Error error;
+
+ uint8_t info_bits = process_sp->ReadUnsignedIntegerFromMemory(info_bits_location, 1, 0, error);
+ if (error.Fail())
+ return false;
+
+ bool is_mutable = (info_bits & 1) == 1;
+ bool is_inline = (info_bits & 0x60) == 0;
+ bool has_explicit_length = (info_bits & (1 | 4)) != 4;
+ bool is_unicode = (info_bits & 0x10) == 0x10;
+ bool is_path_store = strcmp(class_name,"NSPathStore2") == 0;
+ bool has_null = (info_bits & 8) == 8;
+
+ size_t explicit_length = 0;
+ if (!has_null && has_explicit_length && !is_path_store)
+ {
+ lldb::addr_t explicit_length_offset = 2*ptr_size;
+ if (is_mutable && !is_inline)
+ explicit_length_offset = explicit_length_offset + ptr_size; // notInlineMutable.length;
+ else if (is_inline)
+ explicit_length = explicit_length + 0; // inline1.length;
+ else if (!is_inline && !is_mutable)
+ explicit_length_offset = explicit_length_offset + ptr_size; // notInlineImmutable1.length;
+ else
+ explicit_length_offset = 0;
+
+ if (explicit_length_offset)
+ {
+ explicit_length_offset = valobj_addr + explicit_length_offset;
+ explicit_length = process_sp->ReadUnsignedIntegerFromMemory(explicit_length_offset, 4, 0, error);
+ }
+ }
+
+ if (strcmp(class_name,"NSString") &&
+ strcmp(class_name,"CFStringRef") &&
+ strcmp(class_name,"CFMutableStringRef") &&
+ strcmp(class_name,"__NSCFConstantString") &&
+ strcmp(class_name,"__NSCFString") &&
+ strcmp(class_name,"NSCFConstantString") &&
+ strcmp(class_name,"NSCFString") &&
+ strcmp(class_name,"NSPathStore2"))
+ {
+ // not one of us - but tell me class name
+ stream.Printf("class name = %s",class_name);
+ return true;
+ }
+
+ if (is_mutable)
+ {
+ uint64_t location = 2 * ptr_size + valobj_addr;
+ location = process_sp->ReadPointerFromMemory(location, error);
+ if (error.Fail())
+ return false;
+ if (has_explicit_length && is_unicode)
+ {
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('@');
+ options.SetQuote('"');
+ options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(false);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetBinaryZeroIsTerminator(false);
+ options.SetLanguage(summary_options.GetLanguage());
+ return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
+ }
+ else
+ {
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(location+1);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('@');
+ options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(false);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetBinaryZeroIsTerminator(false);
+ options.SetLanguage(summary_options.GetLanguage());
+ return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options);
+ }
+ }
+ else if (is_inline && has_explicit_length && !is_unicode && !is_path_store && !is_mutable)
+ {
+ uint64_t location = 3 * ptr_size + valobj_addr;
+
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('@');
+ options.SetQuote('"');
+ options.SetSourceSize(explicit_length);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetLanguage(summary_options.GetLanguage());
+ return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII> (options);
+ }
+ else if (is_unicode)
+ {
+ uint64_t location = valobj_addr + 2*ptr_size;
+ if (is_inline)
+ {
+ if (!has_explicit_length)
+ {
+ stream.Printf("found new combo");
+ return true;
+ }
+ else
+ location += ptr_size;
+ }
+ else
+ {
+ location = process_sp->ReadPointerFromMemory(location, error);
+ if (error.Fail())
+ return false;
+ }
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('@');
+ options.SetQuote('"');
+ options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(has_explicit_length == false);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetBinaryZeroIsTerminator(has_explicit_length == false);
+ options.SetLanguage(summary_options.GetLanguage());
+ return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16> (options);
+ }
+ else if (is_path_store)
+ {
+ ProcessStructReader reader(valobj.GetProcessSP().get(), valobj.GetValueAsUnsigned(0), GetNSPathStore2Type(*valobj.GetTargetSP()));
+ explicit_length = reader.GetField<uint32_t>(ConstString("lengthAndRef")) >> 20;
+ lldb::addr_t location = valobj.GetValueAsUnsigned(0) + ptr_size + 4;
+
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('@');
+ options.SetQuote('"');
+ options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(has_explicit_length == false);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetBinaryZeroIsTerminator(has_explicit_length == false);
+ options.SetLanguage(summary_options.GetLanguage());
+ return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16> (options);
+ }
+ else if (is_inline)
+ {
+ uint64_t location = valobj_addr + 2*ptr_size;
+ if (!has_explicit_length)
+ {
+ // in this kind of string, the byte before the string content is a length byte
+ // so let's try and use it to handle the embedded NUL case
+ Error error;
+ explicit_length = process_sp->ReadUnsignedIntegerFromMemory(location, 1, 0, error);
+ if (error.Fail() || explicit_length == 0)
+ has_explicit_length = false;
+ else
+ has_explicit_length = true;
+ location++;
+ }
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken('@');
+ options.SetSourceSize(explicit_length);
+ options.SetNeedsZeroTermination(!has_explicit_length);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetBinaryZeroIsTerminator(!has_explicit_length);
+ options.SetLanguage(summary_options.GetLanguage());
+ if (has_explicit_length)
+ return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options);
+ else
+ return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options);
+ }
+ else
+ {
+ uint64_t location = valobj_addr + 2*ptr_size;
+ location = process_sp->ReadPointerFromMemory(location, error);
+ if (error.Fail())
+ return false;
+ if (has_explicit_length && !has_null)
+ explicit_length++; // account for the fact that there is no NULL and we need to have one added
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(location);
+ options.SetProcessSP(process_sp);
+ options.SetPrefixToken('@');
+ options.SetStream(&stream);
+ options.SetSourceSize(explicit_length);
+ options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped);
+ options.SetLanguage(summary_options.GetLanguage());
+ return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options);
+ }
+}
+
+bool
+lldb_private::formatters::NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
+{
+ TargetSP target_sp(valobj.GetTargetSP());
+ if (!target_sp)
+ return false;
+ uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize();
+ uint64_t pointer_value = valobj.GetValueAsUnsigned(0);
+ if (!pointer_value)
+ return false;
+ pointer_value += addr_size;
+ CompilerType type(valobj.GetCompilerType());
+ ExecutionContext exe_ctx(target_sp,false);
+ ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress("string_ptr", pointer_value, exe_ctx, type));
+ if (!child_ptr_sp)
+ return false;
+ DataExtractor data;
+ Error error;
+ child_ptr_sp->GetData(data, error);
+ if (error.Fail())
+ return false;
+ ValueObjectSP child_sp(child_ptr_sp->CreateValueObjectFromData("string_data", data, exe_ctx, type));
+ child_sp->GetValueAsUnsigned(0);
+ if (child_sp)
+ return NSStringSummaryProvider(*child_sp, stream, options);
+ return false;
+}
+
+bool
+lldb_private::formatters::NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
+{
+ return NSAttributedStringSummaryProvider(valobj, stream, options);
+}
+
+bool
+lldb_private::formatters::NSTaggedString_SummaryProvider (ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream)
+{
+ if (!descriptor)
+ return false;
+ uint64_t len_bits = 0, data_bits = 0;
+ if (!descriptor->GetTaggedPointerInfo(&len_bits,&data_bits,nullptr))
+ return false;
+
+ static const int g_MaxNonBitmaskedLen = 7; //TAGGED_STRING_UNPACKED_MAXLEN
+ static const int g_SixbitMaxLen = 9;
+ static const int g_fiveBitMaxLen = 11;
+
+ static const char *sixBitToCharLookup = "eilotrm.apdnsIc ufkMShjTRxgC4013" "bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX";
+
+ if (len_bits > g_fiveBitMaxLen)
+ return false;
+
+ // this is a fairly ugly trick - pretend that the numeric value is actually a char*
+ // this works under a few assumptions:
+ // little endian architecture
+ // sizeof(uint64_t) > g_MaxNonBitmaskedLen
+ if (len_bits <= g_MaxNonBitmaskedLen)
+ {
+ stream.Printf("@\"%s\"",(const char*)&data_bits);
+ return true;
+ }
+
+ // if the data is bitmasked, we need to actually process the bytes
+ uint8_t bitmask = 0;
+ uint8_t shift_offset = 0;
+
+ if (len_bits <= g_SixbitMaxLen)
+ {
+ bitmask = 0x03f;
+ shift_offset = 6;
+ }
+ else
+ {
+ bitmask = 0x01f;
+ shift_offset = 5;
+ }
+
+ std::vector<uint8_t> bytes;
+ bytes.resize(len_bits);
+ for (; len_bits > 0; data_bits >>= shift_offset, --len_bits)
+ {
+ uint8_t packed = data_bits & bitmask;
+ bytes.insert(bytes.begin(), sixBitToCharLookup[packed]);
+ }
+
+ stream.Printf("@\"%s\"",&bytes[0]);
+ return true;
+}
Added: lldb/trunk/source/Plugins/Language/ObjC/NSString.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/NSString.h?rev=249185&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/NSString.h (added)
+++ lldb/trunk/source/Plugins/Language/ObjC/NSString.h Fri Oct 2 15:59:58 2015
@@ -0,0 +1,42 @@
+//===-- NSString.h ---------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_NSString_h_
+#define liblldb_NSString_h_
+
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/TypeSummary.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+
+namespace lldb_private {
+ namespace formatters
+ {
+ bool
+ NSStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
+
+ bool
+ NSTaggedString_SummaryProvider (ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream);
+
+ bool
+ NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
+
+ bool
+ NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
+
+ class NSString_Additionals
+ {
+ public:
+ static std::map<ConstString, CXXFunctionSummaryFormat::Callback>&
+ GetAdditionalSummaries ();
+ };
+ } // namespace formatters
+} // namespace lldb_private
+
+#endif // liblldb_CF_h_
Modified: lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.cpp?rev=249185&r1=249184&r2=249185&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.cpp (original)
+++ lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.cpp Fri Oct 2 15:59:58 2015
@@ -23,6 +23,9 @@
#include "CF.h"
#include "Cocoa.h"
#include "CoreMedia.h"
+#include "NSDictionary.h"
+#include "NSSet.h"
+#include "NSString.h"
using namespace lldb;
using namespace lldb_private;
More information about the lldb-commits
mailing list