Skip to content

Commit 4b362f1

Browse files
authored
[lldb][DataFormatter] Allow std::string formatters to match against custom allocators (llvm#156050)
This came up in llvm#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`.
1 parent d1050bf commit 4b362f1

File tree

3 files changed

+58
-33
lines changed

3 files changed

+58
-33
lines changed

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -749,31 +749,27 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
749749
lldb_private::formatters::LibcxxStringSummaryProviderASCII,
750750
"std::string summary provider",
751751
"^std::__[[:alnum:]]+::basic_string<char, "
752-
"std::__[[:alnum:]]+::char_traits<char>, "
753-
"std::__[[:alnum:]]+::allocator<char> >$",
752+
"std::__[[:alnum:]]+::char_traits<char>,.*>$",
754753
stl_summary_flags, true);
755754
AddCXXSummary(cpp_category_sp,
756755
lldb_private::formatters::LibcxxStringSummaryProviderASCII,
757756
"std::string summary provider",
758757
"^std::__[[:alnum:]]+::basic_string<unsigned char, "
759-
"std::__[[:alnum:]]+::char_traits<unsigned char>, "
760-
"std::__[[:alnum:]]+::allocator<unsigned char> >$",
758+
"std::__[[:alnum:]]+::char_traits<unsigned char>,.*>$",
761759
stl_summary_flags, true);
762760

763761
AddCXXSummary(cpp_category_sp,
764762
lldb_private::formatters::LibcxxStringSummaryProviderUTF16,
765763
"std::u16string summary provider",
766764
"^std::__[[:alnum:]]+::basic_string<char16_t, "
767-
"std::__[[:alnum:]]+::char_traits<char16_t>, "
768-
"std::__[[:alnum:]]+::allocator<char16_t> >$",
765+
"std::__[[:alnum:]]+::char_traits<char16_t>,.*>$",
769766
stl_summary_flags, true);
770767

771768
AddCXXSummary(cpp_category_sp,
772769
lldb_private::formatters::LibcxxStringSummaryProviderUTF32,
773770
"std::u32string summary provider",
774771
"^std::__[[:alnum:]]+::basic_string<char32_t, "
775-
"std::__[[:alnum:]]+::char_traits<char32_t>, "
776-
"std::__[[:alnum:]]+::allocator<char32_t> >$",
772+
"std::__[[:alnum:]]+::char_traits<char32_t>,.*>$",
777773
stl_summary_flags, true);
778774

779775
AddCXXSummary(cpp_category_sp,
@@ -784,8 +780,7 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
784780
lldb_private::formatters::LibcxxWStringSummaryProvider,
785781
"std::wstring summary provider",
786782
"^std::__[[:alnum:]]+::basic_string<wchar_t, "
787-
"std::__[[:alnum:]]+::char_traits<wchar_t>, "
788-
"std::__[[:alnum:]]+::allocator<wchar_t> >$",
783+
"std::__[[:alnum:]]+::char_traits<wchar_t>,.*>$",
789784
stl_summary_flags, true);
790785

791786
AddCXXSummary(cpp_category_sp,
@@ -1301,24 +1296,16 @@ static void RegisterStdStringSummaryProvider(
13011296

13021297
category_sp->AddTypeSummary(makeSpecifier(string_ty), summary_sp);
13031298

1304-
// std::basic_string<char>
13051299
category_sp->AddTypeSummary(
13061300
makeSpecifier(llvm::formatv("std::basic_string<{}>", char_ty).str()),
13071301
summary_sp);
1308-
// std::basic_string<char,std::char_traits<char>,std::allocator<char> >
1309-
category_sp->AddTypeSummary(
1310-
makeSpecifier(llvm::formatv("std::basic_string<{0},std::char_traits<{0}>,"
1311-
"std::allocator<{0}> >",
1312-
char_ty)
1313-
.str()),
1314-
summary_sp);
1315-
// std::basic_string<char, std::char_traits<char>, std::allocator<char> >
1302+
13161303
category_sp->AddTypeSummary(
1317-
makeSpecifier(
1318-
llvm::formatv("std::basic_string<{0}, std::char_traits<{0}>, "
1319-
"std::allocator<{0}> >",
1304+
std::make_shared<lldb_private::TypeNameSpecifierImpl>(
1305+
llvm::formatv("^std::basic_string<{0}, ?std::char_traits<{0}>,.*>$",
13201306
char_ty)
1321-
.str()),
1307+
.str(),
1308+
eFormatterMatchRegex),
13221309
summary_sp);
13231310
}
13241311

@@ -1363,20 +1350,17 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
13631350
cpp_category_sp->AddTypeSummary("std::__cxx11::string", eFormatterMatchExact,
13641351
string_summary_sp);
13651352
cpp_category_sp->AddTypeSummary(
1366-
"std::__cxx11::basic_string<char, std::char_traits<char>, "
1367-
"std::allocator<char> >",
1368-
eFormatterMatchExact, string_summary_sp);
1369-
cpp_category_sp->AddTypeSummary("std::__cxx11::basic_string<unsigned char, "
1370-
"std::char_traits<unsigned char>, "
1371-
"std::allocator<unsigned char> >",
1372-
eFormatterMatchExact, string_summary_sp);
1353+
"^std::__cxx11::basic_string<char, std::char_traits<char>,.*>$",
1354+
eFormatterMatchRegex, string_summary_sp);
1355+
cpp_category_sp->AddTypeSummary("^std::__cxx11::basic_string<unsigned char, "
1356+
"std::char_traits<unsigned char>,.*>$",
1357+
eFormatterMatchRegex, string_summary_sp);
13731358

13741359
cpp_category_sp->AddTypeSummary("std::__cxx11::wstring", eFormatterMatchExact,
13751360
string_summary_sp);
13761361
cpp_category_sp->AddTypeSummary(
1377-
"std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, "
1378-
"std::allocator<wchar_t> >",
1379-
eFormatterMatchExact, string_summary_sp);
1362+
"^std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>,.*>$",
1363+
eFormatterMatchRegex, string_summary_sp);
13801364

