Skip to content

Commit fa462a6

Browse files
Michael137tru
authored andcommitted
[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`. (cherry picked from commit 4b362f1)
1 parent 12fbb34 commit fa462a6

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
@@ -790,31 +790,27 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
790790
lldb_private::formatters::LibcxxStringSummaryProviderASCII,
791791
"std::string summary provider",
792792
"^std::__[[:alnum:]]+::basic_string<char, "
793-
"std::__[[:alnum:]]+::char_traits<char>, "
794-
"std::__[[:alnum:]]+::allocator<char> >$",
793+
"std::__[[:alnum:]]+::char_traits<char>,.*>$",
795794
stl_summary_flags, true);
796795
AddCXXSummary(cpp_category_sp,
797796
lldb_private::formatters::LibcxxStringSummaryProviderASCII,
798797
"std::string summary provider",
799798
"^std::__[[:alnum:]]+::basic_string<unsigned char, "
800-
"std::__[[:alnum:]]+::char_traits<unsigned char>, "
801-
"std::__[[:alnum:]]+::allocator<unsigned char> >$",
799+
"std::__[[:alnum:]]+::char_traits<unsigned char>,.*>$",
802800
stl_summary_flags, true);
803801

804802
AddCXXSummary(cpp_category_sp,
805803
lldb_private::formatters::LibcxxStringSummaryProviderUTF16,
806804
"std::u16string summary provider",
807805
"^std::__[[:alnum:]]+::basic_string<char16_t, "
808-
"std::__[[:alnum:]]+::char_traits<char16_t>, "
809-
"std::__[[:alnum:]]+::allocator<char16_t> >$",
806+
"std::__[[:alnum:]]+::char_traits<char16_t>,.*>$",
810807
stl_summary_flags, true);
811808

812809
AddCXXSummary(cpp_category_sp,
813810
lldb_private::formatters::LibcxxStringSummaryProviderUTF32,
814811
"std::u32string summary provider",
815812
"^std::__[[:alnum:]]+::basic_string<char32_t, "
816-
"std::__[[:alnum:]]+::char_traits<char32_t>, "
817-
"std::__[[:alnum:]]+::allocator<char32_t> >$",
813+
"std::__[[:alnum:]]+::char_traits<char32_t>,.*>$",
818814
stl_summary_flags, true);
819815

820816
AddCXXSummary(cpp_category_sp,
@@ -825,8 +821,7 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
825821
lldb_private::formatters::LibcxxWStringSummaryProvider,
826822
"std::wstring summary provider",
827823
"^std::__[[:alnum:]]+::basic_string<wchar_t, "
828-
"std::__[[:alnum:]]+::char_traits<wchar_t>, "
829-
"std::__[[:alnum:]]+::allocator<wchar_t> >$",
824+
"std::__[[:alnum:]]+::char_traits<wchar_t>,.*>$",
830825
stl_summary_flags, true);
831826

832827
AddCXXSummary(cpp_category_sp,
@@ -1342,24 +1337,16 @@ static void RegisterStdStringSummaryProvider(
13421337

13431338
category_sp->AddTypeSummary(makeSpecifier(string_ty), summary_sp);
13441339

1345-
// std::basic_string<char>
13461340
category_sp->AddTypeSummary(
13471341
makeSpecifier(llvm::formatv("std::basic_string<{}>", char_ty).str()),
13481342
summary_sp);
1349-
// std::basic_string<char,std::char_traits<char>,std::allocator<char> >
1350-
category_sp->AddTypeSummary(
1351-
makeSpecifier(llvm::formatv("std::basic_string<{0},std::char_traits<{0}>,"
1352-
"std::allocator<{0}> >",
1353-
char_ty)
1354-
.str()),
1355-
summary_sp);
1356-
// std::basic_string<char, std::char_traits<char>, std::allocator<char> >
1343+
13571344
category_sp->AddTypeSummary(
1358-
makeSpecifier(
1359-
llvm::formatv("std::basic_string<{0}, std::char_traits<{0}>, "
1360-
"std::allocator<{0}> >",
1345+
std::make_shared<lldb_private::TypeNameSpecifierImpl>(
1346+
llvm::formatv("^std::basic_string<{0}, ?std::char_traits<{0}>,.*>$",
13611347
char_ty)
1362-
.str()),
1348+
.str(),
1349+
eFormatterMatchRegex),
13631350
summary_sp);
13641351
}
13651352

@@ -1382,20 +1369,17 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
13821369
cpp_category_sp->AddTypeSummary("std::__cxx11::string", eFormatterMatchExact,
13831370
string_summary_sp);
13841371
cpp_category_sp->AddTypeSummary(
1385-
"std::__cxx11::basic_string<char, std::char_traits<char>, "
1386-
"std::allocator<char> >",
1387-
eFormatterMatchExact, string_summary_sp);
1388-
cpp_category_sp->AddTypeSummary("std::__cxx11::basic_string<unsigned char, "
1389-
"std::char_traits<unsigned char>, "
1390-
"std::allocator<unsigned char> >",
1391-
eFormatterMatchExact, string_summary_sp);
1372+
"^std::__cxx11::basic_string<char, std::char_traits<char>,.*>$",
1373+
eFormatterMatchRegex, string_summary_sp);
1374+
cpp_category_sp->AddTypeSummary("^std::__cxx11::basic_string<unsigned char, "
1375+
"std::char_traits<unsigned char>,.*>$",
1376+
eFormatterMatchRegex, string_summary_sp);
13921377

13931378
cpp_category_sp->AddTypeSummary("std::__cxx11::wstring", eFormatterMatchExact,
13941379
string_summary_sp);
13951380
cpp_category_sp->AddTypeSummary(
1396-
"std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, "
1397-
"std::allocator<wchar_t> >",
1398-
eFormatterMatchExact, string_summary_sp);
1381+
"^std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>,.*>$",
1382+
eFormatterMatchRegex, string_summary_sp);
13991383

14001384
SyntheticChildren::Flags stl_synth_flags;
14011385
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)