diff --git a/lldb/include/lldb/Core/UniqueCStringMap.h b/lldb/include/lldb/Core/UniqueCStringMap.h --- a/lldb/include/lldb/Core/UniqueCStringMap.h +++ b/lldb/include/lldb/Core/UniqueCStringMap.h @@ -165,7 +165,21 @@ // my_map.Append (UniqueCStringMap::Entry(GetName(...), GetValue(...))); // } // my_map.Sort(); - void Sort() { llvm::sort(m_map.begin(), m_map.end(), Compare()); } + void Sort() { + Sort([](const T &, const T &) { return false; }); + } + + /// Sort contents of this map using the provided comparator to break ties for + /// entries with the same string value. + template void Sort(TCompare tc) { + Compare c; + llvm::sort(m_map, [&](const Entry &lhs, const Entry &rhs) -> bool { + int result = c.ThreeWay(lhs.cstring, rhs.cstring); + if (result == 0) + return tc(lhs.value, rhs.value); + return result < 0; + }); + } // Since we are using a vector to contain our items it will always double its // memory consumption as things are added to the vector, so if you intend to @@ -205,13 +219,24 @@ return operator()(lhs, rhs.cstring); } + bool operator()(ConstString lhs, ConstString rhs) { + return ThreeWay(lhs, rhs) < 0; + } + // This is only for uniqueness, not lexicographical ordering, so we can // just compare pointers. *However*, comparing pointers from different // allocations is UB, so we need compare their integral values instead. - bool operator()(ConstString lhs, ConstString rhs) { - return uintptr_t(lhs.GetCString()) < uintptr_t(rhs.GetCString()); + int ThreeWay(ConstString lhs, ConstString rhs) { + auto lhsint = uintptr_t(lhs.GetCString()); + auto rhsint = uintptr_t(rhs.GetCString()); + if (lhsint < rhsint) + return -1; + if (lhsint > rhsint) + return 1; + return 0; } }; + collection m_map; }; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -21,7 +21,7 @@ using namespace lldb_private; void NameToDIE::Finalize() { - m_map.Sort(); + m_map.Sort(std::less()); m_map.SizeToFit(); } diff --git a/lldb/unittests/Core/UniqueCStringMapTest.cpp b/lldb/unittests/Core/UniqueCStringMapTest.cpp --- a/lldb/unittests/Core/UniqueCStringMapTest.cpp +++ b/lldb/unittests/Core/UniqueCStringMapTest.cpp @@ -51,3 +51,18 @@ EXPECT_THAT(Map.GetValues(Bar, Values), 0); EXPECT_THAT(Values, testing::IsEmpty()); } + +TEST(UniqueCStringMap, ValueCompare) { + UniqueCStringMap Map; + + ConstString Foo("foo"); + + Map.Append(Foo, 0); + Map.Append(Foo, 5); + Map.Append(Foo, -5); + + Map.Sort(std::less()); + std::vector Values; + EXPECT_THAT(Map.GetValues(Foo, Values), 3); + EXPECT_THAT(Values, testing::ElementsAre(-5, 0, 5)); +}