8e78f0ca13b5411225e94fb9569da129a29a004c
[oota-llvm.git] / unittests / CodeGen / DIEHashTest.cpp
1 //===- llvm/unittest/DebugInfo/DWARFFormValueTest.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 //===----------------------------------------------------------------------===//
9
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"
18
19 using namespace llvm;
20
21 namespace {
22
23 // Test fixture
24 class DIEHashTest : public testing::Test {
25   StringMap<DwarfStringPoolEntry> Pool;
26
27 public:
28   DIEString getString(StringRef S) {
29     DwarfStringPoolEntry Entry = {nullptr, 1, 1};
30     return DIEString(
31         DwarfStringPoolEntryRef(*Pool.insert(std::make_pair(S, Entry)).first));
32   }
33 };
34
35 TEST_F(DIEHashTest, Data1) {
36   DIEHash Hash;
37   DIE Die(dwarf::DW_TAG_base_type);
38   DIEInteger Size(4);
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);
42 }
43
44 // struct {};
45 TEST_F(DIEHashTest, TrivialType) {
46   DIE Unnamed(dwarf::DW_TAG_structure_type);
47   DIEInteger One(1);
48   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
49
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);
54
55   // The exact same hash GCC produces for this DIE.
56   ASSERT_EQ(0x715305ce6cfd9ad1ULL, MD5Res);
57 }
58
59 // struct foo { };
60 TEST_F(DIEHashTest, NamedType) {
61   DIE Foo(dwarf::DW_TAG_structure_type);
62   DIEInteger One(1);
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);
66
67   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
68
69   // The exact same hash GCC produces for this DIE.
70   ASSERT_EQ(0xd566dbd2ca5265ffULL, MD5Res);
71 }
72
73 // namespace space { struct foo { }; }
74 TEST_F(DIEHashTest, NamespacedType) {
75   DIE CU(dwarf::DW_TAG_compile_unit);
76
77   auto Space = make_unique<DIE>(dwarf::DW_TAG_namespace);
78   DIEInteger One(1);
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);
83   // sibling?
84
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);
89
90   DIE &N = *Foo;
91   Space->addChild(std::move(Foo));
92   CU.addChild(std::move(Space));
93
94   uint64_t MD5Res = DIEHash().computeTypeSignature(N);
95
96   // The exact same hash GCC produces for this DIE.
97   ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res);
98 }
99
100 // struct { int member; };
101 TEST_F(DIEHashTest, TypeWithMember) {
102   DIE Unnamed(dwarf::DW_TAG_structure_type);
103   DIEInteger Four(4);
104   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
105
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);
110   DIEInteger Five(5);
111   Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five);
112
113   DIEEntry IntRef(Int);
114
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);
118   DIEInteger Zero(0);
119   Member->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
120                    Zero);
121   Member->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef);
122
123   Unnamed.addChild(std::move(Member));
124
125   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
126
127   ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res);
128 }
129
130 // struct foo { int mem1, mem2; };
131 TEST_F(DIEHashTest, ReusedType) {
132   DIE Unnamed(dwarf::DW_TAG_structure_type);
133   DIEInteger Eight(8);
134   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
135
136   DIEInteger Four(4);
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);
141   DIEInteger Five(5);
142   Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five);
143
144   DIEEntry IntRef(Int);
145
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);
149   DIEInteger Zero(0);
150   Mem1->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
151                  Zero);
152   Mem1->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef);
153
154   Unnamed.addChild(std::move(Mem1));
155
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,
160                  Four);
161   Mem2->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef);
162
163   Unnamed.addChild(std::move(Mem2));
164
165   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
166
167   ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res);
168 }
169
170 // struct foo { static foo f; };
171 TEST_F(DIEHashTest, RecursiveType) {
172   DIE Foo(dwarf::DW_TAG_structure_type);
173   DIEInteger One(1);
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);
177
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.
184
185   Foo.addChild(std::move(Mem));
186
187   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
188
189   ASSERT_EQ(0x73d8b25aef227b06ULL, MD5Res);
190 }
191
192 // struct foo { foo *mem; };
193 TEST_F(DIEHashTest, Pointer) {
194   DIE Foo(dwarf::DW_TAG_structure_type);
195   DIEInteger Eight(8);
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);
199
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);
203   DIEInteger Zero(0);
204   Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero);
205
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);
210
211   DIEEntry FooPtrRef(FooPtr);
212   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooPtrRef);
213
214   Foo.addChild(std::move(Mem));
215
216   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
217
218   ASSERT_EQ(0x74ea73862e8708d2ULL, MD5Res);
219 }
220
221 // struct foo { foo &mem; };
222 TEST_F(DIEHashTest, Reference) {
223   DIE Foo(dwarf::DW_TAG_structure_type);
224   DIEInteger Eight(8);
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);
228
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);
232   DIEInteger Zero(0);
233   Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero);
234
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);
239
240   DIE FooRefConst(dwarf::DW_TAG_const_type);
241   DIEEntry FooRefRef(FooRef);
242   FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefRef);
243
244   DIEEntry FooRefConstRef(FooRefConst);
245   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefConstRef);
246
247   Foo.addChild(std::move(Mem));
248
249   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
250
251   ASSERT_EQ(0xa0b15f467ad4525bULL, MD5Res);
252 }
253
254 // struct foo { foo &&mem; };
255 TEST_F(DIEHashTest, RValueReference) {
256   DIE Foo(dwarf::DW_TAG_structure_type);
257   DIEInteger Eight(8);
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);
261
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);
265   DIEInteger Zero(0);
266   Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero);
267
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);
272
273   DIE FooRefConst(dwarf::DW_TAG_const_type);
274   DIEEntry FooRefRef(FooRef);
275   FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefRef);
276
277   DIEEntry FooRefConstRef(FooRefConst);
278   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefConstRef);
279
280   Foo.addChild(std::move(Mem));
281
282   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
283
284   ASSERT_EQ(0xad211c8c3b31e57ULL, MD5Res);
285 }
286
287 // struct foo { foo foo::*mem; };
288 TEST_F(DIEHashTest, PtrToMember) {
289   DIE Foo(dwarf::DW_TAG_structure_type);
290   DIEInteger Eight(8);
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);
294
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);
298   DIEInteger Zero(0);
299   Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, Zero);
300
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,
305                        FooEntry);
306
307   DIEEntry PtrToFooMemRef(PtrToFooMem);
308   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef);
309
310   Foo.addChild(std::move(Mem));
311
312   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
313
314   ASSERT_EQ(0x852e0c9ff7c04ebULL, MD5Res);
315 }
316
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.
319 //
320 //   struct bar; // { };
321 //   struct foo { bar foo::*mem; };
322 TEST_F(DIEHashTest, PtrToMemberDeclDefMatch) {
323   DIEInteger Zero(0);
324   DIEInteger One(1);
325   DIEInteger Eight(8);
326   DIEString FooStr = getString("foo");
327   DIEString BarStr = getString("bar");
328   DIEString MemStr = getString("mem");
329   uint64_t MD5ResDecl;
330   {
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);
334
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);
338
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,
342                   Zero);
343
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,
349                          FooEntry);
350
351     DIEEntry PtrToFooMemRef(PtrToFooMem);
352     Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef);
353
354     Foo.addChild(std::move(Mem));
355
356     MD5ResDecl = DIEHash().computeTypeSignature(Foo);
357   }
358   uint64_t MD5ResDef;
359   {
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);
363
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);
367
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,
371                   Zero);
372
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,
378                          FooEntry);
379
380     DIEEntry PtrToFooMemRef(PtrToFooMem);
381     Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef);
382
383     Foo.addChild(std::move(Mem));
384
385     MD5ResDef = DIEHash().computeTypeSignature(Foo);
386   }
387   ASSERT_EQ(MD5ResDef, MD5ResDecl);
388 }
389
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.
392 //
393 //   struct bar; // { };
394 //   struct foo { bar bar::*mem; };
395 TEST_F(DIEHashTest, PtrToMemberDeclDefMisMatch) {
396   DIEInteger Zero(0);
397   DIEInteger One(1);
398   DIEInteger Eight(8);
399   DIEString FooStr = getString("foo");
400   DIEString BarStr = getString("bar");
401   DIEString MemStr = getString("mem");
402   uint64_t MD5ResDecl;
403   {
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);
407
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);
411
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,
415                   Zero);
416
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,
421                          BarEntry);
422
423     DIEEntry PtrToFooMemRef(PtrToFooMem);
424     Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef);
425
426     Foo.addChild(std::move(Mem));
427
428     MD5ResDecl = DIEHash().computeTypeSignature(Foo);
429   }
430   uint64_t MD5ResDef;
431   {
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);
435
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);
439
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,
443                   Zero);
444
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,
449                          BarEntry);
450
451     DIEEntry PtrToFooMemRef(PtrToFooMem);
452     Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef);
453
454     Foo.addChild(std::move(Mem));
455
456     MD5ResDef = DIEHash().computeTypeSignature(Foo);
457   }
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);
464 }
465
466 // struct { } a;
467 // struct foo { decltype(a) mem; };
468 TEST_F(DIEHashTest, RefUnnamedType) {
469   DIEInteger Zero(0);
470   DIEInteger One(1);
471   DIEInteger Eight(8);
472   DIEString FooStr = getString("foo");
473   DIEString MemStr = getString("mem");
474
475   DIE Unnamed(dwarf::DW_TAG_structure_type);
476   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
477
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);
481
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);
485
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);
490
491   DIEEntry UnnamedPtrRef(UnnamedPtr);
492   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, UnnamedPtrRef);
493
494   Foo.addChild(std::move(Mem));
495
496   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
497
498   ASSERT_EQ(0x954e026f01c02529ULL, MD5Res);
499 }
500
501 // struct { struct foo { }; };
502 TEST_F(DIEHashTest, NestedType) {
503   DIE Unnamed(dwarf::DW_TAG_structure_type);
504   DIEInteger One(1);
505   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
506
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);
511
512   Unnamed.addChild(std::move(Foo));
513
514   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
515
516   // The exact same hash GCC produces for this DIE.
517   ASSERT_EQ(0xde8a3b7b43807f4aULL, MD5Res);
518 }
519
520 // struct { static void func(); };
521 TEST_F(DIEHashTest, MemberFunc) {
522   DIE Unnamed(dwarf::DW_TAG_structure_type);
523   DIEInteger One(1);
524   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
525
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);
529
530   Unnamed.addChild(std::move(Func));
531
532   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
533
534   // The exact same hash GCC produces for this DIE.
535   ASSERT_EQ(0xd36a1b6dfb604ba0ULL, MD5Res);
536 }
537
538 // struct A {
539 //   static void func();
540 // };
541 TEST_F(DIEHashTest, MemberFuncFlag) {
542   DIE A(dwarf::DW_TAG_structure_type);
543   DIEInteger One(1);
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);
549
550   auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram);
551   DIEString FuncStr = getString("func");
552   DIEString FuncLinkage = getString("_ZN1A4funcEv");
553   DIEInteger Two(2);
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);
560
561   A.addChild(std::move(Func));
562
563   uint64_t MD5Res = DIEHash().computeTypeSignature(A);
564
565   // The exact same hash GCC produces for this DIE.
566   ASSERT_EQ(0x8f78211ddce3df10ULL, MD5Res);
567 }
568
569 // Derived from:
570 // struct A {
571 //   const static int PI = -3;
572 // };
573 // A a;
574 TEST_F(DIEHashTest, MemberSdata) {
575   DIE A(dwarf::DW_TAG_structure_type);
576   DIEInteger One(1);
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);
582
583   DIEInteger Four(4);
584   DIEInteger Five(5);
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);
590
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);
594
595   DIEEntry PITy(*PITyDIE);
596   auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
597   DIEString PIStr = getString("PI");
598   DIEInteger Two(2);
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);
607
608   A.addChild(std::move(PI));
609
610   uint64_t MD5Res = DIEHash().computeTypeSignature(A);
611   ASSERT_EQ(0x9a216000dd3788a7ULL, MD5Res);
612 }
613
614 // Derived from:
615 // struct A {
616 //   const static float PI = 3.14;
617 // };
618 // A a;
619 TEST_F(DIEHashTest, MemberBlock) {
620   DIE A(dwarf::DW_TAG_structure_type);
621   DIEInteger One(1);
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);
627
628   DIEInteger Four(4);
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);
634
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);
638
639   DIEEntry PITy(*PITyDIE);
640   auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
641   DIEString PIStr = getString("PI");
642   DIEInteger Two(2);
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);
649
650   DIEBlock PIBlock;
651   DIEInteger Blk1(0xc3);
652   DIEInteger Blk2(0xf5);
653   DIEInteger Blk3(0x48);
654   DIEInteger Blk4(0x40);
655
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);
660
661   PI->addValue(dwarf::DW_AT_const_value, dwarf::DW_FORM_block1, &PIBlock);
662
663   A.addChild(std::move(PI));
664
665   uint64_t MD5Res = DIEHash().computeTypeSignature(A);
666   ASSERT_EQ(0x493af53ad3d3f651ULL, MD5Res);
667 }
668 }