https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/145872
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 >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] [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; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits