5876bb38f6405ddf9fc30eb09af568cc2230e8d2
[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 "../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 "gtest/gtest.h"
16
17 using namespace llvm;
18
19 namespace {
20 TEST(DIEHashTest, Data1) {
21   DIEHash Hash;
22   DIE Die(dwarf::DW_TAG_base_type);
23   DIEInteger Size(4);
24   Die.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Size);
25   uint64_t MD5Res = Hash.computeTypeSignature(Die);
26   ASSERT_EQ(0x1AFE116E83701108ULL, MD5Res);
27 }
28
29 // struct {};
30 TEST(DIEHashTest, TrivialType) {
31   DIE Unnamed(dwarf::DW_TAG_structure_type);
32   DIEInteger One(1);
33   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
34
35   // Line and file number are ignored.
36   Unnamed.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
37   Unnamed.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
38   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
39
40   // The exact same hash GCC produces for this DIE.
41   ASSERT_EQ(0x715305ce6cfd9ad1ULL, MD5Res);
42 }
43
44 // struct foo { };
45 TEST(DIEHashTest, NamedType) {
46   DIE Foo(dwarf::DW_TAG_structure_type);
47   DIEInteger One(1);
48   DIEString FooStr(&One, "foo");
49   Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
50   Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
51
52   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
53
54   // The exact same hash GCC produces for this DIE.
55   ASSERT_EQ(0xd566dbd2ca5265ffULL, MD5Res);
56 }
57
58 // namespace space { struct foo { }; }
59 TEST(DIEHashTest, NamespacedType) {
60   DIE CU(dwarf::DW_TAG_compile_unit);
61
62   DIE *Space = new DIE(dwarf::DW_TAG_namespace);
63   DIEInteger One(1);
64   DIEString SpaceStr(&One, "space");
65   Space->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &SpaceStr);
66   // DW_AT_declaration is ignored.
67   Space->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
68   // sibling?
69
70   DIE *Foo = new DIE(dwarf::DW_TAG_structure_type);
71   DIEString FooStr(&One, "foo");
72   Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
73   Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
74
75   Space->addChild(Foo);
76   CU.addChild(Space);
77
78   uint64_t MD5Res = DIEHash().computeTypeSignature(*Foo);
79
80   // The exact same hash GCC produces for this DIE.
81   ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res);
82 }
83
84 // struct { int member; };
85 TEST(DIEHashTest, TypeWithMember) {
86   DIE Unnamed(dwarf::DW_TAG_structure_type);
87   DIEInteger Four(4);
88   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
89
90   DIE *Member = new DIE(dwarf::DW_TAG_member);
91   DIEString MemberStr(&Four, "member");
92   Member->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemberStr);
93   DIEInteger Zero(0);
94   Member->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
95                    &Zero);
96
97   Unnamed.addChild(Member);
98
99   DIE Int(dwarf::DW_TAG_base_type);
100   DIEString IntStr(&Four, "int");
101   Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &IntStr);
102   Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
103   DIEInteger Five(5);
104   Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
105
106   DIEEntry IntRef(Int);
107   Member->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
108
109   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
110
111   ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res);
112 }
113
114 // struct foo { int mem1, mem2; };
115 TEST(DIEHashTest, ReusedType) {
116   DIE Unnamed(dwarf::DW_TAG_structure_type);
117   DIEInteger Eight(8);
118   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
119
120   DIE *Mem1 = new DIE(dwarf::DW_TAG_member);
121   DIEInteger Four(4);
122   DIEString Mem1Str(&Four, "mem1");
123   Mem1->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem1Str);
124   DIEInteger Zero(0);
125   Mem1->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
126                  &Zero);
127
128   Unnamed.addChild(Mem1);
129
130   DIE *Mem2 = new DIE(dwarf::DW_TAG_member);
131   DIEString Mem2Str(&Four, "mem2");
132   Mem2->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem2Str);
133   Mem2->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
134                  &Four);
135
136   Unnamed.addChild(Mem2);
137
138   DIE Int(dwarf::DW_TAG_base_type);
139   DIEString IntStr(&Four, "int");
140   Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &IntStr);
141   Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
142   DIEInteger Five(5);
143   Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
144
145   DIEEntry IntRef(Int);
146   Mem1->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
147   Mem2->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
148
149   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
150
151   ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res);
152 }
153
154 // struct foo { static foo f; };
155 TEST(DIEHashTest, RecursiveType) {
156   DIE Foo(dwarf::DW_TAG_structure_type);
157   DIEInteger One(1);
158   Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
159   DIEString FooStr(&One, "foo");
160   Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
161
162   DIE *Mem = new DIE(dwarf::DW_TAG_member);
163   DIEString MemStr(&One, "mem");
164   Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
165   DIEEntry FooRef(Foo);
166   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRef);
167   // DW_AT_external and DW_AT_declaration are ignored anyway, so skip them.
168
169   Foo.addChild(Mem);
170
171   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
172
173   ASSERT_EQ(0x73d8b25aef227b06ULL, MD5Res);
174 }
175
176 // struct foo { foo *mem; };
177 TEST(DIEHashTest, Pointer) {
178   DIE Foo(dwarf::DW_TAG_structure_type);
179   DIEInteger Eight(8);
180   Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
181   DIEString FooStr(&Eight, "foo");
182   Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
183
184   DIE *Mem = new DIE(dwarf::DW_TAG_member);
185   DIEString MemStr(&Eight, "mem");
186   Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
187   DIEInteger Zero(0);
188   Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
189
190   DIE FooPtr(dwarf::DW_TAG_pointer_type);
191   FooPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
192   DIEEntry FooRef(Foo);
193   FooPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRef);
194
195   DIEEntry FooPtrRef(FooPtr);
196   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooPtrRef);
197
198   Foo.addChild(Mem);
199
200   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
201
202   ASSERT_EQ(0x74ea73862e8708d2ULL, MD5Res);
203 }
204
205 // struct foo { foo &mem; };
206 TEST(DIEHashTest, Reference) {
207   DIE Foo(dwarf::DW_TAG_structure_type);
208   DIEInteger Eight(8);
209   Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
210   DIEString FooStr(&Eight, "foo");
211   Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
212
213   DIE *Mem = new DIE(dwarf::DW_TAG_member);
214   DIEString MemStr(&Eight, "mem");
215   Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
216   DIEInteger Zero(0);
217   Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
218
219   DIE FooRef(dwarf::DW_TAG_reference_type);
220   FooRef.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
221   DIEEntry FooEntry(Foo);
222   FooRef.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooEntry);
223
224   DIE FooRefConst(dwarf::DW_TAG_const_type);
225   DIEEntry FooRefRef(FooRef);
226   FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefRef);
227
228   DIEEntry FooRefConstRef(FooRefConst);
229   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefConstRef);
230
231   Foo.addChild(Mem);
232
233   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
234
235   ASSERT_EQ(0xa0b15f467ad4525bULL, MD5Res);
236 }
237
238 // struct foo { foo &&mem; };
239 TEST(DIEHashTest, RValueReference) {
240   DIE Foo(dwarf::DW_TAG_structure_type);
241   DIEInteger Eight(8);
242   Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
243   DIEString FooStr(&Eight, "foo");
244   Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
245
246   DIE *Mem = new DIE(dwarf::DW_TAG_member);
247   DIEString MemStr(&Eight, "mem");
248   Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
249   DIEInteger Zero(0);
250   Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
251
252   DIE FooRef(dwarf::DW_TAG_rvalue_reference_type);
253   FooRef.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
254   DIEEntry FooEntry(Foo);
255   FooRef.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooEntry);
256
257   DIE FooRefConst(dwarf::DW_TAG_const_type);
258   DIEEntry FooRefRef(FooRef);
259   FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefRef);
260
261   DIEEntry FooRefConstRef(FooRefConst);
262   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefConstRef);
263
264   Foo.addChild(Mem);
265
266   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
267
268   ASSERT_EQ(0xad211c8c3b31e57ULL, MD5Res);
269 }
270
271 // struct foo { foo foo::*mem; };
272 TEST(DIEHashTest, PtrToMember) {
273   DIE Foo(dwarf::DW_TAG_structure_type);
274   DIEInteger Eight(8);
275   Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
276   DIEString FooStr(&Eight, "foo");
277   Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
278
279   DIE *Mem = new DIE(dwarf::DW_TAG_member);
280   DIEString MemStr(&Eight, "mem");
281   Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
282   DIEInteger Zero(0);
283   Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
284
285   DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
286   DIEEntry FooEntry(Foo);
287   PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooEntry);
288   PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
289                        &FooEntry);
290
291   DIEEntry PtrToFooMemRef(PtrToFooMem);
292   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
293
294   Foo.addChild(Mem);
295
296   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
297
298   ASSERT_EQ(0x852e0c9ff7c04ebULL, MD5Res);
299 }
300
301 // Check that the hash for a pointer-to-member matches regardless of whether the
302 // pointed-to type is a declaration or a definition.
303 //
304 //   struct bar; // { };
305 //   struct foo { bar foo::*mem; };
306 TEST(DIEHashTest, PtrToMemberDeclDefMatch) {
307   DIEInteger Zero(0);
308   DIEInteger One(1);
309   DIEInteger Eight(8);
310   DIEString FooStr(&Eight, "foo");
311   DIEString BarStr(&Eight, "bar");
312   DIEString MemStr(&Eight, "mem");
313   uint64_t MD5ResDecl;
314   {
315     DIE Bar(dwarf::DW_TAG_structure_type);
316     Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &BarStr);
317     Bar.addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
318
319     DIE Foo(dwarf::DW_TAG_structure_type);
320     Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
321     Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
322
323     DIE *Mem = new DIE(dwarf::DW_TAG_member);
324     Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
325     Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
326                   &Zero);
327
328     DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
329     DIEEntry BarEntry(Bar);
330     PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
331     DIEEntry FooEntry(Foo);
332     PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
333                          &FooEntry);
334
335     DIEEntry PtrToFooMemRef(PtrToFooMem);
336     Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
337
338     Foo.addChild(Mem);
339
340     MD5ResDecl = DIEHash().computeTypeSignature(Foo);
341   }
342   uint64_t MD5ResDef;
343   {
344     DIE Bar(dwarf::DW_TAG_structure_type);
345     Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &BarStr);
346     Bar.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
347
348     DIE Foo(dwarf::DW_TAG_structure_type);
349     Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
350     Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
351
352     DIE *Mem = new DIE(dwarf::DW_TAG_member);
353     Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
354     Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
355                   &Zero);
356
357     DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
358     DIEEntry BarEntry(Bar);
359     PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
360     DIEEntry FooEntry(Foo);
361     PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
362                          &FooEntry);
363
364     DIEEntry PtrToFooMemRef(PtrToFooMem);
365     Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
366
367     Foo.addChild(Mem);
368
369     MD5ResDef = DIEHash().computeTypeSignature(Foo);
370   }
371   ASSERT_EQ(MD5ResDef, MD5ResDecl);
372 }
373
374 // Check that the hash for a pointer-to-member matches regardless of whether the
375 // pointed-to type is a declaration or a definition.
376 //
377 //   struct bar; // { };
378 //   struct foo { bar bar::*mem; };
379 TEST(DIEHashTest, PtrToMemberDeclDefMisMatch) {
380   DIEInteger Zero(0);
381   DIEInteger One(1);
382   DIEInteger Eight(8);
383   DIEString FooStr(&Eight, "foo");
384   DIEString BarStr(&Eight, "bar");
385   DIEString MemStr(&Eight, "mem");
386   uint64_t MD5ResDecl;
387   {
388     DIE Bar(dwarf::DW_TAG_structure_type);
389     Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &BarStr);
390     Bar.addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
391
392     DIE Foo(dwarf::DW_TAG_structure_type);
393     Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
394     Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
395
396     DIE *Mem = new DIE(dwarf::DW_TAG_member);
397     Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
398     Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
399                   &Zero);
400
401     DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
402     DIEEntry BarEntry(Bar);
403     PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
404     PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
405                          &BarEntry);
406
407     DIEEntry PtrToFooMemRef(PtrToFooMem);
408     Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
409
410     Foo.addChild(Mem);
411
412     MD5ResDecl = DIEHash().computeTypeSignature(Foo);
413   }
414   uint64_t MD5ResDef;
415   {
416     DIE Bar(dwarf::DW_TAG_structure_type);
417     Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &BarStr);
418     Bar.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
419
420     DIE Foo(dwarf::DW_TAG_structure_type);
421     Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
422     Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
423
424     DIE *Mem = new DIE(dwarf::DW_TAG_member);
425     Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
426     Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
427                   &Zero);
428
429     DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
430     DIEEntry BarEntry(Bar);
431     PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
432     PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
433                          &BarEntry);
434
435     DIEEntry PtrToFooMemRef(PtrToFooMem);
436     Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
437
438     Foo.addChild(Mem);
439
440     MD5ResDef = DIEHash().computeTypeSignature(Foo);
441   }
442   // FIXME: This seems to be a bug in the DWARF type hashing specification that
443   // only uses the brief name hashing for types referenced via DW_AT_type. In
444   // this case the type is referenced via DW_AT_containing_type and full hashing
445   // causes a hash to differ when the containing type is a declaration in one TU
446   // and a definition in another.
447   ASSERT_NE(MD5ResDef, MD5ResDecl);
448 }
449
450 // struct { } a;
451 // struct foo { decltype(a) mem; };
452 TEST(DIEHashTest, RefUnnamedType) {
453   DIEInteger Zero(0);
454   DIEInteger One(1);
455   DIEInteger Eight(8);
456   DIEString FooStr(&Zero, "foo");
457   DIEString MemStr(&Zero, "mem");
458
459   DIE Unnamed(dwarf::DW_TAG_structure_type);
460   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
461
462   DIE Foo(dwarf::DW_TAG_structure_type);
463   Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
464   Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
465
466   DIE *Mem = new DIE(dwarf::DW_TAG_member);
467   Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
468   Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
469
470   DIE UnnamedPtr(dwarf::DW_TAG_pointer_type);
471   UnnamedPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
472   DIEEntry UnnamedRef(Unnamed);
473   UnnamedPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &UnnamedRef);
474
475   DIEEntry UnnamedPtrRef(UnnamedPtr);
476   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &UnnamedPtrRef);
477
478   Foo.addChild(Mem);
479
480   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
481
482   ASSERT_EQ(0x954e026f01c02529ULL, MD5Res);
483 }
484
485 // struct { struct foo { }; };
486 TEST(DIEHashTest, NestedType) {
487   DIE Unnamed(dwarf::DW_TAG_structure_type);
488   DIEInteger One(1);
489   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
490
491   DIE *Foo = new DIE(dwarf::DW_TAG_structure_type);
492   DIEString FooStr(&One, "foo");
493   Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
494   Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
495
496   Unnamed.addChild(Foo);
497
498   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
499
500   // The exact same hash GCC produces for this DIE.
501   ASSERT_EQ(0xde8a3b7b43807f4aULL, MD5Res);
502 }
503
504 // struct { static void func(); };
505 TEST(DIEHashTest, MemberFunc) {
506   DIE Unnamed(dwarf::DW_TAG_structure_type);
507   DIEInteger One(1);
508   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
509
510   DIE *Func = new DIE(dwarf::DW_TAG_subprogram);
511   DIEString FuncStr(&One, "func");
512   Func->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FuncStr);
513
514   Unnamed.addChild(Func);
515
516   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
517
518   // The exact same hash GCC produces for this DIE.
519   ASSERT_EQ(0xd36a1b6dfb604ba0ULL, MD5Res);
520 }
521
522 // struct A {
523 //   static void func();
524 // };
525 TEST(DIEHashTest, MemberFuncFlag) {
526   DIE A(dwarf::DW_TAG_structure_type);
527   DIEInteger One(1);
528   DIEString AStr(&One, "A");
529   A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &AStr);
530   A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
531   A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
532   A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
533
534   DIE *Func = new DIE(dwarf::DW_TAG_subprogram);
535   DIEString FuncStr(&One, "func");
536   DIEString FuncLinkage(&One, "_ZN1A4funcEv");
537   DIEInteger Two(2);
538   Func->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, &One);
539   Func->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FuncStr);
540   Func->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
541   Func->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &Two);
542   Func->addValue(dwarf::DW_AT_linkage_name, dwarf::DW_FORM_strp, &FuncLinkage);
543   Func->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
544
545   A.addChild(Func);
546
547   uint64_t MD5Res = DIEHash().computeTypeSignature(A);
548
549   // The exact same hash GCC produces for this DIE.
550   ASSERT_EQ(0x8f78211ddce3df10ULL, MD5Res);
551 }
552
553 // Derived from:
554 // struct A {
555 //   const static int PI = -3;
556 // };
557 // A a;
558 TEST(DIEHashTest, MemberSdata) {
559   DIE A(dwarf::DW_TAG_structure_type);
560   DIEInteger One(1);
561   DIEString AStr(&One, "A");
562   A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &AStr);
563   A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
564   A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
565   A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
566
567   DIEInteger Four(4);
568   DIEInteger Five(5);
569   DIEString FStr(&One, "int");
570   DIE IntTyDIE(dwarf::DW_TAG_base_type);
571   IntTyDIE.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
572   IntTyDIE.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
573   IntTyDIE.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FStr);
574
575   DIEEntry IntTy(IntTyDIE);
576   DIE *PITyDIE = new DIE(dwarf::DW_TAG_const_type);
577   PITyDIE->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntTy);
578
579   DIEEntry PITy(*PITyDIE);
580   DIE *PI = new DIE(dwarf::DW_TAG_member);
581   DIEString PIStr(&One, "PI");
582   DIEInteger Two(2);
583   DIEInteger NegThree(-3);
584   PI->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &PIStr);
585   PI->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
586   PI->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &Two);
587   PI->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PITy);
588   PI->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, &One);
589   PI->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
590   PI->addValue(dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, &NegThree);
591
592   A.addChild(PI);
593
594   uint64_t MD5Res = DIEHash().computeTypeSignature(A);
595   ASSERT_EQ(0x9a216000dd3788a7ULL, MD5Res);
596 }
597
598 // Derived from:
599 // struct A {
600 //   const static float PI = 3.14;
601 // };
602 // A a;
603 TEST(DIEHashTest, MemberBlock) {
604   DIE A(dwarf::DW_TAG_structure_type);
605   DIEInteger One(1);
606   DIEString AStr(&One, "A");
607   A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &AStr);
608   A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
609   A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
610   A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
611
612   DIEInteger Four(4);
613   DIEString FStr(&One, "float");
614   DIE *FloatTyDIE = new DIE(dwarf::DW_TAG_base_type);
615   FloatTyDIE->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
616   FloatTyDIE->addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Four);
617   FloatTyDIE->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FStr);
618
619   DIEEntry FloatTy(*FloatTyDIE);
620   DIE *PITyDIE = new DIE(dwarf::DW_TAG_const_type);
621   PITyDIE->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FloatTy);
622
623   DIEEntry PITy(*PITyDIE);
624   DIE *PI = new DIE(dwarf::DW_TAG_member);
625   DIEString PIStr(&One, "PI");
626   DIEInteger Two(2);
627   PI->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &PIStr);
628   PI->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
629   PI->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &Two);
630   PI->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PITy);
631   PI->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, &One);
632   PI->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
633
634   DIEBlock PIBlock;
635   DIEInteger Blk1(0xc3);
636   DIEInteger Blk2(0xf5);
637   DIEInteger Blk3(0x48);
638   DIEInteger Blk4(0x40);
639
640   PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk1);
641   PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk2);
642   PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk3);
643   PIBlock.addValue((dwarf::Attribute)0, dwarf::DW_FORM_data1, &Blk4);
644
645   PI->addValue(dwarf::DW_AT_const_value, dwarf::DW_FORM_block1, &PIBlock);
646
647   A.addChild(PI);
648
649   uint64_t MD5Res = DIEHash().computeTypeSignature(A);
650   ASSERT_EQ(0x493af53ad3d3f651ULL, MD5Res);
651 }
652 }