LLVM 18.0.0git
Public Types | Public Member Functions | List of all members
llvm::HashBuilderImpl< HasherT, Endianness > Class Template Reference

Implementation of the HashBuilder interface. More...

#include "llvm/Support/HashBuilder.h"

Inheritance diagram for llvm::HashBuilderImpl< HasherT, Endianness >:
Inheritance graph
[legend]

Public Types

template<typename T >
using HasAddHashT = decltype(addHash(std::declval< HashBuilderImpl & >(), std::declval< T & >()))
 
template<typename T >
using HasByteSwapT = decltype(support::endian::byte_swap(std::declval< T & >(), support::endianness::little))
 
- Public Types inherited from llvm::HashBuilderBase< HasherT >
template<typename HasherT_ = HasherT>
using HashResultTy = decltype(std::declval< HasherT_ & >().final())
 

Public Member Functions

 HashBuilderImpl (HasherT &Hasher)
 
template<typename... ArgTypes>
 HashBuilderImpl (ArgTypes &&...Args)
 
template<typename T >
std::enable_if_t< hashbuilder_detail::IsHashableData< T >::value, HashBuilderImpl & > add (T Value)
 Implement hashing for hashable data types, e.g. integral or enum values.
 
template<typename T >
HashBuilderImpladd (ArrayRef< T > Value)
 Support hashing ArrayRef.
 
HashBuilderImpladd (StringRef Value)
 Support hashing StringRef.
 
template<typename T >
std::enable_if_t< is_detected< HasAddHashT, T >::value &&!hashbuilder_detail::IsHashableData< T >::value, HashBuilderImpl & > add (const T &Value)
 Implement hashing for user-defined structs.
 
template<typename T1 , typename T2 >
HashBuilderImpladd (const std::pair< T1, T2 > &Value)
 
template<typename... Ts>
HashBuilderImpladd (const std::tuple< Ts... > &Arg)
 
template<typename... Ts>
std::enable_if_t<(sizeof...(Ts) > 1), HashBuilderImpl & > add (const Ts &...Args)
 A convenenience variadic helper.
 
template<typename ForwardIteratorT >
HashBuilderImpladdRange (ForwardIteratorT First, ForwardIteratorT Last)
 
template<typename RangeT >
HashBuilderImpladdRange (const RangeT &Range)
 
template<typename ForwardIteratorT >
HashBuilderImpladdRangeElements (ForwardIteratorT First, ForwardIteratorT Last)
 
template<typename RangeT >
HashBuilderImpladdRangeElements (const RangeT &Range)
 
template<typename T >
std::enable_if_t< is_detected< HasByteSwapT, T >::value, HashBuilderImpl & > adjustForEndiannessAndAdd (const T &Value)
 Adjust Value for the target endianness and add it to the hash.
 
- Public Member Functions inherited from llvm::HashBuilderBase< HasherT >
HasherT & getHasher ()
 
void update (ArrayRef< uint8_t > Data)
 Forward to HasherT::update(ArrayRef<uint8_t>).
 
void update (StringRef Data)
 Forward to HasherT::update(ArrayRef<uint8_t>).
 
template<typename HasherT_ = HasherT>
HashResultTy< HasherT_ > final ()
 Forward to HasherT::final() if available.
 
template<typename HasherT_ = HasherT>
HashResultTy< HasherT_ > result ()
 Forward to HasherT::result() if available.
 

Additional Inherited Members

- Protected Member Functions inherited from llvm::HashBuilderBase< HasherT >
 HashBuilderBase (HasherT &Hasher)
 
template<typename... ArgTypes>
 HashBuilderBase (ArgTypes &&...Args)
 

Detailed Description

template<typename HasherT, support::endianness Endianness>
class llvm::HashBuilderImpl< HasherT, Endianness >

Implementation of the HashBuilder interface.

support::endianness::native is not supported. HashBuilder is expected to canonicalize support::endianness::native to one of support::endianness::big or support::endianness::little.

Definition at line 94 of file HashBuilder.h.

Member Typedef Documentation

◆ HasAddHashT

template<typename HasherT , support::endianness Endianness>
template<typename T >
using llvm::HashBuilderImpl< HasherT, Endianness >::HasAddHashT = decltype(addHash(std::declval<HashBuilderImpl &>(), std::declval<T &>()))

