1 //===- llvm/unittest/DebugInfo/CodeView/TypeHashingTest.cpp ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/DebugInfo/CodeView/TypeHashing.h"
11 #include "llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h"
13 #include "gtest/gtest.h"
16 using namespace llvm::codeview
;
18 static TypeIndex
createPointerRecord(AppendingTypeTableBuilder
&Builder
,
20 PointerRecord
PR(TypeRecordKind::Pointer
);
21 PR
.setAttrs(PointerKind::Near32
, PointerMode::Pointer
, PointerOptions::None
,
24 return Builder
.writeLeafType(PR
);
27 static TypeIndex
createArgListRecord(AppendingTypeTableBuilder
&Builder
,
28 TypeIndex Q
, TypeIndex R
) {
29 ArgListRecord
AR(TypeRecordKind::ArgList
);
30 AR
.ArgIndices
.push_back(Q
);
31 AR
.ArgIndices
.push_back(R
);
32 return Builder
.writeLeafType(AR
);
35 static TypeIndex
createProcedureRecord(AppendingTypeTableBuilder
&Builder
,
36 uint32_t ParamCount
, TypeIndex Return
,
38 ProcedureRecord
PR(TypeRecordKind::Procedure
);
39 PR
.ArgumentList
= ArgList
;
40 PR
.CallConv
= CallingConvention::NearC
;
41 PR
.Options
= FunctionOptions::None
;
42 PR
.ParameterCount
= ParamCount
;
43 PR
.ReturnType
= Return
;
44 return Builder
.writeLeafType(PR
);
47 static ArrayRef
<uint8_t> hash_of(ArrayRef
<GloballyHashedType
> Hashes
,
49 return Hashes
[TI
.toArrayIndex()].Hash
;
52 static void verifyHashUniqueness(ArrayRef
<GloballyHashedType
> Hashes
) {
53 assert(!Hashes
.empty());
55 for (size_t I
= 0; I
< Hashes
.size() - 1; ++I
) {
56 for (size_t J
= I
+ 1; J
< Hashes
.size(); ++J
) {
57 EXPECT_NE(Hashes
[I
].Hash
, Hashes
[J
].Hash
);
62 TEST(TypeHashingTest
, ContentHash
) {
63 SimpleTypeSerializer Serializer
;
65 TypeIndex
CharStar(SimpleTypeKind::SignedCharacter
,
66 SimpleTypeMode::NearPointer32
);
68 BumpPtrAllocator Alloc
;
69 AppendingTypeTableBuilder
Ordering1(Alloc
);
70 AppendingTypeTableBuilder
Ordering2(Alloc
);
72 TypeIndex
CharP(SimpleTypeKind::SignedCharacter
, SimpleTypeMode::NearPointer
);
73 TypeIndex
IntP(SimpleTypeKind::Int32
, SimpleTypeMode::NearPointer
);
74 TypeIndex
DoubleP(SimpleTypeKind::Float64
, SimpleTypeMode::NearPointer
);
76 // We're going to the same type sequence with two different orderings, and
77 // then confirm all records are hashed the same.
82 TypeIndex DoublePP
[2];
87 // ----------------------------------------
88 // LF_POINTER 0x1000 {char**}
90 // LF_POINTER 0x1001 {int**}
92 // LF_POINTER 0x1002 {int***}
94 // LF_ARGLIST 0x1003 {(char**, int***)}
97 // LF_PROCEDURE 0x1004 {int** func(char**, int***)}
99 // ReturnType = 0x1001
100 std::vector
<GloballyHashedType
> Ordering1Hashes
;
101 CharPP
[0] = createPointerRecord(Ordering1
, CharP
);
102 IntPP
[0] = createPointerRecord(Ordering1
, IntP
);
103 IntPPP
[0] = createPointerRecord(Ordering1
, IntPP
[0]);
104 Args
[0] = createArgListRecord(Ordering1
, CharPP
[0], IntPPP
[0]);
105 Proc
[0] = createProcedureRecord(Ordering1
, 2, IntPP
[0], Args
[0]);
107 ASSERT_EQ(0x1000U
, CharPP
[0].getIndex());
108 ASSERT_EQ(0x1001U
, IntPP
[0].getIndex());
109 ASSERT_EQ(0x1002U
, IntPPP
[0].getIndex());
110 ASSERT_EQ(0x1003U
, Args
[0].getIndex());
111 ASSERT_EQ(0x1004U
, Proc
[0].getIndex());
113 auto Hashes1
= GloballyHashedType::hashTypes(Ordering1
.records());
116 // ----------------------------------------
117 // LF_POINTER 0x1000 {int**}
119 // LF_POINTER 0x1001 {int***}
121 // LF_POINTER 0x1002 {char**}
123 // LF_POINTER 0x1003 {double**}
124 // Referent = double*
125 // LF_ARGLIST 0x1004 {(char**, int***)}
128 // LF_PROCEDURE 0x1005 {int** func(char**, int***)}
130 // ReturnType = 0x1000
131 IntPP
[1] = createPointerRecord(Ordering2
, IntP
);
132 IntPPP
[1] = createPointerRecord(Ordering2
, IntPP
[1]);
133 CharPP
[1] = createPointerRecord(Ordering2
, CharP
);
134 DoublePP
[1] = createPointerRecord(Ordering2
, DoubleP
);
135 Args
[1] = createArgListRecord(Ordering2
, CharPP
[1], IntPPP
[1]);
136 Proc
[1] = createProcedureRecord(Ordering2
, 2, IntPP
[1], Args
[1]);
137 auto Hashes2
= GloballyHashedType::hashTypes(Ordering2
.records());
139 ASSERT_EQ(0x1000U
, IntPP
[1].getIndex());
140 ASSERT_EQ(0x1001U
, IntPPP
[1].getIndex());
141 ASSERT_EQ(0x1002U
, CharPP
[1].getIndex());
142 ASSERT_EQ(0x1003U
, DoublePP
[1].getIndex());
143 ASSERT_EQ(0x1004U
, Args
[1].getIndex());
144 ASSERT_EQ(0x1005U
, Proc
[1].getIndex());
146 // Sanity check to make sure all same-ordering hashes are different
148 verifyHashUniqueness(Hashes1
);
149 verifyHashUniqueness(Hashes2
);
151 EXPECT_EQ(hash_of(Hashes1
, IntPP
[0]), hash_of(Hashes2
, IntPP
[1]));
152 EXPECT_EQ(hash_of(Hashes1
, IntPPP
[0]), hash_of(Hashes2
, IntPPP
[1]));
153 EXPECT_EQ(hash_of(Hashes1
, CharPP
[0]), hash_of(Hashes2
, CharPP
[1]));
154 EXPECT_EQ(hash_of(Hashes1
, Args
[0]), hash_of(Hashes2
, Args
[1]));
155 EXPECT_EQ(hash_of(Hashes1
, Proc
[0]), hash_of(Hashes2
, Proc
[1]));