Skip to content

Commit 7050eb8

Browse files
authored
Add a function to translate a canonical value to key. (#6222)
This is to address concerns about the `==` and hash duplication.
1 parent a486c12 commit 7050eb8

File tree

3 files changed

+30
-39
lines changed

3 files changed

+30
-39
lines changed

toolchain/base/canonical_value_store.h

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,13 @@ namespace Carbon {
2222
// `KeyT` can optionally be different from `ValueT`, and if so is used for the
2323
// argument to `Lookup`. It must be valid to use both `KeyT` and `ValueT` as
2424
// lookup types in the underlying `Set`.
25-
template <typename IdT, typename KeyT, typename ValueT = KeyT>
25+
template <typename IdT, typename KeyT, typename ValueT = KeyT,
26+
// Parentheses around the lambda to help clang-format.
27+
auto ValueToKeyFn =
28+
([](typename ValueStoreTypes<ValueT>::ConstRefType value) ->
29+
typename ValueStoreTypes<ValueT>::ConstRefType {
30+
return value;
31+
})>
2632
class CanonicalValueStore {
2733
public:
2834
using KeyType = std::remove_cvref_t<KeyT>;
@@ -75,37 +81,43 @@ class CanonicalValueStore {
7581
Set<IdT, /*SmallSize=*/0, KeyContext> set_;
7682
};
7783

78-
template <typename IdT, typename KeyT, typename ValueT>
79-
class CanonicalValueStore<IdT, KeyT, ValueT>::KeyContext
84+
template <typename IdT, typename KeyT, typename ValueT, auto ValueToKeyFn>
85+
class CanonicalValueStore<IdT, KeyT, ValueT, ValueToKeyFn>::KeyContext
8086
: public TranslatingKeyContext<KeyContext> {
8187
public:
8288
explicit KeyContext(const ValueStore<IdT, ValueType>* values)
8389
: values_(values) {}
8490

8591
// Note that it is safe to return a `const` reference here as the underlying
8692
// object's lifetime is provided by the `ValueStore`.
87-
auto TranslateKey(IdT id) const -> ConstRefType { return values_->Get(id); }
93+
auto TranslateKey(IdT id) const
94+
-> llvm::function_traits<decltype(ValueToKeyFn)>::result_t {
95+
return ValueToKeyFn(values_->Get(id));
96+
}
8897

8998
private:
9099
const ValueStore<IdT, ValueType>* values_;
91100
};
92101

93-
template <typename IdT, typename KeyT, typename ValueT>
94-
auto CanonicalValueStore<IdT, KeyT, ValueT>::Add(ValueType value) -> IdT {
102+
template <typename IdT, typename KeyT, typename ValueT, auto ValueToKeyFn>
103+
auto CanonicalValueStore<IdT, KeyT, ValueT, ValueToKeyFn>::Add(ValueType value)
104+
-> IdT {
95105
auto make_key = [&] { return IdT(values_.Add(std::move(value))); };
96-
return set_.Insert(value, make_key, KeyContext(&values_)).key();
106+
return set_.Insert(ValueToKeyFn(value), make_key, KeyContext(&values_)).key();
97107
}
98108

99-
template <typename IdT, typename KeyT, typename ValueT>
100-
auto CanonicalValueStore<IdT, KeyT, ValueT>::Lookup(KeyType key) const -> IdT {
109+
template <typename IdT, typename KeyT, typename ValueT, auto ValueToKeyFn>
110+
auto CanonicalValueStore<IdT, KeyT, ValueT, ValueToKeyFn>::Lookup(
111+
KeyType key) const -> IdT {
101112
if (auto result = set_.Lookup(key, KeyContext(&values_))) {
102113
return result.key();
103114
}
104115
return IdT::None;
105116
}
106117

107-
template <typename IdT, typename KeyT, typename ValueT>
108-
auto CanonicalValueStore<IdT, KeyT, ValueT>::Reserve(size_t size) -> void {
118+
template <typename IdT, typename KeyT, typename ValueT, auto ValueToKeyFn>
119+
auto CanonicalValueStore<IdT, KeyT, ValueT, ValueToKeyFn>::Reserve(size_t size)
120+
-> void {
109121
// Compute the resulting new insert count using the size of values -- the
110122
// set doesn't have a fast to compute current size.
111123
if (size > values_.size()) {

toolchain/sem_ir/clang_decl.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,6 @@ struct ClangDeclKey : public Printable<ClangDeclKey> {
8383
// Instances of this type are managed by a `ClangDeclStore`, which ensures that
8484
// a single `ClangDecl` exists for each `ClangDeclKey` used.
8585
struct ClangDecl : public Printable<ClangDecl> {
86-
// Comparison against ClangDeclKey, required by CanonicalValueStore.
87-
auto operator==(const ClangDeclKey& rhs) const -> bool { return key == rhs; }
88-
auto operator==(const ClangDecl& rhs) const -> bool { return key == rhs.key; }
89-
90-
// Hashing for ClangDecl. See common/hashing.h.
91-
friend auto CarbonHashValue(const ClangDecl& value, uint64_t seed)
92-
-> HashCode {
93-
return HashValue(value.key, seed);
94-
}
95-
9686
auto Print(llvm::raw_ostream& out) const -> void;
9787

9888
// The key by which this declaration can be looked up.
@@ -118,7 +108,10 @@ struct ClangDeclId : public IdBase<ClangDeclId> {
118108

119109
// Use the AST node pointer directly when doing `Lookup` to find an ID.
120110
using ClangDeclStore =
121-
CanonicalValueStore<ClangDeclId, ClangDeclKey, ClangDecl>;
111+
CanonicalValueStore<ClangDeclId, ClangDeclKey, ClangDecl,
112+
[](const ClangDecl& value) -> const ClangDeclKey& {
113+
return value.key;
114+
}>;
122115

123116
} // namespace Carbon::SemIR
124117

toolchain/sem_ir/cpp_global_var.h

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,6 @@ struct CppGlobalVar : public Printable<CppGlobalVar> {
3636
out << "{key: " << key << ", clang_decl_id: " << clang_decl_id << "}";
3737
}
3838

39-
// Comparison against `CppGlobalVarKey`, required by `CanonicalValueStore`.
40-
friend auto operator==(const CppGlobalVar& lhs, const CppGlobalVarKey& rhs)
41-
-> bool {
42-
return lhs.key == rhs;
43-
}
44-
friend auto operator==(const CppGlobalVar& lhs, const CppGlobalVar& rhs)
45-
-> bool {
46-
return lhs.key == rhs.key;
47-
}
48-
49-
// Hashing for `CppGlobalVar`. See common/hashing.h.
50-
friend auto CarbonHashValue(const CppGlobalVar& value, uint64_t seed)
51-
-> HashCode {
52-
return HashValue(value.key, seed);
53-
}
54-
5539
// The key by which this variable can be looked up.
5640
CppGlobalVarKey key;
5741

@@ -64,7 +48,9 @@ struct CppGlobalVar : public Printable<CppGlobalVar> {
6448

6549
// Use the name of a C++ global variable when doing `Lookup` to find an ID.
6650
using CppGlobalVarStore =
67-
CanonicalValueStore<CppGlobalVarId, CppGlobalVarKey, CppGlobalVar>;
51+
CanonicalValueStore<CppGlobalVarId, CppGlobalVarKey, CppGlobalVar,
52+
[](const CppGlobalVar& value)
53+
-> const CppGlobalVarKey& { return value.key; }>;
6854

6955
} // namespace Carbon::SemIR
7056

0 commit comments

Comments
 (0)