Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[lldb][DataFormatters] Adjust retrieval of unordered_map element type #140256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
Loading
from

Conversation

Michael137
Copy link
Member

A user ran into an issue where the libc++ std::unordered_mapformatter fails because it can't deduce theelement_type. That happens because the node_typeis a forwad declaration. And, in fact, dsymutil stripped the definition forstd::__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

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
@llvmbot
Copy link
Member

llvmbot commented May 16, 2025

@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)

Changes

A user ran into an issue where the libc++ std::unordered_mapformatter fails because it can't deduce theelement_type. That happens because the node_typeis a forwad declaration. And, in fact, dsymutil stripped the definition forstd::__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&lt;...&gt; 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


Full diff: https://github.com/llvm/llvm-project/pull/140256.diff

1 Files Affected:

  • (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp (+12-11)
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;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.