1544b23d8SJustin Lebar //===- llvm/unittest/CodeGen/DIEHashTest.cpp ------------------------------===//
225b7adc8SEric Christopher //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
625b7adc8SEric Christopher //
725b7adc8SEric Christopher //===----------------------------------------------------------------------===//
825b7adc8SEric Christopher 
925b7adc8SEric Christopher #include "../lib/CodeGen/AsmPrinter/DIEHash.h"
10027d47d1SIgor Kudrin #include "TestAsmPrinter.h"
11d9903888SChandler Carruth #include "llvm/ADT/STLExtras.h"
12264b5d9eSZachary Turner #include "llvm/BinaryFormat/Dwarf.h"
139a67b073SChandler Carruth #include "llvm/CodeGen/DIE.h"
14f73bcf40SDuncan P. N. Exon Smith #include "llvm/CodeGen/DwarfStringPoolEntry.h"
1525b7adc8SEric Christopher #include "llvm/Support/Debug.h"
1625b7adc8SEric Christopher #include "llvm/Support/Format.h"
17027d47d1SIgor Kudrin #include "llvm/Support/Host.h"
18027d47d1SIgor Kudrin #include "llvm/Testing/Support/Error.h"
1925b7adc8SEric Christopher #include "gtest/gtest.h"
2025b7adc8SEric Christopher 
2125b7adc8SEric Christopher using namespace llvm;
2259804193SDavid Blaikie 
2359804193SDavid Blaikie namespace {
24f73bcf40SDuncan P. N. Exon Smith 
25f73bcf40SDuncan P. N. Exon Smith // Test fixture
26f73bcf40SDuncan P. N. Exon Smith class DIEHashTest : public testing::Test {
274fb1f9cdSDuncan P. N. Exon Smith public:
284fb1f9cdSDuncan P. N. Exon Smith   BumpPtrAllocator Alloc;
294fb1f9cdSDuncan P. N. Exon Smith 
304fb1f9cdSDuncan P. N. Exon Smith private:
31f73bcf40SDuncan P. N. Exon Smith   StringMap<DwarfStringPoolEntry> Pool;
32027d47d1SIgor Kudrin   std::unique_ptr<TestAsmPrinter> TestPrinter;
33027d47d1SIgor Kudrin 
setupTestPrinter()34027d47d1SIgor Kudrin   void setupTestPrinter() {
35027d47d1SIgor Kudrin     auto ExpectedTestPrinter = TestAsmPrinter::create(
36027d47d1SIgor Kudrin         sys::getDefaultTargetTriple(), /*DwarfVersion=*/4, dwarf::DWARF32);
37027d47d1SIgor Kudrin     ASSERT_THAT_EXPECTED(ExpectedTestPrinter, Succeeded());
38027d47d1SIgor Kudrin     TestPrinter = std::move(ExpectedTestPrinter.get());
39027d47d1SIgor Kudrin   }
40f73bcf40SDuncan P. N. Exon Smith 
41f73bcf40SDuncan P. N. Exon Smith public:
getString(StringRef S)42f73bcf40SDuncan P. N. Exon Smith   DIEString getString(StringRef S) {
43f73bcf40SDuncan P. N. Exon Smith     DwarfStringPoolEntry Entry = {nullptr, 1, 1};
44501d5b24SAlexey Lapshin     return DIEString(
45501d5b24SAlexey Lapshin         DwarfStringPoolEntryRef(*Pool.insert(std::make_pair(S, Entry)).first));
46f73bcf40SDuncan P. N. Exon Smith   }
47027d47d1SIgor Kudrin 
getAsmPrinter()48027d47d1SIgor Kudrin   AsmPrinter *getAsmPrinter() {
49027d47d1SIgor Kudrin     if (!TestPrinter)
50027d47d1SIgor Kudrin       setupTestPrinter();
51027d47d1SIgor Kudrin     return TestPrinter ? TestPrinter->getAP() : nullptr;
52027d47d1SIgor Kudrin   }
53f73bcf40SDuncan P. N. Exon Smith };
54f73bcf40SDuncan P. N. Exon Smith 
TEST_F(DIEHashTest,Data1)55f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, Data1) {
5625b7adc8SEric Christopher   DIEHash Hash;
57827200c8SDuncan P. N. Exon Smith   DIE &Die = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
580f01d4e3SBenjamin Kramer   DIEInteger Size(4);
594fb1f9cdSDuncan P. N. Exon Smith   Die.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Size);
602aee7be8SDavid Blaikie   uint64_t MD5Res = Hash.computeTypeSignature(Die);
616316ca45SDavid Blaikie   ASSERT_EQ(0x1AFE116E83701108ULL, MD5Res);
626316ca45SDavid Blaikie }
636316ca45SDavid Blaikie 
646cf58c89SDavid Blaikie // struct {};
TEST_F(DIEHashTest,TrivialType)65f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, TrivialType) {
66827200c8SDuncan P. N. Exon Smith   DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
676316ca45SDavid Blaikie   DIEInteger One(1);
684fb1f9cdSDuncan P. N. Exon Smith   Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
696316ca45SDavid Blaikie 
706316ca45SDavid Blaikie   // Line and file number are ignored.
714fb1f9cdSDuncan P. N. Exon Smith   Unnamed.addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
724fb1f9cdSDuncan P. N. Exon Smith   Unnamed.addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
732aee7be8SDavid Blaikie   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
746316ca45SDavid Blaikie 
756316ca45SDavid Blaikie   // The exact same hash GCC produces for this DIE.
76*a84e1e6cSAlexander Yermolovich   ASSERT_EQ(0x715305CE6CFD9AD1ULL, MD5Res);
7725b7adc8SEric Christopher }
788a142aaaSDavid Blaikie 
796cf58c89SDavid Blaikie // struct foo { };
TEST_F(DIEHashTest,NamedType)80f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, NamedType) {
81827200c8SDuncan P. N. Exon Smith   DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
828a142aaaSDavid Blaikie   DIEInteger One(1);
83f73bcf40SDuncan P. N. Exon Smith   DIEString FooStr = getString("foo");
844fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
854fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
868a142aaaSDavid Blaikie 
872aee7be8SDavid Blaikie   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
888a142aaaSDavid Blaikie 
898a142aaaSDavid Blaikie   // The exact same hash GCC produces for this DIE.
90*a84e1e6cSAlexander Yermolovich   ASSERT_EQ(0xD566DBD2CA5265FFULL, MD5Res);
918a142aaaSDavid Blaikie }
928a142aaaSDavid Blaikie 
936cf58c89SDavid Blaikie // namespace space { struct foo { }; }
TEST_F(DIEHashTest,NamespacedType)94f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, NamespacedType) {
95827200c8SDuncan P. N. Exon Smith   DIE &CU = *DIE::get(Alloc, dwarf::DW_TAG_compile_unit);
968a142aaaSDavid Blaikie 
97827200c8SDuncan P. N. Exon Smith   auto Space = DIE::get(Alloc, dwarf::DW_TAG_namespace);
988a142aaaSDavid Blaikie   DIEInteger One(1);
99f73bcf40SDuncan P. N. Exon Smith   DIEString SpaceStr = getString("space");
1004fb1f9cdSDuncan P. N. Exon Smith   Space->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, SpaceStr);
1018a142aaaSDavid Blaikie   // DW_AT_declaration is ignored.
1024fb1f9cdSDuncan P. N. Exon Smith   Space->addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
1034fb1f9cdSDuncan P. N. Exon Smith                   One);
1048a142aaaSDavid Blaikie   // sibling?
1058a142aaaSDavid Blaikie 
106827200c8SDuncan P. N. Exon Smith   auto Foo = DIE::get(Alloc, dwarf::DW_TAG_structure_type);
107f73bcf40SDuncan P. N. Exon Smith   DIEString FooStr = getString("foo");
1084fb1f9cdSDuncan P. N. Exon Smith   Foo->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
1094fb1f9cdSDuncan P. N. Exon Smith   Foo->addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
1108a142aaaSDavid Blaikie 
111914046e1SDavid Blaikie   DIE &N = *Foo;
112914046e1SDavid Blaikie   Space->addChild(std::move(Foo));
113914046e1SDavid Blaikie   CU.addChild(std::move(Space));
1148a142aaaSDavid Blaikie 
115914046e1SDavid Blaikie   uint64_t MD5Res = DIEHash().computeTypeSignature(N);
1168a142aaaSDavid Blaikie 
1178a142aaaSDavid Blaikie   // The exact same hash GCC produces for this DIE.
1188a142aaaSDavid Blaikie   ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res);
1198a142aaaSDavid Blaikie }
120ca353be6SDavid Blaikie 
1216cf58c89SDavid Blaikie // struct { int member; };
TEST_F(DIEHashTest,TypeWithMember)122f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, TypeWithMember) {
123827200c8SDuncan P. N. Exon Smith   DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
124ca353be6SDavid Blaikie   DIEInteger Four(4);
1254fb1f9cdSDuncan P. N. Exon Smith   Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
126ca353be6SDavid Blaikie 
127827200c8SDuncan P. N. Exon Smith   DIE &Int = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
128f73bcf40SDuncan P. N. Exon Smith   DIEString IntStr = getString("int");
1294fb1f9cdSDuncan P. N. Exon Smith   Int.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, IntStr);
1304fb1f9cdSDuncan P. N. Exon Smith   Int.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
131ca353be6SDavid Blaikie   DIEInteger Five(5);
1324fb1f9cdSDuncan P. N. Exon Smith   Int.addValue(Alloc, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five);
133ca353be6SDavid Blaikie 
1348dbcc3feSDavid Blaikie   DIEEntry IntRef(Int);
135914046e1SDavid Blaikie 
136827200c8SDuncan P. N. Exon Smith   auto Member = DIE::get(Alloc, dwarf::DW_TAG_member);
137f73bcf40SDuncan P. N. Exon Smith   DIEString MemberStr = getString("member");
1384fb1f9cdSDuncan P. N. Exon Smith   Member->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemberStr);
139914046e1SDavid Blaikie   DIEInteger Zero(0);
1404fb1f9cdSDuncan P. N. Exon Smith   Member->addValue(Alloc, dwarf::DW_AT_data_member_location,
1414fb1f9cdSDuncan P. N. Exon Smith                    dwarf::DW_FORM_data1, Zero);
1424fb1f9cdSDuncan P. N. Exon Smith   Member->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef);
143ca353be6SDavid Blaikie 
144914046e1SDavid Blaikie   Unnamed.addChild(std::move(Member));
145914046e1SDavid Blaikie 
1462aee7be8SDavid Blaikie   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
147ca353be6SDavid Blaikie 
148ca353be6SDavid Blaikie   ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res);
149ca353be6SDavid Blaikie }
150980d4994SDavid Blaikie 
1516cf58c89SDavid Blaikie // struct foo { int mem1, mem2; };
TEST_F(DIEHashTest,ReusedType)152f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, ReusedType) {
153827200c8SDuncan P. N. Exon Smith   DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
154980d4994SDavid Blaikie   DIEInteger Eight(8);
1554fb1f9cdSDuncan P. N. Exon Smith   Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
156980d4994SDavid Blaikie 
157980d4994SDavid Blaikie   DIEInteger Four(4);
158827200c8SDuncan P. N. Exon Smith   DIE &Int = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
159f73bcf40SDuncan P. N. Exon Smith   DIEString IntStr = getString("int");
1604fb1f9cdSDuncan P. N. Exon Smith   Int.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, IntStr);
1614fb1f9cdSDuncan P. N. Exon Smith   Int.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
162980d4994SDavid Blaikie   DIEInteger Five(5);
1634fb1f9cdSDuncan P. N. Exon Smith   Int.addValue(Alloc, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five);
164980d4994SDavid Blaikie 
1658dbcc3feSDavid Blaikie   DIEEntry IntRef(Int);
166914046e1SDavid Blaikie 
167827200c8SDuncan P. N. Exon Smith   auto Mem1 = DIE::get(Alloc, dwarf::DW_TAG_member);
168f73bcf40SDuncan P. N. Exon Smith   DIEString Mem1Str = getString("mem1");
1694fb1f9cdSDuncan P. N. Exon Smith   Mem1->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, Mem1Str);
170914046e1SDavid Blaikie   DIEInteger Zero(0);
1714fb1f9cdSDuncan P. N. Exon Smith   Mem1->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
172e7e1d0c7SDuncan P. N. Exon Smith                  Zero);
1734fb1f9cdSDuncan P. N. Exon Smith   Mem1->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef);
174914046e1SDavid Blaikie 
175914046e1SDavid Blaikie   Unnamed.addChild(std::move(Mem1));
176914046e1SDavid Blaikie 
177827200c8SDuncan P. N. Exon Smith   auto Mem2 = DIE::get(Alloc, dwarf::DW_TAG_member);
178f73bcf40SDuncan P. N. Exon Smith   DIEString Mem2Str = getString("mem2");
1794fb1f9cdSDuncan P. N. Exon Smith   Mem2->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, Mem2Str);
1804fb1f9cdSDuncan P. N. Exon Smith   Mem2->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
181e7e1d0c7SDuncan P. N. Exon Smith                  Four);
1824fb1f9cdSDuncan P. N. Exon Smith   Mem2->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntRef);
183980d4994SDavid Blaikie 
184914046e1SDavid Blaikie   Unnamed.addChild(std::move(Mem2));
185914046e1SDavid Blaikie 
1862aee7be8SDavid Blaikie   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
187980d4994SDavid Blaikie 
188980d4994SDavid Blaikie   ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res);
189980d4994SDavid Blaikie }
190980d4994SDavid Blaikie 
1916cf58c89SDavid Blaikie // struct foo { static foo f; };
TEST_F(DIEHashTest,RecursiveType)192f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, RecursiveType) {
193827200c8SDuncan P. N. Exon Smith   DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
194980d4994SDavid Blaikie   DIEInteger One(1);
1954fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
196f73bcf40SDuncan P. N. Exon Smith   DIEString FooStr = getString("foo");
1974fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
198980d4994SDavid Blaikie 
199827200c8SDuncan P. N. Exon Smith   auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
200f73bcf40SDuncan P. N. Exon Smith   DIEString MemStr = getString("mem");
2014fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
2028dbcc3feSDavid Blaikie   DIEEntry FooRef(Foo);
2034fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRef);
204980d4994SDavid Blaikie   // DW_AT_external and DW_AT_declaration are ignored anyway, so skip them.
205980d4994SDavid Blaikie 
206914046e1SDavid Blaikie   Foo.addChild(std::move(Mem));
207980d4994SDavid Blaikie 
2082aee7be8SDavid Blaikie   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
209980d4994SDavid Blaikie 
210980d4994SDavid Blaikie   ASSERT_EQ(0x73d8b25aef227b06ULL, MD5Res);
211980d4994SDavid Blaikie }
2126cf58c89SDavid Blaikie 
2136cf58c89SDavid Blaikie // struct foo { foo *mem; };
TEST_F(DIEHashTest,Pointer)214f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, Pointer) {
215827200c8SDuncan P. N. Exon Smith   DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
2166cf58c89SDavid Blaikie   DIEInteger Eight(8);
2174fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
218f73bcf40SDuncan P. N. Exon Smith   DIEString FooStr = getString("foo");
2194fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
2206cf58c89SDavid Blaikie 
221827200c8SDuncan P. N. Exon Smith   auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
222f73bcf40SDuncan P. N. Exon Smith   DIEString MemStr = getString("mem");
2234fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
2246cf58c89SDavid Blaikie   DIEInteger Zero(0);
2254fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
2264fb1f9cdSDuncan P. N. Exon Smith                 Zero);
2276cf58c89SDavid Blaikie 
228827200c8SDuncan P. N. Exon Smith   DIE &FooPtr = *DIE::get(Alloc, dwarf::DW_TAG_pointer_type);
2294fb1f9cdSDuncan P. N. Exon Smith   FooPtr.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
2308dbcc3feSDavid Blaikie   DIEEntry FooRef(Foo);
2314fb1f9cdSDuncan P. N. Exon Smith   FooPtr.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRef);
2326cf58c89SDavid Blaikie 
2338dbcc3feSDavid Blaikie   DIEEntry FooPtrRef(FooPtr);
2344fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooPtrRef);
2356cf58c89SDavid Blaikie 
236914046e1SDavid Blaikie   Foo.addChild(std::move(Mem));
2376cf58c89SDavid Blaikie 
2382aee7be8SDavid Blaikie   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
2396cf58c89SDavid Blaikie 
2406cf58c89SDavid Blaikie   ASSERT_EQ(0x74ea73862e8708d2ULL, MD5Res);
2416cf58c89SDavid Blaikie }
242fe3233a5SDavid Blaikie 
243fe3233a5SDavid Blaikie // struct foo { foo &mem; };
TEST_F(DIEHashTest,Reference)244f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, Reference) {
245827200c8SDuncan P. N. Exon Smith   DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
246fe3233a5SDavid Blaikie   DIEInteger Eight(8);
2474fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
248f73bcf40SDuncan P. N. Exon Smith   DIEString FooStr = getString("foo");
2494fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
250fe3233a5SDavid Blaikie 
251827200c8SDuncan P. N. Exon Smith   auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
252f73bcf40SDuncan P. N. Exon Smith   DIEString MemStr = getString("mem");
2534fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
254fe3233a5SDavid Blaikie   DIEInteger Zero(0);
2554fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
2564fb1f9cdSDuncan P. N. Exon Smith                 Zero);
257fe3233a5SDavid Blaikie 
258827200c8SDuncan P. N. Exon Smith   DIE &FooRef = *DIE::get(Alloc, dwarf::DW_TAG_reference_type);
2594fb1f9cdSDuncan P. N. Exon Smith   FooRef.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
2608dbcc3feSDavid Blaikie   DIEEntry FooEntry(Foo);
2614fb1f9cdSDuncan P. N. Exon Smith   FooRef.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
262fe3233a5SDavid Blaikie 
263827200c8SDuncan P. N. Exon Smith   DIE &FooRefConst = *DIE::get(Alloc, dwarf::DW_TAG_const_type);
2648dbcc3feSDavid Blaikie   DIEEntry FooRefRef(FooRef);
2654fb1f9cdSDuncan P. N. Exon Smith   FooRefConst.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
2664fb1f9cdSDuncan P. N. Exon Smith                        FooRefRef);
267fe3233a5SDavid Blaikie 
2688dbcc3feSDavid Blaikie   DIEEntry FooRefConstRef(FooRefConst);
2694fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefConstRef);
270fe3233a5SDavid Blaikie 
271914046e1SDavid Blaikie   Foo.addChild(std::move(Mem));
272fe3233a5SDavid Blaikie 
2732aee7be8SDavid Blaikie   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
274fe3233a5SDavid Blaikie 
275fe3233a5SDavid Blaikie   ASSERT_EQ(0xa0b15f467ad4525bULL, MD5Res);
276fe3233a5SDavid Blaikie }
277fe3233a5SDavid Blaikie 
278fe3233a5SDavid Blaikie // struct foo { foo &&mem; };
TEST_F(DIEHashTest,RValueReference)279f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, RValueReference) {
280827200c8SDuncan P. N. Exon Smith   DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
281fe3233a5SDavid Blaikie   DIEInteger Eight(8);
2824fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
283f73bcf40SDuncan P. N. Exon Smith   DIEString FooStr = getString("foo");
2844fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
285fe3233a5SDavid Blaikie 
286827200c8SDuncan P. N. Exon Smith   auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
287f73bcf40SDuncan P. N. Exon Smith   DIEString MemStr = getString("mem");
2884fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
289fe3233a5SDavid Blaikie   DIEInteger Zero(0);
2904fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
2914fb1f9cdSDuncan P. N. Exon Smith                 Zero);
292fe3233a5SDavid Blaikie 
293827200c8SDuncan P. N. Exon Smith   DIE &FooRef = *DIE::get(Alloc, dwarf::DW_TAG_rvalue_reference_type);
2944fb1f9cdSDuncan P. N. Exon Smith   FooRef.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
2958dbcc3feSDavid Blaikie   DIEEntry FooEntry(Foo);
2964fb1f9cdSDuncan P. N. Exon Smith   FooRef.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
297fe3233a5SDavid Blaikie 
298827200c8SDuncan P. N. Exon Smith   DIE &FooRefConst = *DIE::get(Alloc, dwarf::DW_TAG_const_type);
2998dbcc3feSDavid Blaikie   DIEEntry FooRefRef(FooRef);
3004fb1f9cdSDuncan P. N. Exon Smith   FooRefConst.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
3014fb1f9cdSDuncan P. N. Exon Smith                        FooRefRef);
302fe3233a5SDavid Blaikie 
3038dbcc3feSDavid Blaikie   DIEEntry FooRefConstRef(FooRefConst);
3044fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRefConstRef);
305fe3233a5SDavid Blaikie 
306914046e1SDavid Blaikie   Foo.addChild(std::move(Mem));
307fe3233a5SDavid Blaikie 
3082aee7be8SDavid Blaikie   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
309fe3233a5SDavid Blaikie 
310fe3233a5SDavid Blaikie   ASSERT_EQ(0xad211c8c3b31e57ULL, MD5Res);
311fe3233a5SDavid Blaikie }
312d70a0553SDavid Blaikie 
313d70a0553SDavid Blaikie // struct foo { foo foo::*mem; };
TEST_F(DIEHashTest,PtrToMember)314f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, PtrToMember) {
315827200c8SDuncan P. N. Exon Smith   DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
316d70a0553SDavid Blaikie   DIEInteger Eight(8);
3174fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
318f73bcf40SDuncan P. N. Exon Smith   DIEString FooStr = getString("foo");
3194fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
320d70a0553SDavid Blaikie 
321827200c8SDuncan P. N. Exon Smith   auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
322f73bcf40SDuncan P. N. Exon Smith   DIEString MemStr = getString("mem");
3234fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
324d70a0553SDavid Blaikie   DIEInteger Zero(0);
3254fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
3264fb1f9cdSDuncan P. N. Exon Smith                 Zero);
327d70a0553SDavid Blaikie 
328827200c8SDuncan P. N. Exon Smith   DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
3298dbcc3feSDavid Blaikie   DIEEntry FooEntry(Foo);
3304fb1f9cdSDuncan P. N. Exon Smith   PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
3314fb1f9cdSDuncan P. N. Exon Smith   PtrToFooMem.addValue(Alloc, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
332e7e1d0c7SDuncan P. N. Exon Smith                        FooEntry);
333d70a0553SDavid Blaikie 
3348dbcc3feSDavid Blaikie   DIEEntry PtrToFooMemRef(PtrToFooMem);
3354fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PtrToFooMemRef);
336d70a0553SDavid Blaikie 
337914046e1SDavid Blaikie   Foo.addChild(std::move(Mem));
338d70a0553SDavid Blaikie 
3392aee7be8SDavid Blaikie   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
340d70a0553SDavid Blaikie 
341d70a0553SDavid Blaikie   ASSERT_EQ(0x852e0c9ff7c04ebULL, MD5Res);
342d70a0553SDavid Blaikie }
343d70a0553SDavid Blaikie 
344d70a0553SDavid Blaikie // Check that the hash for a pointer-to-member matches regardless of whether the
345d70a0553SDavid Blaikie // pointed-to type is a declaration or a definition.
346d70a0553SDavid Blaikie //
347d70a0553SDavid Blaikie //   struct bar; // { };
348d70a0553SDavid Blaikie //   struct foo { bar foo::*mem; };
TEST_F(DIEHashTest,PtrToMemberDeclDefMatch)349f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, PtrToMemberDeclDefMatch) {
350d70a0553SDavid Blaikie   DIEInteger Zero(0);
351d70a0553SDavid Blaikie   DIEInteger One(1);
352d70a0553SDavid Blaikie   DIEInteger Eight(8);
353f73bcf40SDuncan P. N. Exon Smith   DIEString FooStr = getString("foo");
354f73bcf40SDuncan P. N. Exon Smith   DIEString BarStr = getString("bar");
355f73bcf40SDuncan P. N. Exon Smith   DIEString MemStr = getString("mem");
356d70a0553SDavid Blaikie   uint64_t MD5ResDecl;
357d70a0553SDavid Blaikie   {
358827200c8SDuncan P. N. Exon Smith     DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
3594fb1f9cdSDuncan P. N. Exon Smith     Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
3604fb1f9cdSDuncan P. N. Exon Smith     Bar.addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
3614fb1f9cdSDuncan P. N. Exon Smith                  One);
362d70a0553SDavid Blaikie 
363827200c8SDuncan P. N. Exon Smith     DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
3644fb1f9cdSDuncan P. N. Exon Smith     Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
3654fb1f9cdSDuncan P. N. Exon Smith     Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
366d70a0553SDavid Blaikie 
367827200c8SDuncan P. N. Exon Smith     auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
3684fb1f9cdSDuncan P. N. Exon Smith     Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
3694fb1f9cdSDuncan P. N. Exon Smith     Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
3704fb1f9cdSDuncan P. N. Exon Smith                   dwarf::DW_FORM_data1, Zero);
371d70a0553SDavid Blaikie 
372827200c8SDuncan P. N. Exon Smith     DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
3738dbcc3feSDavid Blaikie     DIEEntry BarEntry(Bar);
3744fb1f9cdSDuncan P. N. Exon Smith     PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
3754fb1f9cdSDuncan P. N. Exon Smith                          BarEntry);
3768dbcc3feSDavid Blaikie     DIEEntry FooEntry(Foo);
3774fb1f9cdSDuncan P. N. Exon Smith     PtrToFooMem.addValue(Alloc, dwarf::DW_AT_containing_type,
3784fb1f9cdSDuncan P. N. Exon Smith                          dwarf::DW_FORM_ref4, FooEntry);
379d70a0553SDavid Blaikie 
3808dbcc3feSDavid Blaikie     DIEEntry PtrToFooMemRef(PtrToFooMem);
3814fb1f9cdSDuncan P. N. Exon Smith     Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
3824fb1f9cdSDuncan P. N. Exon Smith                   PtrToFooMemRef);
383d70a0553SDavid Blaikie 
384914046e1SDavid Blaikie     Foo.addChild(std::move(Mem));
385d70a0553SDavid Blaikie 
3862aee7be8SDavid Blaikie     MD5ResDecl = DIEHash().computeTypeSignature(Foo);
387d70a0553SDavid Blaikie   }
388d70a0553SDavid Blaikie   uint64_t MD5ResDef;
389d70a0553SDavid Blaikie   {
390827200c8SDuncan P. N. Exon Smith     DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
3914fb1f9cdSDuncan P. N. Exon Smith     Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
3924fb1f9cdSDuncan P. N. Exon Smith     Bar.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
393d70a0553SDavid Blaikie 
394827200c8SDuncan P. N. Exon Smith     DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
3954fb1f9cdSDuncan P. N. Exon Smith     Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
3964fb1f9cdSDuncan P. N. Exon Smith     Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
397d70a0553SDavid Blaikie 
398827200c8SDuncan P. N. Exon Smith     auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
3994fb1f9cdSDuncan P. N. Exon Smith     Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
4004fb1f9cdSDuncan P. N. Exon Smith     Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
4014fb1f9cdSDuncan P. N. Exon Smith                   dwarf::DW_FORM_data1, Zero);
402d70a0553SDavid Blaikie 
403827200c8SDuncan P. N. Exon Smith     DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
4048dbcc3feSDavid Blaikie     DIEEntry BarEntry(Bar);
4054fb1f9cdSDuncan P. N. Exon Smith     PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
4064fb1f9cdSDuncan P. N. Exon Smith                          BarEntry);
4078dbcc3feSDavid Blaikie     DIEEntry FooEntry(Foo);
4084fb1f9cdSDuncan P. N. Exon Smith     PtrToFooMem.addValue(Alloc, dwarf::DW_AT_containing_type,
4094fb1f9cdSDuncan P. N. Exon Smith                          dwarf::DW_FORM_ref4, FooEntry);
410d70a0553SDavid Blaikie 
4118dbcc3feSDavid Blaikie     DIEEntry PtrToFooMemRef(PtrToFooMem);
4124fb1f9cdSDuncan P. N. Exon Smith     Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
4134fb1f9cdSDuncan P. N. Exon Smith                   PtrToFooMemRef);
414d70a0553SDavid Blaikie 
415914046e1SDavid Blaikie     Foo.addChild(std::move(Mem));
416d70a0553SDavid Blaikie 
4172aee7be8SDavid Blaikie     MD5ResDef = DIEHash().computeTypeSignature(Foo);
418d70a0553SDavid Blaikie   }
419d70a0553SDavid Blaikie   ASSERT_EQ(MD5ResDef, MD5ResDecl);
420d70a0553SDavid Blaikie }
421d70a0553SDavid Blaikie 
422d70a0553SDavid Blaikie // Check that the hash for a pointer-to-member matches regardless of whether the
423d70a0553SDavid Blaikie // pointed-to type is a declaration or a definition.
424d70a0553SDavid Blaikie //
425d70a0553SDavid Blaikie //   struct bar; // { };
426d70a0553SDavid Blaikie //   struct foo { bar bar::*mem; };
TEST_F(DIEHashTest,PtrToMemberDeclDefMisMatch)427f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, PtrToMemberDeclDefMisMatch) {
428d70a0553SDavid Blaikie   DIEInteger Zero(0);
429d70a0553SDavid Blaikie   DIEInteger One(1);
430d70a0553SDavid Blaikie   DIEInteger Eight(8);
431f73bcf40SDuncan P. N. Exon Smith   DIEString FooStr = getString("foo");
432f73bcf40SDuncan P. N. Exon Smith   DIEString BarStr = getString("bar");
433f73bcf40SDuncan P. N. Exon Smith   DIEString MemStr = getString("mem");
434d70a0553SDavid Blaikie   uint64_t MD5ResDecl;
435d70a0553SDavid Blaikie   {
436827200c8SDuncan P. N. Exon Smith     DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
4374fb1f9cdSDuncan P. N. Exon Smith     Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
4384fb1f9cdSDuncan P. N. Exon Smith     Bar.addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
4394fb1f9cdSDuncan P. N. Exon Smith                  One);
440d70a0553SDavid Blaikie 
441827200c8SDuncan P. N. Exon Smith     DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
4424fb1f9cdSDuncan P. N. Exon Smith     Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
4434fb1f9cdSDuncan P. N. Exon Smith     Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
444d70a0553SDavid Blaikie 
445827200c8SDuncan P. N. Exon Smith     auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
4464fb1f9cdSDuncan P. N. Exon Smith     Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
4474fb1f9cdSDuncan P. N. Exon Smith     Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
4484fb1f9cdSDuncan P. N. Exon Smith                   dwarf::DW_FORM_data1, Zero);
449d70a0553SDavid Blaikie 
450827200c8SDuncan P. N. Exon Smith     DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
4518dbcc3feSDavid Blaikie     DIEEntry BarEntry(Bar);
4524fb1f9cdSDuncan P. N. Exon Smith     PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
453e7e1d0c7SDuncan P. N. Exon Smith                          BarEntry);
4544fb1f9cdSDuncan P. N. Exon Smith     PtrToFooMem.addValue(Alloc, dwarf::DW_AT_containing_type,
4554fb1f9cdSDuncan P. N. Exon Smith                          dwarf::DW_FORM_ref4, BarEntry);
456d70a0553SDavid Blaikie 
4578dbcc3feSDavid Blaikie     DIEEntry PtrToFooMemRef(PtrToFooMem);
4584fb1f9cdSDuncan P. N. Exon Smith     Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
4594fb1f9cdSDuncan P. N. Exon Smith                   PtrToFooMemRef);
460d70a0553SDavid Blaikie 
461914046e1SDavid Blaikie     Foo.addChild(std::move(Mem));
462d70a0553SDavid Blaikie 
4632aee7be8SDavid Blaikie     MD5ResDecl = DIEHash().computeTypeSignature(Foo);
464d70a0553SDavid Blaikie   }
465d70a0553SDavid Blaikie   uint64_t MD5ResDef;
466d70a0553SDavid Blaikie   {
467827200c8SDuncan P. N. Exon Smith     DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
4684fb1f9cdSDuncan P. N. Exon Smith     Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
4694fb1f9cdSDuncan P. N. Exon Smith     Bar.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
470d70a0553SDavid Blaikie 
471827200c8SDuncan P. N. Exon Smith     DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
4724fb1f9cdSDuncan P. N. Exon Smith     Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
4734fb1f9cdSDuncan P. N. Exon Smith     Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
474d70a0553SDavid Blaikie 
475827200c8SDuncan P. N. Exon Smith     auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
4764fb1f9cdSDuncan P. N. Exon Smith     Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
4774fb1f9cdSDuncan P. N. Exon Smith     Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
4784fb1f9cdSDuncan P. N. Exon Smith                   dwarf::DW_FORM_data1, Zero);
479d70a0553SDavid Blaikie 
480827200c8SDuncan P. N. Exon Smith     DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
4818dbcc3feSDavid Blaikie     DIEEntry BarEntry(Bar);
4824fb1f9cdSDuncan P. N. Exon Smith     PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
483e7e1d0c7SDuncan P. N. Exon Smith                          BarEntry);
4844fb1f9cdSDuncan P. N. Exon Smith     PtrToFooMem.addValue(Alloc, dwarf::DW_AT_containing_type,
4854fb1f9cdSDuncan P. N. Exon Smith                          dwarf::DW_FORM_ref4, BarEntry);
486d70a0553SDavid Blaikie 
4878dbcc3feSDavid Blaikie     DIEEntry PtrToFooMemRef(PtrToFooMem);
4884fb1f9cdSDuncan P. N. Exon Smith     Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
4894fb1f9cdSDuncan P. N. Exon Smith                   PtrToFooMemRef);
490d70a0553SDavid Blaikie 
491914046e1SDavid Blaikie     Foo.addChild(std::move(Mem));
492d70a0553SDavid Blaikie 
4932aee7be8SDavid Blaikie     MD5ResDef = DIEHash().computeTypeSignature(Foo);
494d70a0553SDavid Blaikie   }
495d70a0553SDavid Blaikie   // FIXME: This seems to be a bug in the DWARF type hashing specification that
496d70a0553SDavid Blaikie   // only uses the brief name hashing for types referenced via DW_AT_type. In
497d70a0553SDavid Blaikie   // this case the type is referenced via DW_AT_containing_type and full hashing
498d70a0553SDavid Blaikie   // causes a hash to differ when the containing type is a declaration in one TU
499d70a0553SDavid Blaikie   // and a definition in another.
500d70a0553SDavid Blaikie   ASSERT_NE(MD5ResDef, MD5ResDecl);
501d70a0553SDavid Blaikie }
50232744412SDavid Blaikie 
50332744412SDavid Blaikie // struct { } a;
50432744412SDavid Blaikie // struct foo { decltype(a) mem; };
TEST_F(DIEHashTest,RefUnnamedType)505f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, RefUnnamedType) {
50632744412SDavid Blaikie   DIEInteger Zero(0);
50732744412SDavid Blaikie   DIEInteger One(1);
50832744412SDavid Blaikie   DIEInteger Eight(8);
509f73bcf40SDuncan P. N. Exon Smith   DIEString FooStr = getString("foo");
510f73bcf40SDuncan P. N. Exon Smith   DIEString MemStr = getString("mem");
51132744412SDavid Blaikie 
512827200c8SDuncan P. N. Exon Smith   DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
5134fb1f9cdSDuncan P. N. Exon Smith   Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
51432744412SDavid Blaikie 
515827200c8SDuncan P. N. Exon Smith   DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
5164fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
5174fb1f9cdSDuncan P. N. Exon Smith   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
51832744412SDavid Blaikie 
519827200c8SDuncan P. N. Exon Smith   auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
5204fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
5214fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
5224fb1f9cdSDuncan P. N. Exon Smith                 Zero);
52332744412SDavid Blaikie 
524827200c8SDuncan P. N. Exon Smith   DIE &UnnamedPtr = *DIE::get(Alloc, dwarf::DW_TAG_pointer_type);
5254fb1f9cdSDuncan P. N. Exon Smith   UnnamedPtr.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1,
5264fb1f9cdSDuncan P. N. Exon Smith                       Eight);
5278dbcc3feSDavid Blaikie   DIEEntry UnnamedRef(Unnamed);
5284fb1f9cdSDuncan P. N. Exon Smith   UnnamedPtr.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
5294fb1f9cdSDuncan P. N. Exon Smith                       UnnamedRef);
53032744412SDavid Blaikie 
5318dbcc3feSDavid Blaikie   DIEEntry UnnamedPtrRef(UnnamedPtr);
5324fb1f9cdSDuncan P. N. Exon Smith   Mem->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, UnnamedPtrRef);
53332744412SDavid Blaikie 
534914046e1SDavid Blaikie   Foo.addChild(std::move(Mem));
53532744412SDavid Blaikie 
5362aee7be8SDavid Blaikie   uint64_t MD5Res = DIEHash().computeTypeSignature(Foo);
53732744412SDavid Blaikie 
53832744412SDavid Blaikie   ASSERT_EQ(0x954e026f01c02529ULL, MD5Res);
53932744412SDavid Blaikie }
54065cc969fSDavid Blaikie 
5415ad8d90bSEric Christopher // struct { struct foo { }; };
TEST_F(DIEHashTest,NestedType)542f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, NestedType) {
543827200c8SDuncan P. N. Exon Smith   DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
54465cc969fSDavid Blaikie   DIEInteger One(1);
5454fb1f9cdSDuncan P. N. Exon Smith   Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
54665cc969fSDavid Blaikie 
547827200c8SDuncan P. N. Exon Smith   auto Foo = DIE::get(Alloc, dwarf::DW_TAG_structure_type);
548f73bcf40SDuncan P. N. Exon Smith   DIEString FooStr = getString("foo");
5494fb1f9cdSDuncan P. N. Exon Smith   Foo->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
5504fb1f9cdSDuncan P. N. Exon Smith   Foo->addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
55165cc969fSDavid Blaikie 
552914046e1SDavid Blaikie   Unnamed.addChild(std::move(Foo));
55365cc969fSDavid Blaikie 
55465cc969fSDavid Blaikie   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
55565cc969fSDavid Blaikie 
55665cc969fSDavid Blaikie   // The exact same hash GCC produces for this DIE.
55765cc969fSDavid Blaikie   ASSERT_EQ(0xde8a3b7b43807f4aULL, MD5Res);
55865cc969fSDavid Blaikie }
5598bc7db77SDavid Blaikie 
5608bc7db77SDavid Blaikie // struct { static void func(); };
TEST_F(DIEHashTest,MemberFunc)561f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, MemberFunc) {
562827200c8SDuncan P. N. Exon Smith   DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
5638bc7db77SDavid Blaikie   DIEInteger One(1);
5644fb1f9cdSDuncan P. N. Exon Smith   Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
5658bc7db77SDavid Blaikie 
566827200c8SDuncan P. N. Exon Smith   auto Func = DIE::get(Alloc, dwarf::DW_TAG_subprogram);
567f73bcf40SDuncan P. N. Exon Smith   DIEString FuncStr = getString("func");
5684fb1f9cdSDuncan P. N. Exon Smith   Func->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FuncStr);
5698bc7db77SDavid Blaikie 
570914046e1SDavid Blaikie   Unnamed.addChild(std::move(Func));
5718bc7db77SDavid Blaikie 
5728bc7db77SDavid Blaikie   uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
5738bc7db77SDavid Blaikie 
5748bc7db77SDavid Blaikie   // The exact same hash GCC produces for this DIE.
5758bc7db77SDavid Blaikie   ASSERT_EQ(0xd36a1b6dfb604ba0ULL, MD5Res);
5768bc7db77SDavid Blaikie }
5774b1cf580SEric Christopher 
5784b1cf580SEric Christopher // struct A {
5794b1cf580SEric Christopher //   static void func();
5804b1cf580SEric Christopher // };
TEST_F(DIEHashTest,MemberFuncFlag)581f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, MemberFuncFlag) {
582827200c8SDuncan P. N. Exon Smith   DIE &A = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
5834b1cf580SEric Christopher   DIEInteger One(1);
584f73bcf40SDuncan P. N. Exon Smith   DIEString AStr = getString("A");
5854fb1f9cdSDuncan P. N. Exon Smith   A.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
5864fb1f9cdSDuncan P. N. Exon Smith   A.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
5874fb1f9cdSDuncan P. N. Exon Smith   A.addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
5884fb1f9cdSDuncan P. N. Exon Smith   A.addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
5894b1cf580SEric Christopher 
590827200c8SDuncan P. N. Exon Smith   auto Func = DIE::get(Alloc, dwarf::DW_TAG_subprogram);
591f73bcf40SDuncan P. N. Exon Smith   DIEString FuncStr = getString("func");
592f73bcf40SDuncan P. N. Exon Smith   DIEString FuncLinkage = getString("_ZN1A4funcEv");
5934b1cf580SEric Christopher   DIEInteger Two(2);
5944fb1f9cdSDuncan P. N. Exon Smith   Func->addValue(Alloc, dwarf::DW_AT_external, dwarf::DW_FORM_flag_present,
5954fb1f9cdSDuncan P. N. Exon Smith                  One);
5964fb1f9cdSDuncan P. N. Exon Smith   Func->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FuncStr);
5974fb1f9cdSDuncan P. N. Exon Smith   Func->addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
5984fb1f9cdSDuncan P. N. Exon Smith   Func->addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, Two);
5994fb1f9cdSDuncan P. N. Exon Smith   Func->addValue(Alloc, dwarf::DW_AT_linkage_name, dwarf::DW_FORM_strp,
6004fb1f9cdSDuncan P. N. Exon Smith                  FuncLinkage);
6014fb1f9cdSDuncan P. N. Exon Smith   Func->addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
6024fb1f9cdSDuncan P. N. Exon Smith                  One);
6034b1cf580SEric Christopher 
604914046e1SDavid Blaikie   A.addChild(std::move(Func));
6054b1cf580SEric Christopher 
6064b1cf580SEric Christopher   uint64_t MD5Res = DIEHash().computeTypeSignature(A);
6074b1cf580SEric Christopher 
6084b1cf580SEric Christopher   // The exact same hash GCC produces for this DIE.
609*a84e1e6cSAlexander Yermolovich   ASSERT_EQ(0x8F78211DDCE3DF10ULL, MD5Res);
6104b1cf580SEric Christopher }
6118192ba2aSEric Christopher 
6128192ba2aSEric Christopher // Derived from:
6138192ba2aSEric Christopher // struct A {
614f5ec3a02SEric Christopher //   const static int PI = -3;
6158192ba2aSEric Christopher // };
6168192ba2aSEric Christopher // A a;
TEST_F(DIEHashTest,MemberSdata)617f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, MemberSdata) {
618827200c8SDuncan P. N. Exon Smith   DIE &A = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
6198192ba2aSEric Christopher   DIEInteger One(1);
620f73bcf40SDuncan P. N. Exon Smith   DIEString AStr = getString("A");
6214fb1f9cdSDuncan P. N. Exon Smith   A.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
6224fb1f9cdSDuncan P. N. Exon Smith   A.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
6234fb1f9cdSDuncan P. N. Exon Smith   A.addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
6244fb1f9cdSDuncan P. N. Exon Smith   A.addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
6258192ba2aSEric Christopher 
6268192ba2aSEric Christopher   DIEInteger Four(4);
6278192ba2aSEric Christopher   DIEInteger Five(5);
628f73bcf40SDuncan P. N. Exon Smith   DIEString FStr = getString("int");
629827200c8SDuncan P. N. Exon Smith   DIE &IntTyDIE = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
6304fb1f9cdSDuncan P. N. Exon Smith   IntTyDIE.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
6314fb1f9cdSDuncan P. N. Exon Smith   IntTyDIE.addValue(Alloc, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five);
6324fb1f9cdSDuncan P. N. Exon Smith   IntTyDIE.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FStr);
6338192ba2aSEric Christopher 
6348dbcc3feSDavid Blaikie   DIEEntry IntTy(IntTyDIE);
635827200c8SDuncan P. N. Exon Smith   auto PITyDIE = DIE::get(Alloc, dwarf::DW_TAG_const_type);
6364fb1f9cdSDuncan P. N. Exon Smith   PITyDIE->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntTy);
6378192ba2aSEric Christopher 
6388dbcc3feSDavid Blaikie   DIEEntry PITy(*PITyDIE);
639827200c8SDuncan P. N. Exon Smith   auto PI = DIE::get(Alloc, dwarf::DW_TAG_member);
640f73bcf40SDuncan P. N. Exon Smith   DIEString PIStr = getString("PI");
6418192ba2aSEric Christopher   DIEInteger Two(2);
6428192ba2aSEric Christopher   DIEInteger NegThree(-3);
6434fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, PIStr);
6444fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
6454fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, Two);
6464fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PITy);
6474fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, One);
6484fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
6494fb1f9cdSDuncan P. N. Exon Smith                One);
6504fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, NegThree);
6518192ba2aSEric Christopher 
652914046e1SDavid Blaikie   A.addChild(std::move(PI));
6538192ba2aSEric Christopher 
6548192ba2aSEric Christopher   uint64_t MD5Res = DIEHash().computeTypeSignature(A);
655*a84e1e6cSAlexander Yermolovich   ASSERT_EQ(0x9A216000DD3788A7ULL, MD5Res);
6568192ba2aSEric Christopher }
657420569beSEric Christopher 
658420569beSEric Christopher // Derived from:
659420569beSEric Christopher // struct A {
660420569beSEric Christopher //   const static float PI = 3.14;
661420569beSEric Christopher // };
662420569beSEric Christopher // A a;
TEST_F(DIEHashTest,MemberBlock)663f73bcf40SDuncan P. N. Exon Smith TEST_F(DIEHashTest, MemberBlock) {
664027d47d1SIgor Kudrin   if (!this->getAsmPrinter())
6655bbf1feaSIgor Kudrin     GTEST_SKIP();
666027d47d1SIgor Kudrin 
667827200c8SDuncan P. N. Exon Smith   DIE &A = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
668420569beSEric Christopher   DIEInteger One(1);
669f73bcf40SDuncan P. N. Exon Smith   DIEString AStr = getString("A");
6704fb1f9cdSDuncan P. N. Exon Smith   A.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
6714fb1f9cdSDuncan P. N. Exon Smith   A.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
6724fb1f9cdSDuncan P. N. Exon Smith   A.addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
6734fb1f9cdSDuncan P. N. Exon Smith   A.addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
674420569beSEric Christopher 
675420569beSEric Christopher   DIEInteger Four(4);
676f73bcf40SDuncan P. N. Exon Smith   DIEString FStr = getString("float");
677827200c8SDuncan P. N. Exon Smith   auto FloatTyDIE = DIE::get(Alloc, dwarf::DW_TAG_base_type);
6784fb1f9cdSDuncan P. N. Exon Smith   FloatTyDIE->addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1,
6794fb1f9cdSDuncan P. N. Exon Smith                        Four);
6804fb1f9cdSDuncan P. N. Exon Smith   FloatTyDIE->addValue(Alloc, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
6814fb1f9cdSDuncan P. N. Exon Smith                        Four);
6824fb1f9cdSDuncan P. N. Exon Smith   FloatTyDIE->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FStr);
6838dbcc3feSDavid Blaikie   DIEEntry FloatTy(*FloatTyDIE);
684827200c8SDuncan P. N. Exon Smith   auto PITyDIE = DIE::get(Alloc, dwarf::DW_TAG_const_type);
6854fb1f9cdSDuncan P. N. Exon Smith   PITyDIE->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FloatTy);
686420569beSEric Christopher 
6878dbcc3feSDavid Blaikie   DIEEntry PITy(*PITyDIE);
688827200c8SDuncan P. N. Exon Smith   auto PI = DIE::get(Alloc, dwarf::DW_TAG_member);
689f73bcf40SDuncan P. N. Exon Smith   DIEString PIStr = getString("PI");
690420569beSEric Christopher   DIEInteger Two(2);
6914fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, PIStr);
6924fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
6934fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, Two);
6944fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, PITy);
6954fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, One);
6964fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
6974fb1f9cdSDuncan P. N. Exon Smith                One);
698420569beSEric Christopher 
699de519a2dSDavid Blaikie   DIEBlock PIBlock;
700420569beSEric Christopher   DIEInteger Blk1(0xc3);
701420569beSEric Christopher   DIEInteger Blk2(0xf5);
702420569beSEric Christopher   DIEInteger Blk3(0x48);
703420569beSEric Christopher   DIEInteger Blk4(0x40);
704420569beSEric Christopher 
7054fb1f9cdSDuncan P. N. Exon Smith   PIBlock.addValue(Alloc, (dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk1);
7064fb1f9cdSDuncan P. N. Exon Smith   PIBlock.addValue(Alloc, (dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk2);
7074fb1f9cdSDuncan P. N. Exon Smith   PIBlock.addValue(Alloc, (dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk3);
7084fb1f9cdSDuncan P. N. Exon Smith   PIBlock.addValue(Alloc, (dwarf::Attribute)0, dwarf::DW_FORM_data1, Blk4);
709420569beSEric Christopher 
7104fb1f9cdSDuncan P. N. Exon Smith   PI->addValue(Alloc, dwarf::DW_AT_const_value, dwarf::DW_FORM_block1,
7114fb1f9cdSDuncan P. N. Exon Smith                &PIBlock);
712420569beSEric Christopher 
713914046e1SDavid Blaikie   A.addChild(std::move(PI));
714420569beSEric Christopher 
715027d47d1SIgor Kudrin   uint64_t MD5Res = DIEHash(this->getAsmPrinter()).computeTypeSignature(A);
716*a84e1e6cSAlexander Yermolovich   ASSERT_EQ(0x493AF53AD3D3F651ULL, MD5Res);
717420569beSEric Christopher }
71825b7adc8SEric Christopher }
719