Skip to content

[Support] Rename HashBuilderImpl to HashBuilder (NFC) #68173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/ObjCRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ class ObjCRuntime {
}

template <typename HasherT, llvm::support::endianness Endianness>
friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
friend void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
const ObjCRuntime &OCR) {
HBuilder.add(OCR.getKind(), OCR.getVersion());
}
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/Sanitizers.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class SanitizerMask {
llvm::hash_code hash_value() const;

template <typename HasherT, llvm::support::endianness Endianness>
friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
friend void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
const SanitizerMask &SM) {
HBuilder.addRange(&SM.maskLoToHigh[0], &SM.maskLoToHigh[kNumElem]);
}
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Lex/HeaderSearchOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ inline llvm::hash_code hash_value(const HeaderSearchOptions::Entry &E) {
}

template <typename HasherT, llvm::support::endianness Endianness>
inline void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
inline void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
const HeaderSearchOptions::Entry &E) {
HBuilder.add(E.Path, E.Group, E.IsFramework, E.IgnoreSysRoot);
}
Expand All @@ -279,7 +279,7 @@ hash_value(const HeaderSearchOptions::SystemHeaderPrefix &SHP) {
}

template <typename HasherT, llvm::support::endianness Endianness>
inline void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
inline void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
const HeaderSearchOptions::SystemHeaderPrefix &SHP) {
HBuilder.add(SHP.Prefix, SHP.IsSystemHeader);
}
Expand Down
3 changes: 1 addition & 2 deletions clang/include/clang/Serialization/ModuleFileExtension.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ class ModuleFileExtension
/// The default implementation of this function simply does nothing, so the
/// presence/absence of this extension does not distinguish module files.
using ExtensionHashBuilder =
llvm::HashBuilderImpl<llvm::MD5,
llvm::support::endian::system_endianness()>;
llvm::HashBuilder<llvm::MD5, llvm::support::endian::system_endianness()>;
virtual void hashExtension(ExtensionHashBuilder &HBuilder) const;

/// Create a new module file extension writer, which will be
Expand Down
154 changes: 73 additions & 81 deletions llvm/include/llvm/Support/HashBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,67 @@ template <typename HasherT> class HashBuilderBase {
HasherT &Hasher;
};

