[Lldb-commits] [lldb] [lldb] Fix std::unordered_* synthetic children when typedefs are used. (PR #123125)

via lldb-commits lldb-commits at lists.llvm.org
Wed Jan 15 13:57:25 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Greg Clayton (clayborg)

<details>
<summary>Changes</summary>

There was a bug in both the GNU and libc++ library synthetic child providers when a typedef was used in the type of the variable. Previous code was looking at the top level typename to try and determine if std::unordered_ was a map or set and this failed when typedefs were being used. This patch fixes both C++ library synthetic child providers with updated tests.

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


4 Files Affected:

- (modified) lldb/examples/synthetic/gnu_libstdcpp.py (+2-10) 
- (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp (+2-1) 
- (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py (+6-6) 
- (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/main.cpp (+18-6) 


``````````diff
diff --git a/lldb/examples/synthetic/gnu_libstdcpp.py b/lldb/examples/synthetic/gnu_libstdcpp.py
index a6605a7a7eb5b3..20b9488af55977 100644
--- a/lldb/examples/synthetic/gnu_libstdcpp.py
+++ b/lldb/examples/synthetic/gnu_libstdcpp.py
@@ -61,19 +61,11 @@ class StdUnorderedMapSynthProvider:
     def __init__(self, valobj, dict):
         self.valobj = valobj
         self.count = None
-        self.kind = self.get_object_kind(valobj)
-
-    def get_object_kind(self, valobj):
-        type_name = valobj.GetTypeName()
-        return "set" if "set" in type_name else "map"
 
     def extract_type(self):
         type = self.valobj.GetType()
-        # type of std::pair<key, value> is the first template
-        # argument type of the 4th template argument to std::map and
-        # 3rd template argument for std::set. That's why
-        # we need to know kind of the object
-        template_arg_num = 4 if self.kind == "map" else 3
+        # The last template argument is the allocator type.
+        template_arg_num = type.GetNumberOfTemplateArguments() - 1
         allocator_type = type.GetTemplateArgumentType(template_arg_num)
         data_type = allocator_type.GetTemplateArgumentType(0)
         return data_type
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index bf91fc42482f3f..be520ee27af06c 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -111,7 +111,8 @@ CompilerType lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
   // 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())) {
+  if (isUnorderedMap(
+          m_backend.GetCompilerType().GetCanonicalType().GetTypeName())) {
     std::string name;
     CompilerType field_type =
         element_type.GetFieldAtIndex(0, name, nullptr, nullptr, nullptr);
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py
index 59c24bcead4a4a..c3043b489d951b 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/TestDataFormatterGenericUnordered.py
@@ -54,7 +54,7 @@ def cleanup():
         self.look_for_content_and_continue(
             "map",
             [
-                "%s::unordered_map" % ns,
+                "UnorderedMap",
                 children_are_key_value,
                 "size=5 {",
                 "hello",
@@ -68,7 +68,7 @@ def cleanup():
         self.look_for_content_and_continue(
             "mmap",
             [
-                "%s::unordered_multimap" % ns,
+                "UnorderedMultiMap",
                 children_are_key_value,
                 "size=6 {",
                 "first = 3",
@@ -81,7 +81,7 @@ def cleanup():
         self.look_for_content_and_continue(
             "iset",
             [
-                "%s::unordered_set" % ns,
+                "IntsUnorderedSet",
                 "size=5 {",
                 "\[\d\] = 5",
                 "\[\d\] = 3",
@@ -92,7 +92,7 @@ def cleanup():
         self.look_for_content_and_continue(
             "sset",
             [
-                "%s::unordered_set" % ns,
+                "StringsUnorderedSet",
                 "size=5 {",
                 '\[\d\] = "is"',
                 '\[\d\] = "world"',
@@ -103,7 +103,7 @@ def cleanup():
         self.look_for_content_and_continue(
             "imset",
             [
-                "%s::unordered_multiset" % ns,
+                "IntsUnorderedMultiSet",
                 "size=6 {",
                 "(\[\d\] = 3(\\n|.)+){3}",
                 "\[\d\] = 2",
@@ -114,7 +114,7 @@ def cleanup():
         self.look_for_content_and_continue(
             "smset",
             [
-                "%s::unordered_multiset" % ns,
+                "StringsUnorderedMultiSet",
                 "size=5 {",
                 '(\[\d\] = "is"(\\n|.)+){2}',
                 '(\[\d\] = "world"(\\n|.)+){2}',
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/main.cpp
index 00d37dcb4bd040..59a5166c505b35 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/unordered/main.cpp
@@ -18,7 +18,9 @@ int main() {
   char buffer[sizeof(std::unordered_map<int, std::string>)] = {0};
   std::unordered_map<int, std::string> &corrupt_map = *(std::unordered_map<int, std::string> *)buffer;
 
-  std::unordered_map<int, std::string> map; // Set break point at this line.
+  // Make a typedef to ensure functionality when typedefs are used.
+  typedef std::unordered_map<int, std::string> UnorderedMap;
+  UnorderedMap map; // Set break point at this line.
   map.emplace(1, "hello");
   map.emplace(2, "world");
   map.emplace(3, "this");
@@ -26,7 +28,9 @@ int main() {
   map.emplace(5, "me");
   thefoo_rw(); // Set break point at this line.
 
-  std::unordered_multimap<int, std::string> mmap;
+  // Make a typedef to ensure functionality when typedefs are used.
+  typedef std::unordered_multimap<int, std::string> UnorderedMultiMap;
+  UnorderedMultiMap mmap;
   mmap.emplace(1, "hello");
   mmap.emplace(2, "hello");
   mmap.emplace(2, "world");
@@ -35,7 +39,9 @@ int main() {
   mmap.emplace(3, "this");
   thefoo_rw(); // Set break point at this line.
 
-  std::unordered_set<int> iset;
+  // Make a typedef to ensure functionality when typedefs are used.
+  typedef std::unordered_set<int> IntsUnorderedSet;
+  IntsUnorderedSet iset;
   iset.emplace(1);
   iset.emplace(2);
   iset.emplace(3);
@@ -43,7 +49,9 @@ int main() {
   iset.emplace(5);
   thefoo_rw(); // Set break point at this line.
 
-  std::unordered_set<std::string> sset;
+  // Make a typedef to ensure functionality when typedefs are used.
+  typedef std::unordered_set<std::string> StringsUnorderedSet;
+  StringsUnorderedSet sset;
   sset.emplace("hello");
   sset.emplace("world");
   sset.emplace("this");
@@ -51,7 +59,9 @@ int main() {
   sset.emplace("me");
   thefoo_rw(); // Set break point at this line.
 
-  std::unordered_multiset<int> imset;
+  // Make a typedef to ensure functionality when typedefs are used.
+  typedef std::unordered_multiset<int> IntsUnorderedMultiSet;
+  IntsUnorderedMultiSet imset;
   imset.emplace(1);
   imset.emplace(2);
   imset.emplace(2);
@@ -60,7 +70,9 @@ int main() {
   imset.emplace(3);
   thefoo_rw(); // Set break point at this line.
 
-  std::unordered_multiset<std::string> smset;
+  // Make a typedef to ensure functionality when typedefs are used.
+  typedef std::unordered_multiset<std::string> StringsUnorderedMultiSet;
+  StringsUnorderedMultiSet smset;
   smset.emplace("hello");
   smset.emplace("world");
   smset.emplace("world");

``````````

</details>


https://github.com/llvm/llvm-project/pull/123125


More information about the lldb-commits mailing list