Index: include/llvm/ADT/ArrayRef.h =================================================================== --- include/llvm/ADT/ArrayRef.h +++ include/llvm/ADT/ArrayRef.h @@ -10,6 +10,7 @@ #ifndef LLVM_ADT_ARRAYREF_H #define LLVM_ADT_ARRAYREF_H +#include "llvm/ADT/Hashing.h" #include "llvm/ADT/None.h" #include "llvm/ADT/SmallVector.h" #include @@ -374,6 +375,10 @@ template struct isPodLike > { static const bool value = true; }; + + template hash_code hash_value(ArrayRef S) { + return hash_combine_range(S.begin(), S.end()); + } } #endif Index: include/llvm/ADT/DenseMapInfo.h =================================================================== --- include/llvm/ADT/DenseMapInfo.h +++ include/llvm/ADT/DenseMapInfo.h @@ -14,6 +14,7 @@ #ifndef LLVM_ADT_DENSEMAPINFO_H #define LLVM_ADT_DENSEMAPINFO_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/PointerLikeTypeTraits.h" @@ -190,6 +191,31 @@ } }; +// Provide DenseMapInfo for ArrayRefs. +template struct DenseMapInfo> { + static inline ArrayRef getEmptyKey() { + return ArrayRef(reinterpret_cast(~static_cast(0)), + size_t(0)); + } + static inline ArrayRef getTombstoneKey() { + return ArrayRef(reinterpret_cast(~static_cast(1)), + size_t(0)); + } + static unsigned getHashValue(ArrayRef Val) { + assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!"); + assert(Val.data() != getTombstoneKey().data() && + "Cannot hash the tombstone key!"); + return (unsigned)(hash_value(Val)); + } + static bool isEqual(ArrayRef LHS, ArrayRef RHS) { + if (RHS.data() == getEmptyKey().data()) + return LHS.data() == getEmptyKey().data(); + if (RHS.data() == getTombstoneKey().data()) + return LHS.data() == getTombstoneKey().data(); + return LHS == RHS; + } +}; + } // end namespace llvm #endif