[Lldb-commits] [PATCH] D117383: [lldb] Expose std::pair children for unordered_map

Dave Lee via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Fri Aug 12 20:29:34 PDT 2022


kastiglione updated this revision to Diff 452366.
kastiglione added a comment.

Handle GetTypeName() returning strings both with and without std:: namespace


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117383/new/

https://reviews.llvm.org/D117383

Files:
  lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
  lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py


Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py
===================================================================
--- lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py
+++ 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(
Index: lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
===================================================================
--- lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -13,10 +13,12 @@
 #include "lldb/Core/ValueObjectConstResult.h"
 #include "lldb/DataFormatters/FormattersHelpers.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/DataBufferHeap.h"
 #include "lldb/Utility/Endian.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/Stream.h"
+#include "llvm/ADT/StringRef.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -65,6 +67,21 @@
   return m_num_elements;
 }
 
+static bool isUnorderedMap(ConstString type_name) {
+  llvm::StringRef name = type_name.GetStringRef();
+  // Unlike for pair, GetTypeName() returns a name without a namespace.
+  return name.startswith("unordered_map<") ||
+         name.startswith("unordered_multimap<") ||
+         name.startswith("std::__1::unordered_map<") ||
+         name.startswith("std::__1::unordered_multimap<");
+}
+
+static bool isPair(ConstString type_name) {
+  llvm::StringRef name = type_name.GetStringRef();
+  // Unlike for unordered_map, GetTypeName() returns a name the namespace.
+  return name.startswith("std::__1::pair<") || name.startswith("pair<");
+}
+
 lldb::ValueObjectSP lldb_private::formatters::
     LibcxxStdUnorderedMapSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
   if (idx >= CalculateNumChildren())
@@ -118,10 +135,20 @@
         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_(multi)map and
+        // unordered_(multi)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 (isUnorderedMap(m_backend.GetTypeName())) {
+          std::string name;
+          CompilerType field_type = m_element_type.GetFieldAtIndex(
+              0, name, nullptr, nullptr, nullptr);
+          CompilerType actual_type = field_type.GetTypedefedType();
+          if (isPair(actual_type.GetTypeName()))
+            m_element_type = actual_type;
+        }
       }
       if (!m_node_type)
         return nullptr;
@@ -153,7 +180,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::


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D117383.452366.patch
Type: text/x-patch
Size: 4648 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20220813/2fc6da48/attachment.bin>


More information about the lldb-commits mailing list