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