Skip to content

Commit e59566a

Browse files
authored
[lldb][DataFormatters] Adjust retrieval of unordered_map element type (#10701)
A user ran into an issue where the libc++ std::unordered_map` formatter fails because it can't deduce the `element_type`. That happens because the `node_type` is a forwad declaration. And, in fact, dsymutil stripped the definition for `std::__1::__hash_node<...>` for a particular instantiation. While I'm still unclear whether this is a dsymutil bug, this patch works around said issue by getting the element type from the `__table_` member. Drive-by: - Set the `m_element_type` in `Update`, which is where the other members are initialized I don't have a reduced example of this unfortunately. But the crux of the issue is that `std::__1::__hash_node<...>` only has a forward declaration in the dsym. Then trying to call `GetTypeTemplateArgument` on that `CompilerType` fails. And even if the definition was present in the dsym it seems like we're stopped in a context where the CU only had a forward declaration DIE for that type and the `node_type` never ends up being completed with the definition that lives in another CU. rdar://150813798
1 parent 3307906 commit e59566a

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

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

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class LibcxxStdUnorderedMapSyntheticFrontEnd
4646

4747
private:
4848
CompilerType GetNodeType();
49-
CompilerType GetElementType(CompilerType node_type);
49+
CompilerType GetElementType(CompilerType table_type);
5050
llvm::Expected<size_t> CalculateNumChildrenImpl(ValueObject &table);
5151

5252
CompilerType m_element_type;
@@ -102,8 +102,8 @@ static bool isUnorderedMap(ConstString type_name) {
102102
}
103103

104104
CompilerType lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
105-
GetElementType(CompilerType node_type) {
106-
CompilerType element_type = node_type.GetTypeTemplateArgument(0);
105+
GetElementType(CompilerType table_type) {
106+
auto element_type = table_type.GetTypedefedType().GetTypeTemplateArgument(0);
107107

108108
// This synthetic provider is used for both unordered_(multi)map and
109109
// unordered_(multi)set. For unordered_map, the element type has an
@@ -117,7 +117,7 @@ CompilerType lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
117117
element_type.GetFieldAtIndex(0, name, nullptr, nullptr, nullptr);
118118
CompilerType actual_type = field_type.GetTypedefedType();
119119
if (isStdTemplate(actual_type.GetTypeName(), "pair"))
120-
element_type = actual_type;
120+
return actual_type;
121121
}
122122

123123
return element_type;
@@ -164,13 +164,6 @@ lldb::ValueObjectSP lldb_private::formatters::
164164
ValueObjectSP value_sp = node_sp->GetChildMemberWithName("__value_");
165165
ValueObjectSP hash_sp = node_sp->GetChildMemberWithName("__hash_");
166166
if (!hash_sp || !value_sp) {
167-
if (!m_element_type) {
168-
m_node_type = GetNodeType();
169-
if (!m_node_type)
170-
return nullptr;
171-
172-
m_element_type = GetElementType(m_node_type);
173-
}
174167
node_sp = m_next_element->Cast(m_node_type.GetPointerType())
175168
->Dereference(error);
176169
if (!node_sp || error.Fail())
@@ -274,6 +267,14 @@ lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::Update() {
274267
if (!table_sp)
275268
return lldb::ChildCacheState::eRefetch;
276269

270+
m_node_type = GetNodeType();
271+
if (!m_node_type)
272+
return lldb::ChildCacheState::eRefetch;
273+
274+
m_element_type = GetElementType(table_sp->GetCompilerType());
275+
if (!m_element_type)
276+
return lldb::ChildCacheState::eRefetch;
277+
277278
ValueObjectSP tree_sp = GetTreePointer(*table_sp);
278279
if (!tree_sp)
279280
return lldb::ChildCacheState::eRefetch;

0 commit comments

Comments
 (0)