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 "../lib/CodeGen/AsmPrinter/DIE.h"
11 #include "../lib/CodeGen/AsmPrinter/DIEHash.h"
12 #include "llvm/Support/Debug.h"
13 #include "llvm/Support/Dwarf.h"
14 #include "llvm/Support/Format.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "gtest/gtest.h"
21 TEST(DIEHashTest, Data1) {
23 DIE Die(dwarf::DW_TAG_base_type);
25 Die.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Size);
26 uint64_t MD5Res = Hash.computeTypeSignature(Die);
27 ASSERT_EQ(0x1AFE116E83701108ULL, MD5Res);
31 TEST(DIEHashTest, TrivialType) {
32 DIE Unnamed(dwarf::DW_TAG_structure_type);
34 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
36 // Line and file number are ignored.
37 Unnamed.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
38 Unnamed.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
39 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
41 // The exact same hash GCC produces for this DIE.
42 ASSERT_EQ(0x715305ce6cfd9ad1ULL, MD5Res);
46 TEST(DIEHashTest, NamedType) {
47 DIE Foo(dwarf::DW_TAG_structure_type);
49 DIEString FooStr(&One, "foo");
50 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
51 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
53 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
55 // The exact same hash GCC produces for this DIE.
56 ASSERT_EQ(0xd566dbd2ca5265ffULL, MD5Res);
59 // namespace space { struct foo { }; }
60 TEST(DIEHashTest, NamespacedType) {
61 DIE CU(dwarf::DW_TAG_compile_unit);
63 auto Space = make_unique<DIE>(dwarf::DW_TAG_namespace);
65 DIEString SpaceStr(&One, "space");
66 Space->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &SpaceStr);
67 // DW_AT_declaration is ignored.
68 Space->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
71 auto Foo = make_unique<DIE>(dwarf::DW_TAG_structure_type);
72 DIEString FooStr(&One, "foo");
73 Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
74 Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
77 Space->addChild(std::move(Foo));
78 CU.addChild(std::move(Space));
80 uint64_t MD5Res = DIEHash().computeTypeSignature(N);
82 // The exact same hash GCC produces for this DIE.
83 ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res);
86 // struct { int member; };
87 TEST(DIEHashTest, TypeWithMember) {
88 DIE Unnamed(dwarf::DW_TAG_structure_type);
90 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
92 DIE Int(dwarf::DW_TAG_base_type);
93 DIEString IntStr(&Four, "int");
94 Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &IntStr);
95 Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
97 Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
101 auto Member = make_unique<DIE>(dwarf::DW_TAG_member);
102 DIEString MemberStr(&Four, "member");
103 Member->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemberStr);
105 Member->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
107 Member->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
109 Unnamed.addChild(std::move(Member));
111 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
113 ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res);
116 // struct foo { int mem1, mem2; };
117 TEST(DIEHashTest, ReusedType) {
118 DIE Unnamed(dwarf::DW_TAG_structure_type);
120 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
123 DIE Int(dwarf::DW_TAG_base_type);
124 DIEString IntStr(&Four, "int");
125 Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &IntStr);
126 Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
128 Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
130 DIEEntry IntRef(Int);
132 auto Mem1 = make_unique<DIE>(dwarf::DW_TAG_member);
133 DIEString Mem1Str(&Four, "mem1");
134 Mem1->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem1Str);
136 Mem1->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
138 Mem1->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
140 Unnamed.addChild(std::move(Mem1));
142 auto Mem2 = make_unique<DIE>(dwarf::DW_TAG_member);
143 DIEString Mem2Str(&Four, "mem2");
144 Mem2->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem2Str);
145 Mem2->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
147 Mem2->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
149 Unnamed.addChild(std::move(Mem2));
151 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
153 ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res);
156 // struct foo { static foo f; };
157 TEST(DIEHashTest, RecursiveType) {
158 DIE Foo(dwarf::DW_TAG_structure_type);
160 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
161 DIEString FooStr(&One, "foo");
162 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
164 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
165 DIEString MemStr(&One, "mem");
166 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
167 DIEEntry FooRef(Foo);
168 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRef);
169 // DW_AT_external and DW_AT_declaration are ignored anyway, so skip them.
171 Foo.addChild(std::move(Mem));
173 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
175 ASSERT_EQ(0x73d8b25aef227b06ULL, MD5Res);
178 // struct foo { foo *mem; };
179 TEST(DIEHashTest, Pointer) {
180 DIE Foo(dwarf::DW_TAG_structure_type);
182 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
183 DIEString FooStr(&Eight, "foo");
184 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
186 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
187 DIEString MemStr(&Eight, "mem");
188 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
190 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
192 DIE FooPtr(dwarf::DW_TAG_pointer_type);
193 FooPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
194 DIEEntry FooRef(Foo);
195 FooPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRef);
197 DIEEntry FooPtrRef(FooPtr);
198 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooPtrRef);
200 Foo.addChild(std::move(Mem));
202 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
204 ASSERT_EQ(0x74ea73862e8708d2ULL, MD5Res);
207 // struct foo { foo &mem; };
208 TEST(DIEHashTest, Reference) {
209 DIE Foo(dwarf::DW_TAG_structure_type);
211 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
212 DIEString FooStr(&Eight, "foo");
213 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
215 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
216 DIEString MemStr(&Eight, "mem");
217 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
219 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
221 DIE FooRef(dwarf::DW_TAG_reference_type);
222 FooRef.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
223 DIEEntry FooEntry(Foo);
224 FooRef.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooEntry);
226 DIE FooRefConst(dwarf::DW_TAG_const_type);
227 DIEEntry FooRefRef(FooRef);
228 FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefRef);
230 DIEEntry FooRefConstRef(FooRefConst);
231 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefConstRef);
233 Foo.addChild(std::move(Mem));
235 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
237 ASSERT_EQ(0xa0b15f467ad4525bULL, MD5Res);
240 // struct foo { foo &&mem; };
241 TEST(DIEHashTest, RValueReference) {
242 DIE Foo(dwarf::DW_TAG_structure_type);
244 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
245 DIEString FooStr(&Eight, "foo");
246 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
248 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
249 DIEString MemStr(&Eight, "mem");
250 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
252 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
254 DIE FooRef(dwarf::DW_TAG_rvalue_reference_type);
255 FooRef.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
256 DIEEntry FooEntry(Foo);
257 FooRef.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooEntry);
259 DIE FooRefConst(dwarf::DW_TAG_const_type);
260 DIEEntry FooRefRef(FooRef);
261 FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefRef);
263 DIEEntry FooRefConstRef(FooRefConst);
264 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefConstRef);
266 Foo.addChild(std::move(Mem));
268 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
270 ASSERT_EQ(0xad211c8c3b31e57ULL, MD5Res);
273 // struct foo { foo foo::*mem; };
274 TEST(DIEHashTest, PtrToMember) {
275 DIE Foo(dwarf::DW_TAG_structure_type);
277 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
278 DIEString FooStr(&Eight, "foo");
279 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
281 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
282 DIEString MemStr(&Eight, "mem");
283 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
285 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
287 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
288 DIEEntry FooEntry(Foo);
289 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooEntry);
290 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
293 DIEEntry PtrToFooMemRef(PtrToFooMem);
294 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
296 Foo.addChild(std::move(Mem));
298 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
300 ASSERT_EQ(0x852e0c9ff7c04ebULL, MD5Res);
303 // Check that the hash for a pointer-to-member matches regardless of whether the
304 // pointed-to type is a declaration or a definition.
306 // struct bar; // { };
307 // struct foo { bar foo::*mem; };
308 TEST(DIEHashTest, PtrToMemberDeclDefMatch) {
312 DIEString FooStr(&Eight, "foo");
313 DIEString BarStr(&Eight, "bar");
314 DIEString MemStr(&Eight, "mem");
317 DIE Bar(dwarf::DW_TAG_structure_type);
318 Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &BarStr);
319 Bar.addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
321 DIE Foo(dwarf::DW_TAG_structure_type);
322 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
323 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
325 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
326 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
327 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
330 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
331 DIEEntry BarEntry(Bar);
332 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
333 DIEEntry FooEntry(Foo);
334 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
337 DIEEntry PtrToFooMemRef(PtrToFooMem);
338 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
340 Foo.addChild(std::move(Mem));
342 MD5ResDecl = DIEHash().computeTypeSignature(Foo);
346 DIE Bar(dwarf::DW_TAG_structure_type);
347 Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &BarStr);
348 Bar.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
350 DIE Foo(dwarf::DW_TAG_structure_type);
351 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
352 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
354 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
355 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
356 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
359 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
360 DIEEntry BarEntry(Bar);
361 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
362 DIEEntry FooEntry(Foo);
363 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
366 DIEEntry PtrToFooMemRef(PtrToFooMem);
367 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
369 Foo.addChild(std::move(Mem));
371 MD5ResDef = DIEHash().computeTypeSignature(Foo);
373 ASSERT_EQ(MD5ResDef, MD5ResDecl);
376 // Check that the hash for a pointer-to-member matches regardless of whether the
377 // pointed-to type is a declaration or a definition.
379 // struct bar; // { };
380 // struct foo { bar bar::*mem; };
381 TEST(DIEHashTest, PtrToMemberDeclDefMisMatch) {
385 DIEString FooStr(&Eight, "foo");
386 DIEString BarStr(&Eight, "bar");
387 DIEString MemStr(&Eight, "mem");
390 DIE Bar(dwarf::DW_TAG_structure_type);
391 Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &BarStr);
392 Bar.addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
394 DIE Foo(dwarf::DW_TAG_structure_type);
395 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
396 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
398 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
399 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
400 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
403 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
404 DIEEntry BarEntry(Bar);
405 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
406 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
409 DIEEntry PtrToFooMemRef(PtrToFooMem);
410 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
412 Foo.addChild(std::move(Mem));
414 MD5ResDecl = DIEHash().computeTypeSignature(Foo);
418 DIE Bar(dwarf::DW_TAG_structure_type);
419 Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &BarStr);
420 Bar.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
422 DIE Foo(dwarf::DW_TAG_structure_type);
423 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
424 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
426 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
427 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
428 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
431 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
432 DIEEntry BarEntry(Bar);
433 PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
434 PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
437 DIEEntry PtrToFooMemRef(PtrToFooMem);
438 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
440 Foo.addChild(std::move(Mem));
442 MD5ResDef = DIEHash().computeTypeSignature(Foo);
444 // FIXME: This seems to be a bug in the DWARF type hashing specification that
445 // only uses the brief name hashing for types referenced via DW_AT_type. In
446 // this case the type is referenced via DW_AT_containing_type and full hashing
447 // causes a hash to differ when the containing type is a declaration in one TU
448 // and a definition in another.
449 ASSERT_NE(MD5ResDef, MD5ResDecl);
453 // struct foo { decltype(a) mem; };
454 TEST(DIEHashTest, RefUnnamedType) {
458 DIEString FooStr(&Zero, "foo");
459 DIEString MemStr(&Zero, "mem");
461 DIE Unnamed(dwarf::DW_TAG_structure_type);
462 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
464 DIE Foo(dwarf::DW_TAG_structure_type);
465 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
466 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
468 auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
469 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
470 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
472 DIE UnnamedPtr(dwarf::DW_TAG_pointer_type);
473 UnnamedPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
474 DIEEntry UnnamedRef(Unnamed);
475 UnnamedPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &UnnamedRef);
477 DIEEntry UnnamedPtrRef(UnnamedPtr);
478 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &UnnamedPtrRef);
480 Foo.addChild(std::move(Mem));
482 uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
484 ASSERT_EQ(0x954e026f01c02529ULL, MD5Res);
487 // struct { struct foo { }; };
488 TEST(DIEHashTest, NestedType) {
489 DIE Unnamed(dwarf::DW_TAG_structure_type);
491 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
493 auto Foo = make_unique<DIE>(dwarf::DW_TAG_structure_type);
494 DIEString FooStr(&One, "foo");
495 Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
496 Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
498 Unnamed.addChild(std::move(Foo));
500 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
502 // The exact same hash GCC produces for this DIE.
503 ASSERT_EQ(0xde8a3b7b43807f4aULL, MD5Res);
506 // struct { static void func(); };
507 TEST(DIEHashTest, MemberFunc) {
508 DIE Unnamed(dwarf::DW_TAG_structure_type);
510 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
512 auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram);
513 DIEString FuncStr(&One, "func");
514 Func->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FuncStr);
516 Unnamed.addChild(std::move(Func));
518 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
520 // The exact same hash GCC produces for this DIE.
521 ASSERT_EQ(0xd36a1b6dfb604ba0ULL, MD5Res);
525 // static void func();
527 TEST(DIEHashTest, MemberFuncFlag) {
528 DIE A(dwarf::DW_TAG_structure_type);
530 DIEString AStr(&One, "A");
531 A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &AStr);
532 A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
533 A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
534 A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
536 auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram);
537 DIEString FuncStr(&One, "func");
538 DIEString FuncLinkage(&One, "_ZN1A4funcEv");
540 Func->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, &One);
541 Func->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FuncStr);
542 Func->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
543 Func->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &Two);
544 Func->addValue(dwarf::DW_AT_linkage_name, dwarf::DW_FORM_strp, &FuncLinkage);
545 Func->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
547 A.addChild(std::move(Func));
549 uint64_t MD5Res = DIEHash().computeTypeSignature(A);
551 // The exact same hash GCC produces for this DIE.
552 ASSERT_EQ(0x8f78211ddce3df10ULL, MD5Res);
557 // const static int PI = -3;
560 TEST(DIEHashTest, MemberSdata) {
561 DIE A(dwarf::DW_TAG_structure_type);
563 DIEString AStr(&One, "A");
564 A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &AStr);
565 A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
566 A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
567 A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
571 DIEString FStr(&One, "int");
572 DIE IntTyDIE(dwarf::DW_TAG_base_type);
573 IntTyDIE.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
574 IntTyDIE.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
575 IntTyDIE.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FStr);
577 DIEEntry IntTy(IntTyDIE);
578 auto PITyDIE = make_unique<DIE>(dwarf::DW_TAG_const_type);
579 PITyDIE->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntTy);
581 DIEEntry PITy(*PITyDIE);
582 auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
583 DIEString PIStr(&One, "PI");
585 DIEInteger NegThree(-3);
586 PI->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &PIStr);
587 PI->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
588 PI->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &Two);
589 PI->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PITy);
590 PI->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, &One);
591 PI->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
592 PI->addValue(dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, &NegThree);
594 A.addChild(std::move(PI));
596 uint64_t MD5Res = DIEHash().computeTypeSignature(A);
597 ASSERT_EQ(0x9a216000dd3788a7ULL, MD5Res);
602 // const static float PI = 3.14;
605 TEST(DIEHashTest, MemberBlock) {
606 DIE A(dwarf::DW_TAG_structure_type);
608 DIEString AStr(&One, "A");
609 A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &AStr);
610 A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
611 A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
612 A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
615 DIEString FStr(&One, "float");
616 auto FloatTyDIE = make_unique<DIE>(dwarf::DW_TAG_base_type);
617 FloatTyDIE->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
618 FloatTyDIE->addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Four);
619 FloatTyDIE->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FStr);
621 DIEEntry FloatTy(*FloatTyDIE);
622 auto PITyDIE = make_unique<DIE>(dwarf::DW_TAG_const_type);
623 PITyDIE->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FloatTy);
625 DIEEntry PITy(*PITyDIE);
626 auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
627 DIEString PIStr(&One, "PI");
629 PI->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &PIStr);
630 PI->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
631 PI->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &Two);
632 PI->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PITy);
633 PI->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, &One);
634 PI->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
637 DIEInteger Blk1(0xc3);
638 DIEInteger Blk2(0xf5);
639 DIEInteger Blk3(0x48);
640 DIEInteger Blk4(0x40);
642 PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk1);
643 PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk2);
644 PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk3);
645 PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk4);
647 PI->addValue(dwarf::DW_AT_const_value, dwarf::DW_FORM_block1, &PIBlock);
649 A.addChild(std::move(PI));
651 uint64_t MD5Res = DIEHash().computeTypeSignature(A);
652 ASSERT_EQ(0x493af53ad3d3f651ULL, MD5Res);