brintos

brintos / llvm-project-archived public Read only

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