akyrtzi created this revision.
Herald added subscribers: ayermolo, sdasgup3, wenzhicui, wrengr, Chia-hungDuan, 
dcaballe, cota, teijeong, dexonsmith, rdzhabarov, tatianashp, msifontes, 
jurahul, Kayjukh, grosul1, Joonsoo, liufengdb, aartbik, mgester, arpith-jacob, 
antiagainst, shauheen, rriddle, mehdi_amini, hiraditya, arichardson, emaste.
Herald added a reviewer: jhenderson.
Herald added a reviewer: rriddle.
Herald added a reviewer: MaskRay.
Herald added a reviewer: rafauler.
Herald added a reviewer: Amir.
Herald added a reviewer: maksfb.
Herald added projects: lld-macho, All.
Herald added a reviewer: lld-macho.
akyrtzi requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, yota9, StephenFan, 
stephenneuendorffer, nicolasvasilache.
Herald added projects: clang, MLIR, LLVM.

Returning `std::array<uint8_t, N>` is better ergonomics for the hashing 
functions usage, instead of a `StringRef`:

- When returning `StringRef`, client code is "jumping through hoops" to do 
string manipulations instead of dealing with array of bytes directly, which is 
more natural
- Returning `std::array<uint8_t, N>` avoids the need for the hasher classes to 
keep a field just for the purpose of wrapping it and returning it as a 
`StringRef`

As part of this patch also change the `BLAKE3` class API to match 
`HashBuilder`'s generic hash API.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D123100

Files:
  bolt/lib/Core/DebugData.cpp
  clang/include/clang/Basic/Module.h
  clang/lib/Serialization/ASTWriter.cpp
  lld/ELF/Writer.cpp
  lld/MachO/SyntheticSections.cpp
  llvm/include/llvm/Support/BLAKE3.h
  llvm/include/llvm/Support/HashBuilder.h
  llvm/include/llvm/Support/MD5.h
  llvm/include/llvm/Support/SHA1.h
  llvm/include/llvm/Support/SHA256.h
  llvm/include/llvm/Support/raw_sha1_ostream.h
  llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp
  llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
  llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
  llvm/lib/ObjCopy/MachO/MachOWriter.cpp
  llvm/lib/Support/BLAKE3/README.md
  llvm/lib/Support/MD5.cpp
  llvm/lib/Support/SHA1.cpp
  llvm/lib/Support/SHA256.cpp
  llvm/unittests/Support/BLAKE3Test.cpp
  llvm/unittests/Support/HashBuilderTest.cpp
  llvm/unittests/Support/MD5Test.cpp
  llvm/unittests/Support/SHA256.cpp
  llvm/unittests/Support/raw_sha1_ostream_test.cpp
  mlir/lib/Pass/IRPrinting.cpp

STAMPS
actor(@akyrtzi) application(Differential) author(@akyrtzi) herald(H105) 
herald(H123) herald(H208) herald(H224) herald(H225) herald(H311) herald(H423) 
herald(H452) herald(H530) herald(H532) herald(H533) herald(H538) herald(H540) 
herald(H541) herald(H544) herald(H546) herald(H547) herald(H550) herald(H551) 
herald(H554) herald(H557) herald(H560) herald(H561) herald(H565) herald(H576) 
herald(H592) herald(H597) herald(H598) herald(H607) herald(H610) herald(H615) 
herald(H625) herald(H629) herald(H645) herald(H672) herald(H685) herald(H688) 
herald(H698) herald(H723) herald(H727) herald(H729) herald(H739) herald(H802) 
herald(H805) herald(H809) herald(H827) herald(H842) herald(H844) herald(H845) 
herald(H847) herald(H854) herald(H855) herald(H861) herald(H864) 
monogram(D123100) object-type(DREV) phid(PHID-DREV-ngvkfimyomxukhcmhald) 
reviewer(#lld-macho) reviewer(@Amir) reviewer(@jhenderson) reviewer(@maksfb) 
reviewer(@MaskRay) reviewer(@rafauler) reviewer(@rriddle) 
revision-repository(rG) revision-status(needs-review) subscriber(@aartbik) 
subscriber(@antiagainst) subscriber(@arichardson) subscriber(@arpith-jacob) 
subscriber(@ayermolo) subscriber(@cfe-commits) subscriber(@Chia-hungDuan) 
subscriber(@cota) subscriber(@dcaballe) subscriber(@dexonsmith) 
subscriber(@emaste) subscriber(@grosul1) subscriber(@hiraditya) 
subscriber(@Joonsoo) subscriber(@jurahul) subscriber(@Kayjukh) 
subscriber(@liufengdb) subscriber(@llvm-commits) subscriber(@mehdi_amini) 
subscriber(@mgester) subscriber(@msifontes) subscriber(@nicolasvasilache) 
subscriber(@rdzhabarov) subscriber(@rriddle) subscriber(@sdasgup3) 
subscriber(@shauheen) subscriber(@StephenFan) subscriber(@stephenneuendorffer) 
subscriber(@tatianashp) subscriber(@teijeong) subscriber(@wenzhicui) 
subscriber(@wrengr) subscriber(@yota9) tag(#all) tag(#clang) tag(#lld-macho) 
tag(#llvm) tag(#mlir) via(conduit)

Index: mlir/lib/Pass/IRPrinting.cpp
===================================================================
--- mlir/lib/Pass/IRPrinting.cpp
+++ mlir/lib/Pass/IRPrinting.cpp
@@ -66,7 +66,7 @@
         ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&data), sizeof(T)));
   }
 
-  SmallString<20> hash;
+  std::array<uint8_t, 20> hash;
 };
 
 //===----------------------------------------------------------------------===//
Index: llvm/unittests/Support/raw_sha1_ostream_test.cpp
===================================================================
--- llvm/unittests/Support/raw_sha1_ostream_test.cpp
+++ llvm/unittests/Support/raw_sha1_ostream_test.cpp
@@ -14,7 +14,7 @@
 
 using namespace llvm;
 
-static std::string toHex(StringRef Input) {
+static std::string toHex(ArrayRef<uint8_t> Input) {
   static const char *const LUT = "0123456789ABCDEF";
   size_t Length = Input.size();
 
@@ -39,7 +39,7 @@
 TEST(sha1_hash_test, Basic) {
   ArrayRef<uint8_t> Input((const uint8_t *)"Hello World!", 12);
   std::array<uint8_t, 20> Vec = SHA1::hash(Input);
-  std::string Hash = toHex({(const char *)Vec.data(), 20});
+  std::string Hash = toHex(Vec);
   ASSERT_EQ("2EF7BDE608CE5404E97D5F042F95F89F1C232871", Hash);
 }
 
Index: llvm/unittests/Support/SHA256.cpp
===================================================================
--- llvm/unittests/Support/SHA256.cpp
+++ llvm/unittests/Support/SHA256.cpp
@@ -20,7 +20,7 @@
 
 namespace {
 
-static std::string toHex(StringRef Input) {
+static std::string toHex(ArrayRef<uint8_t> Input) {
   static const char *const LUT = "0123456789abcdef";
   size_t Length = Input.size();
 
Index: llvm/unittests/Support/MD5Test.cpp
===================================================================
--- llvm/unittests/Support/MD5Test.cpp
+++ llvm/unittests/Support/MD5Test.cpp
@@ -79,10 +79,7 @@
     ReferenceHash.update("abcd");
     MD5::MD5Result ReferenceResult;
     ReferenceHash.final(ReferenceResult);
-    StringRef ExpectedResult =
-        StringRef(reinterpret_cast<char *>(ReferenceResult.Bytes.data()),
-                  ReferenceResult.Bytes.size());
-    EXPECT_EQ(Hash.result(), ExpectedResult);
+    EXPECT_EQ(Hash.result(), ReferenceResult.Bytes);
   }
 
   Hash.update("xyz");
@@ -93,10 +90,7 @@
     ReferenceHash.update("xyz");
     MD5::MD5Result ReferenceResult;
     ReferenceHash.final(ReferenceResult);
-    StringRef ExpectedResult =
-        StringRef(reinterpret_cast<char *>(ReferenceResult.Bytes.data()),
-                  ReferenceResult.Bytes.size());
-    EXPECT_EQ(Hash.final(), ExpectedResult);
+    EXPECT_EQ(Hash.final(), ReferenceResult.Bytes);
   }
 }
 } // namespace
Index: llvm/unittests/Support/HashBuilderTest.cpp
===================================================================
--- llvm/unittests/Support/HashBuilderTest.cpp
+++ llvm/unittests/Support/HashBuilderTest.cpp
@@ -44,13 +44,15 @@
                                       HasherTAndEndianness::Endianness>;
 
 template <typename HasherTAndEndianness, typename... Ts>
-static std::string hashWithBuilder(const Ts &...Args) {
-  return HashBuilder<HasherTAndEndianness>().add(Args...).final().str();
+static typename HashBuilder<HasherTAndEndianness>::template HashResultTy<>
+hashWithBuilder(const Ts &...Args) {
+  return HashBuilder<HasherTAndEndianness>().add(Args...).final();
 }
 
 template <typename HasherTAndEndianness, typename... Ts>
-static std::string hashRangeWithBuilder(const Ts &...Args) {
-  return HashBuilder<HasherTAndEndianness>().addRange(Args...).final().str();
+static typename HashBuilder<HasherTAndEndianness>::template HashResultTy<>
+hashRangeWithBuilder(const Ts &...Args) {
+  return HashBuilder<HasherTAndEndianness>().addRange(Args...).final();
 }
 
 // All the test infrastructure relies on the variadic helpers. Test them first.
@@ -102,7 +104,7 @@
     auto SwappedData = llvm::support::endian::byte_swap(Data, E);
     Hasher.update(llvm::makeArrayRef(
         reinterpret_cast<const uint8_t *>(&SwappedData), sizeof(Data)));
-    return static_cast<std::string>(Hasher.final());
+    return Hasher.final();
   };
 
   char C = 'c';
Index: llvm/unittests/Support/BLAKE3Test.cpp
===================================================================
--- llvm/unittests/Support/BLAKE3Test.cpp
+++ llvm/unittests/Support/BLAKE3Test.cpp
@@ -12,6 +12,7 @@
 
 #include "llvm/Support/BLAKE3.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/HashBuilder.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -20,7 +21,7 @@
 
 /// Tests an arbitrary set of bytes passed as \p Input.
 void TestBLAKE3Sum(ArrayRef<uint8_t> Input, StringRef Final) {
-  BLAKE3 Hash;
+  BLAKE3<> Hash;
   Hash.update(Input);
   auto hash = Hash.final();
   auto hashStr = toHex(hash);
@@ -51,7 +52,7 @@
   }
 
   std::string rep(1000, 'a');
-  BLAKE3 Hash;
+  BLAKE3<> Hash;
   for (int i = 0; i < 1000; ++i) {
     Hash.update({reinterpret_cast<const uint8_t *>(rep.data()), rep.size()});
   }
@@ -65,14 +66,22 @@
   const char *InputStr = "abc";
   ArrayRef<uint8_t> Input(reinterpret_cast<const uint8_t *>(InputStr),
                           strlen(InputStr));
-  BLAKE3 Hash;
+  BLAKE3<16> Hash;
   Hash.update(Input);
-  auto hash1 = Hash.final<16>();
-  auto hash2 = BLAKE3::hash<16>(Input);
+  auto hash1 = Hash.final();
+  auto hash2 = BLAKE3<16>::hash(Input);
   auto hashStr1 = toHex(hash1);
   auto hashStr2 = toHex(hash2);
   EXPECT_EQ(hashStr1, hashStr2);
   EXPECT_EQ(hashStr1, "6437B3AC38465133FFB63B75273A8DB5");
+
+  // Using generic HashBuilder
+  HashBuilder<BLAKE3<16>, support::endianness::native> HashBuilder;
+  HashBuilder.update(Input);
+  auto hash3 = HashBuilder.final();
+  auto hash4 = HashBuilder.result();
+  EXPECT_EQ(hashStr1, toHex(hash3));
+  EXPECT_EQ(hashStr1, toHex(hash4));
 }
 
 } // namespace
