diff options
-rw-r--r-- | lldb/include/lldb/Core/CXXFormatterFunctions.h | 11 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectExpression.cpp | 3 | ||||
-rw-r--r-- | lldb/source/Core/CXXFormatterFunctions.cpp | 246 | ||||
-rw-r--r-- | lldb/source/Core/FormatManager.cpp | 19 | ||||
-rw-r--r-- | lldb/test/lang/cpp/char1632_t/TestChar1632T.py | 4 | ||||
-rw-r--r-- | lldb/test/lang/cpp/wchar_t/TestCxxWCharT.py | 2 |
6 files changed, 212 insertions, 73 deletions
diff --git a/lldb/include/lldb/Core/CXXFormatterFunctions.h b/lldb/include/lldb/Core/CXXFormatterFunctions.h index 9c4eaf12fee..48734f98f4e 100644 --- a/lldb/include/lldb/Core/CXXFormatterFunctions.h +++ b/lldb/include/lldb/Core/CXXFormatterFunctions.h @@ -41,7 +41,7 @@ namespace lldb_private { const char* key); bool - Char16StringSummaryProvider (ValueObject& valobj, Stream& stream); // char16_t* + Char16StringSummaryProvider (ValueObject& valobj, Stream& stream); // char16_t* and unichar* bool Char32StringSummaryProvider (ValueObject& valobj, Stream& stream); // char32_t* @@ -50,6 +50,15 @@ namespace lldb_private { WCharStringSummaryProvider (ValueObject& valobj, Stream& stream); // wchar_t* bool + Char16SummaryProvider (ValueObject& valobj, Stream& stream); // char16_t and unichar + + bool + Char32SummaryProvider (ValueObject& valobj, Stream& stream); // char32_t + + bool + WCharSummaryProvider (ValueObject& valobj, Stream& stream); // wchar_t + + bool LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::string bool diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index 81633d38283..9689b401fb5 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -370,6 +370,9 @@ CommandObjectExpression::EvaluateExpression .SetSummary() .SetShowSummary(!m_varobj_options.use_objc) .SetHideRootType(m_varobj_options.use_objc); + + if (m_varobj_options.be_raw) + options.SetRawDisplay(true); ValueObject::DumpValueObject (*(output_stream), result_valobj_sp.get(), // Variable object to dump diff --git a/lldb/source/Core/CXXFormatterFunctions.cpp b/lldb/source/Core/CXXFormatterFunctions.cpp index e9863de7e70..a907d793989 100644 --- a/lldb/source/Core/CXXFormatterFunctions.cpp +++ b/lldb/source/Core/CXXFormatterFunctions.cpp @@ -135,55 +135,34 @@ lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj, return valobj_sp; } -template<typename SourceDataType, ConversionResult (*ConvertFunction) (const SourceDataType**, - const SourceDataType*, - UTF8**, - UTF8*, - ConversionFlags)> +// use this call if you already have an LLDB-side buffer for the data +template<typename SourceDataType> static bool -ReadUTFBufferAndDumpToStream (uint64_t location, - const ProcessSP& process_sp, - Stream& stream, - char prefix_token = '@', - bool want_quotes = true) +DumpUTFBufferToStream (ConversionResult (*ConvertFunction) (const SourceDataType**, + const SourceDataType*, + UTF8**, + UTF8*, + ConversionFlags), + DataExtractor& data, + Stream& stream, + char prefix_token = '@', + char quote = '"', + int sourceSize = 0) { - 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 sourceSize = process_sp->GetTarget().GetMaximumSizeOfStringSummary(); - const int bufferSPSize = sourceSize * (origin_encoding >> 2); - - Error error; - lldb::DataBufferSP buffer_sp(new DataBufferHeap(bufferSPSize,0)); - - if (!buffer_sp->GetBytes()) - return false; - - size_t data_read = process_sp->ReadMemoryFromInferior(location, (char*)buffer_sp->GetBytes(), bufferSPSize, error); - if (error.Fail()) + if (prefix_token != 0) + stream.Printf("%c",prefix_token); + if (quote != 0) + stream.Printf("%c",quote); + if (data.GetByteSize() && data.GetDataStart() && data.GetDataEnd()) { - stream.Printf("unable to read data"); - return true; - } - else - { - if (prefix_token != 0) - stream.Printf("%c",prefix_token); - if (want_quotes) - stream.Printf("\""); - } - if (data_read) - { - SourceDataType *data_ptr = (SourceDataType*)buffer_sp->GetBytes(); + const int bufferSPSize = data.GetByteSize(); + if (sourceSize == 0) + { + const int origin_encoding = 8*sizeof(SourceDataType); + sourceSize = bufferSPSize/(origin_encoding >> 2); + } + + SourceDataType *data_ptr = (SourceDataType*)data.GetDataStart(); SourceDataType *data_end_ptr = data_ptr + sourceSize; while (data_ptr < data_end_ptr) @@ -197,12 +176,12 @@ ReadUTFBufferAndDumpToStream (uint64_t location, } *data_ptr = 0; - data_ptr = (SourceDataType*)buffer_sp->GetBytes(); + data_ptr = (SourceDataType*)data.GetDataStart(); lldb::DataBufferSP utf8_data_buffer_sp; UTF8* utf8_data_ptr = nullptr; UTF8* utf8_data_end_ptr = nullptr; - + if (ConvertFunction) { utf8_data_buffer_sp.reset(new DataBufferHeap(bufferSPSize,0)); @@ -228,15 +207,60 @@ ReadUTFBufferAndDumpToStream (uint64_t location, break; stream.Printf("%c",*utf8_data_ptr); } - if (want_quotes) - stream.Printf("\""); - return true; } - if (want_quotes) - stream.Printf("\""); + if (quote != 0) + stream.Printf("%c",quote); return true; } +template<typename SourceDataType> +static bool +ReadUTFBufferAndDumpToStream (ConversionResult (*ConvertFunction) (const SourceDataType**, + const SourceDataType*, + UTF8**, + UTF8*, + ConversionFlags), + uint64_t location, + const ProcessSP& process_sp, + Stream& stream, + char prefix_token = '@', + char quote = '"', + int sourceSize = 0) +{ + 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; + + if (sourceSize == 0) + sourceSize = process_sp->GetTarget().GetMaximumSizeOfStringSummary(); + const int bufferSPSize = sourceSize * (origin_encoding >> 2); + + Error error; + lldb::DataBufferSP buffer_sp(new DataBufferHeap(bufferSPSize,0)); + + if (!buffer_sp->GetBytes()) + return false; + + size_t data_read = process_sp->ReadMemoryFromInferior(location, (char*)buffer_sp->GetBytes(), bufferSPSize, error); + if (error.Fail() || data_read == 0) + { + stream.Printf("unable to read data"); + return true; + } + + DataExtractor data(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()); + + return DumpUTFBufferToStream(ConvertFunction, data, stream, prefix_token, quote, sourceSize); +} + bool lldb_private::formatters::Char16StringSummaryProvider (ValueObject& valobj, Stream& stream) { @@ -249,11 +273,10 @@ lldb_private::formatters::Char16StringSummaryProvider (ValueObject& valobj, Stre if (!valobj_addr) return false; - if (!ReadUTFBufferAndDumpToStream<UTF16, ConvertUTF16toUTF8>(valobj_addr, + if (!ReadUTFBufferAndDumpToStream<UTF16>(ConvertUTF16toUTF8,valobj_addr, process_sp, stream, - 'u', - true)) // but use quotes + 'u')) { stream.Printf("Summary Unavailable"); return true; @@ -274,11 +297,10 @@ lldb_private::formatters::Char32StringSummaryProvider (ValueObject& valobj, Stre if (!valobj_addr) return false; - if (!ReadUTFBufferAndDumpToStream<UTF32, ConvertUTF32toUTF8>(valobj_addr, + if (!ReadUTFBufferAndDumpToStream<UTF32>(ConvertUTF32toUTF8,valobj_addr, process_sp, stream, - 'U', - true)) // but use quotes + 'U')) { stream.Printf("Summary Unavailable"); return true; @@ -315,25 +337,107 @@ lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Strea { case 8: // utf 8 - return ReadUTFBufferAndDumpToStream<UTF8, nullptr>(data_addr, + return ReadUTFBufferAndDumpToStream<UTF8>(nullptr, data_addr, process_sp, stream, - 'L', - true); // but use quotes + 'L'); case 16: // utf 16 - return ReadUTFBufferAndDumpToStream<UTF16, ConvertUTF16toUTF8>(data_addr, + return ReadUTFBufferAndDumpToStream<UTF16>(ConvertUTF16toUTF8, data_addr, process_sp, stream, - 'L', - true); // but use quotes + 'L'); case 32: // utf 32 - return ReadUTFBufferAndDumpToStream<UTF32, ConvertUTF32toUTF8>(data_addr, + return ReadUTFBufferAndDumpToStream<UTF32>(ConvertUTF32toUTF8, data_addr, process_sp, stream, - 'L', - true); // but use quotes + 'L'); + default: + stream.Printf("size for wchar_t is not valid"); + return true; + } + return true; +} + +bool +lldb_private::formatters::Char16SummaryProvider (ValueObject& valobj, Stream& stream) +{ + DataExtractor data; + valobj.GetData(data); + + std::string value; + valobj.GetValueAsCString(lldb::eFormatUnicode16, value); + if (!value.empty()) + stream.Printf("%s ", value.c_str()); + + return DumpUTFBufferToStream<UTF16>(ConvertUTF16toUTF8,data,stream, 'u','\'',1); +} + +bool +lldb_private::formatters::Char32SummaryProvider (ValueObject& valobj, Stream& stream) +{ + DataExtractor data; + valobj.GetData(data); + + std::string value; + valobj.GetValueAsCString(lldb::eFormatUnicode32, value); + if (!value.empty()) + stream.Printf("%s ", value.c_str()); + + return DumpUTFBufferToStream<UTF32>(ConvertUTF32toUTF8,data,stream, 'U','\'',1); +} + +bool +lldb_private::formatters::WCharSummaryProvider (ValueObject& valobj, Stream& stream) +{ + DataExtractor data; + valobj.GetData(data); + + clang::ASTContext* ast = valobj.GetClangAST(); + + if (!ast) + return false; + + std::string value; + + uint32_t wchar_size = ClangASTType::GetClangTypeBitWidth(ast, ClangASTType::GetBasicType(ast, lldb::eBasicTypeWChar).GetOpaqueQualType()); + + switch (wchar_size) + { + case 8: + // utf 8 + valobj.GetValueAsCString(lldb::eFormatChar, value); + if (!value.empty()) + stream.Printf("%s ", value.c_str()); + return DumpUTFBufferToStream<UTF8>(nullptr, + data, + stream, + 'L', + '\'', + 1); + case 16: + // utf 16 + valobj.GetValueAsCString(lldb::eFormatUnicode16, value); + if (!value.empty()) + stream.Printf("%s ", value.c_str()); + return DumpUTFBufferToStream<UTF16>(ConvertUTF16toUTF8, + data, + stream, + 'L', + '\'', + 1); + case 32: + // utf 32 + valobj.GetValueAsCString(lldb::eFormatUnicode32, value); + if (!value.empty()) + stream.Printf("%s ", value.c_str()); + return DumpUTFBufferToStream<UTF32>(ConvertUTF32toUTF8, + data, + stream, + 'L', + '\'', + 1); default: stream.Printf("size for wchar_t is not valid"); return true; @@ -827,7 +931,7 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& if (error.Fail()) return false; if (has_explicit_length and is_unicode) - return ReadUTFBufferAndDumpToStream<UTF16,ConvertUTF16toUTF8> (location, process_sp, stream, '@'); + return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8,location, process_sp, stream, '@'); else { location++; @@ -870,12 +974,12 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& if (error.Fail()) return false; } - return ReadUTFBufferAndDumpToStream<UTF16,ConvertUTF16toUTF8> (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<UTF16,ConvertUTF16toUTF8> (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 85723505230..73e1466c65d 100644 --- a/lldb/source/Core/FormatManager.cpp +++ b/lldb/source/Core/FormatManager.cpp @@ -968,6 +968,25 @@ FormatManager::LoadSystemFormatters() AddCXXSummary(sys_category_sp, lldb_private::formatters::WCharStringSummaryProvider, "wchar_t * summary provider", ConstString("wchar_t *"), string_flags); AddCXXSummary(sys_category_sp, lldb_private::formatters::WCharStringSummaryProvider, "wchar_t * summary provider", ConstString("const wchar_t *"), string_flags); + + AddCXXSummary(sys_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "unichar * summary provider", ConstString("unichar *"), string_flags); + AddCXXSummary(sys_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "unichar * summary provider", ConstString("const unichar *"), string_flags); + + TypeSummaryImpl::Flags widechar_flags; + widechar_flags.SetDontShowValue(true) + .SetSkipPointers(true) + .SetSkipReferences(false) + .SetCascades(true) + .SetDontShowChildren(true) + .SetHideItemNames(true) + .SetShowMembersOneLiner(false); + + AddCXXSummary(sys_category_sp, lldb_private::formatters::Char16SummaryProvider, "char16_t summary provider", ConstString("char16_t"), widechar_flags); + AddCXXSummary(sys_category_sp, lldb_private::formatters::Char32SummaryProvider, "char32_t summary provider", ConstString("char32_t"), widechar_flags); + AddCXXSummary(sys_category_sp, lldb_private::formatters::WCharSummaryProvider, "wchar_t summary provider", ConstString("wchar_t"), widechar_flags); + + AddCXXSummary(sys_category_sp, lldb_private::formatters::Char16SummaryProvider, "unichar summary provider", ConstString("unichar"), widechar_flags); + #endif } diff --git a/lldb/test/lang/cpp/char1632_t/TestChar1632T.py b/lldb/test/lang/cpp/char1632_t/TestChar1632T.py index 88d09db7042..bd93ce827a5 100644 --- a/lldb/test/lang/cpp/char1632_t/TestChar1632T.py +++ b/lldb/test/lang/cpp/char1632_t/TestChar1632T.py @@ -74,6 +74,10 @@ class Char1632TestCase(TestBase): self.expect("frame variable s16 s32", substrs = ['(char16_t *) s16 = 0x','(char32_t *) s32 = ','"色ハ匂ヘト散リヌルヲ"','"෴"']) + # Check that we can run expressions that return charN_t + self.expect("expression u'a'",substrs = ['(char16_t) $',"61 u'a'"]) + self.expect("expression U'a'",substrs = ['(char32_t) $',"61 U'a'"]) + if __name__ == '__main__': import atexit lldb.SBDebugger.Initialize() diff --git a/lldb/test/lang/cpp/wchar_t/TestCxxWCharT.py b/lldb/test/lang/cpp/wchar_t/TestCxxWCharT.py index f4d4f054e00..52fab1f98cf 100644 --- a/lldb/test/lang/cpp/wchar_t/TestCxxWCharT.py +++ b/lldb/test/lang/cpp/wchar_t/TestCxxWCharT.py @@ -67,7 +67,7 @@ class CxxWCharTTestCase(TestBase): substrs = ['(int) foo_x.object = ']) # Check that we can run expressions that return wchar_t - self.expect("expression L'a'",substrs = ['(wchar_t) $']) + self.expect("expression L'a'",substrs = ['(wchar_t) $',"61 L'a'"]) # Mazel Tov if this works! self.expect("frame variable mazeltov", |