diff options
| author | Enrico Granata <egranata@apple.com> | 2015-10-07 18:36:53 +0000 |
|---|---|---|
| committer | Enrico Granata <egranata@apple.com> | 2015-10-07 18:36:53 +0000 |
| commit | 675f49bbd58ef78c947ac0ba32835051ff33f4e5 (patch) | |
| tree | 00baf04dc2cd932e2cf4e227fa51f78f4c444f23 /lldb/source/Plugins | |
| parent | 75230398c233828a07806c4ffd627df3b239b73d (diff) | |
| download | bcm5719-llvm-675f49bbd58ef78c947ac0ba32835051ff33f4e5.tar.gz bcm5719-llvm-675f49bbd58ef78c947ac0ba32835051ff33f4e5.zip | |
This is the work I was building up to with my patches yesterday
Introduce the notion of Language-based formatter prefix/suffix
This is meant for languages that share certain data types but present them in syntatically different ways, such that LLDB can now have language-based awareness of which of the syntax variations it has to present to the user when formatting those values
This is goodness for new languages and interoperability, but is NFC for existing languages. As such, existing tests cover this
llvm-svn: 249587
Diffstat (limited to 'lldb/source/Plugins')
| -rw-r--r-- | lldb/source/Plugins/Language/ObjC/CF.cpp | 47 | ||||
| -rw-r--r-- | lldb/source/Plugins/Language/ObjC/Cocoa.cpp | 162 | ||||
| -rw-r--r-- | lldb/source/Plugins/Language/ObjC/NSArray.cpp | 37 | ||||
| -rw-r--r-- | lldb/source/Plugins/Language/ObjC/NSDictionary.cpp | 50 | ||||
| -rw-r--r-- | lldb/source/Plugins/Language/ObjC/NSSet.cpp | 86 | ||||
| -rw-r--r-- | lldb/source/Plugins/Language/ObjC/NSString.cpp | 55 | ||||
| -rw-r--r-- | lldb/source/Plugins/Language/ObjC/NSString.h | 2 | ||||
| -rw-r--r-- | lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp | 81 | ||||
| -rw-r--r-- | lldb/source/Plugins/Language/ObjC/ObjCLanguage.h | 4 |
9 files changed, 429 insertions, 95 deletions
diff --git a/lldb/source/Plugins/Language/ObjC/CF.cpp b/lldb/source/Plugins/Language/ObjC/CF.cpp index fb1b87154a8..0dc0c662fe9 100644 --- a/lldb/source/Plugins/Language/ObjC/CF.cpp +++ b/lldb/source/Plugins/Language/ObjC/CF.cpp @@ -17,6 +17,7 @@ #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/Host/Endian.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Target/Language.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Target.h" @@ -42,6 +43,8 @@ lldb_private::formatters::CFAbsoluteTimeSummaryProvider (ValueObject& valobj, St bool lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { + static ConstString g_TypeHint("CFBag"); + ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; @@ -84,7 +87,9 @@ lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& str ValueObjectSP count_sp; StreamString expr; expr.Printf("(int)CFBagGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue()); - if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp) != eExpressionCompleted) + EvaluateExpressionOptions options; + options.SetResultIsInternal(true); + if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp, options) != eExpressionCompleted) return false; if (!count_sp) return false; @@ -98,8 +103,21 @@ lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& str if (error.Fail()) return false; } - stream.Printf("@\"%u value%s\"", - count,(count == 1 ? "" : "s")); + + std::string prefix,suffix; + if (Language* language = Language::FindPlugin(options.GetLanguage())) + { + if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) + { + prefix.clear(); + suffix.clear(); + } + } + + stream.Printf("%s\"%u value%s\"%s", + prefix.c_str(), + count,(count == 1 ? "" : "s"), + suffix.c_str()); return true; } @@ -236,6 +254,8 @@ lldb_private::formatters::CFBitVectorSummaryProvider (ValueObject& valobj, Strea bool lldb_private::formatters::CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { + static ConstString g_TypeHint("CFBinaryHeap"); + ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; @@ -278,7 +298,9 @@ lldb_private::formatters::CFBinaryHeapSummaryProvider (ValueObject& valobj, Stre ValueObjectSP count_sp; StreamString expr; expr.Printf("(int)CFBinaryHeapGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue()); - if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp) != eExpressionCompleted) + EvaluateExpressionOptions options; + options.SetResultIsInternal(true); + if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp, options) != eExpressionCompleted) return false; if (!count_sp) return false; @@ -292,7 +314,20 @@ lldb_private::formatters::CFBinaryHeapSummaryProvider (ValueObject& valobj, Stre if (error.Fail()) return false; } - stream.Printf("@\"%u item%s\"", - count,(count == 1 ? "" : "s")); + + std::string prefix,suffix; + if (Language* language = Language::FindPlugin(options.GetLanguage())) + { + if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) + { + prefix.clear(); + suffix.clear(); + } + } + + stream.Printf("%s\"%u item%s\"%s", + prefix.c_str(), + count,(count == 1 ? "" : "s"), + suffix.c_str()); return true; } diff --git a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp index 84699a20b60..3645ad8bcf3 100644 --- a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp +++ b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp @@ -20,6 +20,7 @@ #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/Host/Endian.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Target/Language.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Target/Process.h" @@ -64,7 +65,7 @@ lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream& { uint64_t offset = 5 * ptr_size; ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID), true)); - + StreamString summary_stream; bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream, options); if (was_nsstring_ok && summary_stream.GetSize() > 0) @@ -295,6 +296,145 @@ lldb_private::formatters::NSIndexSetSummaryProvider (ValueObject& valobj, Stream return true; } +static void +NSNumber_FormatChar (ValueObject& valobj, + Stream& stream, + char value, + lldb::LanguageType lang) +{ + static ConstString g_TypeHint("NSNumber:char"); + + std::string prefix,suffix; + if (Language* language = Language::FindPlugin(lang)) + { + if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) + { + prefix.clear(); + suffix.clear(); + } + } + + stream.Printf("%s%hhd%s", + prefix.c_str(), + value, + suffix.c_str()); +} +static void +NSNumber_FormatShort (ValueObject& valobj, + Stream& stream, + short value, + lldb::LanguageType lang) +{ + static ConstString g_TypeHint("NSNumber:short"); + + std::string prefix,suffix; + if (Language* language = Language::FindPlugin(lang)) + { + if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) + { + prefix.clear(); + suffix.clear(); + } + } + + stream.Printf("%s%hd%s", + prefix.c_str(), + value, + suffix.c_str()); +} +static void +NSNumber_FormatInt (ValueObject& valobj, + Stream& stream, + int value, + lldb::LanguageType lang) +{ + static ConstString g_TypeHint("NSNumber:int"); + + std::string prefix,suffix; + if (Language* language = Language::FindPlugin(lang)) + { + if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) + { + prefix.clear(); + suffix.clear(); + } + } + + stream.Printf("%s%d%s", + prefix.c_str(), + value, + suffix.c_str()); +} +static void +NSNumber_FormatLong (ValueObject& valobj, + Stream& stream, + uint64_t value, + lldb::LanguageType lang) +{ + static ConstString g_TypeHint("NSNumber:long"); + + std::string prefix,suffix; + if (Language* language = Language::FindPlugin(lang)) + { + if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) + { + prefix.clear(); + suffix.clear(); + } + } + + stream.Printf("%s%" PRId64 "%s", + prefix.c_str(), + value, + suffix.c_str()); +} +static void +NSNumber_FormatFloat (ValueObject& valobj, + Stream& stream, + float value, + lldb::LanguageType lang) +{ + static ConstString g_TypeHint("NSNumber:float"); + + std::string prefix,suffix; + if (Language* language = Language::FindPlugin(lang)) + { + if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) + { + prefix.clear(); + suffix.clear(); + } + } + + stream.Printf("%s%f%s", + prefix.c_str(), + value, + suffix.c_str()); +} +static void +NSNumber_FormatDouble (ValueObject& valobj, + Stream& stream, + double value, + lldb::LanguageType lang) +{ + static ConstString g_TypeHint("NSNumber:double"); + + std::string prefix,suffix; + if (Language* language = Language::FindPlugin(lang)) + { + if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) + { + prefix.clear(); + suffix.clear(); + } + } + + stream.Printf("%s%g%s", + prefix.c_str(), + value, + suffix.c_str()); +} + bool lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { @@ -333,19 +473,19 @@ lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& switch (i_bits) { case 0: - stream.Printf("(char)%hhd",(char)value); + NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage()); break; case 1: case 4: - stream.Printf("(short)%hd",(short)value); + NSNumber_FormatShort(valobj, stream, (short)value, options.GetLanguage()); break; case 2: case 8: - stream.Printf("(int)%d",(int)value); + NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage()); break; case 3: case 12: - stream.Printf("(long)%" PRId64,value); + NSNumber_FormatLong(valobj, stream, value, options.GetLanguage()); break; default: return false; @@ -366,19 +506,19 @@ lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0, error); if (error.Fail()) return false; - stream.Printf("(char)%hhd",(char)value); + NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage()); break; case 2: // 0B0010 value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0, error); if (error.Fail()) return false; - stream.Printf("(short)%hd",(short)value); + NSNumber_FormatShort(valobj, stream, (short)value, options.GetLanguage()); break; case 3: // 0B0011 value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error); if (error.Fail()) return false; - stream.Printf("(int)%d",(int)value); + NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage()); break; case 17: // 0B10001 data_location += 8; @@ -386,7 +526,7 @@ lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error); if (error.Fail()) return false; - stream.Printf("(long)%" PRId64,value); + NSNumber_FormatLong(valobj, stream, value, options.GetLanguage()); break; case 5: // 0B0101 { @@ -394,7 +534,7 @@ lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& if (error.Fail()) return false; float flt_value = *((float*)&flt_as_int); - stream.Printf("(float)%f",flt_value); + NSNumber_FormatFloat(valobj, stream, flt_value, options.GetLanguage()); break; } case 6: // 0B0110 @@ -403,7 +543,7 @@ lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& if (error.Fail()) return false; double dbl_value = *((double*)&dbl_as_lng); - stream.Printf("(double)%g",dbl_value); + NSNumber_FormatDouble(valobj, stream, dbl_value, options.GetLanguage()); break; } default: diff --git a/lldb/source/Plugins/Language/ObjC/NSArray.cpp b/lldb/source/Plugins/Language/ObjC/NSArray.cpp index a85169996cc..2a6c886ce20 100644 --- a/lldb/source/Plugins/Language/ObjC/NSArray.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSArray.cpp @@ -18,6 +18,7 @@ #include "lldb/Expression/FunctionCaller.h" #include "lldb/Host/Endian.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Target/Language.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" #include "lldb/Target/Target.h" @@ -230,6 +231,8 @@ namespace lldb_private { bool lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { + static ConstString g_TypeHint("NSArray"); + ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; @@ -285,16 +288,29 @@ lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& s return false; } - stream.Printf("@\"%" PRIu64 " object%s\"", + std::string prefix,suffix; + if (Language* language = Language::FindPlugin(options.GetLanguage())) + { + if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) + { + prefix.clear(); + suffix.clear(); + } + } + + stream.Printf("%s%" PRIu64 " %s%s%s", + prefix.c_str(), value, - value == 1 ? "" : "s"); + "element", + value == 1 ? "" : "s", + suffix.c_str()); return true; } lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp), - m_exe_ctx_ref(), - m_ptr_size(8), +m_exe_ctx_ref(), +m_ptr_size(8), m_id_type(), m_children() { @@ -524,11 +540,11 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd_1010::~NSArrayMSyntheticFron } lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : - SyntheticChildrenFrontEnd (*valobj_sp.get()), - m_exe_ctx_ref (), - m_ptr_size (8), - m_items (0), - m_data_ptr (0) +SyntheticChildrenFrontEnd (*valobj_sp.get()), +m_exe_ctx_ref (), +m_ptr_size (8), +m_items (0), +m_data_ptr (0) { if (valobj_sp) { @@ -686,7 +702,10 @@ lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetChildAtIndex ( idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); lldb::ValueObjectSP valobj_sp = CallSelectorOnObject(m_backend,"id","objectAtIndex:",idx); if (valobj_sp) + { + valobj_sp->SetPreferredDisplayLanguage(m_backend.GetPreferredDisplayLanguage()); valobj_sp->SetName(ConstString(idx_name.GetData())); + } return valobj_sp; } diff --git a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp index bb5a0acdc54..8f56d96ace8 100644 --- a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp @@ -17,6 +17,7 @@ #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/Host/Endian.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Target/Language.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Target.h" @@ -46,13 +47,13 @@ static CompilerType GetLLDBNSPairType (TargetSP target_sp) { CompilerType compiler_type; - + ClangASTContext *target_ast_context = target_sp->GetScratchClangASTContext(); - + if (target_ast_context) { ConstString g___lldb_autogen_nspair("__lldb_autogen_nspair"); - + compiler_type = target_ast_context->GetTypeForIdentifier<clang::CXXRecordDecl>(g___lldb_autogen_nspair); if (!compiler_type) @@ -213,6 +214,7 @@ template<bool name_entries> bool lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { + static ConstString g_TypeHint("NSDictionary"); ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; @@ -260,14 +262,14 @@ lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stre value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); } /*else if (!strcmp(class_name,"__NSCFDictionary")) - { - Error error; - value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error); - if (error.Fail()) - return false; - if (is_64bit) - value &= ~0x0f1f000000000000UL; - }*/ + { + Error error; + value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error); + if (error.Fail()) + return false; + if (is_64bit) + value &= ~0x0f1f000000000000UL; + }*/ else { auto& map(NSDictionary_Additionals::GetAdditionalSummaries()); @@ -278,11 +280,22 @@ lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stre return false; } - stream.Printf("%s%" PRIu64 " %s%s", - (name_entries ? "@\"" : ""), + std::string prefix,suffix; + if (Language* language = Language::FindPlugin(options.GetLanguage())) + { + if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) + { + prefix.clear(); + suffix.clear(); + } + } + + stream.Printf("%s%" PRIu64 " %s%s%s", + prefix.c_str(), value, - (name_entries ? (value == 1 ? "entry" : "entries") : (value == 1 ? "key/value pair" : "key/value pairs")), - (name_entries ? "\"" : "")); + "key/value pair", + value == 1 ? "" : "s", + suffix.c_str()); return true; } @@ -295,7 +308,10 @@ SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontE if (!runtime) return NULL; - if (!valobj_sp->IsPointerType()) + CompilerType valobj_type(valobj_sp->GetCompilerType()); + Flags flags(valobj_type.GetTypeInfo()); + + if (flags.IsClear(eTypeIsPointer)) { Error error; valobj_sp = valobj_sp->AddressOf(error); @@ -359,6 +375,8 @@ lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetChildAtIn lldb::ValueObjectSP child_sp; EvaluateExpressionOptions options; options.SetKeepInMemory(true); + options.SetLanguage(lldb::eLanguageTypeObjC_plus_plus); + options.SetResultIsInternal(true); m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(), GetViableFrame(m_backend.GetTargetSP().get()), child_sp, diff --git a/lldb/source/Plugins/Language/ObjC/NSSet.cpp b/lldb/source/Plugins/Language/ObjC/NSSet.cpp index 1c3758b33f8..602db12faea 100644 --- a/lldb/source/Plugins/Language/ObjC/NSSet.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSSet.cpp @@ -17,6 +17,7 @@ #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/Host/Endian.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Target/Language.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Target.h" @@ -198,6 +199,8 @@ template<bool cf_style> bool lldb_private::formatters::NSSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { + static ConstString g_TypeHint("NSSet"); + ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; @@ -245,26 +248,26 @@ lldb_private::formatters::NSSetSummaryProvider (ValueObject& valobj, Stream& str value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); } /*else if (!strcmp(class_name,"__NSCFSet")) - { - Error error; - value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error); - if (error.Fail()) - return false; - if (is_64bit) - value &= ~0x1fff000000000000UL; - } - else if (!strcmp(class_name,"NSCountedSet")) - { - Error error; - value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error); - if (error.Fail()) - return false; - value = process_sp->ReadUnsignedIntegerFromMemory(value + (is_64bit ? 20 : 12), 4, 0, error); - if (error.Fail()) - return false; - if (is_64bit) - value &= ~0x1fff000000000000UL; - }*/ + { + Error error; + value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error); + if (error.Fail()) + return false; + if (is_64bit) + value &= ~0x1fff000000000000UL; + } + else if (!strcmp(class_name,"NSCountedSet")) + { + Error error; + value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error); + if (error.Fail()) + return false; + value = process_sp->ReadUnsignedIntegerFromMemory(value + (is_64bit ? 20 : 12), 4, 0, error); + if (error.Fail()) + return false; + if (is_64bit) + value &= ~0x1fff000000000000UL; + }*/ else { auto& map(NSSet_Additionals::GetAdditionalSummaries()); @@ -275,11 +278,22 @@ lldb_private::formatters::NSSetSummaryProvider (ValueObject& valobj, Stream& str return false; } - stream.Printf("%s%" PRIu64 " %s%s", - (cf_style ? "@\"" : ""), + std::string prefix,suffix; + if (Language* language = Language::FindPlugin(options.GetLanguage())) + { + if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) + { + prefix.clear(); + suffix.clear(); + } + } + + stream.Printf("%s%" PRIu64 " %s%s%s", + prefix.c_str(), value, - (cf_style ? (value == 1 ? "value" : "values") : (value == 1 ? "object" : "objects")), - (cf_style ? "\"" : "")); + "element", + value == 1 ? "" : "s", + suffix.c_str()); return true; } @@ -292,7 +306,10 @@ SyntheticChildrenFrontEnd* lldb_private::formatters::NSSetSyntheticFrontEndCreat if (!runtime) return NULL; - if (!valobj_sp->IsPointerType()) + CompilerType valobj_type(valobj_sp->GetCompilerType()); + Flags flags(valobj_type.GetTypeInfo()); + + if (flags.IsClear(eTypeIsPointer)) { Error error; valobj_sp = valobj_sp->AddressOf(error); @@ -492,10 +509,10 @@ lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex (size_t idx) process_sp->GetAddressByteSize()); set_item.valobj_sp = - CreateValueObjectFromData(idx_name.GetData(), - data, - m_exe_ctx_ref, - m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID)); + CreateValueObjectFromData(idx_name.GetData(), + data, + m_exe_ctx_ref, + m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID)); } return set_item.valobj_sp; } @@ -590,7 +607,7 @@ lldb::ValueObjectSP lldb_private::formatters::NSSetMSyntheticFrontEnd::GetChildAtIndex (size_t idx) { lldb::addr_t m_objs_addr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr); - + uint32_t num_children = CalculateNumChildren(); if (idx >= num_children) @@ -660,10 +677,10 @@ lldb_private::formatters::NSSetMSyntheticFrontEnd::GetChildAtIndex (size_t idx) process_sp->GetAddressByteSize()); set_item.valobj_sp = - CreateValueObjectFromData(idx_name.GetData(), - data, - m_exe_ctx_ref, - m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID)); + CreateValueObjectFromData(idx_name.GetData(), + data, + m_exe_ctx_ref, + m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID)); } return set_item.valobj_sp; } @@ -740,3 +757,4 @@ lldb_private::formatters::NSSetSummaryProvider<true> (ValueObject& valobj, Strea template bool lldb_private::formatters::NSSetSummaryProvider<false> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); + diff --git a/lldb/source/Plugins/Language/ObjC/NSString.cpp b/lldb/source/Plugins/Language/ObjC/NSString.cpp index 0717d6dcff9..80896631baf 100644 --- a/lldb/source/Plugins/Language/ObjC/NSString.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSString.cpp @@ -18,6 +18,7 @@ #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/Host/Endian.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Target/Language.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ProcessStructReader.h" @@ -55,6 +56,8 @@ GetNSPathStore2Type (Target &target) bool lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options) { + static ConstString g_TypeHint("NSString"); + ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; @@ -85,7 +88,7 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& 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); + return NSTaggedString_SummaryProvider(valobj, descriptor, stream, summary_options); auto& additionals_map(NSString_Additionals::GetAdditionalSummaries()); auto iter = additionals_map.find(class_name_cs), end = additionals_map.end(); @@ -144,6 +147,20 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& return true; } + std::string prefix,suffix; + if (Language* language = Language::FindPlugin(summary_options.GetLanguage())) + { + if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) + { + prefix.clear(); + suffix.clear(); + } + } + + StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); + options.SetPrefixToken(prefix); + options.SetSuffixToken(suffix); + if (is_mutable) { uint64_t location = 2 * ptr_size + valobj_addr; @@ -152,11 +169,9 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& 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); @@ -167,11 +182,9 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& } 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); @@ -184,11 +197,9 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& { 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); @@ -214,11 +225,9 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& 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); @@ -233,11 +242,9 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& 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); @@ -261,11 +268,9 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& 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); @@ -284,10 +289,8 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& 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); @@ -331,8 +334,10 @@ lldb_private::formatters::NSMutableAttributedStringSummaryProvider (ValueObject& } bool -lldb_private::formatters::NSTaggedString_SummaryProvider (ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream) +lldb_private::formatters::NSTaggedString_SummaryProvider (ValueObject& valobj, ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream, const TypeSummaryOptions& summary_options) { + static ConstString g_TypeHint("NSString"); + if (!descriptor) return false; uint64_t len_bits = 0, data_bits = 0; @@ -348,13 +353,25 @@ lldb_private::formatters::NSTaggedString_SummaryProvider (ObjCLanguageRuntime::C if (len_bits > g_fiveBitMaxLen) return false; + std::string prefix,suffix; + if (Language* language = Language::FindPlugin(summary_options.GetLanguage())) + { + if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) + { + prefix.clear(); + suffix.clear(); + } + } + // 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); + stream.Printf("%s",prefix.c_str()); + stream.Printf("\"%s\"",(const char*)&data_bits); + stream.Printf("%s",suffix.c_str()); return true; } @@ -381,6 +398,8 @@ lldb_private::formatters::NSTaggedString_SummaryProvider (ObjCLanguageRuntime::C bytes.insert(bytes.begin(), sixBitToCharLookup[packed]); } - stream.Printf("@\"%s\"",&bytes[0]); + stream.Printf("%s",prefix.c_str()); + stream.Printf("\"%s\"",&bytes[0]); + stream.Printf("%s",suffix.c_str()); return true; } diff --git a/lldb/source/Plugins/Language/ObjC/NSString.h b/lldb/source/Plugins/Language/ObjC/NSString.h index 46da71637d3..6a767a55e00 100644 --- a/lldb/source/Plugins/Language/ObjC/NSString.h +++ b/lldb/source/Plugins/Language/ObjC/NSString.h @@ -22,7 +22,7 @@ namespace lldb_private { NSStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); bool - NSTaggedString_SummaryProvider (ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream); + NSTaggedString_SummaryProvider (ValueObject& valobj, ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream, const TypeSummaryOptions& summary_options); bool NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp index 2fd85c0d395..3995be919f8 100644 --- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp +++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp @@ -770,3 +770,84 @@ ObjCLanguage::GetTypeScavenger () return std::unique_ptr<TypeScavenger>(new ObjCTypeScavenger()); } + +bool +ObjCLanguage::GetFormatterPrefixSuffix (ValueObject& valobj, ConstString type_hint, + std::string& prefix, std::string& suffix) +{ + static ConstString g_CFBag("CFBag"); + static ConstString g_CFBinaryHeap("CFBinaryHeap"); + + static ConstString g_NSNumberChar("NSNumber:char"); + static ConstString g_NSNumberShort("NSNumber:short"); + static ConstString g_NSNumberInt("NSNumber:int"); + static ConstString g_NSNumberLong("NSNumber:long"); + static ConstString g_NSNumberFloat("NSNumber:float"); + static ConstString g_NSNumberDouble("NSNumber:double"); + + static ConstString g_NSData("NSData"); + static ConstString g_NSArray("NSArray"); + static ConstString g_NSString("NSString"); + static ConstString g_NSStringStar("NSString*"); + + if (type_hint.IsEmpty()) + return false; + + prefix.clear(); + suffix.clear(); + + if (type_hint == g_CFBag || + type_hint == g_CFBinaryHeap) + { + prefix = "@"; + return true; + } + + if (type_hint == g_NSNumberChar) + { + prefix = "(char)"; + return true; + } + if (type_hint == g_NSNumberShort) + { + prefix = "(short)"; + return true; + } + if (type_hint == g_NSNumberInt) + { + prefix = "(int)"; + return true; + } + if (type_hint == g_NSNumberLong) + { + prefix = "(long)"; + return true; + } + if (type_hint == g_NSNumberFloat) + { + prefix = "(float)"; + return true; + } + if (type_hint == g_NSNumberDouble) + { + prefix = "(double)"; + return true; + } + + if (type_hint == g_NSData || + type_hint == g_NSArray) + { + prefix = "@\""; + suffix = "\""; + return true; + } + + if (type_hint == g_NSString || + type_hint == g_NSStringStar) + { + prefix = "@"; + return true; + } + + return false; +} diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h index 09ee55d274f..e6a1f482777 100644 --- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h +++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h @@ -149,6 +149,10 @@ public: std::unique_ptr<TypeScavenger> GetTypeScavenger () override; + bool + GetFormatterPrefixSuffix (ValueObject& valobj, ConstString type_hint, + std::string& prefix, std::string& suffix) override; + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ |

