diff --git a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp index fc17b76804d9f..bf8c393445908 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp @@ -116,15 +116,7 @@ bool lldb_private::formatters::WCharStringSummaryProvider( return false; // Get a wchar_t basic type from the current type system - CompilerType wchar_compiler_type = - valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar); - - if (!wchar_compiler_type) - return false; - - // Safe to pass nullptr for exe_scope here. - std::optional size = - llvm::expectedToOptional(wchar_compiler_type.GetBitSize(nullptr)); + std::optional size = GetWCharByteSize(valobj); if (!size) return false; const uint32_t wchar_size = *size; @@ -136,13 +128,13 @@ bool lldb_private::formatters::WCharStringSummaryProvider( options.SetPrefixToken("L"); switch (wchar_size) { - case 8: + case 1: return StringPrinter::ReadStringAndDumpToStream( options); - case 16: + case 2: return StringPrinter::ReadStringAndDumpToStream( options); - case 32: + case 4: return StringPrinter::ReadStringAndDumpToStream( options); default: @@ -177,15 +169,7 @@ bool lldb_private::formatters::WCharSummaryProvider( return false; // Get a wchar_t basic type from the current type system - CompilerType wchar_compiler_type = - valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar); - - if (!wchar_compiler_type) - return false; - - // Safe to pass nullptr for exe_scope here. - std::optional size = - llvm::expectedToOptional(wchar_compiler_type.GetBitSize(nullptr)); + std::optional size = GetWCharByteSize(valobj); if (!size) return false; const uint32_t wchar_size = *size; @@ -199,13 +183,13 @@ bool lldb_private::formatters::WCharSummaryProvider( options.SetBinaryZeroIsTerminator(false); switch (wchar_size) { - case 8: + case 1: return StringPrinter::ReadBufferAndDumpToStream( options); - case 16: + case 2: return StringPrinter::ReadBufferAndDumpToStream( options); - case 32: + case 4: return StringPrinter::ReadBufferAndDumpToStream( options); default: @@ -214,3 +198,73 @@ bool lldb_private::formatters::WCharSummaryProvider( } return true; } + +std::optional +lldb_private::formatters::GetWCharByteSize(ValueObject &valobj) { + return llvm::expectedToOptional( + valobj.GetCompilerType() + .GetBasicTypeFromAST(lldb::eBasicTypeWChar) + .GetByteSize(nullptr)); +} + +template +bool lldb_private::formatters::StringBufferSummaryProvider( + Stream &stream, const TypeSummaryOptions &summary_options, + lldb::ValueObjectSP location_sp, uint64_t size, std::string prefix_token) { + + if (size == 0) { + stream.PutCString(prefix_token); + stream.PutCString("\"\""); + return true; + } + + if (!location_sp) + return false; + + StringPrinter::ReadBufferAndDumpToStreamOptions options(*location_sp); + + if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { + const auto max_size = + location_sp->GetTargetSP()->GetMaximumSizeOfStringSummary(); + if (size > max_size) { + size = max_size; + options.SetIsTruncated(true); + } + } + + { + DataExtractor extractor; + const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); + if (bytes_read < size) + return false; + + options.SetData(std::move(extractor)); + } + options.SetStream(&stream); + if (prefix_token.empty()) + options.SetPrefixToken(nullptr); + else + options.SetPrefixToken(prefix_token); + options.SetQuote('"'); + options.SetSourceSize(size); + options.SetBinaryZeroIsTerminator(false); + return StringPrinter::ReadBufferAndDumpToStream(options); +} + +// explicit instantiations for all string element types +template bool +lldb_private::formatters::StringBufferSummaryProvider( + Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t, + std::string); +template bool +lldb_private::formatters::StringBufferSummaryProvider( + Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t, + std::string); +template bool +lldb_private::formatters::StringBufferSummaryProvider( + Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t, + std::string); +template bool +lldb_private::formatters::StringBufferSummaryProvider( + Stream &, const TypeSummaryOptions &, lldb::ValueObjectSP, uint64_t, + std::string); diff --git a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h index a2b606d28cac1..337dcf2fefdcf 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h +++ b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h @@ -10,6 +10,7 @@ #ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CXXSTRINGTYPES_H #define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CXXSTRINGTYPES_H +#include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/Utility/Stream.h" #include "lldb/ValueObject/ValueObject.h" @@ -43,6 +44,34 @@ bool Char32SummaryProvider(ValueObject &valobj, Stream &stream, bool WCharSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // wchar_t +std::optional GetWCharByteSize(ValueObject &valobj); + +/// Print a summary for a string buffer to \a stream. +/// +/// \param[in] stream +/// The output stream to print the summary to. +/// +/// \param[in] summary_options +/// Options for printing the string contents. This function respects the +/// capping. +/// +/// \param[in] location_sp +/// ValueObject of a pointer to the string being printed. +/// +/// \param[in] size +/// The size of the buffer pointed to by \a location_sp. +/// +/// \param[in] prefix_token +/// A prefix before the double quotes (e.g. 'u' results in u"..."). +/// +/// \return +/// Returns whether the string buffer was successfully printed. +template +bool StringBufferSummaryProvider(Stream &stream, + const TypeSummaryOptions &summary_options, + lldb::ValueObjectSP location_sp, uint64_t size, + std::string prefix_token); + } // namespace formatters } // namespace lldb_private diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 358cf7d78fa21..7143089209dd3 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -24,6 +24,7 @@ #include "lldb/ValueObject/ValueObject.h" #include "lldb/ValueObject/ValueObjectConstResult.h" +#include "Plugins/Language/CPlusPlus/CxxStringTypes.h" #include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/lldb-enumerations.h" @@ -535,70 +536,6 @@ ExtractLibcxxStringInfo(ValueObject &valobj) { return std::make_pair(size, location_sp); } -static bool -LibcxxWStringSummaryProvider(ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &summary_options, - ValueObjectSP location_sp, size_t size) { - if (size == 0) { - stream.Printf("L\"\""); - return true; - } - if (!location_sp) - return false; - - StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); - if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { - const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); - if (size > max_size) { - size = max_size; - options.SetIsTruncated(true); - } - } - - DataExtractor extractor; - const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); - if (bytes_read < size) - return false; - - // std::wstring::size() is measured in 'characters', not bytes - TypeSystemClangSP scratch_ts_sp = - ScratchTypeSystemClang::GetForTarget(*valobj.GetTargetSP()); - if (!scratch_ts_sp) - return false; - - auto wchar_t_size = - scratch_ts_sp->GetBasicType(lldb::eBasicTypeWChar).GetByteSize(nullptr); - if (!wchar_t_size) - return false; - - options.SetData(std::move(extractor)); - options.SetStream(&stream); - options.SetPrefixToken("L"); - options.SetQuote('"'); - options.SetSourceSize(size); - options.SetBinaryZeroIsTerminator(false); - - switch (*wchar_t_size) { - case 1: - return StringPrinter::ReadBufferAndDumpToStream< - lldb_private::formatters::StringPrinter::StringElementType::UTF8>( - options); - break; - - case 2: - return StringPrinter::ReadBufferAndDumpToStream< - lldb_private::formatters::StringPrinter::StringElementType::UTF16>( - options); - break; - - case 4: - return StringPrinter::ReadBufferAndDumpToStream< - lldb_private::formatters::StringPrinter::StringElementType::UTF32>( - options); - } - return false; -} - bool lldb_private::formatters::LibcxxWStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options) { @@ -609,52 +546,22 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( ValueObjectSP location_sp; std::tie(size, location_sp) = *string_info; - return ::LibcxxWStringSummaryProvider(valobj, stream, summary_options, - location_sp, size); -} - -template -static bool -LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &summary_options, - std::string prefix_token, ValueObjectSP location_sp, - uint64_t size) { - - if (size == 0) { - stream.Printf("\"\""); - return true; - } - - if (!location_sp) + auto wchar_t_size = GetWCharByteSize(valobj); + if (!wchar_t_size) return false; - StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); - - if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { - const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); - if (size > max_size) { - size = max_size; - options.SetIsTruncated(true); - } - } - - { - DataExtractor extractor; - const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); - if (bytes_read < size) - return false; - - options.SetData(std::move(extractor)); + switch (*wchar_t_size) { + case 1: + return StringBufferSummaryProvider( + stream, summary_options, location_sp, size, "L"); + case 2: + return StringBufferSummaryProvider( + stream, summary_options, location_sp, size, "L"); + case 4: + return StringBufferSummaryProvider( + stream, summary_options, location_sp, size, "L"); } - options.SetStream(&stream); - if (prefix_token.empty()) - options.SetPrefixToken(nullptr); - else - options.SetPrefixToken(prefix_token); - options.SetQuote('"'); - options.SetSourceSize(size); - options.SetBinaryZeroIsTerminator(false); - return StringPrinter::ReadBufferAndDumpToStream(options); + return false; } template @@ -669,8 +576,8 @@ LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, ValueObjectSP location_sp; std::tie(size, location_sp) = *string_info; - return LibcxxStringSummaryProvider( - valobj, stream, summary_options, prefix_token, location_sp, size); + return StringBufferSummaryProvider( + stream, summary_options, location_sp, size, prefix_token); } template static bool formatStringImpl(ValueObject &valobj, Stream &stream, @@ -742,8 +649,8 @@ static bool formatStringViewImpl(ValueObject &valobj, Stream &stream, return true; } - return LibcxxStringSummaryProvider( - valobj, stream, summary_options, prefix_token, dataobj, size); + return StringBufferSummaryProvider(stream, summary_options, + dataobj, size, prefix_token); } bool lldb_private::formatters::LibcxxStringViewSummaryProviderASCII( @@ -781,8 +688,22 @@ bool lldb_private::formatters::LibcxxWStringViewSummaryProvider( return true; } - return ::LibcxxWStringSummaryProvider(valobj, stream, summary_options, - dataobj, size); + auto wchar_t_size = GetWCharByteSize(valobj); + if (!wchar_t_size) + return false; + + switch (*wchar_t_size) { + case 1: + return StringBufferSummaryProvider( + stream, summary_options, dataobj, size, "L"); + case 2: + return StringBufferSummaryProvider( + stream, summary_options, dataobj, size, "L"); + case 4: + return StringBufferSummaryProvider( + stream, summary_options, dataobj, size, "L"); + } + return false; } static bool diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py index 5c5cf4ca16b98..32764629d65a7 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py @@ -65,11 +65,9 @@ def cleanup(): '(%s::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"' % ns, '(%s::u16string) u16_string = u"ß水氶"' % ns, - # FIXME: This should have a 'u' prefix. - '(%s::u16string) u16_empty = ""' % ns, + '(%s::u16string) u16_empty = u""' % ns, '(%s::u32string) u32_string = U"🍄🍅🍆🍌"' % ns, - # FIXME: This should have a 'U' prefix. - '(%s::u32string) u32_empty = ""' % ns, + '(%s::u32string) u32_empty = U""' % ns, "(%s::string *) null_str = nullptr" % ns, ], ) @@ -123,7 +121,7 @@ def cleanup(): % ns, '(%s::u16string) u16_string = u"ß水氶"' % ns, '(%s::u32string) u32_string = U"🍄🍅🍆🍌"' % ns, - '(%s::u32string) u32_empty = ""' % ns, + '(%s::u32string) u32_empty = U""' % ns, "(%s::string *) null_str = nullptr" % ns, ], ) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/TestDataFormatterLibcxxStringView.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/TestDataFormatterLibcxxStringView.py index f8fc8ae66405b..3883395f23924 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/TestDataFormatterLibcxxStringView.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string_view/TestDataFormatterLibcxxStringView.py @@ -81,11 +81,11 @@ def cleanup(): summary='L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"', ) self.expect_var_path("u16_string", type="std::u16string_view", summary='u"ß水氶"') - self.expect_var_path("u16_empty", type="std::u16string_view", summary='""') + self.expect_var_path("u16_empty", type="std::u16string_view", summary='u""') self.expect_var_path( "u32_string", type="std::u32string_view", summary='U"🍄🍅🍆🍌"' ) - self.expect_var_path("u32_empty", type="std::u32string_view", summary='""') + self.expect_var_path("u32_empty", type="std::u32string_view", summary='U""') self.expect_var_path( "oops", type="std::string_view", summary='"Hellooo World\\n"' ) @@ -145,11 +145,11 @@ def cleanup(): summary='L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"', ) self.expect_var_path("u16_string", type="std::u16string_view", summary='u"ß水氶"') - self.expect_var_path("u16_empty", type="std::u16string_view", summary='""') + self.expect_var_path("u16_empty", type="std::u16string_view", summary='u""') self.expect_var_path( "u32_string", type="std::u32string_view", summary='U"🍄🍅🍆🍌"' ) - self.expect_var_path("u32_empty", type="std::u32string_view", summary='""') + self.expect_var_path("u32_empty", type="std::u32string_view", summary='U""') self.runCmd("cont") self.expect( pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy