TypeHashingTest.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. //===- llvm/unittest/DebugInfo/CodeView/TypeHashingTest.cpp ---------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/DebugInfo/CodeView/TypeHashing.h"
  9. #include "llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h"
  10. #include "gtest/gtest.h"
  11. using namespace llvm;
  12. using namespace llvm::codeview;
  13. static TypeIndex createPointerRecord(AppendingTypeTableBuilder &Builder,
  14. TypeIndex TI) {
  15. PointerRecord PR(TypeRecordKind::Pointer);
  16. PR.setAttrs(PointerKind::Near32, PointerMode::Pointer, PointerOptions::None,
  17. 4);
  18. PR.ReferentType = TI;
  19. return Builder.writeLeafType(PR);
  20. }
  21. static TypeIndex createArgListRecord(AppendingTypeTableBuilder &Builder,
  22. TypeIndex Q, TypeIndex R) {
  23. ArgListRecord AR(TypeRecordKind::ArgList);
  24. AR.ArgIndices.push_back(Q);
  25. AR.ArgIndices.push_back(R);
  26. return Builder.writeLeafType(AR);
  27. }
  28. static TypeIndex createProcedureRecord(AppendingTypeTableBuilder &Builder,
  29. uint32_t ParamCount, TypeIndex Return,
  30. TypeIndex ArgList) {
  31. ProcedureRecord PR(TypeRecordKind::Procedure);
  32. PR.ArgumentList = ArgList;
  33. PR.CallConv = CallingConvention::NearC;
  34. PR.Options = FunctionOptions::None;
  35. PR.ParameterCount = ParamCount;
  36. PR.ReturnType = Return;
  37. return Builder.writeLeafType(PR);
  38. }
  39. static ArrayRef<uint8_t> hash_of(ArrayRef<GloballyHashedType> Hashes,
  40. TypeIndex TI) {
  41. return Hashes[TI.toArrayIndex()].Hash;
  42. }
  43. static void verifyHashUniqueness(ArrayRef<GloballyHashedType> Hashes) {
  44. assert(!Hashes.empty());
  45. for (size_t I = 0; I < Hashes.size() - 1; ++I) {
  46. for (size_t J = I + 1; J < Hashes.size(); ++J) {
  47. EXPECT_NE(Hashes[I].Hash, Hashes[J].Hash);
  48. }
  49. }
  50. }
  51. TEST(TypeHashingTest, ContentHash) {
  52. SimpleTypeSerializer Serializer;
  53. TypeIndex CharStar(SimpleTypeKind::SignedCharacter,
  54. SimpleTypeMode::NearPointer32);
  55. BumpPtrAllocator Alloc;
  56. AppendingTypeTableBuilder Ordering1(Alloc);
  57. AppendingTypeTableBuilder Ordering2(Alloc);
  58. TypeIndex CharP(SimpleTypeKind::SignedCharacter, SimpleTypeMode::NearPointer);
  59. TypeIndex IntP(SimpleTypeKind::Int32, SimpleTypeMode::NearPointer);
  60. TypeIndex DoubleP(SimpleTypeKind::Float64, SimpleTypeMode::NearPointer);
  61. // We're going to the same type sequence with two different orderings, and
  62. // then confirm all records are hashed the same.
  63. TypeIndex CharPP[2];
  64. TypeIndex IntPP[2];
  65. TypeIndex IntPPP[2];
  66. TypeIndex DoublePP[2];
  67. TypeIndex Args[2];
  68. TypeIndex Proc[2];
  69. // Ordering 1
  70. // ----------------------------------------
  71. // LF_POINTER 0x1000 {char**}
  72. // Referent = char*
  73. // LF_POINTER 0x1001 {int**}
  74. // Referent = int*
  75. // LF_POINTER 0x1002 {int***}
  76. // Referent = 0x1001
  77. // LF_ARGLIST 0x1003 {(char**, int***)}
  78. // Arg[0] = 0x1000
  79. // Arg[1] = 0x1002
  80. // LF_PROCEDURE 0x1004 {int** func(char**, int***)}
  81. // ArgList = 0x1003
  82. // ReturnType = 0x1001
  83. std::vector<GloballyHashedType> Ordering1Hashes;
  84. CharPP[0] = createPointerRecord(Ordering1, CharP);
  85. IntPP[0] = createPointerRecord(Ordering1, IntP);
  86. IntPPP[0] = createPointerRecord(Ordering1, IntPP[0]);
  87. Args[0] = createArgListRecord(Ordering1, CharPP[0], IntPPP[0]);
  88. Proc[0] = createProcedureRecord(Ordering1, 2, IntPP[0], Args[0]);
  89. ASSERT_EQ(0x1000U, CharPP[0].getIndex());
  90. ASSERT_EQ(0x1001U, IntPP[0].getIndex());
  91. ASSERT_EQ(0x1002U, IntPPP[0].getIndex());
  92. ASSERT_EQ(0x1003U, Args[0].getIndex());
  93. ASSERT_EQ(0x1004U, Proc[0].getIndex());
  94. auto Hashes1 = GloballyHashedType::hashTypes(Ordering1.records());
  95. // Ordering 2
  96. // ----------------------------------------
  97. // LF_POINTER 0x1000 {int**}
  98. // Referent = int*
  99. // LF_POINTER 0x1001 {int***}
  100. // Referent = 0x1000
  101. // LF_POINTER 0x1002 {char**}
  102. // Referent = char*
  103. // LF_POINTER 0x1003 {double**}
  104. // Referent = double*
  105. // LF_ARGLIST 0x1004 {(char**, int***)}
  106. // Arg[0] = 0x1002
  107. // Arg[1] = 0x1001
  108. // LF_PROCEDURE 0x1005 {int** func(char**, int***)}
  109. // ArgList = 0x1004
  110. // ReturnType = 0x1000
  111. IntPP[1] = createPointerRecord(Ordering2, IntP);
  112. IntPPP[1] = createPointerRecord(Ordering2, IntPP[1]);
  113. CharPP[1] = createPointerRecord(Ordering2, CharP);
  114. DoublePP[1] = createPointerRecord(Ordering2, DoubleP);
  115. Args[1] = createArgListRecord(Ordering2, CharPP[1], IntPPP[1]);
  116. Proc[1] = createProcedureRecord(Ordering2, 2, IntPP[1], Args[1]);
  117. auto Hashes2 = GloballyHashedType::hashTypes(Ordering2.records());
  118. ASSERT_EQ(0x1000U, IntPP[1].getIndex());
  119. ASSERT_EQ(0x1001U, IntPPP[1].getIndex());
  120. ASSERT_EQ(0x1002U, CharPP[1].getIndex());
  121. ASSERT_EQ(0x1003U, DoublePP[1].getIndex());
  122. ASSERT_EQ(0x1004U, Args[1].getIndex());
  123. ASSERT_EQ(0x1005U, Proc[1].getIndex());
  124. // Sanity check to make sure all same-ordering hashes are different
  125. // from each other.
  126. verifyHashUniqueness(Hashes1);
  127. verifyHashUniqueness(Hashes2);
  128. EXPECT_EQ(hash_of(Hashes1, IntPP[0]), hash_of(Hashes2, IntPP[1]));
  129. EXPECT_EQ(hash_of(Hashes1, IntPPP[0]), hash_of(Hashes2, IntPPP[1]));
  130. EXPECT_EQ(hash_of(Hashes1, CharPP[0]), hash_of(Hashes2, CharPP[1]));
  131. EXPECT_EQ(hash_of(Hashes1, Args[0]), hash_of(Hashes2, Args[1]));
  132. EXPECT_EQ(hash_of(Hashes1, Proc[0]), hash_of(Hashes2, Proc[1]));
  133. }