https://github.com/Michael137 updated 
https://github.com/llvm/llvm-project/pull/145872

>From f86827c1592779537b10dafcbf8b8abba4acccf2 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Thu, 26 Jun 2025 12:06:13 +0100
Subject: [PATCH 1/2] [lldb][DataFormatter] Unwrap reference type when
 formatting std::unordered_map

Desugar any potential references/typedefs before checking
`isStdTemplate`. Previously, the typename might've been:
```
const std::unordered_map<...> &
```
for references. This patch gets the pointee type before grabbing the
canonical type. `GetNonReferenceType` will unwrap typedefs too, so we
should always end up with a non-reference before we get to
`GetCanonicalType`.

https://github.com/llvm/llvm-project/issues/145847
---
 .../Language/CPlusPlus/LibCxxUnorderedMap.cpp |   6 +-
 .../TestDataFormatterLibccUnorderedMap.py     | 128 ++++++++++++++++++
 .../libcxx/unordered_map/main.cpp             |  13 ++
 3 files changed, 145 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp 
b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index ffc33395830bb..501fd0945b82c 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -113,8 +113,10 @@ CompilerType 
lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
   // 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.GetCompilerType().GetCanonicalType().GetTypeName())) {
+  if (isUnorderedMap(m_backend.GetCompilerType()
+                         .GetNonReferenceType()
+                         .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/libcxx/unordered_map/TestDataFormatterLibccUnorderedMap.py
 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/TestDataFormatterLibccUnorderedMap.py
index c021a46a17b51..3b412996c6cb4 100644
--- 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/TestDataFormatterLibccUnorderedMap.py
+++ 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/TestDataFormatterLibccUnorderedMap.py
@@ -64,3 +64,131 @@ def test_iterator_formatters(self):
                 ValueCheck(name="second", summary='"Qux"'),
             ],
         )
+
+        lldbutil.continue_to_breakpoint(process, bkpt)
+
+        # Test references to std::unordered_map
+        self.expect_var_path(
+            "ref1",
+            summary="size=2",
+            type="const StringMapT &",
+            children=[
+                ValueCheck(
+                    name="[0]",
+                    children=[
+                        ValueCheck(name="first", summary='"Baz"'),
+                        ValueCheck(name="second", summary='"Qux"'),
+                    ],
+                ),
+                ValueCheck(
+                    name="[1]",
+                    children=[
+                        ValueCheck(name="first", summary='"Foo"'),
+                        ValueCheck(name="second", summary='"Bar"'),
+                    ],
+                ),
+            ],
+        )
+
+        self.expect_var_path(
+            "ref2",
+            summary="size=2",
+            type="StringMapT &",
+            children=[
+                ValueCheck(
+                    name="[0]",
+                    children=[
+                        ValueCheck(name="first", summary='"Baz"'),
+                        ValueCheck(name="second", summary='"Qux"'),
+                    ],
+                ),
+                ValueCheck(
+                    name="[1]",
+                    children=[
+                        ValueCheck(name="first", summary='"Foo"'),
+                        ValueCheck(name="second", summary='"Bar"'),
+                    ],
+                ),
+            ],
+        )
+
+        self.expect_var_path(
+            "ref3",
+            summary="size=2",
+            type="StringMapTRef",
+            children=[
+                ValueCheck(
+                    name="[0]",
+                    children=[
+                        ValueCheck(name="first", summary='"Baz"'),
+                        ValueCheck(name="second", summary='"Qux"'),
+                    ],
+                ),
+                ValueCheck(
+                    name="[1]",
+                    children=[
+                        ValueCheck(name="first", summary='"Foo"'),
+                        ValueCheck(name="second", summary='"Bar"'),
+                    ],
+                ),
+            ],
+        )
+
+        self.expect_var_path(
+            "ref4",
+            summary="size=2",
+            type="const StringMapT &",
+            children=[
+                ValueCheck(
+                    name="[0]",
+                    children=[
+                        ValueCheck(name="first", summary='"Baz"'),
+                        ValueCheck(name="second", summary='"Qux"'),
+                    ],
+                ),
+                ValueCheck(
+                    name="[1]",
+                    children=[
+                        ValueCheck(name="first", summary='"Foo"'),
+                        ValueCheck(name="second", summary='"Bar"'),
+                    ],
+                ),
+            ],
+        )
+
+        self.expect_var_path(
+            "ref5",
+            summary="size=1",
+            type="const StringMapT &&",
+            children=[
+                ValueCheck(
+                    name="[0]",
+                    children=[
+                        ValueCheck(name="first", summary='"Foo"'),
+                        ValueCheck(name="second", summary='"Bar"'),
+                    ],
+                ),
+            ],
+        )
+
+        self.expect_var_path(
+            "ref6",
+            summary="size=1",
+            type="StringMapT &&",
+            children=[
+                ValueCheck(
+                    name="[0]",
+                    children=[
+                        ValueCheck(name="first", summary='"Baz"'),
+                        ValueCheck(name="second", summary='"Qux"'),
+                    ],
+                ),
+            ],
+        )
+
+        # FIXME: we're getting this wrong.
+        self.expect_var_path(
+            "ref7",
+            summary="size=0",
+            type="const StringMapT *const &",
+        )
diff --git 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/main.cpp
 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/main.cpp
