diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp @@ -118,10 +118,21 @@ m_element_type = m_element_type.GetPointeeType(); m_node_type = m_element_type; m_element_type = m_element_type.GetTypeTemplateArgument(0); - std::string name; - m_element_type = - m_element_type.GetFieldAtIndex(0, name, nullptr, nullptr, nullptr); - m_element_type = m_element_type.GetTypedefedType(); + // This synthetic provider is used for both unordered_map and + // unordered_set. For unordered_map, the element type has an additional + // type layer, an internal struct (`__hash_value_type`) that wraps a + // std::pair. Peel away the internal wrapper type - whose structure is + // of no value to users, to expose the std::pair. This matches the + // structure returned by the std::map synthetic provider. + if (m_backend.GetTypeName().GetStringRef().startswith( + "unordered_map<")) { + std::string name; + CompilerType field_type = m_element_type.GetFieldAtIndex( + 0, name, nullptr, nullptr, nullptr); + CompilerType actual_type = field_type.GetTypedefedType(); + if (actual_type.GetTypeName().GetStringRef().startswith("pair<")) + m_element_type = actual_type; + } } if (!m_node_type) return nullptr; @@ -153,7 +164,7 @@ ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock( thread_and_frame_only_if_stopped); return CreateValueObjectFromData(stream.GetString(), data, exe_ctx, - val_hash.first->GetCompilerType()); + m_element_type); } bool lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd:: diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py @@ -47,12 +47,17 @@ "corrupt_map", ['%s::unordered_map' % ns, 'size=0 {}']) - self.look_for_content_and_continue( - "map", ['%s::unordered_map' % - ns, 'size=5 {', 'hello', 'world', 'this', 'is', 'me']) + must_not_contain__cc = r'(?s)^(?!.*\b__cc = )' self.look_for_content_and_continue( - "mmap", ['%s::unordered_multimap' % ns, 'size=6 {', 'first = 3', 'second = "this"', + "map", ['%s::unordered_map' % ns, + must_not_contain__cc, + 'size=5 {', 'hello', 'world', 'this', 'is', 'me']) + + self.look_for_content_and_continue( + "mmap", ['%s::unordered_multimap' % ns, + must_not_contain__cc, + 'size=6 {', 'first = 3', 'second = "this"', 'first = 2', 'second = "hello"']) self.look_for_content_and_continue(