1 //===- llvm/unittest/DebugInfo/DWARFFormValueTest.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/CodeGen/DIE.h"
11 #include "../lib/CodeGen/AsmPrinter/DIEHash.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/CodeGen/DwarfStringPoolEntry.h"
14 #include "llvm/Support/Debug.h"
15 #include "llvm/Support/Dwarf.h"
16 #include "llvm/Support/Format.h"
17 #include "gtest/gtest.h"
24 class DIEHashTest : public testing::Test {
25 StringMap<DwarfStringPoolEntry> Pool;
28 DIEString getString(StringRef S) {
29 DwarfStringPoolEntry Entry = {nullptr, 1, 1};
31 DwarfStringPoolEntryRef(*Pool.insert(std::make_pair(S, Entry)).first));
35 TEST_F(DIEHashTest, Data1) {
37 DIE Die(dwarf::DW_TAG_base_type);
39 Die.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Size);
40 uint64_t MD5Res = Hash.computeTypeSignature(Die);
41 ASSERT_EQ(0x1AFE116E83701108ULL, MD5Res);
45 TEST_F(DIEHashTest, TrivialType) {
46 DIE Unnamed(dwarf::DW_TAG_structure_type);
48 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
50 // Line and file number are ignored.
51 Unnamed.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
52 Unnamed.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
53 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
55 // The exact same hash GCC produces for this DIE.
56 ASSERT_EQ(0x715305ce6cfd9ad1ULL, MD5Res);
60 TEST_F(DIEHashTest, NamedType) {
61 DIE Foo(dwarf::DW_TAG_structure_type);
63 DIEString FooStr = getString("foo");
64 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
65 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
67 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
69 // The exact same hash GCC produces for this DIE.
70 ASSERT_EQ(0xd566dbd2ca5265ffULL, MD5Res);
73 // namespace space { struct foo { }; }
74 TEST_F(DIEHashTest, NamespacedType) {
75 DIE CU(dwarf::DW_TAG_compile_unit);
77 auto Space = make_unique<DIE>(dwarf::DW_TAG_namespace);
79 DIEString SpaceStr = getString("space");
80 Space->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, SpaceStr);
81 // DW_AT_declaration is ignored.
82 Space->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, One);
85 auto Foo = make_unique<DIE>(dwarf::DW_TAG_structure_type);
86 DIEString FooStr = getString("foo");
87 Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
88 Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
91 Space->addChild(std::move(Foo));
92 CU.addChild(std::move(Space));
94 uint64_t MD5Res = DIEHash().computeTypeSignature(N);
96 // The exact same hash GCC produces for this DIE.
97 ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res);
100 // struct { int member; };
101 TEST_F(DIEHashTest, TypeWithMember) {
102 DIE Unnamed(dwarf::DW_TAG_structure_type);
104 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
106 DIE Int(dwarf::DW_TAG_base_type);
107 DIEString IntStr = getString("int");
108 Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, IntStr);
109 Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
111 Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five);
113 DIEEntry IntRef(Int);
115 auto Member = make_unique<DIE>(dwarf::DW_TAG_member);
116 DIEString MemberStr = getString("member");
117 Member->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemberStr);
119 Member->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
121 Member->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef);
123 Unnamed.addChild(std::move(Member));
125 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
127 ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res);
130 // struct foo { int mem1, mem2; };
131 TEST_F(DIEHashTest, ReusedType) {
132 DIE Unnamed(dwarf::DW_TAG_structure_type);
134 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
137 DIE Int(dwarf::DW_TAG_base_type);
138 DIEString IntStr = getString("int");
139 Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, IntStr);
140 Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
142 Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five);
144 DIEEntry IntRef(Int);
146 auto Mem1 = make_unique<DIE>(dwarf::DW_TAG_member);
147 DIEString Mem1Str = getString("mem1");
148 Mem1->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, Mem1Str);
150 Mem1->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
152 Mem1->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef);
154 Unnamed.addChild(std::move(Mem1));
156 auto Mem2 = make_unique<DIE>(dwarf::DW_TAG_member);
157 DIEString Mem2Str = getString("mem2");
158 Mem2->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, Mem2Str);
159 Mem2->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
161 Mem2->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef);
163 Unnamed.addChild(std::move(Mem2));
165 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
167 ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res);
170 // struct foo { static foo f; };
171 TEST_F(DIEHashTest, RecursiveType) {
172 DIE Foo(dwarf::DW_TAG_structure_type);
174 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
175 DIEString FooStr = getString("foo");
176 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
178 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
179 DIEString MemStr = getString("mem");
180 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
181 DIEEntry FooRef(Foo);
182 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRef);
183 // DW_AT_external and DW_AT_declaration are ignored anyway, so skip them.
185 Foo.addChild(std::move(Mem));
187 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
189 ASSERT_EQ(0x73d8b25aef227b06ULL, MD5Res);
192 // struct foo { foo *mem; };
193 TEST_F(DIEHashTest, Pointer) {
194 DIE Foo(dwarf::DW_TAG_structure_type);
196 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
197 DIEString FooStr = getString("foo");
198 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
200 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
201 DIEString MemStr = getString("mem");
202 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
204 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero);
206 DIE FooPtr(dwarf::DW_TAG_pointer_type);
207 FooPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
208 DIEEntry FooRef(Foo);
209 FooPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRef);
211 DIEEntry FooPtrRef(FooPtr);
212 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooPtrRef);
214 Foo.addChild(std::move(Mem));
216 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
218 ASSERT_EQ(0x74ea73862e8708d2ULL, MD5Res);
221 // struct foo { foo &mem; };
222 TEST_F(DIEHashTest, Reference) {
223 DIE Foo(dwarf::DW_TAG_structure_type);
225 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
226 DIEString FooStr = getString("foo");
227 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
229 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
230 DIEString MemStr = getString("mem");
231 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
233 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero);
235 DIE FooRef(dwarf::DW_TAG_reference_type);
236 FooRef.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
237 DIEEntry FooEntry(Foo);
238 FooRef.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
240 DIE FooRefConst(dwarf::DW_TAG_const_type);
241 DIEEntry FooRefRef(FooRef);
242 FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefRef);
244 DIEEntry FooRefConstRef(FooRefConst);
245 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefConstRef);
247 Foo.addChild(std::move(Mem));
249 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
251 ASSERT_EQ(0xa0b15f467ad4525bULL, MD5Res);
254 // struct foo { foo &&mem; };
255 TEST_F(DIEHashTest, RValueReference) {
256 DIE Foo(dwarf::DW_TAG_structure_type);
258 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
259 DIEString FooStr = getString("foo");
260 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
262 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
263 DIEString MemStr = getString("mem");
264 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
266 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero);
268 DIE FooRef(dwarf::DW_TAG_rvalue_reference_type);
269 FooRef.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
270 DIEEntry FooEntry(Foo);
271 FooRef.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
273 DIE FooRefConst(dwarf::DW_TAG_const_type);
274 DIEEntry FooRefRef(FooRef);
275 FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefRef);
277 DIEEntry FooRefConstRef(FooRefConst);
278 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefConstRef);
280 Foo.addChild(std::move(Mem));
282 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
284 ASSERT_EQ(0xad211c8c3b31e57ULL, MD5Res);
287 // struct foo { foo foo::*mem; };
288 TEST_F(DIEHashTest, PtrToMember) {
289 DIE Foo(dwarf::DW_TAG_structure_type);
291 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
292 DIEString FooStr = getString("foo");
293 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
295 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
296 DIEString MemStr = getString("mem");
297 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
299 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero);
301 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
302 DIEEntry FooEntry(Foo);
303 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
304 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
307 DIEEntry PtrToFooMemRef(PtrToFooMem);
308 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef);
310 Foo.addChild(std::move(Mem));
312 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
314 ASSERT_EQ(0x852e0c9ff7c04ebULL, MD5Res);
317 // Check that the hash for a pointer-to-member matches regardless of whether the
318 // pointed-to type is a declaration or a definition.
320 // struct bar; // { };
321 // struct foo { bar foo::*mem; };
322 TEST_F(DIEHashTest, PtrToMemberDeclDefMatch) {
326 DIEString FooStr = getString("foo");
327 DIEString BarStr = getString("bar");
328 DIEString MemStr = getString("mem");
331 DIE Bar(dwarf::DW_TAG_structure_type);
332 Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
333 Bar.addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, One);
335 DIE Foo(dwarf::DW_TAG_structure_type);
336 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
337 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
339 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
340 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
341 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
344 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
345 DIEEntry BarEntry(Bar);
346 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, BarEntry);
347 DIEEntry FooEntry(Foo);
348 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
351 DIEEntry PtrToFooMemRef(PtrToFooMem);
352 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef);
354 Foo.addChild(std::move(Mem));
356 MD5ResDecl = DIEHash().computeTypeSignature(Foo);
360 DIE Bar(dwarf::DW_TAG_structure_type);
361 Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
362 Bar.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
364 DIE Foo(dwarf::DW_TAG_structure_type);
365 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
366 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
368 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
369 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
370 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
373 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
374 DIEEntry BarEntry(Bar);
375 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, BarEntry);
376 DIEEntry FooEntry(Foo);
377 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
380 DIEEntry PtrToFooMemRef(PtrToFooMem);
381 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef);
383 Foo.addChild(std::move(Mem));
385 MD5ResDef = DIEHash().computeTypeSignature(Foo);
387 ASSERT_EQ(MD5ResDef, MD5ResDecl);
390 // Check that the hash for a pointer-to-member matches regardless of whether the
391 // pointed-to type is a declaration or a definition.
393 // struct bar; // { };
394 // struct foo { bar bar::*mem; };
395 TEST_F(DIEHashTest, PtrToMemberDeclDefMisMatch) {
399 DIEString FooStr = getString("foo");
400 DIEString BarStr = getString("bar");
401 DIEString MemStr = getString("mem");
404 DIE Bar(dwarf::DW_TAG_structure_type);
405 Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
406 Bar.addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, One);
408 DIE Foo(dwarf::DW_TAG_structure_type);
409 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
410 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
412 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
413 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
414 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
417 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
418 DIEEntry BarEntry(Bar);
419 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, BarEntry);
420 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
423 DIEEntry PtrToFooMemRef(PtrToFooMem);
424 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef);
426 Foo.addChild(std::move(Mem));
428 MD5ResDecl = DIEHash().computeTypeSignature(Foo);
432 DIE Bar(dwarf::DW_TAG_structure_type);
433 Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
434 Bar.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
436 DIE Foo(dwarf::DW_TAG_structure_type);
437 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
438 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
440 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
441 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
442 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
445 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
446 DIEEntry BarEntry(Bar);
447 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, BarEntry);
448 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
451 DIEEntry PtrToFooMemRef(PtrToFooMem);
452 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef);
454 Foo.addChild(std::move(Mem));
456 MD5ResDef = DIEHash().computeTypeSignature(Foo);
458 // FIXME: This seems to be a bug in the DWARF type hashing specification that
459 // only uses the brief name hashing for types referenced via DW_AT_type. In
460 // this case the type is referenced via DW_AT_containing_type and full hashing
461 // causes a hash to differ when the containing type is a declaration in one TU
462 // and a definition in another.
463 ASSERT_NE(MD5ResDef, MD5ResDecl);
467 // struct foo { decltype(a) mem; };
468 TEST_F(DIEHashTest, RefUnnamedType) {
472 DIEString FooStr = getString("foo");
473 DIEString MemStr = getString("mem");
475 DIE Unnamed(dwarf::DW_TAG_structure_type);
476 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
478 DIE Foo(dwarf::DW_TAG_structure_type);
479 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
480 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
482 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
483 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
484 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero);
486 DIE UnnamedPtr(dwarf::DW_TAG_pointer_type);
487 UnnamedPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
488 DIEEntry UnnamedRef(Unnamed);
489 UnnamedPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, UnnamedRef);
491 DIEEntry UnnamedPtrRef(UnnamedPtr);
492 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, UnnamedPtrRef);
494 Foo.addChild(std::move(Mem));
496 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
498 ASSERT_EQ(0x954e026f01c02529ULL, MD5Res);
501 // struct { struct foo { }; };
502 TEST_F(DIEHashTest, NestedType) {
503 DIE Unnamed(dwarf::DW_TAG_structure_type);
505 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
507 auto Foo = make_unique<DIE>(dwarf::DW_TAG_structure_type);
508 DIEString FooStr = getString("foo");
509 Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
510 Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
512 Unnamed.addChild(std::move(Foo));
514 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
516 // The exact same hash GCC produces for this DIE.
517 ASSERT_EQ(0xde8a3b7b43807f4aULL, MD5Res);
520 // struct { static void func(); };
521 TEST_F(DIEHashTest, MemberFunc) {
522 DIE Unnamed(dwarf::DW_TAG_structure_type);
524 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
526 auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram);
527 DIEString FuncStr = getString("func");
528 Func->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FuncStr);
530 Unnamed.addChild(std::move(Func));
532 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
534 // The exact same hash GCC produces for this DIE.
535 ASSERT_EQ(0xd36a1b6dfb604ba0ULL, MD5Res);
539 // static void func();
541 TEST_F(DIEHashTest, MemberFuncFlag) {
542 DIE A(dwarf::DW_TAG_structure_type);
544 DIEString AStr = getString("A");
545 A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
546 A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
547 A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
548 A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
550 auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram);
551 DIEString FuncStr = getString("func");
552 DIEString FuncLinkage = getString("_ZN1A4funcEv");
554 Func->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, One);
555 Func->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FuncStr);
556 Func->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
557 Func->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, Two);
558 Func->addValue(dwarf::DW_AT_linkage_name, dwarf::DW_FORM_strp, FuncLinkage);
559 Func->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, One);
561 A.addChild(std::move(Func));
563 uint64_t MD5Res = DIEHash().computeTypeSignature(A);
565 // The exact same hash GCC produces for this DIE.
566 ASSERT_EQ(0x8f78211ddce3df10ULL, MD5Res);
571 // const static int PI = -3;
574 TEST_F(DIEHashTest, MemberSdata) {
575 DIE A(dwarf::DW_TAG_structure_type);
577 DIEString AStr = getString("A");
578 A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
579 A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
580 A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
581 A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
585 DIEString FStr = getString("int");
586 DIE IntTyDIE(dwarf::DW_TAG_base_type);
587 IntTyDIE.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
588 IntTyDIE.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five);
589 IntTyDIE.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FStr);
591 DIEEntry IntTy(IntTyDIE);
592 auto PITyDIE = make_unique<DIE>(dwarf::DW_TAG_const_type);
593 PITyDIE->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntTy);
595 DIEEntry PITy(*PITyDIE);
596 auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
597 DIEString PIStr = getString("PI");
599 DIEInteger NegThree(-3);
600 PI->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, PIStr);
601 PI->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
602 PI->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, Two);
603 PI->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PITy);
604 PI->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, One);
605 PI->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, One);
606 PI->addValue(dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, NegThree);
608 A.addChild(std::move(PI));
610 uint64_t MD5Res = DIEHash().computeTypeSignature(A);
611 ASSERT_EQ(0x9a216000dd3788a7ULL, MD5Res);
616 // const static float PI = 3.14;
619 TEST_F(DIEHashTest, MemberBlock) {
620 DIE A(dwarf::DW_TAG_structure_type);
622 DIEString AStr = getString("A");
623 A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
624 A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
625 A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
626 A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
629 DIEString FStr = getString("float");
630 auto FloatTyDIE = make_unique<DIE>(dwarf::DW_TAG_base_type);
631 FloatTyDIE->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
632 FloatTyDIE->addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Four);
633 FloatTyDIE->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, FStr);
635 DIEEntry FloatTy(*FloatTyDIE);
636 auto PITyDIE = make_unique<DIE>(dwarf::DW_TAG_const_type);
637 PITyDIE->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FloatTy);
639 DIEEntry PITy(*PITyDIE);
640 auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
641 DIEString PIStr = getString("PI");
643 PI->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, PIStr);
644 PI->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
645 PI->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, Two);
646 PI->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PITy);
647 PI->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, One);
648 PI->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, One);
651 DIEInteger Blk1(0xc3);
652 DIEInteger Blk2(0xf5);
653 DIEInteger Blk3(0x48);
654 DIEInteger Blk4(0x40);
656 PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk1);
657 PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk2);
658 PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk3);
659 PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk4);
661 PI->addValue(dwarf::DW_AT_const_value, dwarf::DW_FORM_block1, &PIBlock);
663 A.addChild(std::move(PI));
665 uint64_t MD5Res = DIEHash().computeTypeSignature(A);
666 ASSERT_EQ(0x493af53ad3d3f651ULL, MD5Res);