Definition at line 168 of file HashBuilder.h.

◆ HasByteSwapT

template<typename HasherT , support::endianness Endianness>
template<typename T >
using llvm::HashBuilderImpl< HasherT, Endianness >::HasByteSwapT = decltype(support::endian::byte_swap( std::declval<T &>(), support::endianness::little))

Definition at line 312 of file HashBuilder.h.

Constructor & Destructor Documentation

◆ HashBuilderImpl() [1/2]

template<typename HasherT , support::endianness Endianness>
llvm::HashBuilderImpl< HasherT, Endianness >::HashBuilderImpl ( HasherT &  Hasher)
inlineexplicit

Definition at line 99 of file HashBuilder.h.

◆ HashBuilderImpl() [2/2]

template<typename HasherT , support::endianness Endianness>
template<typename... ArgTypes>
llvm::HashBuilderImpl< HasherT, Endianness >::HashBuilderImpl ( ArgTypes &&...  Args)
inlineexplicit

Definition at line 102 of file HashBuilder.h.

Member Function Documentation

◆ add() [1/7]

template<typename HasherT , support::endianness Endianness>
template<typename T >
HashBuilderImpl & llvm::HashBuilderImpl< HasherT, Endianness >::add ( ArrayRef< T Value)
inline

Support hashing ArrayRef.

Value.size() is taken into account to ensure cases like

builder.add({1});
builder.add({2, 3});
assume builder

and

builder.add({1, 2});
builder.add({3});

do not collide.

Definition at line 126 of file HashBuilder.h.

References llvm::HashBuilderImpl< HasherT, Endianness >::add(), llvm::support::endian::system_endianness(), and llvm::HashBuilderBase< HasherT >::update().

◆ add() [2/7]

template<typename HasherT , support::endianness Endianness>
template<typename T1 , typename T2 >
HashBuilderImpl & llvm::HashBuilderImpl< HasherT, Endianness >::add ( const std::pair< T1, T2 > &  Value)
inline

◆ add() [3/7]

template<typename HasherT , support::endianness Endianness>
template<typename... Ts>
HashBuilderImpl & llvm::HashBuilderImpl< HasherT, Endianness >::add ( const std::tuple< Ts... > &  Arg)
inline

◆ add() [4/7]

template<typename HasherT , support::endianness Endianness>
template<typename T >
std::enable_if_t< is_detected< HasAddHashT, T >::value && !hashbuilder_detail::IsHashableData< T >::value, HashBuilderImpl & > llvm::HashBuilderImpl< HasherT, Endianness >::add ( const T Value)
inline

Implement hashing for user-defined structs.

Any user-define struct can participate in hashing via HashBuilder by providing a addHash templated function.

template <typename HasherT, support::endianness Endianness>
void addHash(HashBuilder<HasherT, Endianness> &HBuilder,
const UserDefinedStruct &Value);
Implementation of the HashBuilder interface.
Definition: HashBuilder.h:94
LLVM Value Representation.
Definition: Value.h:74

For example:

struct SimpleStruct {
char c;
int i;
};
template <typename HasherT, support::endianness Endianness>
void addHash(HashBuilderImpl<HasherT, Endianness> &HBuilder,
const SimpleStruct &Value) {
HBuilder.add(Value.c);
HBuilder.add(Value.i);
}
std::enable_if_t< hashbuilder_detail::IsHashableData< T >::value, HashBuilderImpl & > add(T Value)
Implement hashing for hashable data types, e.g. integral or enum values.
Definition: HashBuilder.h:109

To avoid endianness issues, specializations of addHash should generally rely on exising add, addRange, and addRangeElements functions. If directly using update, an implementation must correctly handle endianness.

struct __attribute__ ((packed)) StructWithFastHash {
int I;
char C;
// 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,
const StructWithFastHash &Value) {
if (Endianness == support::endian::system_endianness()) {
HBuilder.update(ArrayRef(
reinterpret_cast<const uint8_t *>(&Value), sizeof(Value)));
} else {
// Rely on existing `add` methods to handle endianness.
HBuilder.add(Value.I);
HBuilder.add(Value.C);
}
}
};
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
#define I(x, y, z)
Definition: MD5.cpp:58
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
void update(ArrayRef< uint8_t > Data)
Forward to HasherT::update(ArrayRef<uint8_t>).
Definition: HashBuilder.h:53

To avoid collisions, specialization of addHash for variable-size types must take the size into account.

For example:

struct CustomContainer {
private:
size_t Size;
int Elements[100];
public:
CustomContainer(size_t Size) : Size(Size) {
for (size_t I = 0; I != Size; ++I)
Elements[I] = I;
}
template <typename HasherT, support::endianness Endianness>
friend void addHash(HashBuilderImpl<HasherT, Endianness> &HBuilder,
const CustomContainer &Value) {
if (Endianness == support::endian::system_endianness()) {
HBuilder.update(ArrayRef(
reinterpret_cast<const uint8_t *>(&Value.Size),
sizeof(Value.Size) + Value.Size * sizeof(Value.Elements[0])));
} else {
// `addRange` will take care of encoding the size.
HBuilder.addRange(&Value.Elements[0], &Value.Elements[0] +
Value.Size);
}
}
};
uint64_t Size
HashBuilderImpl & addRange(ForwardIteratorT First, ForwardIteratorT Last)
Definition: HashBuilder.h:289

Definition at line 257 of file HashBuilder.h.

◆ add() [5/7]

template<typename HasherT , support::endianness Endianness>
template<typename... Ts>
std::enable_if_t<(sizeof...(Ts) > 1), HashBuilderImpl & > llvm::HashBuilderImpl< HasherT, Endianness >::add ( const Ts &...  Args)
inline

A convenenience variadic helper.

It simply iterates over its arguments, in order.

add(Arg1, Arg2);

is equivalent to

add(Arg1)
add(Arg2)

Definition at line 284 of file HashBuilder.h.

References llvm::HashBuilderImpl< HasherT, Endianness >::add().

◆ add() [6/7]

template<typename HasherT , support::endianness Endianness>
HashBuilderImpl & llvm::HashBuilderImpl< HasherT, Endianness >::add ( StringRef  Value)
inline

Support hashing StringRef.

Value.size() is taken into account to ensure cases like

builder.add("a");
builder.add("bc");

and

builder.add("ab");
builder.add("c");

do not collide.

Definition at line 156 of file HashBuilder.h.

References llvm::HashBuilderImpl< HasherT, Endianness >::add(), and llvm::HashBuilderBase< HasherT >::update().

◆ add() [7/7]

template<typename HasherT , support::endianness Endianness>
template<typename T >
std::enable_if_t< hashbuilder_detail::IsHashableData< T >::value, HashBuilderImpl & > llvm::HashBuilderImpl< HasherT, Endianness >::add ( T  Value)
inline

◆ addRange() [1/2]

template<typename HasherT , support::endianness Endianness>
template<typename RangeT >
HashBuilderImpl & llvm::HashBuilderImpl< HasherT, Endianness >::addRange ( const RangeT &  Range)
inline

◆ addRange() [2/2]

template<typename HasherT , support::endianness Endianness>
template<typename ForwardIteratorT >
HashBuilderImpl & llvm::HashBuilderImpl< HasherT, Endianness >::addRange ( ForwardIteratorT  First,
ForwardIteratorT  Last 
)
inline

◆ addRangeElements() [1/2]

template<typename HasherT , support::endianness Endianness>
template<typename RangeT >
HashBuilderImpl & llvm::HashBuilderImpl< HasherT, Endianness >::addRangeElements ( const RangeT &  Range)
inline

◆ addRangeElements() [2/2]

template<typename HasherT , support::endianness Endianness>
template<typename ForwardIteratorT >
HashBuilderImpl & llvm::HashBuilderImpl< HasherT, Endianness >::addRangeElements ( ForwardIteratorT  First,
ForwardIteratorT  Last 
)
inline

◆ adjustForEndiannessAndAdd()

template<typename HasherT , support::endianness Endianness>
template<typename T >
std::enable_if_t< is_detected< HasByteSwapT, T >::value, HashBuilderImpl & > llvm::HashBuilderImpl< HasherT, Endianness >::adjustForEndiannessAndAdd ( const T Value)
inline

Adjust Value for the target endianness and add it to the hash.

Definition at line 317 of file HashBuilder.h.

References llvm::support::endian::byte_swap(), and llvm::HashBuilderBase< HasherT >::update().

Referenced by llvm::HashBuilderImpl< HasherT, Endianness >::add().


The documentation for this class was generated from the following file: