[Lldb-commits] [lldb] [lldb][DataFormatters] Adjust retrieval of unordered_map element type (PR #140256)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Fri May 16 07:11:39 PDT 2025
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/140256
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
>From f1b931c5b80abb623ff98ef5e55aa662765de50e Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 16 May 2025 11:17:32 +0100
Subject: [PATCH] [lldb][DataFormatters] Adjust retrieval of unordered_map
element type
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
---
.../Language/CPlusPlus/LibCxxUnorderedMap.cpp | 23 ++++++++++---------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index aad387137ea50..642723dd91132 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -44,7 +44,7 @@ class LibcxxStdUnorderedMapSyntheticFrontEnd
private:
CompilerType GetNodeType();
- CompilerType GetElementType(CompilerType node_type);
+ CompilerType GetElementType(CompilerType table_type);
llvm::Expected<size_t> CalculateNumChildrenImpl(ValueObject &table);
CompilerType m_element_type;
@@ -98,8 +98,8 @@ static bool isUnorderedMap(ConstString type_name) {
}
CompilerType lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
- GetElementType(CompilerType node_type) {
- CompilerType element_type = node_type.GetTypeTemplateArgument(0);
+ GetElementType(CompilerType table_type) {
+ auto element_type = table_type.GetTypedefedType().GetTypeTemplateArgument(0);
// This synthetic provider is used for both unordered_(multi)map and
// unordered_(multi)set. For unordered_map, the element type has an
@@ -114,7 +114,7 @@ CompilerType lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
element_type.GetFieldAtIndex(0, name, nullptr, nullptr, nullptr);
CompilerType actual_type = field_type.GetTypedefedType();
if (isStdTemplate(actual_type.GetTypeName(), "pair"))
- element_type = actual_type;
+ return actual_type;
}
return element_type;
@@ -161,13 +161,6 @@ lldb::ValueObjectSP lldb_private::formatters::
ValueObjectSP value_sp = node_sp->GetChildMemberWithName("__value_");
ValueObjectSP hash_sp = node_sp->GetChildMemberWithName("__hash_");
if (!hash_sp || !value_sp) {
- if (!m_element_type) {
- m_node_type = GetNodeType();
- if (!m_node_type)
- return nullptr;
-
- m_element_type = GetElementType(m_node_type);
- }
node_sp = m_next_element->Cast(m_node_type.GetPointerType())
->Dereference(error);
if (!node_sp || error.Fail())
@@ -271,6 +264,14 @@ lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::Update() {
if (!table_sp)
return lldb::ChildCacheState::eRefetch;
+ m_node_type = GetNodeType();
+ if (!m_node_type)
+ return lldb::ChildCacheState::eRefetch;
+
+ m_element_type = GetElementType(table_sp->GetCompilerType());
+ if (!m_element_type)
+ return lldb::ChildCacheState::eRefetch;
+
ValueObjectSP tree_sp = GetTreePointer(*table_sp);
if (!tree_sp)
return lldb::ChildCacheState::eRefetch;
More information about the lldb-commits
mailing list