Index: llvm/lib/Support/SHA256.cpp
===================================================================
--- llvm/lib/Support/SHA256.cpp
+++ llvm/lib/Support/SHA256.cpp
@@ -243,7 +243,7 @@
   addUncounted(len);
 }
 
-StringRef SHA256::final() {
+void SHA256::final(std::array<uint32_t, HASH_LENGTH / 4> &HashResult) {
   // Pad to complete the last block
   pad();
 
@@ -261,12 +261,19 @@
                     (((InternalState.State[i]) >> 24) & 0x000000ff);
   }
 #endif
+}
 
-  // Return pointer to hash (32 characters)
-  return StringRef((char *)HashResult, HASH_LENGTH);
+std::array<uint8_t, 32> SHA256::final() {
+  union {
+    std::array<uint32_t, HASH_LENGTH / 4> HashResult;
+    std::array<uint8_t, 32> ReturnResult;
+  };
+  static_assert(sizeof(HashResult) == sizeof(ReturnResult), "");
+  final(HashResult);
+  return ReturnResult;
 }
 
-StringRef SHA256::result() {
+std::array<uint8_t, 32> SHA256::result() {
   auto StateToRestore = InternalState;
 
   auto Hash = final();
@@ -281,11 +288,7 @@
 std::array<uint8_t, 32> SHA256::hash(ArrayRef<uint8_t> Data) {
   SHA256 Hash;
   Hash.update(Data);
-  StringRef S = Hash.final();
-
-  std::array<uint8_t, 32> Arr;
-  memcpy(Arr.data(), S.data(), S.size());
-  return Arr;
+  return Hash.final();
 }
 
 } // namespace llvm
Index: llvm/lib/Support/SHA1.cpp
===================================================================
--- llvm/lib/Support/SHA1.cpp
+++ llvm/lib/Support/SHA1.cpp
@@ -263,7 +263,7 @@
   addUncounted(InternalState.ByteCount << 3);
 }
 
-StringRef SHA1::final() {
+void SHA1::final(std::array<uint32_t, HASH_LENGTH / 4> &HashResult) {
   // Pad to complete the last block
   pad();
 
@@ -281,12 +281,19 @@
                     (((InternalState.State[i]) >> 24) & 0x000000ff);
   }
 #endif
+}
 
-  // Return pointer to hash (20 characters)
-  return StringRef((char *)HashResult, HASH_LENGTH);
+std::array<uint8_t, 20> SHA1::final() {
+  union {
+    std::array<uint32_t, HASH_LENGTH / 4> HashResult;
+    std::array<uint8_t, 20> ReturnResult;
+  };
+  static_assert(sizeof(HashResult) == sizeof(ReturnResult), "");
+  final(HashResult);
+  return ReturnResult;
 }
 
-StringRef SHA1::result() {
+std::array<uint8_t, 20> SHA1::result() {
   auto StateToRestore = InternalState;
 
   auto Hash = final();
@@ -301,9 +308,5 @@
 std::array<uint8_t, 20> SHA1::hash(ArrayRef<uint8_t> Data) {
   SHA1 Hash;
   Hash.update(Data);
-  StringRef S = Hash.final();
-
-  std::array<uint8_t, 20> Arr;
-  memcpy(Arr.data(), S.data(), S.size());
-  return Arr;
+  return Hash.final();
 }
Index: llvm/lib/Support/MD5.cpp
===================================================================
--- llvm/lib/Support/MD5.cpp
+++ llvm/lib/Support/MD5.cpp
@@ -261,13 +261,13 @@
   support::endian::write32le(&Result[12], InternalState.d);
 }
 
-StringRef MD5::final() {
+std::array<uint8_t, 16> MD5::final() {
+  MD5Result Result;
   final(Result);
-  return StringRef(reinterpret_cast<char *>(Result.Bytes.data()),
-                   Result.Bytes.size());
+  return Result.Bytes;
 }
 
-StringRef MD5::result() {
+std::array<uint8_t, 16> MD5::result() {
   auto StateToRestore = InternalState;
 
   auto Hash = final();
Index: llvm/lib/Support/BLAKE3/README.md
===================================================================
--- llvm/lib/Support/BLAKE3/README.md
+++ llvm/lib/Support/BLAKE3/README.md
@@ -17,7 +17,7 @@
 
 int main() {
   // Initialize the hasher.
-  llvm::BLAKE3 hasher;
+  llvm::BLAKE3<> hasher;
 
   // Read input bytes from stdin.
   char buf[65536];
@@ -92,6 +92,7 @@
 ## The Class/Struct
 
 ```c++
+template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
 class BLAKE3 {
   // API
 private:
@@ -149,10 +150,10 @@
 using BLAKE3Result = std::array<uint8_t, NumBytes>;
 
 template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
-void BLAKE3::final(BLAKE3Result<NumBytes> &Result);
+void BLAKE3<NumBytes>::final(BLAKE3Result<NumBytes> &Result);
 
 template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
-BLAKE3Result<NumBytes> final();
+BLAKE3Result<NumBytes> BLAKE3<NumBytes>::final();
 ```
 ```c
 void llvm_blake3_hasher_finalize(
Index: llvm/lib/ObjCopy/MachO/MachOWriter.cpp
===================================================================
--- llvm/lib/ObjCopy/MachO/MachOWriter.cpp
+++ llvm/lib/ObjCopy/MachO/MachOWriter.cpp
@@ -570,7 +570,7 @@
                              static_cast<ssize_t>(CodeSignature.BlockSize)));
     SHA256 Hasher;
     Hasher.update(Block);
-    StringRef Hash = Hasher.final();
+    auto Hash = Hasher.final();
     assert(Hash.size() == CodeSignature.HashSize);
     memcpy(CurrHashWritePosition, Hash.data(), CodeSignature.HashSize);
     CurrHashReadPosition += CodeSignature.BlockSize;
Index: llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
===================================================================
--- llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
+++ llvm/lib/DebugInfo/CodeView/TypeHashing.cpp
@@ -76,5 +76,6 @@
   auto TrailingBytes = RecordData.drop_front(Off);
   S.update(TrailingBytes);
 
-  return {S.final().take_back(8)};
+  auto Hash = S.final();
+  return {ArrayRef<uint8_t>(Hash).take_back(8)};
 }
Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
===================================================================
--- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -4387,7 +4387,7 @@
     uint32_t Vals[5];
     Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&(Buffer)[BlockStartPos],
                                     Buffer.size() - BlockStartPos));
-    StringRef Hash = Hasher.result();
+    auto Hash = Hasher.result();
     for (int Pos = 0; Pos < 20; Pos += 4) {
       Vals[Pos / 4] = support::endian::read32be(Hash.data() + Pos);
     }
Index: llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp
===================================================================
--- llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp
+++ llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp
@@ -903,7 +903,7 @@
         else {
           // Recompute the hash and compare it to the one in the bitcode
           SHA1 Hasher;
-          StringRef Hash;
+          std::array<uint8_t, 20> Hash;
           Hasher.update(*CheckHash);
           {
             int BlockSize = (CurrentRecordPos / 8) - BlockEntryPos;
@@ -911,14 +911,14 @@
             Hasher.update(ArrayRef<uint8_t>(Ptr, BlockSize));
             Hash = Hasher.result();
           }
-          std::array<char, 20> RecordedHash;
+          std::array<uint8_t, 20> RecordedHash;
           int Pos = 0;
           for (auto &Val : Record) {
             assert(!(Val >> 32) && "Unexpected high bits set");
             support::endian::write32be(&RecordedHash[Pos], Val);
             Pos += 4;
           }
-          if (Hash == StringRef(RecordedHash.data(), RecordedHash.size()))
+          if (Hash == RecordedHash)
             O->OS << " (match)";
           else
             O->OS << " (!mismatch!)";
Index: llvm/include/llvm/Support/raw_sha1_ostream.h
===================================================================
--- llvm/include/llvm/Support/raw_sha1_ostream.h
+++ llvm/include/llvm/Support/raw_sha1_ostream.h
@@ -30,7 +30,7 @@
 
 public:
   /// Return the current SHA1 hash for the content of the stream
-  StringRef sha1() {
+  std::array<uint8_t, 20> sha1() {
     flush();
     return State.result();
   }
Index: llvm/include/llvm/Support/SHA256.h
===================================================================
--- llvm/include/llvm/Support/SHA256.h
+++ llvm/include/llvm/Support/SHA256.h
@@ -43,17 +43,17 @@
   /// Digest more data.
   void update(StringRef Str);
 
-  /// Return a reference to the current raw 256-bits SHA256 for the digested
+  /// Return the current raw 256-bits SHA256 for the digested
   /// data since the last call to init(). This call will add data to the
   /// internal state and as such is not suited for getting an intermediate
   /// result (see result()).
-  StringRef final();
+  std::array<uint8_t, 32> final();
 
-  /// Return a reference to the current raw 256-bits SHA256 for the digested
+  /// Return the current raw 256-bits SHA256 for the digested
   /// data since the last call to init(). This is suitable for getting the
   /// SHA256 at any time without invalidating the internal state so that more
   /// calls can be made into update.
-  StringRef result();
+  std::array<uint8_t, 32> result();
 
   /// Returns a raw 256-bit SHA256 hash for the given data.
   static std::array<uint8_t, 32> hash(ArrayRef<uint8_t> Data);
@@ -75,14 +75,13 @@
     uint8_t BufferOffset;
   } InternalState;
 
-  // Internal copy of the hash, populated and accessed on calls to result()
-  uint32_t HashResult[HASH_LENGTH / 4];
-
   // Helper
   void writebyte(uint8_t data);
   void hashBlock();
   void addUncounted(uint8_t data);
   void pad();
+
+  void final(std::array<uint32_t, HASH_LENGTH / 4> &HashResult);
 };
 
 } // namespace llvm
Index: llvm/include/llvm/Support/SHA1.h
===================================================================
--- llvm/include/llvm/Support/SHA1.h
+++ llvm/include/llvm/Support/SHA1.h
@@ -36,17 +36,17 @@
   /// Digest more data.
   void update(StringRef Str);
 
-  /// Return a reference to the current raw 160-bits SHA1 for the digested data
+  /// Return the current raw 160-bits SHA1 for the digested data
   /// since the last call to init(). This call will add data to the internal
   /// state and as such is not suited for getting an intermediate result
   /// (see result()).
-  StringRef final();
+  std::array<uint8_t, 20> final();
 
-  /// Return a reference to the current raw 160-bits SHA1 for the digested data
+  /// Return the current raw 160-bits SHA1 for the digested data
   /// since the last call to init(). This is suitable for getting the SHA1 at
   /// any time without invalidating the internal state so that more calls can be
   /// made into update.
-  StringRef result();
+  std::array<uint8_t, 20> result();
 
   /// Returns a raw 160-bit SHA1 hash for the given data.
   static std::array<uint8_t, 20> hash(ArrayRef<uint8_t> Data);
@@ -68,14 +68,13 @@
     uint8_t BufferOffset;
   } InternalState;
 
-  // Internal copy of the hash, populated and accessed on calls to result()
-  uint32_t HashResult[HASH_LENGTH / 4];
-
   // Helper
   void writebyte(uint8_t data);
   void hashBlock();
   void addUncounted(uint8_t data);
   void pad();
+
+  void final(std::array<uint32_t, HASH_LENGTH / 4> &HashResult);
 };
 
 } // end llvm namespace
Index: llvm/include/llvm/Support/MD5.h
===================================================================
--- llvm/include/llvm/Support/MD5.h
+++ llvm/include/llvm/Support/MD5.h
@@ -78,13 +78,13 @@
   /// Finishes off the hash and puts the result in result.
   void final(MD5Result &Result);
 
-  /// Finishes off the hash, and returns a reference to the 16-byte hash data.
-  StringRef final();
+  /// Finishes off the hash, and returns the 16-byte hash data.
+  std::array<uint8_t, 16> final();
 
-  /// Finishes off the hash, and returns a reference to the 16-byte hash data.
+  /// Finishes off the hash, and returns the 16-byte hash data.
   /// This is suitable for getting the MD5 at any time without invalidating the
   /// internal state, so that more calls can be made into `update`.
-  StringRef result();
+  std::array<uint8_t, 16> result();
 
   /// Translates the bytes in \p Res to a hex string that is
   /// deposited into \p Str. The result will be of length 32.
@@ -109,8 +109,6 @@
     MD5_u32plus block[16];
   } InternalState;
 
-  MD5Result Result;
-
   const uint8_t *body(ArrayRef<uint8_t> Data);
 };
 
Index: llvm/include/llvm/Support/HashBuilder.h
===================================================================
--- llvm/include/llvm/Support/HashBuilder.h
+++ llvm/include/llvm/Support/HashBuilder.h
@@ -39,6 +39,9 @@
 /// Declares the hasher member, and functions forwarding directly to the hasher.
 template <typename HasherT> class HashBuilderBase {
 public:
+  template <typename HasherT_ = HasherT>
+  using HashResultTy = decltype(std::declval<HasherT_ &>().final());
+
   HasherT &getHasher() { return Hasher; }
 
   /// Forward to `HasherT::update(ArrayRef<uint8_t>)`.
@@ -59,12 +62,12 @@
   }
 
   /// Forward to `HasherT::final()` if available.
-  template <typename HasherT_ = HasherT> StringRef final() {
+  template <typename HasherT_ = HasherT> HashResultTy<HasherT_> final() {
     return this->getHasher().final();
   }
 
   /// Forward to `HasherT::result()` if available.
-  template <typename HasherT_ = HasherT> StringRef result() {
+  template <typename HasherT_ = HasherT> HashResultTy<HasherT_> result() {
     return this->getHasher().result();
   }
 
Index: llvm/include/llvm/Support/BLAKE3.h
===================================================================
--- llvm/include/llvm/Support/BLAKE3.h
+++ llvm/include/llvm/Support/BLAKE3.h
@@ -34,8 +34,8 @@
 template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
 using BLAKE3Result = std::array<uint8_t, NumBytes>;
 
-/// A class that wrap the BLAKE3 algorithm.
-class BLAKE3 {
+/// A class that wraps the BLAKE3 algorithm.
+template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN> class BLAKE3 {
 public:
   BLAKE3() { init(); }
 
@@ -55,7 +55,6 @@
   /// Finalize the hasher and put the result in \p Result.
   /// This doesn't modify the hasher itself, and it's possible to finalize again
   /// after adding more input.
-  template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
   void final(BLAKE3Result<NumBytes> &Result) {
     llvm_blake3_hasher_finalize(&Hasher, Result.data(), Result.size());
   }
@@ -63,19 +62,25 @@
   /// Finalize the hasher and return an output of any length, given in bytes.
   /// This doesn't modify the hasher itself, and it's possible to finalize again
   /// after adding more input.
-  template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
   BLAKE3Result<NumBytes> final() {
     BLAKE3Result<NumBytes> Result;
     llvm_blake3_hasher_finalize(&Hasher, Result.data(), Result.size());
     return Result;
   }
 
+  /// Return the current output for the digested data since the last call to
+  /// init().
+  ///
+  /// Other hash functions distinguish between \p result() and \p final(), with
+  /// \p result() allowing more calls into \p update(), but there's no
+  // difference for the BLAKE3 function.
+  BLAKE3Result<NumBytes> result() { return final(); }
+
   /// Returns a BLAKE3 hash for the given data.
-  template <size_t NumBytes = LLVM_BLAKE3_OUT_LEN>
   static BLAKE3Result<NumBytes> hash(ArrayRef<uint8_t> Data) {
-    BLAKE3 Hasher;
+    BLAKE3<NumBytes> Hasher;
     Hasher.update(Data);
-    return Hasher.final<NumBytes>();
+    return Hasher.final();
   }
 
 private:
Index: lld/MachO/SyntheticSections.cpp
===================================================================
--- lld/MachO/SyntheticSections.cpp
+++ lld/MachO/SyntheticSections.cpp
@@ -1202,7 +1202,7 @@
                     std::min(codeEnd - code, static_cast<ssize_t>(blockSize)));
     SHA256 hasher;
     hasher.update(block);
-    StringRef hash = hasher.final();
+    auto hash = hasher.final();
     assert(hash.size() == hashSize);
     memcpy(hashes, hash.data(), hashSize);
     code += blockSize;
Index: lld/ELF/Writer.cpp
===================================================================
--- lld/ELF/Writer.cpp
+++ lld/ELF/Writer.cpp
@@ -2944,12 +2944,12 @@
     break;
   case BuildIdKind::Md5:
     computeHash(output, input, [&](uint8_t *dest, ArrayRef<uint8_t> arr) {
-      memcpy(dest, BLAKE3::hash<16>(arr).data(), hashSize);
+      memcpy(dest, BLAKE3<16>::hash(arr).data(), hashSize);
     });
     break;
   case BuildIdKind::Sha1:
     computeHash(output, input, [&](uint8_t *dest, ArrayRef<uint8_t> arr) {
-      memcpy(dest, BLAKE3::hash<20>(arr).data(), hashSize);
+      memcpy(dest, BLAKE3<20>::hash(arr).data(), hashSize);
     });
     break;
   case BuildIdKind::Uuid:
Index: clang/lib/Serialization/ASTWriter.cpp
===================================================================
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1118,7 +1118,7 @@
   llvm::SHA1 Hasher;
   Hasher.update(ASTBlockBytes);
   auto Hash = Hasher.result();
-  ASTFileSignature ASTBlockHash = ASTFileSignature::create(Hash);
+  ASTFileSignature ASTBlockHash = ASTFileSignature::create(std::move(Hash));
 
   // Add the remaining bytes (i.e. bytes before the unhashed control block that
   // are not part of the AST block).
@@ -1127,7 +1127,7 @@
   Hasher.update(
       AllBytes.take_back(AllBytes.bytes_end() - ASTBlockBytes.bytes_end()));
   Hash = Hasher.result();
-  ASTFileSignature Signature = ASTFileSignature::create(Hash);
+  ASTFileSignature Signature = ASTFileSignature::create(std::move(Hash));
 
   return std::make_pair(ASTBlockHash, Signature);
 }
Index: clang/include/clang/Basic/Module.h
===================================================================
--- clang/include/clang/Basic/Module.h
+++ clang/include/clang/Basic/Module.h
@@ -71,6 +71,10 @@
     return Value;
   }
 
+  static ASTFileSignature create(std::array<uint8_t, 20> Bytes) {
+    return ASTFileSignature(std::move(Bytes));
+  }
+
   static ASTFileSignature create(StringRef Bytes) {
     return create(Bytes.bytes_begin(), Bytes.bytes_end());
   }
Index: bolt/lib/Core/DebugData.cpp
===================================================================
--- bolt/lib/Core/DebugData.cpp
+++ bolt/lib/Core/DebugData.cpp
@@ -820,7 +820,8 @@
   auto hashAndAddAbbrev = [&](StringRef AbbrevData) -> bool {
     llvm::SHA1 Hasher;
     Hasher.update(AbbrevData);
-    StringRef Key = Hasher.final();
+    auto Hash = Hasher.final();
+    StringRef Key((const char *)Hash.data(), Hash.size());
     auto Iter = AbbrevDataCache.find(Key);
     if (Iter != AbbrevDataCache.end()) {
       UnitsAbbrevData[&Unit] = Iter->second.get();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to