index adcea69629770..b3bfdfbbdd7f7 100644
--- 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/main.cpp
+++ 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/main.cpp
@@ -3,6 +3,14 @@
 #include <unordered_map>
 
 using StringMapT = std::unordered_map<std::string, std::string>;
+using StringMapTRef = const StringMapT &;
+
+void check_references(const StringMapT &ref1, StringMapT &ref2,
+                      StringMapTRef ref3, StringMapTRef &ref4,
+                      const StringMapT &&ref5, StringMapT &&ref6,
+                      const StringMapT *const &ref7) {
+  std::printf("Break here");
+}
 
 int main() {
   StringMapT string_map;
@@ -21,7 +29,12 @@ int main() {
     StringMapT::const_iterator const_baz = string_map.find("Baz");
     auto bucket_it = string_map.begin(string_map.bucket("Baz"));
     auto const_bucket_it = string_map.cbegin(string_map.bucket("Baz"));
+
     std::printf("Break here");
+
+    check_references(string_map, string_map, string_map, string_map,
+                     StringMapT{{"Foo", "Bar"}}, StringMapT{{"Baz", "Qux"}},
+                     &string_map);
   }
 
   return 0;

>From 3c23be1889009a68ab61a3842e7cb8ffca00516a Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Thu, 26 Jun 2025 13:49:06 +0100
Subject: [PATCH 2/2] fixup! add helper function in test

---
 .../TestDataFormatterLibccUnorderedMap.py     | 139 +++---------------
 .../libcxx/unordered_map/main.cpp             |  14 +-
 2 files changed, 29 insertions(+), 124 deletions(-)

diff --git 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/TestDataFormatterLibccUnorderedMap.py
 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/TestDataFormatterLibccUnorderedMap.py
index 3b412996c6cb4..2b1bd676a5b34 100644
--- 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/TestDataFormatterLibccUnorderedMap.py
+++ 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/TestDataFormatterLibccUnorderedMap.py
@@ -9,6 +9,22 @@
 
 
 class LibcxxUnorderedMapDataFormatterTestCase(TestBase):
+    def check_reference(self, var_name: str, expected_type: str):
+        self.expect_var_path(
+            var_name,
+            summary="size=1",
+            type=expected_type,
+            children=[
+                ValueCheck(
+                    name="[0]",
+                    children=[
+                        ValueCheck(name="first", summary='"Hello"'),
+                        ValueCheck(name="second", summary='"World"'),
+                    ],
+                ),
+            ],
+        )
+
     @add_test_categories(["libc++"])
     def test_iterator_formatters(self):
         """Test that std::unordered_map related structures are formatted 
correctly when printed.
@@ -68,123 +84,12 @@ def test_iterator_formatters(self):
         lldbutil.continue_to_breakpoint(process, bkpt)
 
         # Test references to std::unordered_map
-        self.expect_var_path(
-            "ref1",
-            summary="size=2",
-            type="const StringMapT &",
-            children=[
-                ValueCheck(
-                    name="[0]",
-                    children=[
-                        ValueCheck(name="first", summary='"Baz"'),
-                        ValueCheck(name="second", summary='"Qux"'),
-                    ],
-                ),
-                ValueCheck(
-                    name="[1]",
-                    children=[
-                        ValueCheck(name="first", summary='"Foo"'),
-                        ValueCheck(name="second", summary='"Bar"'),
-                    ],
-                ),
-            ],
-        )
-
-        self.expect_var_path(
-            "ref2",
-            summary="size=2",
-            type="StringMapT &",
-            children=[
-                ValueCheck(
-                    name="[0]",
-                    children=[
-                        ValueCheck(name="first", summary='"Baz"'),
-                        ValueCheck(name="second", summary='"Qux"'),
-                    ],
-                ),
-                ValueCheck(
-                    name="[1]",
-                    children=[
-                        ValueCheck(name="first", summary='"Foo"'),
-                        ValueCheck(name="second", summary='"Bar"'),
-                    ],
-                ),
-            ],
-        )
-
-        self.expect_var_path(
-            "ref3",
-            summary="size=2",
-            type="StringMapTRef",
-            children=[
-                ValueCheck(
-                    name="[0]",
-                    children=[
-                        ValueCheck(name="first", summary='"Baz"'),
-                        ValueCheck(name="second", summary='"Qux"'),
-                    ],
-                ),
-                ValueCheck(
-                    name="[1]",
-                    children=[
-                        ValueCheck(name="first", summary='"Foo"'),
-                        ValueCheck(name="second", summary='"Bar"'),
-                    ],
-                ),
-            ],
-        )
-
-        self.expect_var_path(
-            "ref4",
-            summary="size=2",
-            type="const StringMapT &",
-            children=[
-                ValueCheck(
-                    name="[0]",
-                    children=[
-                        ValueCheck(name="first", summary='"Baz"'),
-                        ValueCheck(name="second", summary='"Qux"'),
-                    ],
-                ),
-                ValueCheck(
-                    name="[1]",
-                    children=[
-                        ValueCheck(name="first", summary='"Foo"'),
-                        ValueCheck(name="second", summary='"Bar"'),
-                    ],
-                ),
-            ],
-        )
-
-        self.expect_var_path(
-            "ref5",
-            summary="size=1",
-            type="const StringMapT &&",
-            children=[
-                ValueCheck(
-                    name="[0]",
-                    children=[
-                        ValueCheck(name="first", summary='"Foo"'),
-                        ValueCheck(name="second", summary='"Bar"'),
-                    ],
-                ),
-            ],
-        )
-
-        self.expect_var_path(
-            "ref6",
-            summary="size=1",
-            type="StringMapT &&",
-            children=[
-                ValueCheck(
-                    name="[0]",
-                    children=[
-                        ValueCheck(name="first", summary='"Baz"'),
-                        ValueCheck(name="second", summary='"Qux"'),
-                    ],
-                ),
-            ],
-        )
+        self.check_reference("ref1", "const StringMapT &")
+        self.check_reference("ref2", "StringMapT &")
+        self.check_reference("ref3", "StringMapTRef")
+        self.check_reference("ref4", "const StringMapT &")
+        self.check_reference("ref5", "const StringMapT &&")
+        self.check_reference("ref6", "StringMapT &&")
 
         # FIXME: we're getting this wrong.
         self.expect_var_path(
diff --git 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/main.cpp
 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/main.cpp
index b3bfdfbbdd7f7..c581fded1ec5f 100644
--- 
a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/main.cpp
+++ 
b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unordered_map/main.cpp
@@ -5,10 +5,10 @@
 using StringMapT = std::unordered_map<std::string, std::string>;
 using StringMapTRef = const StringMapT &;
 
-void check_references(const StringMapT &ref1, StringMapT &ref2,
-                      StringMapTRef ref3, StringMapTRef &ref4,
-                      const StringMapT &&ref5, StringMapT &&ref6,
-                      const StringMapT *const &ref7) {
+static void check_references(const StringMapT &ref1, StringMapT &ref2,
+                             StringMapTRef ref3, StringMapTRef &ref4,
+                             const StringMapT &&ref5, StringMapT &&ref6,
+                             const StringMapT *const &ref7) {
   std::printf("Break here");
 }
 
@@ -32,9 +32,9 @@ int main() {
 
     std::printf("Break here");
 
-    check_references(string_map, string_map, string_map, string_map,
-                     StringMapT{{"Foo", "Bar"}}, StringMapT{{"Baz", "Qux"}},
-                     &string_map);
+    StringMapT tmp{{"Hello", "World"}};
+    check_references(tmp, tmp, tmp, tmp, StringMapT{tmp}, StringMapT{tmp},
+                     &tmp);
   }
 
   return 0;

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to