13811365
SyntheticChildren::Flags stl_synth_flags;
13821366
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/TestDataFormatterStdString.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ def cleanup():
8080
'(%s::string) Q = "quite a long std::strin with lots of info inside it"'
8181
% ns,
8282
"(%s::string *) null_str = nullptr" % ns,
83+
'(CustomString) custom_str = "hello!"',
84+
'(CustomWString) custom_wstr = L"hello!"',
8385
],
8486
)
8587

@@ -143,6 +145,10 @@ def do_test_multibyte(self):
143145
'(%s::u16string) u16_empty = u""' % ns,
144146
'(%s::u32string) u32_string = U"🍄🍅🍆🍌"' % ns,
145147
'(%s::u32string) u32_empty = U""' % ns,
148+
'(CustomStringU16) custom_u16 = u"ß水氶"',
149+
'(CustomStringU16) custom_u16_empty = u""',
150+
'(CustomStringU32) custom_u32 = U"🍄🍅🍆🍌"',
151+
'(CustomStringU32) custom_u32_empty = U""',
146152
],
147153
)
148154

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/string/main.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,33 @@
1+
#include <cstdlib>
12
#include <stdint.h>
23
#include <string>
34

5+
template <typename T> struct CustomAlloc {
6+
using value_type = T;
7+
using pointer = value_type *;
8+
using const_pointer = const value_type *;
9+
using size_type = std::size_t;
10+
11+
pointer allocate(size_type n) { return (T *)malloc(n * sizeof(T)); }
12+
13+
void deallocate(pointer p, size_type) {
14+
if (p)
15+
free(p);
16+
}
17+
};
18+
19+
using CustomString =
20+
std::basic_string<char, std::char_traits<char>, CustomAlloc<char>>;
21+
22+
using CustomWString =
23+
std::basic_string<wchar_t, std::char_traits<wchar_t>, CustomAlloc<wchar_t>>;
24+
25+
using CustomStringU16 = std::basic_string<char16_t, std::char_traits<char16_t>,
26+
CustomAlloc<char16_t>>;
27+
28+
using CustomStringU32 = std::basic_string<char32_t, std::char_traits<char32_t>,
29+
CustomAlloc<char32_t>>;
30+
431
size_t touch_string(std::string &in_str) {
532
return in_str.size(); // Break here to look at bad string
633
}
@@ -99,8 +126,16 @@ int main() {
99126
std::string *pq = &q;
100127
std::string *pQ = &Q;
101128

129+
CustomString custom_str("hello!");
130+
CustomWString custom_wstr(L"hello!");
131+
CustomStringU16 custom_u16(u16_string.c_str());
132+
CustomStringU16 custom_u16_empty(u"");
133+
CustomStringU32 custom_u32(u32_string.c_str());
134+
CustomStringU32 custom_u32_empty(U"");
135+
102136
S.assign(L"!!!!!"); // Set break point at this line.
103137
std::string *not_a_string = (std::string *)0x0;
104138
touch_string(*not_a_string);
139+
105140
return 0;
106141
}

0 commit comments

Comments
 (0)