Skip to content

Commit f86827c

Browse files
committed
[lldb][DataFormatter] Unwrap reference type when formatting std::unordered_map
Desugar any potential references/typedefs before checking `isStdTemplate`. Previously, the typename might've been: ``` const std::unordered_map<...> & ``` for references. This patch gets the pointee type before grabbing the canonical type. `GetNonReferenceType` will unwrap typedefs too, so we should always end up with a non-reference before we get to `GetCanonicalType`. #145847
1 parent 7fcd2ca commit f86827c

File tree

3 files changed

+145
-2
lines changed

3 files changed

+145
-2
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,10 @@ CompilerType lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
113113
// wraps a std::pair. Peel away the internal wrapper type - whose structure is
114114
// of no value to users, to expose the std::pair. This matches the structure
115115
// returned by the std::map synthetic provider.
116-
if (isUnorderedMap(
117-
m_backend.GetCompilerType().GetCanonicalType().GetTypeName())) {
116+
if (isUnorderedMap(m_backend.GetCompilerType()
117+
.GetNonReferenceType()
118+
.GetCanonicalType()
119+
.GetTypeName())) {
118120
std::string name;
119121
CompilerType field_type =
120122
element_type.GetFieldAtIndex(0, name, nullptr, nullptr, nullptr);

lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/TestDataFormatterLibccUnorderedMap.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,131 @@ def test_iterator_formatters(self):
6464
ValueCheck(name="second", summary='"Qux"'),
6565
],
6666
)
67+
68+
lldbutil.continue_to_breakpoint(process, bkpt)
69+
70+
# Test references to std::unordered_map
71+
self.expect_var_path(
72+
"ref1",
73+
summary="size=2",
74+
type="const StringMapT &",
75+
children=[
76+
ValueCheck(
77+
name="[0]",
78+
children=[
79+
ValueCheck(name="first", summary='"Baz"'),
80+
ValueCheck(name="second", summary='"Qux"'),
81+
],
82+
),
83+
ValueCheck(
84+
name="[1]",
85+
children=[
86+
ValueCheck(name="first", summary='"Foo"'),
87+
ValueCheck(name="second", summary='"Bar"'),
88+
],
89+
),
90+
],
91+
)
92+
93+
self.expect_var_path(
94+
"ref2",
95+
summary="size=2",
96+
type="StringMapT &",
97+
children=[
98+
ValueCheck(
99+
name="[0]",
100+
children=[
101+
ValueCheck(name="first", summary='"Baz"'),
102+
ValueCheck(name="second", summary='"Qux"'),
103+
],
104+
),
105+
ValueCheck(
106+
name="[1]",
107+
children=[
108+
ValueCheck(name="first", summary='"Foo"'),
109+
ValueCheck(name="second", summary='"Bar"'),
110+
],
111+
),
112+
],
113+
)
114+
115+
self.expect_var_path(
116+
"ref3",
117+
summary="size=2",
118+
type="StringMapTRef",
119+
children=[
120+
ValueCheck(
121+
name="[0]",
122+
children=[
123+
ValueCheck(name="first", summary='"Baz"'),
124+
ValueCheck(name="second", summary='"Qux"'),
125+
],
126+
),
127+
ValueCheck(
128+
name="[1]",
129+
children=[
130+
ValueCheck(name="first", summary='"Foo"'),
131+
ValueCheck(name="second", summary='"Bar"'),
132+
],
133+
),
134+
],
135+
)
136+
137+
self.expect_var_path(
138+
"ref4",
139+
summary="size=2",
140+
type="const StringMapT &",
141+
children=[
142+
ValueCheck(
143+
name="[0]",
144+
children=[
145+
ValueCheck(name="first", summary='"Baz"'),
146+
ValueCheck(name="second", summary='"Qux"'),
147+
],
148+
),
149+
ValueCheck(
150+
name="[1]",
151+
children=[
152+
ValueCheck(name="first", summary='"Foo"'),
153+
ValueCheck(name="second", summary='"Bar"'),
154+
],
155+
),
156+
],
157+
)
158+
159+
self.expect_var_path(
160+
"ref5",
161+
summary="size=1",
162+
type="const StringMapT &&",
163+
children=[
164+
ValueCheck(
165+
name="[0]",
166+
children=[
167+
ValueCheck(name="first", summary='"Foo"'),
168+
ValueCheck(name="second", summary='"Bar"'),
169+
],
170+
),
171+
],
172+
)
173+
174+
self.expect_var_path(
175+
"ref6",
176+
summary="size=1",
177+
type="StringMapT &&",
178+
children=[
179+
ValueCheck(
180+
name="[0]",
181+
children=[
182+
ValueCheck(name="first", summary='"Baz"'),
183+
ValueCheck(name="second", summary='"Qux"'),
184+
],
185+
),
186+
],
187+
)
188+
189+
# FIXME: we're getting this wrong.
190+
self.expect_var_path(
191+
"ref7",
192+
summary="size=0",
193+
type="const StringMapT *const &",
194+
)

lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/main.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
#include <unordered_map>
44

55
using StringMapT = std::unordered_map<std::string, std::string>;
6+
using StringMapTRef = const StringMapT &;
7+
8+
void check_references(const StringMapT &ref1, StringMapT &ref2,
9+
StringMapTRef ref3, StringMapTRef &ref4,
10+
const StringMapT &&ref5, StringMapT &&ref6,
11+
const StringMapT *const &ref7) {
12+
std::printf("Break here");
13+
}
614

715
int main() {
816
StringMapT string_map;
@@ -21,7 +29,12 @@ int main() {
2129
StringMapT::const_iterator const_baz = string_map.find("Baz");
2230
auto bucket_it = string_map.begin(string_map.bucket("Baz"));
2331
auto const_bucket_it = string_map.cbegin(string_map.bucket("Baz"));
32+
2433
std::printf("Break here");
34+
35+
check_references(string_map, string_map, string_map, string_map,
36+
StringMapT{{"Foo", "Bar"}}, StringMapT{{"Baz", "Qux"}},
37+
&string_map);
2538
}
2639

2740
return 0;

0 commit comments

Comments
 (0)