Home | History | Annotate | Download | only in CodeGen
      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 "llvm/ADT/STLExtras.h"
     16 #include "gtest/gtest.h"
     17 
     18 using namespace llvm;
     19 
     20 namespace {
     21 TEST(DIEHashTest, Data1) {
     22   DIEHash Hash;
     23   DIE Die(dwarf::DW_TAG_base_type);
     24   DIEInteger Size(4);
     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);
     28 }
     29 
     30 // struct {};
     31 TEST(DIEHashTest, TrivialType) {
     32   DIE Unnamed(dwarf::DW_TAG_structure_type);
     33   DIEInteger One(1);
     34   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
     35 
     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);
     40 
     41   // The exact same hash GCC produces for this DIE.
     42   ASSERT_EQ(0x715305ce6cfd9ad1ULL, MD5Res);
     43 }
     44 
     45 // struct foo { };
     46 TEST(DIEHashTest, NamedType) {
     47   DIE Foo(dwarf::DW_TAG_structure_type);
     48   DIEInteger One(1);
     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);
     52 
     53   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
     54 
     55   // The exact same hash GCC produces for this DIE.
     56   ASSERT_EQ(0xd566dbd2ca5265ffULL, MD5Res);
     57 }
     58 
     59 // namespace space { struct foo { }; }
     60 TEST(DIEHashTest, NamespacedType) {
     61   DIE CU(dwarf::DW_TAG_compile_unit);
     62 
     63   auto Space = make_unique<DIE>(dwarf::DW_TAG_namespace);
     64   DIEInteger One(1);
     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);
     69   // sibling?
     70 
     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);
     75 
     76   DIE &N = *Foo;
     77   Space->addChild(std::move(Foo));
     78   CU.addChild(std::move(Space));
     79 
     80   uint64_t MD5Res = DIEHash().computeTypeSignature(N);
     81 
     82   // The exact same hash GCC produces for this DIE.
     83   ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res);
     84 }
     85 
     86 // struct { int member; };
     87 TEST(DIEHashTest, TypeWithMember) {
     88   DIE Unnamed(dwarf::DW_TAG_structure_type);
     89   DIEInteger Four(4);
     90   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
     91 
     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);
     96   DIEInteger Five(5);
     97   Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
     98 
     99   DIEEntry IntRef(Int);
    100 
    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);
    104   DIEInteger Zero(0);
    105   Member->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
    106                    &Zero);
    107   Member->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
    108 
    109   Unnamed.addChild(std::move(Member));
    110 
    111   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
    112 
    113   ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res);
    114 }
    115 
    116 // struct foo { int mem1, mem2; };
    117 TEST(DIEHashTest, ReusedType) {
    118   DIE Unnamed(dwarf::DW_TAG_structure_type);
    119   DIEInteger Eight(8);
    120   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
    121 
    122   DIEInteger Four(4);
    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);
    127   DIEInteger Five(5);
    128   Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
    129 
    130   DIEEntry IntRef(Int);
    131 
    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);
    135   DIEInteger Zero(0);
    136   Mem1->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
    137                  &Zero);
    138   Mem1->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
    139 
    140   Unnamed.addChild(std::move(Mem1));
    141 
    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,
    146                  &Four);
    147   Mem2->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
    148 
    149   Unnamed.addChild(std::move(Mem2));
    150 
    151   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
    152 
    153   ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res);
    154 }
    155 
    156 // struct foo { static foo f; };
    157 TEST(DIEHashTest, RecursiveType) {
    158   DIE Foo(dwarf::DW_TAG_structure_type);
    159   DIEInteger One(1);
    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);
    163 
    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.
    170 
    171   Foo.addChild(std::move(Mem));
    172 
    173   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
    174 
    175   ASSERT_EQ(0x73d8b25aef227b06ULL, MD5Res);
    176 }
    177 
    178 // struct foo { foo *mem; };
    179 TEST(DIEHashTest, Pointer) {
    180   DIE Foo(dwarf::DW_TAG_structure_type);
    181   DIEInteger Eight(8);
    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);
    185 
    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);
    189   DIEInteger Zero(0);
    190   Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
    191 
    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);
    196 
    197   DIEEntry FooPtrRef(FooPtr);
    198   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooPtrRef);
    199 
    200   Foo.addChild(std::move(Mem));
    201 
    202   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
    203 
    204   ASSERT_EQ(0x74ea73862e8708d2ULL, MD5Res);
    205 }
    206 
    207 // struct foo { foo &mem; };
    208 TEST(DIEHashTest, Reference) {
    209   DIE Foo(dwarf::DW_TAG_structure_type);
    210   DIEInteger Eight(8);
    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);
    214 
    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);
    218   DIEInteger Zero(0);
    219   Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
    220 
    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);
    225 
    226   DIE FooRefConst(dwarf::DW_TAG_const_type);
    227   DIEEntry FooRefRef(FooRef);
    228   FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefRef);
    229 
    230   DIEEntry FooRefConstRef(FooRefConst);
    231   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefConstRef);
    232 
    233   Foo.addChild(std::move(Mem));
    234 
    235   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
    236 
    237   ASSERT_EQ(0xa0b15f467ad4525bULL, MD5Res);
    238 }
    239 
    240 // struct foo { foo &&mem; };
    241 TEST(DIEHashTest, RValueReference) {
    242   DIE Foo(dwarf::DW_TAG_structure_type);
    243   DIEInteger Eight(8);
    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);
    247 
    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);
    251   DIEInteger Zero(0);
    252   Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
    253 
    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);
    258 
    259   DIE FooRefConst(dwarf::DW_TAG_const_type);
    260   DIEEntry FooRefRef(FooRef);
    261   FooRefConst.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefRef);
    262 
    263   DIEEntry FooRefConstRef(FooRefConst);
    264   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRefConstRef);
    265 
    266   Foo.addChild(std::move(Mem));
    267 
    268   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
    269 
    270   ASSERT_EQ(0xad211c8c3b31e57ULL, MD5Res);
    271 }
    272 
    273 // struct foo { foo foo::*mem; };
    274 TEST(DIEHashTest, PtrToMember) {
    275   DIE Foo(dwarf::DW_TAG_structure_type);
    276   DIEInteger Eight(8);
    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);
    280 
    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);
    284   DIEInteger Zero(0);
    285   Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
    286 
    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,
    291                        &FooEntry);
    292 
    293   DIEEntry PtrToFooMemRef(PtrToFooMem);
    294   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
    295 
    296   Foo.addChild(std::move(Mem));
    297 
    298   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
    299 
    300   ASSERT_EQ(0x852e0c9ff7c04ebULL, MD5Res);
    301 }
    302 
    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.
    305 //
    306 //   struct bar; // { };
    307 //   struct foo { bar foo::*mem; };
    308 TEST(DIEHashTest, PtrToMemberDeclDefMatch) {
    309   DIEInteger Zero(0);
    310   DIEInteger One(1);
    311   DIEInteger Eight(8);
    312   DIEString FooStr(&Eight, "foo");
    313   DIEString BarStr(&Eight, "bar");
    314   DIEString MemStr(&Eight, "mem");
    315   uint64_t MD5ResDecl;
    316   {
    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);
    320 
    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);
    324 
    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,
    328                   &Zero);
    329 
    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,
    335                          &FooEntry);
    336 
    337     DIEEntry PtrToFooMemRef(PtrToFooMem);
    338     Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
    339 
    340     Foo.addChild(std::move(Mem));
    341 
    342     MD5ResDecl = DIEHash().computeTypeSignature(Foo);
    343   }
    344   uint64_t MD5ResDef;
    345   {
    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);
    349 
    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);
    353 
    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,
    357                   &Zero);
    358 
    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,
    364                          &FooEntry);
    365 
    366     DIEEntry PtrToFooMemRef(PtrToFooMem);
    367     Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
    368 
    369     Foo.addChild(std::move(Mem));
    370 
    371     MD5ResDef = DIEHash().computeTypeSignature(Foo);
    372   }
    373   ASSERT_EQ(MD5ResDef, MD5ResDecl);
    374 }
    375 
    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.
    378 //
    379 //   struct bar; // { };
    380 //   struct foo { bar bar::*mem; };
    381 TEST(DIEHashTest, PtrToMemberDeclDefMisMatch) {
    382   DIEInteger Zero(0);
    383   DIEInteger One(1);
    384   DIEInteger Eight(8);
    385   DIEString FooStr(&Eight, "foo");
    386   DIEString BarStr(&Eight, "bar");
    387   DIEString MemStr(&Eight, "mem");
    388   uint64_t MD5ResDecl;
    389   {
    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);
    393 
    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);
    397 
    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,
    401                   &Zero);
    402 
    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,
    407                          &BarEntry);
    408 
    409     DIEEntry PtrToFooMemRef(PtrToFooMem);
    410     Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
    411 
    412     Foo.addChild(std::move(Mem));
    413 
    414     MD5ResDecl = DIEHash().computeTypeSignature(Foo);
    415   }
    416   uint64_t MD5ResDef;
    417   {
    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);
    421 
    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);
    425 
    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,
    429                   &Zero);
    430 
    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,
    435                          &BarEntry);
    436 
    437     DIEEntry PtrToFooMemRef(PtrToFooMem);
    438     Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &PtrToFooMemRef);
    439 
    440     Foo.addChild(std::move(Mem));
    441 
    442     MD5ResDef = DIEHash().computeTypeSignature(Foo);
    443   }
    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);
    450 }
    451 
    452 // struct { } a;
    453 // struct foo { decltype(a) mem; };
    454 TEST(DIEHashTest, RefUnnamedType) {
    455   DIEInteger Zero(0);
    456   DIEInteger One(1);
    457   DIEInteger Eight(8);
    458   DIEString FooStr(&Zero, "foo");
    459   DIEString MemStr(&Zero, "mem");
    460 
    461   DIE Unnamed(dwarf::DW_TAG_structure_type);
    462   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
    463 
    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);
    467 
    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);
    471 
    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);
    476 
    477   DIEEntry UnnamedPtrRef(UnnamedPtr);
    478   Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &UnnamedPtrRef);
    479 
    480   Foo.addChild(std::move(Mem));
    481 
    482   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
    483 
    484   ASSERT_EQ(0x954e026f01c02529ULL, MD5Res);
    485 }
    486 
    487 // struct { struct foo { }; };
    488 TEST(DIEHashTest, NestedType) {
    489   DIE Unnamed(dwarf::DW_TAG_structure_type);
    490   DIEInteger One(1);
    491   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
    492 
    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);
    497 
    498   Unnamed.addChild(std::move(Foo));
    499 
    500   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
    501 
    502   // The exact same hash GCC produces for this DIE.
    503   ASSERT_EQ(0xde8a3b7b43807f4aULL, MD5Res);
    504 }
    505 
    506 // struct { static void func(); };
    507 TEST(DIEHashTest, MemberFunc) {
    508   DIE Unnamed(dwarf::DW_TAG_structure_type);
    509   DIEInteger One(1);
    510   Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
    511 
    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);
    515 
    516   Unnamed.addChild(std::move(Func));
    517 
    518   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
    519 
    520   // The exact same hash GCC produces for this DIE.
    521   ASSERT_EQ(0xd36a1b6dfb604ba0ULL, MD5Res);
    522 }
    523 
    524 // struct A {
    525 //   static void func();
    526 // };
    527 TEST(DIEHashTest, MemberFuncFlag) {
    528   DIE A(dwarf::DW_TAG_structure_type);
    529   DIEInteger One(1);
    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);
    535 
    536   auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram);
    537   DIEString FuncStr(&One, "func");
    538   DIEString FuncLinkage(&One, "_ZN1A4funcEv");
    539   DIEInteger Two(2);
    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);
    546 
    547   A.addChild(std::move(Func));
    548 
    549   uint64_t MD5Res = DIEHash().computeTypeSignature(A);
    550 
    551   // The exact same hash GCC produces for this DIE.
    552   ASSERT_EQ(0x8f78211ddce3df10ULL, MD5Res);
    553 }
    554 
    555 // Derived from:
    556 // struct A {
    557 //   const static int PI = -3;
    558 // };
    559 // A a;
    560 TEST(DIEHashTest, MemberSdata) {
    561   DIE A(dwarf::DW_TAG_structure_type);
    562   DIEInteger One(1);
    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);
    568 
    569   DIEInteger Four(4);
    570   DIEInteger Five(5);
    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);
    576 
    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);
    580 
    581   DIEEntry PITy(*PITyDIE);
    582   auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
    583   DIEString PIStr(&One, "PI");
    584   DIEInteger Two(2);
    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);
    593 
    594   A.addChild(std::move(PI));
    595 
    596   uint64_t MD5Res = DIEHash().computeTypeSignature(A);
    597   ASSERT_EQ(0x9a216000dd3788a7ULL, MD5Res);
    598 }
    599 
    600 // Derived from:
    601 // struct A {
    602 //   const static float PI = 3.14;
    603 // };
    604 // A a;
    605 TEST(DIEHashTest, MemberBlock) {
    606   DIE A(dwarf::DW_TAG_structure_type);
    607   DIEInteger One(1);
    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);
    613 
    614   DIEInteger Four(4);
    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);
    620 
    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);
    624 
    625   DIEEntry PITy(*PITyDIE);
    626   auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
    627   DIEString PIStr(&One, "PI");
    628   DIEInteger Two(2);
    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);
    635 
    636   DIEBlock PIBlock;
    637   DIEInteger Blk1(0xc3);
    638   DIEInteger Blk2(0xf5);
    639   DIEInteger Blk3(0x48);
    640   DIEInteger Blk4(0x40);
    641 
    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);
    646 
    647   PI->addValue(dwarf::DW_AT_const_value, dwarf::DW_FORM_block1, &PIBlock);
    648 
    649   A.addChild(std::move(PI));
    650 
    651   uint64_t MD5Res = DIEHash().computeTypeSignature(A);
    652   ASSERT_EQ(0x493af53ad3d3f651ULL, MD5Res);
    653 }
    654 }
    655