diff options
| author | Enrico Granata <egranata@apple.com> | 2013-01-10 22:08:35 +0000 |
|---|---|---|
| committer | Enrico Granata <egranata@apple.com> | 2013-01-10 22:08:35 +0000 |
| commit | f68df12fb039d5177e34f4541fa242b891949db6 (patch) | |
| tree | 2d1276ea2c339b9417faf19cf737c1911fa24f4f /lldb/source | |
| parent | 56df644323a5a808cb5559c519ddfc747fcc2eb8 (diff) | |
| download | bcm5719-llvm-f68df12fb039d5177e34f4541fa242b891949db6.tar.gz bcm5719-llvm-f68df12fb039d5177e34f4541fa242b891949db6.zip | |
<rdar://problem/12725746>
Providing data formatters for char16_t* and char32_t* C++11-style Unicode strings
Using this chance to refactor the UTF data reader used for data formatters for added generality
Added a relevant test case
llvm-svn: 172119
Diffstat (limited to 'lldb/source')
| -rw-r--r-- | lldb/source/Core/CXXFormatterFunctions.cpp | 207 | ||||
| -rw-r--r-- | lldb/source/Core/FormatManager.cpp | 144 |
2 files changed, 225 insertions, 126 deletions
diff --git a/lldb/source/Core/CXXFormatterFunctions.cpp b/lldb/source/Core/CXXFormatterFunctions.cpp index 3dc48c560f5..defc2c1d0c0 100644 --- a/lldb/source/Core/CXXFormatterFunctions.cpp +++ b/lldb/source/Core/CXXFormatterFunctions.cpp @@ -135,6 +135,151 @@ lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj, return valobj_sp; } +template<typename SourceDataType, ConversionResult (*ConvertFunction) (const SourceDataType**, + const SourceDataType*, + UTF8**, + UTF8*, + ConversionFlags)> +static bool +ReadUTFBufferAndDumpToStream (uint64_t location, + const ProcessSP& process_sp, + Stream& stream, + bool want_at = true, + bool want_quotes = true) +{ + if (location == 0 || location == LLDB_INVALID_ADDRESS) + return false; + if (!process_sp) + return false; + + const int origin_encoding = 8*sizeof(SourceDataType); + if (origin_encoding != 8 && origin_encoding != 16 && origin_encoding != 32) + return false; + // if not UTF8, I need a conversion function to return proper UTF8 + if (origin_encoding != 8 && !ConvertFunction) + return false; + const int bufferSPSize = 1024; + const int sourceSize = (bufferSPSize / (origin_encoding >> 2)); + + Error error; + lldb::DataBufferSP buffer_sp(new DataBufferHeap(bufferSPSize,0)); + size_t data_read = process_sp->ReadMemoryFromInferior(location, (char*)buffer_sp->GetBytes(), bufferSPSize, error); + if (error.Fail()) + { + stream.Printf("unable to read data"); + return true; + } + else + { + if (want_at) + stream.Printf("@"); + if (want_quotes) + stream.Printf("\""); + } + if (data_read) + { + SourceDataType *data_ptr = (SourceDataType*)buffer_sp->GetBytes(); + SourceDataType *data_end_ptr = data_ptr + sourceSize; + + while (data_ptr < data_end_ptr) + { + if (!*data_ptr) + { + data_end_ptr = data_ptr; + break; + } + data_ptr++; + } + + *data_ptr = 0; + data_ptr = (SourceDataType*)buffer_sp->GetBytes(); + + lldb::DataBufferSP utf8_data_buffer_sp(new DataBufferHeap(bufferSPSize,0)); + UTF8* utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes(); + UTF8* utf8_data_end_ptr = utf8_data_ptr + bufferSPSize; + + if (ConvertFunction) + ConvertFunction ( (const SourceDataType**)&data_ptr, data_end_ptr, &utf8_data_ptr, utf8_data_end_ptr, lenientConversion ); + else + { + // just copy the pointers - the cast is necessary to make the compiler happy + // but this should only happen if we are reading UTF8 data + utf8_data_ptr = (UTF8*)data_ptr; + utf8_data_end_ptr = (UTF8*)data_end_ptr; + } + + utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes(); + for (;utf8_data_ptr != utf8_data_end_ptr; utf8_data_ptr++) + { + if (!*utf8_data_ptr) + break; + stream.Printf("%c",*utf8_data_ptr); + } + if (want_quotes) + stream.Printf("\""); + return true; + } + if (want_quotes) + stream.Printf("\""); + return true; +} + +bool +lldb_private::formatters::Char16StringSummaryProvider (ValueObject& valobj, Stream& stream) +{ + ProcessSP process_sp = valobj.GetProcessSP(); + if (!process_sp) + return false; + + lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); + + if (!valobj_addr) + return false; + + if (!ReadUTFBufferAndDumpToStream<UTF16, ConvertUTF16toUTF8>(valobj_addr, + process_sp, + stream, + false, // no @ sign for C++ + true)) // but use quotes + { + stream.Printf("Summary Unavailable"); + return true; + } + + return true; +} + +bool +lldb_private::formatters::Char32StringSummaryProvider (ValueObject& valobj, Stream& stream) +{ + ProcessSP process_sp = valobj.GetProcessSP(); + if (!process_sp) + return false; + + lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); + + if (!valobj_addr) + return false; + + if (!ReadUTFBufferAndDumpToStream<UTF32, ConvertUTF32toUTF8>(valobj_addr, + process_sp, + stream, + false, // no @ sign for C++ + true)) // but use quotes + { + stream.Printf("Summary Unavailable"); + return true; + } + + return true; +} + +bool +lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Stream& stream) +{ + return false; +} + template<bool name_entries> bool lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream) @@ -476,62 +621,6 @@ lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& } } -static bool -ReadUTFBufferAndDumpToStream (uint64_t location, - const ProcessSP& process_sp, - Stream& stream) -{ - Error error; - lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0)); - size_t data_read = process_sp->ReadMemoryFromInferior(location, (char*)buffer_sp->GetBytes(), 1024, error); - if (error.Fail()) - { - stream.Printf("unable to read data"); - return true; - } - else - stream.Printf("@\""); - if (data_read) - { - UTF16 *data_ptr = (UTF16*)buffer_sp->GetBytes(); - UTF16 *data_end_ptr = data_ptr + 256; - - while (data_ptr < data_end_ptr) - { - if (!*data_ptr) - { - data_end_ptr = data_ptr; - break; - } - data_ptr++; - } - - *data_ptr = 0; - data_ptr = (UTF16*)buffer_sp->GetBytes(); - - lldb::DataBufferSP utf8_data_buffer_sp(new DataBufferHeap(1024,0)); - UTF8* utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes(); - UTF8* utf8_data_end_ptr = utf8_data_ptr + 1024; - - ConvertUTF16toUTF8 ( (const UTF16**)&data_ptr, - data_end_ptr, - &utf8_data_ptr, - utf8_data_end_ptr, - lenientConversion); - utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes(); - for (;utf8_data_ptr != utf8_data_end_ptr; utf8_data_ptr++) - { - if (!*utf8_data_ptr) - break; - stream.Printf("%c",*utf8_data_ptr); - } - stream.Printf("\""); - return true; - } - stream.Printf("\""); - return true; -} - bool lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream) { @@ -597,7 +686,7 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& if (error.Fail()) return false; if (has_explicit_length and is_unicode) - return ReadUTFBufferAndDumpToStream (location, process_sp, stream); + return ReadUTFBufferAndDumpToStream<UTF16,ConvertUTF16toUTF8> (location, process_sp, stream); else { location++; @@ -640,12 +729,12 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& if (error.Fail()) return false; } - return ReadUTFBufferAndDumpToStream (location, process_sp, stream); + return ReadUTFBufferAndDumpToStream<UTF16,ConvertUTF16toUTF8> (location, process_sp, stream); } else if (is_special) { uint64_t location = valobj_addr + (ptr_size == 8 ? 12 : 8); - return ReadUTFBufferAndDumpToStream (location, process_sp, stream); + return ReadUTFBufferAndDumpToStream<UTF16,ConvertUTF16toUTF8> (location, process_sp, stream); } else if (is_inline) { diff --git a/lldb/source/Core/FormatManager.cpp b/lldb/source/Core/FormatManager.cpp index 22dff065445..fe1e6ec05ed 100644 --- a/lldb/source/Core/FormatManager.cpp +++ b/lldb/source/Core/FormatManager.cpp @@ -719,6 +719,63 @@ FormatManager::FormatManager() : EnableCategory(m_system_category_name,CategoryMap::Last); } +static void +AddStringSummary(TypeCategoryImpl::SharedPointer category_sp, + const char* string, + ConstString type_name, + TypeSummaryImpl::Flags flags) +{ + lldb::TypeSummaryImplSP summary_sp(new StringSummaryFormat(flags, + string)); + category_sp->GetSummaryNavigator()->Add(type_name, + summary_sp); +} + +#ifndef LLDB_DISABLE_PYTHON +static void +AddScriptSummary(TypeCategoryImpl::SharedPointer category_sp, + const char* funct_name, + ConstString type_name, + TypeSummaryImpl::Flags flags) +{ + + std::string code(" "); + code.append(funct_name).append("(valobj,internal_dict)"); + + lldb::TypeSummaryImplSP summary_sp(new ScriptSummaryFormat(flags, + funct_name, + code.c_str())); + category_sp->GetSummaryNavigator()->Add(type_name, + summary_sp); +} +#endif + +#ifndef LLDB_DISABLE_PYTHON +static void +AddCXXSummary (TypeCategoryImpl::SharedPointer category_sp, + CXXFunctionSummaryFormat::Callback funct, + const char* description, + ConstString type_name, + TypeSummaryImpl::Flags flags) +{ + lldb::TypeSummaryImplSP summary_sp(new CXXFunctionSummaryFormat(flags,funct,description)); + category_sp->GetSummaryNavigator()->Add(type_name, + summary_sp); +} +#endif + +#ifndef LLDB_DISABLE_PYTHON +static void AddCXXSynthetic (TypeCategoryImpl::SharedPointer category_sp, + CXXSyntheticChildren::CreateFrontEndCallback generator, + const char* description, + ConstString type_name, + TypeSyntheticImpl::Flags flags) +{ + lldb::SyntheticChildrenSP synth_sp(new CXXSyntheticChildren(flags,description,generator)); + category_sp->GetSyntheticNavigator()->Add(type_name,synth_sp); +} +#endif + void FormatManager::LoadSTLFormatters() { @@ -839,14 +896,17 @@ FormatManager::LoadLibcxxFormatters() void FormatManager::LoadSystemFormatters() { - lldb::TypeSummaryImplSP string_format(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false) - .SetSkipPointers(true) - .SetSkipReferences(false) - .SetDontShowChildren(true) - .SetDontShowValue(false) - .SetShowMembersOneLiner(false) - .SetHideItemNames(false), - "${var%s}")); + + TypeSummaryImpl::Flags string_flags; + string_flags.SetCascades(false) + .SetSkipPointers(true) + .SetSkipReferences(false) + .SetDontShowChildren(true) + .SetDontShowValue(false) + .SetShowMembersOneLiner(false) + .SetHideItemNames(false); + + lldb::TypeSummaryImplSP string_format(new StringSummaryFormat(string_flags, "${var%s}")); lldb::TypeSummaryImplSP string_array_format(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false) @@ -876,64 +936,14 @@ FormatManager::LoadSystemFormatters() "${var%O}")); sys_category_sp->GetSummaryNavigator()->Add(ConstString("OSType"), ostype_summary); -} - -static void -AddStringSummary(TypeCategoryImpl::SharedPointer category_sp, - const char* string, - ConstString type_name, - TypeSummaryImpl::Flags flags) -{ - lldb::TypeSummaryImplSP summary_sp(new StringSummaryFormat(flags, - string)); - category_sp->GetSummaryNavigator()->Add(type_name, - summary_sp); -} - -#ifndef LLDB_DISABLE_PYTHON -static void -AddScriptSummary(TypeCategoryImpl::SharedPointer category_sp, - const char* funct_name, - ConstString type_name, - TypeSummaryImpl::Flags flags) -{ - std::string code(" "); - code.append(funct_name).append("(valobj,internal_dict)"); + // FIXME because of a bug in the FormatNavigator we need to add a summary for both X* and const X* (<rdar://problem/12717717>) + AddCXXSummary(sys_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "char16_t * summary provider", ConstString("char16_t *"), string_flags); + AddCXXSummary(sys_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "char16_t * summary provider", ConstString("const char16_t *"), string_flags); - lldb::TypeSummaryImplSP summary_sp(new ScriptSummaryFormat(flags, - funct_name, - code.c_str())); - category_sp->GetSummaryNavigator()->Add(type_name, - summary_sp); -} -#endif - -#ifndef LLDB_DISABLE_PYTHON -static void -AddCXXSummary (TypeCategoryImpl::SharedPointer category_sp, - CXXFunctionSummaryFormat::Callback funct, - const char* description, - ConstString type_name, - TypeSummaryImpl::Flags flags) -{ - lldb::TypeSummaryImplSP summary_sp(new CXXFunctionSummaryFormat(flags,funct,description)); - category_sp->GetSummaryNavigator()->Add(type_name, - summary_sp); + AddCXXSummary(sys_category_sp, lldb_private::formatters::Char32StringSummaryProvider, "char32_t * summary provider", ConstString("char32_t *"), string_flags); + AddCXXSummary(sys_category_sp, lldb_private::formatters::Char32StringSummaryProvider, "char32_t * summary provider", ConstString("const char32_t *"), string_flags); } -#endif - -#ifndef LLDB_DISABLE_PYTHON -static void AddCXXSynthetic (TypeCategoryImpl::SharedPointer category_sp, - CXXSyntheticChildren::CreateFrontEndCallback generator, - const char* description, - ConstString type_name, - TypeSyntheticImpl::Flags flags) -{ - lldb::SyntheticChildrenSP synth_sp(new CXXSyntheticChildren(flags,description,generator)); - category_sp->GetSyntheticNavigator()->Add(type_name,synth_sp); -} -#endif void FormatManager::LoadObjCFormatters() @@ -960,10 +970,10 @@ FormatManager::LoadObjCFormatters() #ifndef LLDB_DISABLE_PYTHON // we need to skip pointers here since we are special casing a SEL* when retrieving its value objc_flags.SetSkipPointers(true); - AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary", ConstString("SEL"), objc_flags); - AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary", ConstString("struct objc_selector"), objc_flags); - AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary", ConstString("objc_selector"), objc_flags); - AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, "SEL summary", ConstString("objc_selector *"), objc_flags); + AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("SEL"), objc_flags); + AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("struct objc_selector"), objc_flags); + AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("objc_selector"), objc_flags); + AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, "SEL summary provider", ConstString("objc_selector *"), objc_flags); AddScriptSummary(objc_category_sp, "lldb.formatters.objc.Class.Class_Summary", ConstString("Class"), objc_flags); #endif // LLDB_DISABLE_PYTHON |

