Skip to content

Commit 3a15ac5

Browse files
committed
[lldb][Formatter] Get element type for unordered_maps from __hash_table::value_type (llvm#144517)
llvm#143501 changes usage of `__hash_value_type` in libcxx to an empty tag type. This type will no longer have a definition in DWARF. Currently the LLDB unordered_map formatter deduces the map's `element_type` by looking at the `__cc_` member of `__hash_value_type`. But that will no longer work because we only have its forward declaration. Since what we're really after is the type that `__hash_value_type` is wrapping, we can just look at the `__hash_table::value_type` typedef. With llvm#143501 that will now point to the `std::pair` element type (which used to be what we got from `__cc_`). TBD: need to double-check this works for older layouts. Quick glance at the code makes me suspicious of cases like `unordered_map<std::pair<int, int>, int>` (cherry picked from commit 382e3fd)
1 parent d4b4877 commit 3a15ac5

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

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

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,22 @@ static bool isUnorderedMap(ConstString type_name) {
103103

104104
CompilerType lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
105105
GetElementType(CompilerType table_type) {
106-
auto element_type = table_type.GetTypedefedType().GetTypeTemplateArgument(0);
106+
auto element_type =
107+
table_type.GetDirectNestedTypeWithName("value_type").GetTypedefedType();
108+
109+
// In newer unordered_map layouts, the std::pair element type isn't wrapped
110+
// in any helper types. So return it directly.
111+
if (isStdTemplate(element_type.GetTypeName(), "pair"))
112+
return element_type;
107113

108114
// This synthetic provider is used for both unordered_(multi)map and
109-
// unordered_(multi)set. For unordered_map, the element type has an
110-
// additional type layer, an internal struct (`__hash_value_type`)
111-
// that wraps a std::pair. Peel away the internal wrapper type - whose
112-
// structure is of no value to users, to expose the std::pair. This
113-
// matches the structure returned by the std::map synthetic provider.
114-
if (isUnorderedMap(m_backend.GetTypeName())) {
115+
// unordered_(multi)set. For older unordered_map layouts, the element type has
116+
// an additional type layer, an internal struct (`__hash_value_type`) that
117+
// wraps a std::pair. Peel away the internal wrapper type - whose structure is
118+
// of no value to users, to expose the std::pair. This matches the structure
119+
// returned by the std::map synthetic provider.
120+
if (isUnorderedMap(
121+
m_backend.GetCompilerType().GetCanonicalType().GetTypeName())) {
115122
std::string name;
116123
CompilerType field_type =
117124
element_type.GetFieldAtIndex(0, name, nullptr, nullptr, nullptr);

0 commit comments

Comments
 (0)