[Lldb-commits] [lldb] 7b42e7c - [LLDB] Add formatters for MSVC STL std::string_view and friends (#150318)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Jul 25 09:01:39 PDT 2025
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.");
+}
More information about the lldb-commits
mailing list