[Lldb-commits] [lldb] [lldb] Add generic string view summary provider (PR #171854)
Sergei Druzhkov via lldb-commits
lldb-commits at lists.llvm.org
Thu Dec 11 09:26:40 PST 2025
https://github.com/DrSergei updated https://github.com/llvm/llvm-project/pull/171854
>From ef8a0e118f394df64e14d4f399ce1246d5ab53f7 Mon Sep 17 00:00:00 2001
From: Druzhkov Sergei <serzhdruzhok at gmail.com>
Date: Thu, 11 Dec 2025 18:19:30 +0300
Subject: [PATCH 1/3] [lldb] Add generic string view summary provider
---
.../Plugins/Language/CPlusPlus/CMakeLists.txt | 1 +
.../Language/CPlusPlus/CPlusPlusLanguage.cpp | 95 +++++++------
.../Plugins/Language/CPlusPlus/Generic.h | 8 ++
.../Language/CPlusPlus/GenericStringView.cpp | 131 ++++++++++++++++++
.../Plugins/Language/CPlusPlus/LibCxx.cpp | 96 +------------
.../Plugins/Language/CPlusPlus/LibCxx.h | 16 ---
.../Plugins/Language/CPlusPlus/MsvcStl.cpp | 63 ---------
.../Plugins/Language/CPlusPlus/MsvcStl.h | 9 --
.../TestDataFormatterStdStringView.py | 5 +
.../TestDataFormatterStdU8StringView.py | 2 -
10 files changed, 196 insertions(+), 230 deletions(-)
create mode 100644 lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index c52d3bdb31284..940737068fd47 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -17,6 +17,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
GenericInitializerList.cpp
GenericList.cpp
GenericOptional.cpp
+ GenericStringView.cpp
LibCxx.cpp
LibCxxAtomic.cpp
LibCxxMap.cpp
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index ae6086ff89d71..bd58abca7ab04 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -54,6 +54,8 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
+using StringElementType = StringPrinter::StringElementType;
+
LLDB_PLUGIN_DEFINE(CPlusPlusLanguage)
void CPlusPlusLanguage::Initialize() {
@@ -799,42 +801,47 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
+ GenericStringViewSummaryProvider<StringElementType::ASCII>,
"std::string_view summary provider",
"^std::__[[:alnum:]]+::string_view$", stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
+ GenericStringViewSummaryProvider<StringElementType::ASCII>,
"std::string_view summary provider",
"^std::__[[:alnum:]]+::basic_string_view<char, "
"std::__[[:alnum:]]+::char_traits<char> >$",
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::LibcxxStringViewSummaryProviderASCII,
+ GenericStringViewSummaryProvider<StringElementType::ASCII>,
"std::string_view summary provider",
"^std::__[[:alnum:]]+::basic_string_view<unsigned char, "
"std::__[[:alnum:]]+::char_traits<unsigned char> >$",
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::LibcxxStringViewSummaryProviderUTF16,
+ GenericStringViewSummaryProvider<StringElementType::UTF8>,
+ "std::u8string_view summary provider",
+ "^std::__[[:alnum:]]+::basic_string_view<char8_t, "
+ "std::__[[:alnum:]]+::char_traits<char8_t> >$",
+ stl_summary_flags, true);
+
+ AddCXXSummary(cpp_category_sp,
+ GenericStringViewSummaryProvider<StringElementType::UTF16>,
"std::u16string_view summary provider",
"^std::__[[:alnum:]]+::basic_string_view<char16_t, "
"std::__[[:alnum:]]+::char_traits<char16_t> >$",
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::LibcxxStringViewSummaryProviderUTF32,
+ GenericStringViewSummaryProvider<StringElementType::UTF32>,
"std::u32string_view summary provider",
"^std::__[[:alnum:]]+::basic_string_view<char32_t, "
"std::__[[:alnum:]]+::char_traits<char32_t> >$",
stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::LibcxxWStringViewSummaryProvider,
+ AddCXXSummary(cpp_category_sp, GenericWStringViewSummaryProvider,
"std::wstring_view summary provider",
"^std::__[[:alnum:]]+::wstring_view$", stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::LibcxxWStringViewSummaryProvider,
+ AddCXXSummary(cpp_category_sp, GenericWStringViewSummaryProvider,
"std::wstring_view summary provider",
"^std::__[[:alnum:]]+::basic_string_view<wchar_t, "
"std::__[[:alnum:]]+::char_traits<wchar_t> >$",
@@ -1696,8 +1703,6 @@ static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
false);
- using StringElementType = StringPrinter::StringElementType;
-
RegisterStdStringSummaryProvider(
cpp_category_sp, "std::string", "char",
std::make_shared<CXXFunctionSummaryFormat>(
@@ -1722,9 +1727,39 @@ static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
},
"MSVC STL/libstdc++ std::wstring summary provider"));
- // NOTE: it is loaded as a common formatter because the libc++ version is not
- // in the `__1` namespace, hence we need to dispatch based on the class
- // layout.
+ RegisterStdStringViewSummaryProvider(
+ cpp_category_sp, "std::string_view", "char",
+ std::make_shared<CXXFunctionSummaryFormat>(
+ stl_summary_flags,
+ GenericStringViewSummaryProvider<StringElementType::ASCII>,
+ "MSVC STL/libstdc++ std::string_view summary provider"));
+ RegisterStdStringViewSummaryProvider(
+ cpp_category_sp, "std::u8string_view", "char8_t",
+ std::make_shared<CXXFunctionSummaryFormat>(
+ stl_summary_flags,
+ GenericStringViewSummaryProvider<StringElementType::UTF8>,
+ "MSVC STL/libstdc++ std::u8string_view summary provider"));
+ RegisterStdStringViewSummaryProvider(
+ cpp_category_sp, "std::u16string_view", "char16_t",
+ std::make_shared<CXXFunctionSummaryFormat>(
+ stl_summary_flags,
+ GenericStringViewSummaryProvider<StringElementType::UTF16>,
+ "MSVC STL/libstdc++ std::u16string_view summary provider"));
+ RegisterStdStringViewSummaryProvider(
+ cpp_category_sp, "std::u32string_view", "char32_t",
+ std::make_shared<CXXFunctionSummaryFormat>(
+ stl_summary_flags,
+ GenericStringViewSummaryProvider<StringElementType::UTF32>,
+ "MSVC STL/libstdc++ std::u32string_view summary provider"));
+ RegisterStdStringViewSummaryProvider(
+ cpp_category_sp, "std::wstring_view", "wchar_t",
+ std::make_shared<CXXFunctionSummaryFormat>(
+ stl_summary_flags, GenericWStringViewSummaryProvider,
+ "MSVC STL/libstdc++ std::wstring_view summary provider"));
+
+ // NOTE: it is loaded as a common formatter because the libc++ version is
+ // not in the `__1` namespace, hence we need to dispatch based on the
+ // class layout.
AddCXXSynthetic(cpp_category_sp,
GenericInitializerListSyntheticFrontEndCreator,
"std::initializer_list synthetic children",
@@ -1837,8 +1872,6 @@ static void LoadMsvcStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
false);
- using StringElementType = StringPrinter::StringElementType;
-
RegisterStdStringSummaryProvider(
cpp_category_sp, "std::u8string", "char8_t",
std::make_shared<CXXFunctionSummaryFormat>(
@@ -1858,36 +1891,6 @@ 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/Generic.h b/lldb/source/Plugins/Language/CPlusPlus/Generic.h
index 539eddd3d3e78..9283875852cf1 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Generic.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/Generic.h
@@ -9,6 +9,7 @@
#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_GENERIC_H
#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_GENERIC_H
+#include "lldb/DataFormatters/StringPrinter.h"
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/Utility/Stream.h"
#include "lldb/ValueObject/ValueObject.h"
@@ -19,6 +20,13 @@ namespace formatters {
bool GenericOptionalSummaryProvider(ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options);
+template <StringPrinter::StringElementType element_type>
+bool GenericStringViewSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
+bool GenericWStringViewSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options);
+
/// Return the ValueObjectSP of the underlying pointer member whose type
/// is a desugared 'std::shared_ptr::element_type *'.
lldb::ValueObjectSP GetDesugaredSmartPointerValue(ValueObject &ptr,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp
new file mode 100644
index 0000000000000..f566ef210489b
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp
@@ -0,0 +1,131 @@
+//===-- GenericStringView.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===---------------------------------------------------------------------===//
+
+#include "Generic.h"
+#include "LibCxx.h"
+
+#include "lldb/ValueObject/ValueObject.h"
+#include "lldb/lldb-forward.h"
+
+#include "Plugins/Language/CPlusPlus/CxxStringTypes.h"
+#include <tuple>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+using StringElementType = StringPrinter::StringElementType;
+
+enum class StlType {
+ LibCxx,
+ LibStdcpp,
+ MsvcStl,
+};
+
+std::tuple<StlType, lldb::ValueObjectSP, lldb::ValueObjectSP>
+extractStringViewData(ValueObject &valobj) {
+ auto data_sp = valobj.GetChildMemberWithName("_Mydata");
+ if (data_sp)
+ return std::make_tuple(StlType::MsvcStl, data_sp,
+ valobj.GetChildMemberWithName("_Mysize"));
+ data_sp = valobj.GetChildMemberWithName("_M_str");
+ if (data_sp)
+ return std::make_tuple(StlType::LibStdcpp, data_sp,
+ valobj.GetChildMemberWithName("_M_len"));
+ return std::make_tuple(
+ StlType::LibCxx,
+ GetChildMemberWithName(valobj,
+ {ConstString("__data_"), ConstString("__data")}),
+ GetChildMemberWithName(valobj,
+ {ConstString("__size_"), ConstString("__size")}));
+}
+
+template <StringPrinter::StringElementType element_type>
+static bool formatStringViewImpl(lldb::ValueObjectSP data_sp,
+ lldb::ValueObjectSP size_sp, Stream &stream,
+ const TypeSummaryOptions &summary_options,
+ std::string prefix_token) {
+ 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;
+}
+
+template <StringElementType element_type>
+static constexpr const char *getPrefixToken() {
+ if constexpr (element_type == StringElementType::ASCII)
+ return "";
+ if constexpr (element_type == StringElementType::UTF8)
+ return "u8";
+ if constexpr (element_type == StringElementType::UTF16)
+ return "u";
+ if constexpr (element_type == StringElementType::UTF32)
+ return "U";
+ llvm_unreachable("invalid element type");
+}
+
+template <StringPrinter::StringElementType element_type>
+bool lldb_private::formatters::GenericStringViewSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ auto [_, data_sp, size_sp] = extractStringViewData(valobj);
+ return formatStringViewImpl<element_type>(data_sp, size_sp, stream, options,
+ getPrefixToken<element_type>());
+}
+
+template bool lldb_private::formatters::GenericStringViewSummaryProvider<
+ StringElementType::ASCII>(ValueObject &, Stream &,
+ const TypeSummaryOptions &);
+template bool lldb_private::formatters::GenericStringViewSummaryProvider<
+ StringElementType::UTF8>(ValueObject &, Stream &,
+ const TypeSummaryOptions &);
+template bool lldb_private::formatters::GenericStringViewSummaryProvider<
+ StringElementType::UTF16>(ValueObject &, Stream &,
+ const TypeSummaryOptions &);
+template bool lldb_private::formatters::GenericStringViewSummaryProvider<
+ StringElementType::UTF32>(ValueObject &, Stream &,
+ const TypeSummaryOptions &);
+
+bool lldb_private::formatters::GenericWStringViewSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ auto [stl, data_sp, size_sp] = extractStringViewData(valobj);
+ if (stl == StlType::LibStdcpp)
+ return formatStringViewImpl<StringElementType::UTF32>(data_sp, size_sp,
+ stream, options, "L");
+
+ auto wchar_t_size = GetWCharByteSize(valobj);
+ if (!wchar_t_size)
+ return false;
+
+ switch (*wchar_t_size) {
+ case 1:
+ return formatStringViewImpl<StringElementType::UTF8>(data_sp, size_sp,
+ stream, options, "L");
+ case 2:
+ return formatStringViewImpl<StringElementType::UTF16>(data_sp, size_sp,
+ stream, options, "L");
+ case 4:
+ return formatStringViewImpl<StringElementType::UTF32>(data_sp, size_sp,
+ stream, options, "L");
+ }
+ return false;
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 141c5c9a2caf9..a68c9f0fdc963 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -495,8 +495,8 @@ ExtractLibcxxStringInfo(ValueObject &valobj) {
StringLayout layout =
*index_or_err == 0 ? StringLayout::DSC : StringLayout::CSD;
- bool short_mode = false; // this means the string is in short-mode and the
- // data is stored inline
+ bool short_mode = false; // this means the string is in short-mode and the
+ // data is stored inline
bool using_bitmasks = true; // Whether the class uses bitmasks for the mode
// flag (pre-D123580).
uint64_t size;
@@ -638,98 +638,6 @@ bool lldb_private::formatters::LibcxxStringSummaryProviderUTF32(
valobj, stream, summary_options, "U");
}
-static std::tuple<bool, ValueObjectSP, size_t>
-LibcxxExtractStringViewData(ValueObject& valobj) {
- auto dataobj = GetChildMemberWithName(
- valobj, {ConstString("__data_"), ConstString("__data")});
- auto sizeobj = GetChildMemberWithName(
- valobj, {ConstString("__size_"), ConstString("__size")});
- if (!dataobj || !sizeobj)
- return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {});
-
- if (!dataobj->GetError().Success() || !sizeobj->GetError().Success())
- return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {});
-
- bool success{false};
- uint64_t size = sizeobj->GetValueAsUnsigned(0, &success);
- if (!success)
- return std::make_tuple<bool,ValueObjectSP,size_t>(false, {}, {});
-
- return std::make_tuple(true,dataobj,size);
-}
-
-template <StringPrinter::StringElementType element_type>
-static bool formatStringViewImpl(ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &summary_options,
- std::string prefix_token) {
-
- bool success;
- ValueObjectSP dataobj;
- size_t size;
- std::tie(success, dataobj, size) = LibcxxExtractStringViewData(valobj);
-
- if (!success) {
- stream << "Summary Unavailable";
- return true;
- }
-
- return StringBufferSummaryProvider<element_type>(stream, summary_options,
- dataobj, size, prefix_token);
-}
-
-bool lldb_private::formatters::LibcxxStringViewSummaryProviderASCII(
- ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &summary_options) {
- return formatStringViewImpl<StringPrinter::StringElementType::ASCII>(
- valobj, stream, summary_options, "");
-}
-
-bool lldb_private::formatters::LibcxxStringViewSummaryProviderUTF16(
- ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &summary_options) {
- return formatStringViewImpl<StringPrinter::StringElementType::UTF16>(
- valobj, stream, summary_options, "u");
-}
-
-bool lldb_private::formatters::LibcxxStringViewSummaryProviderUTF32(
- ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &summary_options) {
- return formatStringViewImpl<StringPrinter::StringElementType::UTF32>(
- valobj, stream, summary_options, "U");
-}
-
-bool lldb_private::formatters::LibcxxWStringViewSummaryProvider(
- ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &summary_options) {
-
- bool success;
- ValueObjectSP dataobj;
- size_t size;
- std::tie(success, dataobj, size) = LibcxxExtractStringViewData(valobj);
-
- if (!success) {
- stream << "Summary Unavailable";
- return true;
- }
-
- auto wchar_t_size = GetWCharByteSize(valobj);
- if (!wchar_t_size)
- return false;
-
- switch (*wchar_t_size) {
- case 1:
- return StringBufferSummaryProvider<StringPrinter::StringElementType::UTF8>(
- stream, summary_options, dataobj, size, "L");
- case 2:
- return StringBufferSummaryProvider<StringPrinter::StringElementType::UTF16>(
- stream, summary_options, dataobj, size, "L");
- case 4:
- return StringBufferSummaryProvider<StringPrinter::StringElementType::UTF32>(
- stream, summary_options, dataobj, size, "L");
- }
- return false;
-}
-
static bool
LibcxxChronoTimePointSecondsSummaryProvider(ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index 8fd29288da35f..d1a30d176fe7a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -59,22 +59,6 @@ bool LibcxxWStringSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // libc++ std::wstring
-bool LibcxxStringViewSummaryProviderASCII(
- ValueObject &valueObj, Stream &stream,
- const TypeSummaryOptions &summary_options); // libc++ std::string_view
-
-bool LibcxxStringViewSummaryProviderUTF16(
- ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &summary_options); // libc++ std::u16string_view
-
-bool LibcxxStringViewSummaryProviderUTF32(
- ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &summary_options); // libc++ std::u32string_view
-
-bool LibcxxWStringViewSummaryProvider(
- ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &options); // libc++ std::wstring_view
-
bool LibcxxStdSliceArraySummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // libc++ std::slice_array
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp
index 8fb305b284bbb..5d0f20b1beaae 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp
@@ -112,33 +112,6 @@ 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,
@@ -180,39 +153,3 @@ 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 e818b88e202ef..dab809bbe10cf 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
@@ -29,15 +29,6 @@ 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 5c915b6d9f588..8895156abb366 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
@@ -175,6 +175,11 @@ def test_libcxx(self):
self.build(dictionary={"USE_LIBCPP": 1})
self.do_test()
+ @add_test_categories(["libstdcxx"])
+ def test_libstdcxx(self):
+ self.build(dictionary={"USE_LIBSTDCPP": 1})
+ self.do_test()
+
@add_test_categories(["msvcstl"])
def test_msvcstl(self):
self.build()
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
index 6cf72d18a864f..7d0f3be8a2623 100644
--- 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
@@ -34,13 +34,11 @@ def do_test(self):
],
)
- @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})
>From a9db3ec49a1a5d6007adc48e8d06886d9794c3eb Mon Sep 17 00:00:00 2001
From: Druzhkov Sergei <serzhdruzhok at gmail.com>
Date: Thu, 11 Dec 2025 20:14:48 +0300
Subject: [PATCH 2/3] Fix review comments
---
.../Language/CPlusPlus/GenericStringView.cpp | 36 +++++++++----------
.../Plugins/Language/CPlusPlus/LibCxx.cpp | 9 +++++
.../Plugins/Language/CPlusPlus/LibCxx.h | 3 ++
.../Plugins/Language/CPlusPlus/LibStdcpp.cpp | 7 +++-
.../Plugins/Language/CPlusPlus/LibStdcpp.h | 3 ++
.../Plugins/Language/CPlusPlus/MsvcStl.cpp | 6 ++++
.../Plugins/Language/CPlusPlus/MsvcStl.h | 3 ++
7 files changed, 47 insertions(+), 20 deletions(-)
diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp
index f566ef210489b..35b574bc6ef8d 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp
@@ -8,6 +8,8 @@
#include "Generic.h"
#include "LibCxx.h"
+#include "LibStdcpp.h"
+#include "MsvcStl.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/lldb-forward.h"
@@ -29,20 +31,14 @@ enum class StlType {
std::tuple<StlType, lldb::ValueObjectSP, lldb::ValueObjectSP>
extractStringViewData(ValueObject &valobj) {
- auto data_sp = valobj.GetChildMemberWithName("_Mydata");
- if (data_sp)
- return std::make_tuple(StlType::MsvcStl, data_sp,
- valobj.GetChildMemberWithName("_Mysize"));
- data_sp = valobj.GetChildMemberWithName("_M_str");
- if (data_sp)
- return std::make_tuple(StlType::LibStdcpp, data_sp,
- valobj.GetChildMemberWithName("_M_len"));
- return std::make_tuple(
- StlType::LibCxx,
- GetChildMemberWithName(valobj,
- {ConstString("__data_"), ConstString("__data")}),
- GetChildMemberWithName(valobj,
- {ConstString("__size_"), ConstString("__size")}));
+ auto [data_sp, size_sp] = MsvcStlExtractStringViewData(valobj);
+ if (data_sp && size_sp)
+ return std::make_tuple(StlType::MsvcStl, data_sp, size_sp);
+ std::tie(data_sp, size_sp) = LibcxxExtractStringViewData(valobj);
+ if (data_sp && size_sp)
+ return std::make_tuple(StlType::LibCxx, data_sp, size_sp);
+ std::tie(data_sp, size_sp) = LibStdcppExtractStringViewData(valobj);
+ return std::make_tuple(StlType::LibStdcpp, data_sp, size_sp);
}
template <StringPrinter::StringElementType element_type>
@@ -73,14 +69,16 @@ static bool formatStringViewImpl(lldb::ValueObjectSP data_sp,
template <StringElementType element_type>
static constexpr const char *getPrefixToken() {
- if constexpr (element_type == StringElementType::ASCII)
+ switch (element_type) {
+ case StringElementType::ASCII:
return "";
- if constexpr (element_type == StringElementType::UTF8)
+ case StringElementType::UTF8:
return "u8";
- if constexpr (element_type == StringElementType::UTF16)
+ case StringElementType::UTF16:
return "u";
- if constexpr (element_type == StringElementType::UTF32)
+ case StringElementType::UTF32:
return "U";
+ }
llvm_unreachable("invalid element type");
}
@@ -108,7 +106,7 @@ template bool lldb_private::formatters::GenericStringViewSummaryProvider<
bool lldb_private::formatters::GenericWStringViewSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
auto [stl, data_sp, size_sp] = extractStringViewData(valobj);
- if (stl == StlType::LibStdcpp)
+ if (stl == StlType::MsvcStl)
return formatStringViewImpl<StringElementType::UTF32>(data_sp, size_sp,
stream, options, "L");
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index a68c9f0fdc963..96de5dbc9ac6b 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -638,6 +638,15 @@ bool lldb_private::formatters::LibcxxStringSummaryProviderUTF32(
valobj, stream, summary_options, "U");
}
+std::tuple<lldb::ValueObjectSP, lldb::ValueObjectSP>
+lldb_private::formatters::LibcxxExtractStringViewData(ValueObject &valobj) {
+ return std::make_tuple(
+ GetChildMemberWithName(valobj,
+ {ConstString("__data_"), ConstString("__data")}),
+ GetChildMemberWithName(valobj,
+ {ConstString("__size_"), ConstString("__size")}));
+}
+
static bool
LibcxxChronoTimePointSecondsSummaryProvider(ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options,
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index d1a30d176fe7a..1287e9af188c6 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -59,6 +59,9 @@ bool LibcxxWStringSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // libc++ std::wstring
+std::tuple<lldb::ValueObjectSP, lldb::ValueObjectSP>
+LibcxxExtractStringViewData(ValueObject &valobj);
+
bool LibcxxStdSliceArraySummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // libc++ std::slice_array
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
index 86f0a5ad78a9a..5da4da92ed075 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
@@ -73,7 +73,6 @@ class LibStdcppSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;
private:
-
// The lifetime of a ValueObject and all its derivative ValueObjects
// (children, clones, etc.) is managed by a ClusterManager. These
// objects are only destroyed when every shared pointer to any of them
@@ -246,6 +245,12 @@ bool lldb_private::formatters::LibStdcppStringSummaryProvider(
return true;
}
+std::tuple<lldb::ValueObjectSP, lldb::ValueObjectSP>
+lldb_private::formatters::LibStdcppExtractStringViewData(ValueObject &valobj) {
+ return std::make_tuple(valobj.GetChildMemberWithName("_M_str"),
+ valobj.GetChildMemberWithName("_M_len"));
+}
+
LibStdcppSharedPtrSyntheticFrontEnd::LibStdcppSharedPtrSyntheticFrontEnd(
lldb::ValueObjectSP valobj_sp)
: SyntheticChildrenFrontEnd(*valobj_sp) {
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
index 8d2c81f2bbcbb..741d69959f24e 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h
@@ -20,6 +20,9 @@ bool LibStdcppStringSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // libstdc++ std::string
+std::tuple<lldb::ValueObjectSP, lldb::ValueObjectSP>
+LibStdcppExtractStringViewData(ValueObject &valobj);
+
bool LibStdcppSmartPointerSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp
index 5d0f20b1beaae..a830cf373cca5 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.cpp
@@ -153,3 +153,9 @@ bool lldb_private::formatters::MsvcStlStringSummaryProvider<
return MsvcStlStringSummaryProviderImpl<StringElementType::UTF32>(
valobj, stream, summary_options, "U");
}
+
+std::tuple<lldb::ValueObjectSP, lldb::ValueObjectSP>
+lldb_private::formatters::MsvcStlExtractStringViewData(ValueObject &valobj) {
+ return std::make_tuple(valobj.GetChildMemberWithName("_Mydata"),
+ valobj.GetChildMemberWithName("_Mysize"));
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
index dab809bbe10cf..89b1867b7a38f 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h
@@ -29,6 +29,9 @@ bool MsvcStlWStringSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // VC 2015+ std::wstring
+std::tuple<lldb::ValueObjectSP, lldb::ValueObjectSP>
+MsvcStlExtractStringViewData(ValueObject &valobj);
+
// MSVC STL std::shared_ptr<> and std::weak_ptr<>
bool IsMsvcStlSmartPointer(ValueObject &valobj);
bool MsvcStlSmartPointerSummaryProvider(ValueObject &valobj, Stream &stream,
>From 824bcee1fb5fa443c72fe8ec105576c3b4e017ec Mon Sep 17 00:00:00 2001
From: Druzhkov Sergei <serzhdruzhok at gmail.com>
Date: Thu, 11 Dec 2025 20:25:36 +0300
Subject: [PATCH 3/3] Unify logic
---
.../Language/CPlusPlus/GenericStringView.cpp | 21 ++++++-------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp
index 35b574bc6ef8d..532394e038a47 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericStringView.cpp
@@ -23,22 +23,16 @@ using namespace lldb_private::formatters;
using StringElementType = StringPrinter::StringElementType;
-enum class StlType {
- LibCxx,
- LibStdcpp,
- MsvcStl,
-};
-
-std::tuple<StlType, lldb::ValueObjectSP, lldb::ValueObjectSP>
+std::tuple<lldb::ValueObjectSP, lldb::ValueObjectSP>
extractStringViewData(ValueObject &valobj) {
auto [data_sp, size_sp] = MsvcStlExtractStringViewData(valobj);
if (data_sp && size_sp)
- return std::make_tuple(StlType::MsvcStl, data_sp, size_sp);
+ return std::make_tuple(data_sp, size_sp);
std::tie(data_sp, size_sp) = LibcxxExtractStringViewData(valobj);
if (data_sp && size_sp)
- return std::make_tuple(StlType::LibCxx, data_sp, size_sp);
+ return std::make_tuple(data_sp, size_sp);
std::tie(data_sp, size_sp) = LibStdcppExtractStringViewData(valobj);
- return std::make_tuple(StlType::LibStdcpp, data_sp, size_sp);
+ return std::make_tuple(data_sp, size_sp);
}
template <StringPrinter::StringElementType element_type>
@@ -85,7 +79,7 @@ static constexpr const char *getPrefixToken() {
template <StringPrinter::StringElementType element_type>
bool lldb_private::formatters::GenericStringViewSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
- auto [_, data_sp, size_sp] = extractStringViewData(valobj);
+ auto [data_sp, size_sp] = extractStringViewData(valobj);
return formatStringViewImpl<element_type>(data_sp, size_sp, stream, options,
getPrefixToken<element_type>());
}
@@ -105,10 +99,7 @@ template bool lldb_private::formatters::GenericStringViewSummaryProvider<
bool lldb_private::formatters::GenericWStringViewSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
- auto [stl, data_sp, size_sp] = extractStringViewData(valobj);
- if (stl == StlType::MsvcStl)
- return formatStringViewImpl<StringElementType::UTF32>(data_sp, size_sp,
- stream, options, "L");
+ auto [data_sp, size_sp] = extractStringViewData(valobj);
auto wchar_t_size = GetWCharByteSize(valobj);
if (!wchar_t_size)
More information about the lldb-commits
mailing list