Author: nerix Date: 2025-07-25T17:01:35+01:00 New Revision: 7b42e7c98e13bd9f50db754346de946b3a6e1bbe
URL: https://github.com/llvm/llvm-project/commit/7b42e7c98e13bd9f50db754346de946b3a6e1bbe DIFF: https://github.com/llvm/llvm-project/commit/7b42e7c98e13bd9f50db754346de946b3a6e1bbe.diff LOG: [LLDB] Add formatters for MSVC STL std::string_view and friends (#150318) Adds summaries for `std::{,w,u8,u16,u32}string_view`s from MSVC's STL. A few functions from the string formatting can be reused. Towards #24834. Added: lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/Makefile lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/TestDataFormatterStdU8StringView.py lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/main.cpp Modified: lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/TestDataFormatterStdStringView.py lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/main.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index e69f2f677e9ab..46753c5efc331 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -1363,6 +1363,28 @@ static void RegisterStdStringSummaryProvider( summary_sp); } +static void RegisterStdStringViewSummaryProvider( + const lldb::TypeCategoryImplSP &category_sp, llvm::StringRef string_ty, + llvm::StringRef char_ty, lldb::TypeSummaryImplSP summary_sp) { + // std::string_view + category_sp->AddTypeSummary( + std::make_shared<lldb_private::TypeNameSpecifierImpl>( + string_ty, eFormatterMatchExact), + summary_sp); + + // std::basic_string_view<char, std::char_traits<char>> + // NativePDB has spaces at diff erent positions compared to PDB and DWARF, so + // use a regex and make them optional. + category_sp->AddTypeSummary( + std::make_shared<lldb_private::TypeNameSpecifierImpl>( + llvm::formatv( + "^std::basic_string_view<{0}, ?std::char_traits<{0}> ?>$", + char_ty) + .str(), + eFormatterMatchRegex), + summary_sp); +} + static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { if (!cpp_category_sp) return; @@ -1863,6 +1885,36 @@ static void LoadMsvcStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { MsvcStlStringSummaryProvider<StringElementType::UTF32>, "MSVC STL std::u32string summary provider")); + RegisterStdStringViewSummaryProvider( + cpp_category_sp, "std::string_view", "char", + std::make_shared<CXXFunctionSummaryFormat>( + stl_summary_flags, + MsvcStlStringViewSummaryProvider<StringElementType::ASCII>, + "MSVC STL std::string_view summary provider")); + RegisterStdStringViewSummaryProvider( + cpp_category_sp, "std::u8string_view", "char8_t", + std::make_shared<CXXFunctionSummaryFormat>( + stl_summary_flags, + MsvcStlStringViewSummaryProvider<StringElementType::UTF8>, + "MSVC STL std::u8string_view summary provider")); + RegisterStdStringViewSummaryProvider( + cpp_category_sp, "std::u16string_view", "char16_t", + std::make_shared<CXXFunctionSummaryFormat>( + stl_summary_flags, + MsvcStlStringViewSummaryProvider<StringElementType::UTF16>, + "MSVC STL std::u16string_view summary provider")); + RegisterStdStringViewSummaryProvider( + cpp_category_sp, "std::u32string_view", "char32_t", + std::make_shared<CXXFunctionSummaryFormat>( + stl_summary_flags, + MsvcStlStringViewSummaryProvider<StringElementType::UTF32>, + "MSVC STL std::u32string_view summary provider")); + RegisterStdStringViewSummaryProvider( + cpp_category_sp, "std::wstring_view", "wchar_t", + std::make_shared<CXXFunctionSummaryFormat>( + stl_summary_flags, MsvcStlWStringViewSummaryProvider, + "MSVC STL std::wstring_view summary provider")); + stl_summary_flags.SetDontShowChildren(false); AddCXXSynthetic(cpp_category_sp, MsvcStlAtomicSyntheticFrontEndCreator, diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp index 5d0f20b1beaae..8fb305b284bbb 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp @@ -112,6 +112,33 @@ static bool formatStringImpl(ValueObject &valobj, Stream &stream, return true; } +template <StringPrinter::StringElementType element_type> +static bool formatStringViewImpl(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options, + std::string prefix_token) { + auto data_sp = valobj.GetChildMemberWithName("_Mydata"); + auto size_sp = valobj.GetChildMemberWithName("_Mysize"); + if (!data_sp || !size_sp) + return false; + + bool success = false; + uint64_t size = size_sp->GetValueAsUnsigned(0, &success); + if (!success) { + stream << "Summary Unavailable"; + return true; + } + + StreamString scratch_stream; + success = StringBufferSummaryProvider<element_type>( + scratch_stream, summary_options, data_sp, size, prefix_token); + + if (success) + stream << scratch_stream.GetData(); + else + stream << "Summary Unavailable"; + return true; +} + bool lldb_private::formatters::IsMsvcStlStringType(ValueObject &valobj) { std::vector<uint32_t> indexes; return valobj.GetCompilerType().GetIndexOfChildMemberWithName("_Mypair", true, @@ -153,3 +180,39 @@ bool lldb_private::formatters::MsvcStlStringSummaryProvider< return MsvcStlStringSummaryProviderImpl<StringElementType::UTF32>( valobj, stream, summary_options, "U"); } + +bool lldb_private::formatters::MsvcStlWStringViewSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options) { + return formatStringViewImpl<StringElementType::UTF16>(valobj, stream, + summary_options, "L"); +} + +template <> +bool lldb_private::formatters::MsvcStlStringViewSummaryProvider< + StringElementType::ASCII>(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options) { + return formatStringViewImpl<StringElementType::ASCII>(valobj, stream, + summary_options, ""); +} +template <> +bool lldb_private::formatters::MsvcStlStringViewSummaryProvider< + StringElementType::UTF8>(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options) { + return formatStringViewImpl<StringElementType::UTF8>(valobj, stream, + summary_options, "u8"); +} +template <> +bool lldb_private::formatters::MsvcStlStringViewSummaryProvider< + StringElementType::UTF16>(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options) { + return formatStringViewImpl<StringElementType::UTF16>(valobj, stream, + summary_options, "u"); +} +template <> +bool lldb_private::formatters::MsvcStlStringViewSummaryProvider< + StringElementType::UTF32>(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options) { + return formatStringViewImpl<StringElementType::UTF32>(valobj, stream, + summary_options, "U"); +} diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h index 490794ccbfb53..8a4918127584f 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h +++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h @@ -29,6 +29,15 @@ bool MsvcStlWStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // VC 2015+ std::wstring +template <StringPrinter::StringElementType element_type> +bool MsvcStlStringViewSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options); // std::{u8,u16,u32}?string_view + +bool MsvcStlWStringViewSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // std::wstring_view + // MSVC STL std::shared_ptr<> and std::weak_ptr<> bool IsMsvcStlSmartPointer(ValueObject &valobj); bool MsvcStlSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream, diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/TestDataFormatterStdStringView.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/TestDataFormatterStdStringView.py index 8c053f0843f9b..181141886c5a2 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/TestDataFormatterStdStringView.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/TestDataFormatterStdStringView.py @@ -78,9 +78,6 @@ def cleanup(): "u32_string", type="std::u32string_view", summary='U"🍄🍅🍆🍌"' ) 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"' - ) # GetSummary returns None so can't be checked by expect_var_path, so we # use the str representation instead @@ -163,3 +160,8 @@ def cleanup(): def test_libcxx(self): self.build(dictionary={"USE_LIBCPP": 1}) self.do_test() + + @add_test_categories(["msvcstl"]) + def test_msvcstl(self): + self.build() + self.do_test() diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/main.cpp index 1e164786bc1a9..e8781fbdf56f9 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/main.cpp +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string_view/main.cpp @@ -95,7 +95,6 @@ int main() { std::string_view *null_str = nullptr; std::string hello = "Hellooo "; - std::string_view oops = hello + "World\n"; q_source[0] = 'H'; // Set break point at this line. diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/Makefile new file mode 100644 index 0000000000000..4f79c0a900c3a --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/Makefile @@ -0,0 +1,4 @@ +CXX_SOURCES := main.cpp +CXXFLAGS_EXTRAS := -std=c++20 + +include Makefile.rules diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/TestDataFormatterStdU8StringView.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/TestDataFormatterStdU8StringView.py new file mode 100644 index 0000000000000..1e35a0f6bb040 --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/TestDataFormatterStdU8StringView.py @@ -0,0 +1,44 @@ +# coding=utf8 +""" +Test std::u8string_view summary. +""" + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class StdU8StringViewDataFormatterTestCase(TestBase): + def do_test(self): + lldbutil.run_to_source_breakpoint( + self, "Set break point at this line.", lldb.SBFileSpec("main.cpp") + ) + + self.expect( + "frame variable", + substrs=[ + '(std::u8string_view) u8_string_small = u8"🍄"', + '(std::u8string_view) u8_string = u8"❤️👍📄📁😃🧑🌾"', + '(std::u8string_view) u8_empty = u8""', + '(std::u8string_view) u8_text = u8"ABCd"', + ], + ) + + @expectedFailureAll(bugnumber="No libc++ formatters for std::u8string_view yet.") + @add_test_categories(["libc++"]) + def test_libcxx(self): + self.build(dictionary={"USE_LIBCPP": 1}) + self.do_test() + + @expectedFailureAll(bugnumber="No libstdc++ formatters for std::u8string_view yet.") + @add_test_categories(["libstdcxx"]) + def test_libstdcxx(self): + self.build(dictionary={"USE_LIBSTDCPP": 1}) + self.do_test() + + @add_test_categories(["msvcstl"]) + def test_msvc(self): + self.build() + self.do_test() diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/main.cpp new file mode 100644 index 0000000000000..458e783a0238a --- /dev/null +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/u8string_view/main.cpp @@ -0,0 +1,12 @@ +#include <cstdio> +#include <string_view> + +int main() { + std::u8string_view u8_string_small(u8"🍄"); + std::u8string_view u8_string(u8"❤️👍📄📁😃🧑🌾"); + std::u8string_view u8_empty(u8""); + std::u8string_view u8_text(u8"ABC"); + u8_text = u8"ABCd"; + + std::puts("// Set break point at this line."); +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits