[llvm-exegesis][NFC] Return many CodeTemplates instead of one.
[llvm-complete.git] / unittests / CodeGen / DIEHashTest.cpp
blobc82876b8058428d643815f03e735b3c3284072aa
1 //===- llvm/unittest/CodeGen/DIEHashTest.cpp ------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
10 #include "../lib/CodeGen/AsmPrinter/DIEHash.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/BinaryFormat/Dwarf.h"
13 #include "llvm/CodeGen/DIE.h"
14 #include "llvm/CodeGen/DwarfStringPoolEntry.h"
15 #include "llvm/Support/Debug.h"
16 #include "llvm/Support/Format.h"
17 #include "gtest/gtest.h"
19 using namespace llvm;
21 namespace {
23 // Test fixture
24 class DIEHashTest : public testing::Test {
25 public:
26 BumpPtrAllocator Alloc;
28 private:
29 StringMap<DwarfStringPoolEntry> Pool;
31 public:
32 DIEString getString(StringRef S) {
33 DwarfStringPoolEntry Entry = {nullptr, 1, 1};
34 return DIEString(DwarfStringPoolEntryRef(
35 *Pool.insert(std::make_pair(S, Entry)).first, Entry.isIndexed()));
39 TEST_F(DIEHashTest, Data1) {
40 DIEHash Hash;
41 DIE &Die = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
42 DIEInteger Size(4);
43 Die.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Size);
44 uint64_t MD5Res = Hash.computeTypeSignature(Die);
45 ASSERT_EQ(0x1AFE116E83701108ULL, MD5Res);
48 // struct {};
49 TEST_F(DIEHashTest, TrivialType) {
50 DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
51 DIEInteger One(1);
52 Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
54 // Line and file number are ignored.
55 Unnamed.addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
56 Unnamed.addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
57 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
59 // The exact same hash GCC produces for this DIE.
60 ASSERT_EQ(0x715305ce6cfd9ad1ULL, MD5Res);
63 // struct foo { };
64 TEST_F(DIEHashTest, NamedType) {
65 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
66 DIEInteger One(1);
67 DIEString FooStr = getString("foo");
68 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
69 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
71 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
73 // The exact same hash GCC produces for this DIE.
74 ASSERT_EQ(0xd566dbd2ca5265ffULL, MD5Res);
77 // namespace space { struct foo { }; }
78 TEST_F(DIEHashTest, NamespacedType) {
79 DIE &CU = *DIE::get(Alloc, dwarf::DW_TAG_compile_unit);
81 auto Space = DIE::get(Alloc, dwarf::DW_TAG_namespace);
82 DIEInteger One(1);
83 DIEString SpaceStr = getString("space");
84 Space->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, SpaceStr);
85 // DW_AT_declaration is ignored.
86 Space->addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
87 One);
88 // sibling?
90 auto Foo = DIE::get(Alloc, dwarf::DW_TAG_structure_type);
91 DIEString FooStr = getString("foo");
92 Foo->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
93 Foo->addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
95 DIE &N = *Foo;
96 Space->addChild(std::move(Foo));
97 CU.addChild(std::move(Space));
99 uint64_t MD5Res = DIEHash().computeTypeSignature(N);
101 // The exact same hash GCC produces for this DIE.
102 ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res);
105 // struct { int member; };
106 TEST_F(DIEHashTest, TypeWithMember) {
107 DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
108 DIEInteger Four(4);
109 Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
111 DIE &Int = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
112 DIEString IntStr = getString("int");
113 Int.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, IntStr);
114 Int.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
115 DIEInteger Five(5);
116 Int.addValue(Alloc, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five);
118 DIEEntry IntRef(Int);
120 auto Member = DIE::get(Alloc, dwarf::DW_TAG_member);
121 DIEString MemberStr = getString("member");
122 Member->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemberStr);
123 DIEInteger Zero(0);
124 Member->addValue(Alloc, dwarf::DW_AT_data_member_location,
125 dwarf::DW_FORM_data1, Zero);
126 Member->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef);
128 Unnamed.addChild(std::move(Member));
130 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
132 ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res);
135 // struct foo { int mem1, mem2; };
136 TEST_F(DIEHashTest, ReusedType) {
137 DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
138 DIEInteger Eight(8);
139 Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
141 DIEInteger Four(4);
142 DIE &Int = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
143 DIEString IntStr = getString("int");
144 Int.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, IntStr);
145 Int.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
146 DIEInteger Five(5);
147 Int.addValue(Alloc, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five);
149 DIEEntry IntRef(Int);
151 auto Mem1 = DIE::get(Alloc, dwarf::DW_TAG_member);
152 DIEString Mem1Str = getString("mem1");
153 Mem1->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, Mem1Str);
154 DIEInteger Zero(0);
155 Mem1->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
156 Zero);
157 Mem1->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef);
159 Unnamed.addChild(std::move(Mem1));
161 auto Mem2 = DIE::get(Alloc, dwarf::DW_TAG_member);
162 DIEString Mem2Str = getString("mem2");
163 Mem2->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, Mem2Str);
164 Mem2->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
165 Four);
166 Mem2->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef);
168 Unnamed.addChild(std::move(Mem2));
170 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
172 ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res);
175 // struct foo { static foo f; };
176 TEST_F(DIEHashTest, RecursiveType) {
177 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
178 DIEInteger One(1);
179 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
180 DIEString FooStr = getString("foo");
181 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
183 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
184 DIEString MemStr = getString("mem");
185 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
186 DIEEntry FooRef(Foo);
187 Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRef);
188 // DW_AT_external and DW_AT_declaration are ignored anyway, so skip them.
190 Foo.addChild(std::move(Mem));
192 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
194 ASSERT_EQ(0x73d8b25aef227b06ULL, MD5Res);
197 // struct foo { foo *mem; };
198 TEST_F(DIEHashTest, Pointer) {
199 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
200 DIEInteger Eight(8);
201 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
202 DIEString FooStr = getString("foo");
203 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
205 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
206 DIEString MemStr = getString("mem");
207 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
208 DIEInteger Zero(0);
209 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
210 Zero);
212 DIE &FooPtr = *DIE::get(Alloc, dwarf::DW_TAG_pointer_type);
213 FooPtr.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
214 DIEEntry FooRef(Foo);
215 FooPtr.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRef);
217 DIEEntry FooPtrRef(FooPtr);
218 Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooPtrRef);
220 Foo.addChild(std::move(Mem));
222 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
224 ASSERT_EQ(0x74ea73862e8708d2ULL, MD5Res);
227 // struct foo { foo &mem; };
228 TEST_F(DIEHashTest, Reference) {
229 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
230 DIEInteger Eight(8);
231 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
232 DIEString FooStr = getString("foo");
233 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
235 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
236 DIEString MemStr = getString("mem");
237 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
238 DIEInteger Zero(0);
239 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
240 Zero);
242 DIE &FooRef = *DIE::get(Alloc, dwarf::DW_TAG_reference_type);
243 FooRef.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
244 DIEEntry FooEntry(Foo);
245 FooRef.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
247 DIE &FooRefConst = *DIE::get(Alloc, dwarf::DW_TAG_const_type);
248 DIEEntry FooRefRef(FooRef);
249 FooRefConst.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
250 FooRefRef);
252 DIEEntry FooRefConstRef(FooRefConst);
253 Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefConstRef);
255 Foo.addChild(std::move(Mem));
257 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
259 ASSERT_EQ(0xa0b15f467ad4525bULL, MD5Res);
262 // struct foo { foo &&mem; };
263 TEST_F(DIEHashTest, RValueReference) {
264 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
265 DIEInteger Eight(8);
266 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
267 DIEString FooStr = getString("foo");
268 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
270 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
271 DIEString MemStr = getString("mem");
272 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
273 DIEInteger Zero(0);
274 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
275 Zero);
277 DIE &FooRef = *DIE::get(Alloc, dwarf::DW_TAG_rvalue_reference_type);
278 FooRef.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
279 DIEEntry FooEntry(Foo);
280 FooRef.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
282 DIE &FooRefConst = *DIE::get(Alloc, dwarf::DW_TAG_const_type);
283 DIEEntry FooRefRef(FooRef);
284 FooRefConst.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
285 FooRefRef);
287 DIEEntry FooRefConstRef(FooRefConst);
288 Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefConstRef);
290 Foo.addChild(std::move(Mem));
292 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
294 ASSERT_EQ(0xad211c8c3b31e57ULL, MD5Res);
297 // struct foo { foo foo::*mem; };
298 TEST_F(DIEHashTest, PtrToMember) {
299 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
300 DIEInteger Eight(8);
301 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
302 DIEString FooStr = getString("foo");
303 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
305 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
306 DIEString MemStr = getString("mem");
307 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
308 DIEInteger Zero(0);
309 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
310 Zero);
312 DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
313 DIEEntry FooEntry(Foo);
314 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
315 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
316 FooEntry);
318 DIEEntry PtrToFooMemRef(PtrToFooMem);
319 Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef);
321 Foo.addChild(std::move(Mem));
323 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
325 ASSERT_EQ(0x852e0c9ff7c04ebULL, MD5Res);
328 // Check that the hash for a pointer-to-member matches regardless of whether the
329 // pointed-to type is a declaration or a definition.
331 // struct bar; // { };
332 // struct foo { bar foo::*mem; };
333 TEST_F(DIEHashTest, PtrToMemberDeclDefMatch) {
334 DIEInteger Zero(0);
335 DIEInteger One(1);
336 DIEInteger Eight(8);
337 DIEString FooStr = getString("foo");
338 DIEString BarStr = getString("bar");
339 DIEString MemStr = getString("mem");
340 uint64_t MD5ResDecl;
342 DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
343 Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
344 Bar.addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
345 One);
347 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
348 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
349 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
351 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
352 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
353 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
354 dwarf::DW_FORM_data1, Zero);
356 DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
357 DIEEntry BarEntry(Bar);
358 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
359 BarEntry);
360 DIEEntry FooEntry(Foo);
361 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_containing_type,
362 dwarf::DW_FORM_ref4, FooEntry);
364 DIEEntry PtrToFooMemRef(PtrToFooMem);
365 Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
366 PtrToFooMemRef);
368 Foo.addChild(std::move(Mem));
370 MD5ResDecl = DIEHash().computeTypeSignature(Foo);
372 uint64_t MD5ResDef;
374 DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
375 Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
376 Bar.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
378 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
379 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
380 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
382 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
383 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
384 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
385 dwarf::DW_FORM_data1, Zero);
387 DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
388 DIEEntry BarEntry(Bar);
389 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
390 BarEntry);
391 DIEEntry FooEntry(Foo);
392 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_containing_type,
393 dwarf::DW_FORM_ref4, FooEntry);
395 DIEEntry PtrToFooMemRef(PtrToFooMem);
396 Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
397 PtrToFooMemRef);
399 Foo.addChild(std::move(Mem));
401 MD5ResDef = DIEHash().computeTypeSignature(Foo);
403 ASSERT_EQ(MD5ResDef, MD5ResDecl);
406 // Check that the hash for a pointer-to-member matches regardless of whether the
407 // pointed-to type is a declaration or a definition.
409 // struct bar; // { };
410 // struct foo { bar bar::*mem; };
411 TEST_F(DIEHashTest, PtrToMemberDeclDefMisMatch) {
412 DIEInteger Zero(0);
413 DIEInteger One(1);
414 DIEInteger Eight(8);
415 DIEString FooStr = getString("foo");
416 DIEString BarStr = getString("bar");
417 DIEString MemStr = getString("mem");
418 uint64_t MD5ResDecl;
420 DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
421 Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
422 Bar.addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
423 One);
425 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
426 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
427 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
429 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
430 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
431 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
432 dwarf::DW_FORM_data1, Zero);
434 DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
435 DIEEntry BarEntry(Bar);
436 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
437 BarEntry);
438 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_containing_type,
439 dwarf::DW_FORM_ref4, BarEntry);
441 DIEEntry PtrToFooMemRef(PtrToFooMem);
442 Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
443 PtrToFooMemRef);
445 Foo.addChild(std::move(Mem));
447 MD5ResDecl = DIEHash().computeTypeSignature(Foo);
449 uint64_t MD5ResDef;
451 DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
452 Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
453 Bar.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
455 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
456 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
457 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
459 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
460 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
461 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
462 dwarf::DW_FORM_data1, Zero);
464 DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
465 DIEEntry BarEntry(Bar);
466 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
467 BarEntry);
468 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_containing_type,
469 dwarf::DW_FORM_ref4, BarEntry);
471 DIEEntry PtrToFooMemRef(PtrToFooMem);
472 Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
473 PtrToFooMemRef);
475 Foo.addChild(std::move(Mem));
477 MD5ResDef = DIEHash().computeTypeSignature(Foo);
479 // FIXME: This seems to be a bug in the DWARF type hashing specification that
480 // only uses the brief name hashing for types referenced via DW_AT_type. In
481 // this case the type is referenced via DW_AT_containing_type and full hashing
482 // causes a hash to differ when the containing type is a declaration in one TU
483 // and a definition in another.
484 ASSERT_NE(MD5ResDef, MD5ResDecl);
487 // struct { } a;
488 // struct foo { decltype(a) mem; };
489 TEST_F(DIEHashTest, RefUnnamedType) {
490 DIEInteger Zero(0);
491 DIEInteger One(1);
492 DIEInteger Eight(8);
493 DIEString FooStr = getString("foo");
494 DIEString MemStr = getString("mem");
496 DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
497 Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
499 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
500 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
501 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
503 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
504 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
505 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
506 Zero);
508 DIE &UnnamedPtr = *DIE::get(Alloc, dwarf::DW_TAG_pointer_type);
509 UnnamedPtr.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1,
510 Eight);
511 DIEEntry UnnamedRef(Unnamed);
512 UnnamedPtr.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
513 UnnamedRef);
515 DIEEntry UnnamedPtrRef(UnnamedPtr);
516 Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, UnnamedPtrRef);
518 Foo.addChild(std::move(Mem));
520 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
522 ASSERT_EQ(0x954e026f01c02529ULL, MD5Res);
525 // struct { struct foo { }; };
526 TEST_F(DIEHashTest, NestedType) {
527 DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
528 DIEInteger One(1);
529 Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
531 auto Foo = DIE::get(Alloc, dwarf::DW_TAG_structure_type);
532 DIEString FooStr = getString("foo");
533 Foo->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
534 Foo->addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
536 Unnamed.addChild(std::move(Foo));
538 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
540 // The exact same hash GCC produces for this DIE.
541 ASSERT_EQ(0xde8a3b7b43807f4aULL, MD5Res);
544 // struct { static void func(); };
545 TEST_F(DIEHashTest, MemberFunc) {
546 DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
547 DIEInteger One(1);
548 Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
550 auto Func = DIE::get(Alloc, dwarf::DW_TAG_subprogram);
551 DIEString FuncStr = getString("func");
552 Func->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FuncStr);
554 Unnamed.addChild(std::move(Func));
556 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
558 // The exact same hash GCC produces for this DIE.
559 ASSERT_EQ(0xd36a1b6dfb604ba0ULL, MD5Res);
562 // struct A {
563 // static void func();
564 // };
565 TEST_F(DIEHashTest, MemberFuncFlag) {
566 DIE &A = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
567 DIEInteger One(1);
568 DIEString AStr = getString("A");
569 A.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
570 A.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
571 A.addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
572 A.addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
574 auto Func = DIE::get(Alloc, dwarf::DW_TAG_subprogram);
575 DIEString FuncStr = getString("func");
576 DIEString FuncLinkage = getString("_ZN1A4funcEv");
577 DIEInteger Two(2);
578 Func->addValue(Alloc, dwarf::DW_AT_external, dwarf::DW_FORM_flag_present,
579 One);
580 Func->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FuncStr);
581 Func->addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
582 Func->addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, Two);
583 Func->addValue(Alloc, dwarf::DW_AT_linkage_name, dwarf::DW_FORM_strp,
584 FuncLinkage);
585 Func->addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
586 One);
588 A.addChild(std::move(Func));
590 uint64_t MD5Res = DIEHash().computeTypeSignature(A);
592 // The exact same hash GCC produces for this DIE.
593 ASSERT_EQ(0x8f78211ddce3df10ULL, MD5Res);
596 // Derived from:
597 // struct A {
598 // const static int PI = -3;
599 // };
600 // A a;
601 TEST_F(DIEHashTest, MemberSdata) {
602 DIE &A = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
603 DIEInteger One(1);
604 DIEString AStr = getString("A");
605 A.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
606 A.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
607 A.addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
608 A.addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
610 DIEInteger Four(4);
611 DIEInteger Five(5);
612 DIEString FStr = getString("int");
613 DIE &IntTyDIE = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
614 IntTyDIE.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
615 IntTyDIE.addValue(Alloc, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five);
616 IntTyDIE.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FStr);
618 DIEEntry IntTy(IntTyDIE);
619 auto PITyDIE = DIE::get(Alloc, dwarf::DW_TAG_const_type);
620 PITyDIE->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntTy);
622 DIEEntry PITy(*PITyDIE);
623 auto PI = DIE::get(Alloc, dwarf::DW_TAG_member);
624 DIEString PIStr = getString("PI");
625 DIEInteger Two(2);
626 DIEInteger NegThree(-3);
627 PI->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, PIStr);
628 PI->addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
629 PI->addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, Two);
630 PI->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PITy);
631 PI->addValue(Alloc, dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, One);
632 PI->addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
633 One);
634 PI->addValue(Alloc, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, NegThree);
636 A.addChild(std::move(PI));
638 uint64_t MD5Res = DIEHash().computeTypeSignature(A);
639 ASSERT_EQ(0x9a216000dd3788a7ULL, MD5Res);
642 // Derived from:
643 // struct A {
644 // const static float PI = 3.14;
645 // };
646 // A a;
647 TEST_F(DIEHashTest, MemberBlock) {
648 DIE &A = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
649 DIEInteger One(1);
650 DIEString AStr = getString("A");
651 A.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
652 A.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
653 A.addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
654 A.addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
656 DIEInteger Four(4);
657 DIEString FStr = getString("float");
658 auto FloatTyDIE = DIE::get(Alloc, dwarf::DW_TAG_base_type);
659 FloatTyDIE->addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1,
660 Four);
661 FloatTyDIE->addValue(Alloc, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
662 Four);
663 FloatTyDIE->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FStr);
664 DIEEntry FloatTy(*FloatTyDIE);
665 auto PITyDIE = DIE::get(Alloc, dwarf::DW_TAG_const_type);
666 PITyDIE->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FloatTy);
668 DIEEntry PITy(*PITyDIE);
669 auto PI = DIE::get(Alloc, dwarf::DW_TAG_member);
670 DIEString PIStr = getString("PI");
671 DIEInteger Two(2);
672 PI->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, PIStr);
673 PI->addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
674 PI->addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, Two);
675 PI->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PITy);
676 PI->addValue(Alloc, dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, One);
677 PI->addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
678 One);
680 DIEBlock PIBlock;
681 DIEInteger Blk1(0xc3);
682 DIEInteger Blk2(0xf5);
683 DIEInteger Blk3(0x48);
684 DIEInteger Blk4(0x40);
686 PIBlock.addValue(Alloc, (dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk1);
687 PIBlock.addValue(Alloc, (dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk2);
688 PIBlock.addValue(Alloc, (dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk3);
689 PIBlock.addValue(Alloc, (dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk4);
691 PI->addValue(Alloc, dwarf::DW_AT_const_value, dwarf::DW_FORM_block1,
692 &PIBlock);
694 A.addChild(std::move(PI));
696 uint64_t MD5Res = DIEHash().computeTypeSignature(A);
697 ASSERT_EQ(0x493af53ad3d3f651ULL, MD5Res);