DIEHashTest.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  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. #include "../lib/CodeGen/AsmPrinter/DIE.h"
  10. #include "../lib/CodeGen/AsmPrinter/DIEHash.h"
  11. #include "llvm/Support/Dwarf.h"
  12. #include "llvm/Support/Debug.h"
  13. #include "llvm/Support/Format.h"
  14. #include "gtest/gtest.h"
  15. using namespace llvm;
  16. namespace {
  17. TEST(DIEHashTest, Data1) {
  18. DIEHash Hash;
  19. DIE Die(dwarf::DW_TAG_base_type);
  20. DIEInteger Size(4);
  21. Die.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Size);
  22. uint64_t MD5Res = Hash.computeTypeSignature(Die);
  23. ASSERT_EQ(0x1AFE116E83701108ULL, MD5Res);
  24. }
  25. // struct {};
  26. TEST(DIEHashTest, TrivialType) {
  27. DIE Unnamed(dwarf::DW_TAG_structure_type);
  28. DIEInteger One(1);
  29. Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
  30. // Line and file number are ignored.
  31. Unnamed.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
  32. Unnamed.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
  33. uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
  34. // The exact same hash GCC produces for this DIE.
  35. ASSERT_EQ(0x715305ce6cfd9ad1ULL, MD5Res);
  36. }
  37. // struct foo { };
  38. TEST(DIEHashTest, NamedType) {
  39. DIE Foo(dwarf::DW_TAG_structure_type);
  40. DIEInteger One(1);
  41. DIEString FooStr(&One, "foo");
  42. Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
  43. Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
  44. uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
  45. // The exact same hash GCC produces for this DIE.
  46. ASSERT_EQ(0xd566dbd2ca5265ffULL, MD5Res);
  47. }
  48. // namespace space { struct foo { }; }
  49. TEST(DIEHashTest, NamespacedType) {
  50. DIE CU(dwarf::DW_TAG_compile_unit);
  51. DIE *Space = new DIE(dwarf::DW_TAG_namespace);
  52. DIEInteger One(1);
  53. DIEString SpaceStr(&One, "space");
  54. Space->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &SpaceStr);
  55. // DW_AT_declaration is ignored.
  56. Space->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
  57. // sibling?
  58. DIE *Foo = new DIE(dwarf::DW_TAG_structure_type);
  59. DIEString FooStr(&One, "foo");
  60. Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
  61. Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
  62. Space->addChild(Foo);
  63. CU.addChild(Space);
  64. uint64_t MD5Res = DIEHash().computeTypeSignature(*Foo);
  65. // The exact same hash GCC produces for this DIE.
  66. ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res);
  67. }
  68. // struct { int member; };
  69. TEST(DIEHashTest, TypeWithMember) {
  70. DIE Unnamed(dwarf::DW_TAG_structure_type);
  71. DIEInteger Four(4);
  72. Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
  73. DIE *Member = new DIE(dwarf::DW_TAG_member);
  74. DIEString MemberStr(&Four, "member");
  75. Member->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemberStr);
  76. DIEInteger Zero(0);
  77. Member->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
  78. Unnamed.addChild(Member);
  79. DIE Int(dwarf::DW_TAG_base_type);
  80. DIEString IntStr(&Four, "int");
  81. Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &IntStr);
  82. Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
  83. DIEInteger Five(5);
  84. Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
  85. DIEEntry IntRef(&Int);
  86. Member->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
  87. uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
  88. ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res);
  89. }
  90. // struct foo { int mem1, mem2; };
  91. TEST(DIEHashTest, ReusedType) {
  92. DIE Unnamed(dwarf::DW_TAG_structure_type);
  93. DIEInteger Eight(8);
  94. Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  95. DIE *Mem1 = new DIE(dwarf::DW_TAG_member);
  96. DIEInteger Four(4);
  97. DIEString Mem1Str(&Four, "mem1");
  98. Mem1->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem1Str);
  99. DIEInteger Zero(0);
  100. Mem1->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
  101. Unnamed.addChild(Mem1);
  102. DIE *Mem2 = new DIE(dwarf::DW_TAG_member);
  103. DIEString Mem2Str(&Four, "mem2");
  104. Mem2->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem2Str);
  105. Mem2->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Four);
  106. Unnamed.addChild(Mem2);
  107. DIE Int(dwarf::DW_TAG_base_type);
  108. DIEString IntStr(&Four, "int");
  109. Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &IntStr);
  110. Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
  111. DIEInteger Five(5);
  112. Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
  113. DIEEntry IntRef(&Int);
  114. Mem1->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
  115. Mem2->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
  116. uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
  117. ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res);
  118. }
  119. // struct foo { static foo f; };
  120. TEST(DIEHashTest, RecursiveType) {
  121. DIE Foo(dwarf::DW_TAG_structure_type);
  122. DIEInteger One(1);
  123. Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
  124. DIEString FooStr(&One, "foo");
  125. Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
  126. DIE *Mem = new DIE(dwarf::DW_TAG_member);
  127. DIEString MemStr(&One, "mem");
  128. Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
  129. DIEEntry FooRef(&Foo);
  130. Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRef);
  131. // DW_AT_external and DW_AT_declaration are ignored anyway, so skip them.
  132. Foo.addChild(Mem);
  133. uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
  134. ASSERT_EQ(0x73d8b25aef227b06ULL, MD5Res);
  135. }
  136. // struct foo { foo *mem; };
  137. TEST(DIEHashTest, Pointer) {
  138. DIE Foo(dwarf::DW_TAG_structure_type);
  139. DIEInteger Eight(8);
  140. Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  141. DIEString FooStr(&Eight, "foo");
  142. Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
  143. DIE *Mem = new DIE(dwarf::DW_TAG_member);
  144. DIEString MemStr(&Eight, "mem");
  145. Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
  146. DIEInteger Zero(0);
  147. Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
  148. DIE FooPtr(dwarf::DW_TAG_pointer_type);
  149. FooPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  150. DIEEntry FooRef(&Foo);
  151. FooPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRef);
  152. DIEEntry FooPtrRef(&FooPtr);
  153. Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooPtrRef);
  154. Foo.addChild(Mem);
  155. uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
  156. ASSERT_EQ(0x74ea73862e8708d2ULL, MD5Res);
  157. }
  158. // struct foo { foo &mem; };
  159. TEST(DIEHashTest, Reference) {
  160. DIE Foo(dwarf::DW_TAG_structure_type);
  161. DIEInteger Eight(8);
  162. Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  163. DIEString FooStr(&Eight, "foo");
  164. Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
  165. DIE *Mem = new DIE(dwarf::DW_TAG_member);
  166. DIEString MemStr(&Eight, "mem");
  167. Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
  168. DIEInteger Zero(0);
  169. Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
  170. DIE FooRef(dwarf::DW_TAG_reference_type);
  171. FooRef.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  172. DIEEntry FooEntry(&Foo);
  173. FooRef.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooEntry);
  174. DIE FooRefConst(dwarf::DW_TAG_const_type);
  175. DIEEntry FooRefRef(&FooRef);
  176. FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefRef);
  177. DIEEntry FooRefConstRef(&FooRefConst);
  178. Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefConstRef);
  179. Foo.addChild(Mem);
  180. uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
  181. ASSERT_EQ(0xa0b15f467ad4525bULL, MD5Res);
  182. }
  183. // struct foo { foo &&mem; };
  184. TEST(DIEHashTest, RValueReference) {
  185. DIE Foo(dwarf::DW_TAG_structure_type);
  186. DIEInteger Eight(8);
  187. Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  188. DIEString FooStr(&Eight, "foo");
  189. Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
  190. DIE *Mem = new DIE(dwarf::DW_TAG_member);
  191. DIEString MemStr(&Eight, "mem");
  192. Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
  193. DIEInteger Zero(0);
  194. Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
  195. DIE FooRef(dwarf::DW_TAG_rvalue_reference_type);
  196. FooRef.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  197. DIEEntry FooEntry(&Foo);
  198. FooRef.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooEntry);
  199. DIE FooRefConst(dwarf::DW_TAG_const_type);
  200. DIEEntry FooRefRef(&FooRef);
  201. FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefRef);
  202. DIEEntry FooRefConstRef(&FooRefConst);
  203. Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefConstRef);
  204. Foo.addChild(Mem);
  205. uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
  206. ASSERT_EQ(0xad211c8c3b31e57ULL, MD5Res);
  207. }
  208. // struct foo { foo foo::*mem; };
  209. TEST(DIEHashTest, PtrToMember) {
  210. DIE Foo(dwarf::DW_TAG_structure_type);
  211. DIEInteger Eight(8);
  212. Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  213. DIEString FooStr(&Eight, "foo");
  214. Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
  215. DIE *Mem = new DIE(dwarf::DW_TAG_member);
  216. DIEString MemStr(&Eight, "mem");
  217. Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
  218. DIEInteger Zero(0);
  219. Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
  220. DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
  221. DIEEntry FooEntry(&Foo);
  222. PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooEntry);
  223. PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, &FooEntry);
  224. DIEEntry PtrToFooMemRef(&PtrToFooMem);
  225. Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
  226. Foo.addChild(Mem);
  227. uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
  228. ASSERT_EQ(0x852e0c9ff7c04ebULL, MD5Res);
  229. }
  230. // Check that the hash for a pointer-to-member matches regardless of whether the
  231. // pointed-to type is a declaration or a definition.
  232. //
  233. // struct bar; // { };
  234. // struct foo { bar foo::*mem; };
  235. TEST(DIEHashTest, PtrToMemberDeclDefMatch) {
  236. DIEInteger Zero(0);
  237. DIEInteger One(1);
  238. DIEInteger Eight(8);
  239. DIEString FooStr(&Eight, "foo");
  240. DIEString BarStr(&Eight, "bar");
  241. DIEString MemStr(&Eight, "mem");
  242. uint64_t MD5ResDecl;
  243. {
  244. DIE Bar(dwarf::DW_TAG_structure_type);
  245. Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &BarStr);
  246. Bar.addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
  247. DIE Foo(dwarf::DW_TAG_structure_type);
  248. Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  249. Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
  250. DIE *Mem = new DIE(dwarf::DW_TAG_member);
  251. Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
  252. Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
  253. &Zero);
  254. DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
  255. DIEEntry BarEntry(&Bar);
  256. PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
  257. DIEEntry FooEntry(&Foo);
  258. PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
  259. &FooEntry);
  260. DIEEntry PtrToFooMemRef(&PtrToFooMem);
  261. Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
  262. Foo.addChild(Mem);
  263. MD5ResDecl = DIEHash().computeTypeSignature(Foo);
  264. }
  265. uint64_t MD5ResDef;
  266. {
  267. DIE Bar(dwarf::DW_TAG_structure_type);
  268. Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &BarStr);
  269. Bar.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
  270. DIE Foo(dwarf::DW_TAG_structure_type);
  271. Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  272. Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
  273. DIE *Mem = new DIE(dwarf::DW_TAG_member);
  274. Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
  275. Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
  276. &Zero);
  277. DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
  278. DIEEntry BarEntry(&Bar);
  279. PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
  280. DIEEntry FooEntry(&Foo);
  281. PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
  282. &FooEntry);
  283. DIEEntry PtrToFooMemRef(&PtrToFooMem);
  284. Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
  285. Foo.addChild(Mem);
  286. MD5ResDef = DIEHash().computeTypeSignature(Foo);
  287. }
  288. ASSERT_EQ(MD5ResDef, MD5ResDecl);
  289. }
  290. // Check that the hash for a pointer-to-member matches regardless of whether the
  291. // pointed-to type is a declaration or a definition.
  292. //
  293. // struct bar; // { };
  294. // struct foo { bar bar::*mem; };
  295. TEST(DIEHashTest, PtrToMemberDeclDefMisMatch) {
  296. DIEInteger Zero(0);
  297. DIEInteger One(1);
  298. DIEInteger Eight(8);
  299. DIEString FooStr(&Eight, "foo");
  300. DIEString BarStr(&Eight, "bar");
  301. DIEString MemStr(&Eight, "mem");
  302. uint64_t MD5ResDecl;
  303. {
  304. DIE Bar(dwarf::DW_TAG_structure_type);
  305. Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &BarStr);
  306. Bar.addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
  307. DIE Foo(dwarf::DW_TAG_structure_type);
  308. Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  309. Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
  310. DIE *Mem = new DIE(dwarf::DW_TAG_member);
  311. Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
  312. Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
  313. &Zero);
  314. DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
  315. DIEEntry BarEntry(&Bar);
  316. PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
  317. PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
  318. &BarEntry);
  319. DIEEntry PtrToFooMemRef(&PtrToFooMem);
  320. Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
  321. Foo.addChild(Mem);
  322. MD5ResDecl = DIEHash().computeTypeSignature(Foo);
  323. }
  324. uint64_t MD5ResDef;
  325. {
  326. DIE Bar(dwarf::DW_TAG_structure_type);
  327. Bar.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &BarStr);
  328. Bar.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
  329. DIE Foo(dwarf::DW_TAG_structure_type);
  330. Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  331. Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
  332. DIE *Mem = new DIE(dwarf::DW_TAG_member);
  333. Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
  334. Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
  335. &Zero);
  336. DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
  337. DIEEntry BarEntry(&Bar);
  338. PtrToFooMem.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &BarEntry);
  339. PtrToFooMem.addValue(dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
  340. &BarEntry);
  341. DIEEntry PtrToFooMemRef(&PtrToFooMem);
  342. Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
  343. Foo.addChild(Mem);
  344. MD5ResDef = DIEHash().computeTypeSignature(Foo);
  345. }
  346. // FIXME: This seems to be a bug in the DWARF type hashing specification that
  347. // only uses the brief name hashing for types referenced via DW_AT_type. In
  348. // this case the type is referenced via DW_AT_containing_type and full hashing
  349. // causes a hash to differ when the containing type is a declaration in one TU
  350. // and a definition in another.
  351. ASSERT_NE(MD5ResDef, MD5ResDecl);
  352. }
  353. // struct { } a;
  354. // struct foo { decltype(a) mem; };
  355. TEST(DIEHashTest, RefUnnamedType) {
  356. DIEInteger Zero(0);
  357. DIEInteger One(1);
  358. DIEInteger Eight(8);
  359. DIEString FooStr(&Zero, "foo");
  360. DIEString MemStr(&Zero, "mem");
  361. DIE Unnamed(dwarf::DW_TAG_structure_type);
  362. Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
  363. DIE Foo(dwarf::DW_TAG_structure_type);
  364. Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  365. Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
  366. DIE *Mem = new DIE(dwarf::DW_TAG_member);
  367. Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
  368. Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
  369. DIE UnnamedPtr(dwarf::DW_TAG_pointer_type);
  370. UnnamedPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
  371. DIEEntry UnnamedRef(&Unnamed);
  372. UnnamedPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &UnnamedRef);
  373. DIEEntry UnnamedPtrRef(&UnnamedPtr);
  374. Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &UnnamedPtrRef);
  375. Foo.addChild(Mem);
  376. uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
  377. ASSERT_EQ(0x954e026f01c02529ULL, MD5Res);
  378. }
  379. // struct { struct bar { }; };
  380. TEST(DIEHashTest, NestedType) {
  381. DIE Unnamed(dwarf::DW_TAG_structure_type);
  382. DIEInteger One(1);
  383. Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
  384. DIE *Foo = new DIE(dwarf::DW_TAG_structure_type);
  385. DIEString FooStr(&One, "foo");
  386. Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
  387. Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
  388. Unnamed.addChild(Foo);
  389. uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
  390. // The exact same hash GCC produces for this DIE.
  391. ASSERT_EQ(0xde8a3b7b43807f4aULL, MD5Res);
  392. }
  393. }