/// Implementation of the `HashBuilder` interface.
/// Interface to help hash various types through a hasher type.
///
/// Via provided specializations of `add`, `addRange`, and `addRangeElements`
/// functions, various types (e.g. `ArrayRef`, `StringRef`, etc.) can be hashed
/// without requiring any knowledge of hashed types from the hasher type.
///
/// The only method expected from the templated hasher type `HasherT` is:
/// * void update(ArrayRef<uint8_t> Data)
///
/// Additionally, the following methods will be forwarded to the hasher type:
/// * decltype(std::declval<HasherT &>().final()) final()
/// * decltype(std::declval<HasherT &>().result()) result()
///
/// From a user point of view, the interface provides the following:
/// * `template<typename T> add(const T &Value)`
/// The `add` function implements hashing of various types.
/// * `template <typename ItT> void addRange(ItT First, ItT Last)`
/// The `addRange` function is designed to aid hashing a range of values.
/// It explicitly adds the size of the range in the hash.
/// * `template <typename ItT> void addRangeElements(ItT First, ItT Last)`
/// The `addRangeElements` function is also designed to aid hashing a range of
/// values. In contrast to `addRange`, it **ignores** the size of the range,
/// behaving as if elements were added one at a time with `add`.
///
/// User-defined `struct` types can participate in this interface by providing
/// an `addHash` templated function. See the associated template specialization
/// for details.
///
/// This interface does not impose requirements on the hasher
/// `update(ArrayRef<uint8_t> Data)` method. We want to avoid collisions for
/// variable-size types; for example for
/// ```
/// builder.add({1});
/// builder.add({2, 3});
/// ```
/// and
/// ```
/// builder.add({1, 2});
/// builder.add({3});
/// ```
/// . Thus, specializations of `add` and `addHash` for variable-size types must
/// not assume that the hasher type considers the size as part of the hash; they
/// must explicitly add the size to the hash. See for example specializations
/// for `ArrayRef` and `StringRef`.
///
/// Additionally, since types are eventually forwarded to the hasher's
/// `void update(ArrayRef<uint8_t>)` method, endianness plays a role in the hash
/// computation (for example when computing `add((int)123)`).
/// Specifiying a non-`native` `Endianness` template parameter allows to compute
/// stable hash across platforms with different endianness.
template <typename HasherT, support::endianness Endianness>
class HashBuilderImpl : public HashBuilderBase<HasherT> {
class HashBuilder : public HashBuilderBase<HasherT> {
public:
explicit HashBuilderImpl(HasherT &Hasher)
: HashBuilderBase<HasherT>(Hasher) {}
explicit HashBuilder(HasherT &Hasher) : HashBuilderBase<HasherT>(Hasher) {}
template <typename... ArgTypes>
explicit HashBuilderImpl(ArgTypes &&...Args)
explicit HashBuilder(ArgTypes &&...Args)
: HashBuilderBase<HasherT>(Args...) {}

/// Implement hashing for hashable data types, e.g. integral or enum values.
template <typename T>
std::enable_if_t<hashbuilder_detail::IsHashableData<T>::value,
HashBuilderImpl &>
std::enable_if_t<hashbuilder_detail::IsHashableData<T>::value, HashBuilder &>
add(T Value) {
return adjustForEndiannessAndAdd(Value);
}
Expand All @@ -116,7 +163,7 @@ class HashBuilderImpl : public HashBuilderBase<HasherT> {
/// builder.add({3});
/// ```
/// do not collide.
template <typename T> HashBuilderImpl &add(ArrayRef<T> Value) {
template <typename T> HashBuilder &add(ArrayRef<T> Value) {
// As of implementation time, simply calling `addRange(Value)` would also go
// through the `update` fast path. But that would rely on the implementation
// details of `ArrayRef::begin()` and `ArrayRef::end()`. Explicitly call
Expand Down Expand Up @@ -146,7 +193,7 @@ class HashBuilderImpl : public HashBuilderBase<HasherT> {
/// builder.add("c");
/// ```
/// do not collide.
HashBuilderImpl &add(StringRef Value) {
HashBuilder &add(StringRef Value) {
// As of implementation time, simply calling `addRange(Value)` would also go
// through `update`. But that would rely on the implementation of
// `StringRef::begin()` and `StringRef::end()`. Explicitly call `update` to
Expand All @@ -159,7 +206,7 @@ class HashBuilderImpl : public HashBuilderBase<HasherT> {

template <typename T>
using HasAddHashT =
decltype(addHash(std::declval<HashBuilderImpl &>(), std::declval<T &>()));
decltype(addHash(std::declval<HashBuilder &>(), std::declval<T &>()));
/// Implement hashing for user-defined `struct`s.
///
/// Any user-define `struct` can participate in hashing via `HashBuilder` by
Expand All @@ -179,7 +226,7 @@ class HashBuilderImpl : public HashBuilderBase<HasherT> {
/// };
///
/// template <typename HasherT, support::endianness Endianness>
/// void addHash(HashBuilderImpl<HasherT, Endianness> &HBuilder,
/// void addHash(HashBuilder<HasherT, Endianness> &HBuilder,
/// const SimpleStruct &Value) {
/// HBuilder.add(Value.c);
/// HBuilder.add(Value.i);
Expand All @@ -199,7 +246,7 @@ class HashBuilderImpl : public HashBuilderBase<HasherT> {
/// // If possible, we want to hash both `I` and `C` in a single
/// // `update` call for performance concerns.
/// template <typename HasherT, support::endianness Endianness>
/// friend void addHash(HashBuilderImpl<HasherT, Endianness> &HBuilder,
/// friend void addHash(HashBuilder<HasherT, Endianness> &HBuilder,
/// const StructWithFastHash &Value) {
/// if (Endianness == support::endian::system_endianness()) {
/// HBuilder.update(ArrayRef(
Expand Down Expand Up @@ -229,7 +276,7 @@ class HashBuilderImpl : public HashBuilderBase<HasherT> {
/// Elements[I] = I;
/// }
/// template <typename HasherT, support::endianness Endianness>
/// friend void addHash(HashBuilderImpl<HasherT, Endianness> &HBuilder,
/// friend void addHash(HashBuilder<HasherT, Endianness> &HBuilder,
/// const CustomContainer &Value) {
/// if (Endianness == support::endian::system_endianness()) {
/// HBuilder.update(ArrayRef(
Expand All @@ -246,18 +293,18 @@ class HashBuilderImpl : public HashBuilderBase<HasherT> {
template <typename T>
std::enable_if_t<is_detected<HasAddHashT, T>::value &&
!hashbuilder_detail::IsHashableData<T>::value,
HashBuilderImpl &>
HashBuilder &>
add(const T &Value) {
addHash(*this, Value);
return *this;
}

template <typename T1, typename T2>
HashBuilderImpl &add(const std::pair<T1, T2> &Value) {
HashBuilder &add(const std::pair<T1, T2> &Value) {
return add(Value.first, Value.second);
}

template <typename... Ts> HashBuilderImpl &add(const std::tuple<Ts...> &Arg) {
template <typename... Ts> HashBuilder &add(const std::tuple<Ts...> &Arg) {
std::apply([this](const auto &...Args) { this->add(Args...); }, Arg);
return *this;
}
Expand All @@ -273,31 +320,29 @@ class HashBuilderImpl : public HashBuilderBase<HasherT> {
/// add(Arg2)
/// ```
template <typename... Ts>
std::enable_if_t<(sizeof...(Ts) > 1), HashBuilderImpl &>
add(const Ts &...Args) {
std::enable_if_t<(sizeof...(Ts) > 1), HashBuilder &> add(const Ts &...Args) {
return (add(Args), ...);
}

template <typename ForwardIteratorT>
HashBuilderImpl &addRange(ForwardIteratorT First, ForwardIteratorT Last) {
HashBuilder &addRange(ForwardIteratorT First, ForwardIteratorT Last) {
add(std::distance(First, Last));
return addRangeElements(First, Last);
}

template <typename RangeT> HashBuilderImpl &addRange(const RangeT &Range) {
template <typename RangeT> HashBuilder &addRange(const RangeT &Range) {
return addRange(adl_begin(Range), adl_end(Range));
}

template <typename ForwardIteratorT>
HashBuilderImpl &addRangeElements(ForwardIteratorT First,
ForwardIteratorT Last) {
HashBuilder &addRangeElements(ForwardIteratorT First, ForwardIteratorT Last) {
return addRangeElementsImpl(
First, Last,
typename std::iterator_traits<ForwardIteratorT>::iterator_category());
}

template <typename RangeT>
HashBuilderImpl &addRangeElements(const RangeT &Range) {
HashBuilder &addRangeElements(const RangeT &Range) {
return addRangeElements(adl_begin(Range), adl_end(Range));
}

Expand All @@ -306,7 +351,7 @@ class HashBuilderImpl : public HashBuilderBase<HasherT> {
std::declval<T &>(), support::endianness::little));
/// Adjust `Value` for the target endianness and add it to the hash.
template <typename T>
std::enable_if_t<is_detected<HasByteSwapT, T>::value, HashBuilderImpl &>
std::enable_if_t<is_detected<HasByteSwapT, T>::value, HashBuilder &>
adjustForEndiannessAndAdd(const T &Value) {
T SwappedValue = support::endian::byte_swap(Value, Endianness);
this->update(ArrayRef(reinterpret_cast<const uint8_t *>(&SwappedValue),
Expand All @@ -318,9 +363,9 @@ class HashBuilderImpl : public HashBuilderBase<HasherT> {
// FIXME: Once available, specialize this function for `contiguous_iterator`s,
// and use it for `ArrayRef` and `StringRef`.
template <typename ForwardIteratorT>
HashBuilderImpl &addRangeElementsImpl(ForwardIteratorT First,
ForwardIteratorT Last,
std::forward_iterator_tag) {
HashBuilder &addRangeElementsImpl(ForwardIteratorT First,
ForwardIteratorT Last,
std::forward_iterator_tag) {
for (auto It = First; It != Last; ++It)
add(*It);
return *this;
Expand All @@ -329,67 +374,14 @@ class HashBuilderImpl : public HashBuilderBase<HasherT> {
template <typename T>
std::enable_if_t<hashbuilder_detail::IsHashableData<T>::value &&
Endianness == support::endian::system_endianness(),
HashBuilderImpl &>
HashBuilder &>
addRangeElementsImpl(T *First, T *Last, std::forward_iterator_tag) {
this->update(ArrayRef(reinterpret_cast<const uint8_t *>(First),
(Last - First) * sizeof(T)));
return *this;
}
};

/// Interface to help hash various types through a hasher type.
///
/// Via provided specializations of `add`, `addRange`, and `addRangeElements`
/// functions, various types (e.g. `ArrayRef`, `StringRef`, etc.) can be hashed
/// without requiring any knowledge of hashed types from the hasher type.
///
/// The only method expected from the templated hasher type `HasherT` is:
/// * void update(ArrayRef<uint8_t> Data)
///
/// Additionally, the following methods will be forwarded to the hasher type:
/// * decltype(std::declval<HasherT &>().final()) final()
/// * decltype(std::declval<HasherT &>().result()) result()
///
/// From a user point of view, the interface provides the following:
/// * `template<typename T> add(const T &Value)`
/// The `add` function implements hashing of various types.
/// * `template <typename ItT> void addRange(ItT First, ItT Last)`
/// The `addRange` function is designed to aid hashing a range of values.
/// It explicitly adds the size of the range in the hash.
/// * `template <typename ItT> void addRangeElements(ItT First, ItT Last)`
/// The `addRangeElements` function is also designed to aid hashing a range of
/// values. In contrast to `addRange`, it **ignores** the size of the range,
/// behaving as if elements were added one at a time with `add`.
///
/// User-defined `struct` types can participate in this interface by providing
/// an `addHash` templated function. See the associated template specialization
/// for details.
///
/// This interface does not impose requirements on the hasher
/// `update(ArrayRef<uint8_t> Data)` method. We want to avoid collisions for
/// variable-size types; for example for
/// ```
/// builder.add({1});
/// builder.add({2, 3});
/// ```
/// and
/// ```
/// builder.add({1, 2});
/// builder.add({3});
/// ```
/// . Thus, specializations of `add` and `addHash` for variable-size types must
/// not assume that the hasher type considers the size as part of the hash; they
/// must explicitly add the size to the hash. See for example specializations
/// for `ArrayRef` and `StringRef`.
///
/// Additionally, since types are eventually forwarded to the hasher's
/// `void update(ArrayRef<uint8_t>)` method, endianness plays a role in the hash
/// computation (for example when computing `add((int)123)`).
/// Specifiying a non-`native` `Endianness` template parameter allows to compute
/// stable hash across platforms with different endianness.
template <class HasherT, support::endianness Endianness>
using HashBuilder = HashBuilderImpl<HasherT, Endianness>;

namespace hashbuilder_detail {
class HashCodeHasher {
public:
Expand Down
5 changes: 2 additions & 3 deletions llvm/include/llvm/Support/VersionTuple.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
#include <tuple>

namespace llvm {
template <typename HasherT, support::endianness Endianness>
class HashBuilderImpl;
template <typename HasherT, support::endianness Endianness> class HashBuilder;
class raw_ostream;
class StringRef;

Expand Down Expand Up @@ -175,7 +174,7 @@ class VersionTuple {
}

template <typename HasherT, llvm::support::endianness Endianness>
friend void addHash(HashBuilderImpl<HasherT, Endianness> &HBuilder,
friend void addHash(HashBuilder<HasherT, Endianness> &HBuilder,
const VersionTuple &VT) {
HBuilder.add(VT.Major, VT.Minor, VT.Subminor, VT.Build);
}
Expand Down
4 changes: 2 additions & 2 deletions llvm/unittests/ADT/HashingTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ struct StructWithHashBuilderSupport {
char C;
int I;
template <typename HasherT, llvm::support::endianness Endianness>
friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
friend void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
const StructWithHashBuilderSupport &Value) {
HBuilder.add(Value.C, Value.I);
}
Expand All @@ -440,7 +440,7 @@ struct StructWithHashBuilderAndHashValueSupport {
char C;
int I;
template <typename HasherT, llvm::support::endianness Endianness>
friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
friend void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
const StructWithHashBuilderAndHashValueSupport &Value) {}
friend hash_code
hash_value(const StructWithHashBuilderAndHashValueSupport &Value) {
Expand Down
8 changes: 4 additions & 4 deletions llvm/unittests/Support/HashBuilderTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ struct SimpleStruct {
};

template <typename HasherT, llvm::support::endianness Endianness>
void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
const SimpleStruct &Value) {
HBuilder.add(Value.C);
HBuilder.add(Value.I);
Expand All @@ -139,7 +139,7 @@ struct StructWithoutCopyOrMove {
StructWithoutCopyOrMove &operator=(const StructWithoutCopyOrMove &) = delete;

template <typename HasherT, llvm::support::endianness Endianness>
friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
friend void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
const StructWithoutCopyOrMove &Value) {
HBuilder.add(Value.I);
}
Expand All @@ -154,7 +154,7 @@ struct /* __attribute__((packed)) */ StructWithFastHash {
// If possible, we want to hash both `I` and `C` in a single `update`
// call for performance concerns.
template <typename HasherT, llvm::support::endianness Endianness>
friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
friend void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
const StructWithFastHash &Value) {
if (Endianness == llvm::support::endian::system_endianness()) {
HBuilder.update(llvm::ArrayRef(reinterpret_cast<const uint8_t *>(&Value),
Expand All @@ -178,7 +178,7 @@ struct CustomContainer {
Elements[I] = I;
}
template <typename HasherT, llvm::support::endianness Endianness>
friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
friend void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
const CustomContainer &Value) {
if (Endianness == llvm::support::endian::system_endianness()) {
HBuilder.update(llvm::ArrayRef(
Expand Down