[Lldb-commits] [lldb] [lldb][DataFormatter] Allow std::string formatters to match against custom allocators (PR #156050)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Fri Aug 29 09:02:31 PDT 2025
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/156050
This came up in https://github.com/llvm/llvm-project/issues/155691.
For `std::basic_string` our formatter matching logic required the allocator template parameter to be a `std::allocator`. There is no compelling reason (that I know of) why this would be required for us to apply the existing formatter to the string. We don't check the `allocator` parameter for other STL containers either. This meant that `std::string` that used custom allocators wouldn't be formatted. This patch relaxes the regex for `basic_string`.
>From 88ec3584771c311a7785c086c6754a92876a189f Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 29 Aug 2025 16:57:35 +0100
Subject: [PATCH] [lldb][DataFormatter] Allow std::string formatters to match
against custom allocators
This came up in https://github.com/llvm/llvm-project/issues/155691.
For `std::basic_string` our formatter matching logic required the
allocator template parameter to be a `std::allocator`. There is no
compelling reason (that I know of) why this would be required for us to
apply the existing formatter to the string. We don't check the
`allocator` parameter for other STL containers either. This meant that
`std::string` that used custom allocators wouldn't be formatted. This
patch relaxes the regex for `basic_string`.
---
.../Language/CPlusPlus/CPlusPlusLanguage.cpp | 15 ++++------
.../string/TestDataFormatterStdString.py | 6 ++++
.../generic/string/main.cpp | 30 +++++++++++++++++++
3 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index b4207439f5285..ec89212ab63fc 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -849,31 +849,27 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
lldb_private::formatters::LibcxxStringSummaryProviderASCII,
"std::string summary provider",
"^std::__[[:alnum:]]+::basic_string<char, "
- "std::__[[:alnum:]]+::char_traits<char>, "
- "std::__[[:alnum:]]+::allocator<char> >$",
+ "std::__[[:alnum:]]+::char_traits<char>,.*>$",
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxStringSummaryProviderASCII,
"std::string summary provider",
"^std::__[[:alnum:]]+::basic_string<unsigned char, "
- "std::__[[:alnum:]]+::char_traits<unsigned char>, "
- "std::__[[:alnum:]]+::allocator<unsigned char> >$",
+ "std::__[[:alnum:]]+::char_traits<unsigned char>,.*>$",
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxStringSummaryProviderUTF16,
"std::u16string summary provider",
"^std::__[[:alnum:]]+::basic_string<char16_t, "
- "std::__[[:alnum:]]+::char_traits<char16_t>, "
- "std::__[[:alnum:]]+::allocator<char16_t> >$",
+ "std::__[[:alnum:]]+::char_traits<char16_t>,.*>$",
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxStringSummaryProviderUTF32,
"std::u32string summary provider",
"^std::__[[:alnum:]]+::basic_string<char32_t, "
- "std::__[[:alnum:]]+::char_traits<char32_t>, "
- "std::__[[:alnum:]]+::allocator<char32_t> >$",
+ "std::__[[:alnum:]]+::char_traits<char32_t>,.*>$",
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
@@ -884,8 +880,7 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
lldb_private::formatters::LibcxxWStringSummaryProvider,
"std::wstring summary provider",
"^std::__[[:alnum:]]+::basic_string<wchar_t, "
- "std::__[[:alnum:]]+::char_traits<wchar_t>, "
- "std::__[[:alnum:]]+::allocator<wchar_t> >$",
+ "std::__[[:alnum:]]+::char_traits<wchar_t>,.*>$",
stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py
index fec20bae997ef..6a27b5d2f0780 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py
@@ -80,6 +80,8 @@ def cleanup():
'(%s::string) Q = "quite a long std::strin with lots of info inside it"'
% ns,
"(%s::string *) null_str = nullptr" % ns,
+ '(CustomString) custom_str = "hello!"',
+ '(CustomWString) custom_wstr = L"hello!"',
],
)
@@ -143,6 +145,10 @@ def do_test_multibyte(self):
'(%s::u16string) u16_empty = u""' % ns,
'(%s::u32string) u32_string = U"🍄🍅🍆🍌"' % ns,
'(%s::u32string) u32_empty = U""' % ns,
+ '(CustomStringU16) custom_u16 = u"ß水氶"',
+ '(CustomStringU16) custom_u16_empty = u""',
+ '(CustomStringU32) custom_u32 = U"🍄🍅🍆🍌"',
+ '(CustomStringU32) custom_u32_empty = U""',
],
)
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
index f22c890861d01..55f2de131b402 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp
@@ -1,6 +1,29 @@
#include <stdint.h>
#include <string>
+template <typename T> struct CustomAlloc {
+ using value_type = T;
+ using pointer = value_type *;
+ using const_pointer = const value_type *;
+ using size_type = std::size_t;
+
+ pointer allocate(size_type) { return new T; }
+
+ void deallocate(pointer p, size_type) { delete p; }
+};
+
+using CustomString =
+ std::basic_string<char, std::char_traits<char>, CustomAlloc<char>>;
+
+using CustomWString =
+ std::basic_string<wchar_t, std::char_traits<wchar_t>, CustomAlloc<wchar_t>>;
+
+using CustomStringU16 = std::basic_string<char16_t, std::char_traits<char16_t>,
+ CustomAlloc<char16_t>>;
+
+using CustomStringU32 = std::basic_string<char32_t, std::char_traits<char32_t>,
+ CustomAlloc<char32_t>>;
+
size_t touch_string(std::string &in_str) {
return in_str.size(); // Break here to look at bad string
}
@@ -99,6 +122,13 @@ int main() {
std::string *pq = &q;
std::string *pQ = &Q;
+ CustomString custom_str("hello!");
+ CustomWString custom_wstr(L"hello!");
+ CustomStringU16 custom_u16(u16_string);
+ CustomStringU16 custom_u16_empty(u"");
+ CustomStringU32 custom_u32(u32_string);
+ CustomStringU32 custom_u32_empty(U"");
+
S.assign(L"!!!!!"); // Set break point at this line.
std::string *not_a_string = (std::string *)0x0;
touch_string(*not_a_string);
More information about the lldb-commits
mailing list