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 <michaelbuc...@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; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits