1a03435ecSPavel Labath //===- llvm/unittest/DebugInfo/DWARFDieTest.cpp ---------------------------===// 2a03435ecSPavel Labath // 3a03435ecSPavel Labath // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a03435ecSPavel Labath // See https://llvm.org/LICENSE.txt for license information. 5a03435ecSPavel Labath // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a03435ecSPavel Labath // 7a03435ecSPavel Labath //===----------------------------------------------------------------------===// 8a03435ecSPavel Labath 9a03435ecSPavel Labath #include "llvm/BinaryFormat/Dwarf.h" 10290e4823Sserge-sans-paille #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" 11a03435ecSPavel Labath #include "llvm/DebugInfo/DWARF/DWARFContext.h" 12*9de73b20SZequan Wu #include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h" 13a03435ecSPavel Labath #include "llvm/ObjectYAML/DWARFEmitter.h" 14a03435ecSPavel Labath #include "llvm/Testing/Support/Error.h" 15a03435ecSPavel Labath #include "gtest/gtest.h" 16a03435ecSPavel Labath 17a03435ecSPavel Labath using namespace llvm; 18a03435ecSPavel Labath using namespace llvm::dwarf; 19a03435ecSPavel Labath 20a03435ecSPavel Labath namespace { 21a03435ecSPavel Labath 22a03435ecSPavel Labath TEST(DWARFDie, getLocations) { 23a03435ecSPavel Labath const char *yamldata = R"( 24a03435ecSPavel Labath debug_abbrev: 25290e399fSXing GUO - Table: 26a03435ecSPavel Labath - Code: 0x00000001 27a03435ecSPavel Labath Tag: DW_TAG_compile_unit 28a03435ecSPavel Labath Children: DW_CHILDREN_no 29a03435ecSPavel Labath Attributes: 30a03435ecSPavel Labath - Attribute: DW_AT_location 31a03435ecSPavel Labath Form: DW_FORM_sec_offset 32a03435ecSPavel Labath - Attribute: DW_AT_data_member_location 33a03435ecSPavel Labath Form: DW_FORM_exprloc 34a03435ecSPavel Labath - Attribute: DW_AT_vtable_elem_location 35a03435ecSPavel Labath Form: DW_FORM_sec_offset 36a03435ecSPavel Labath - Attribute: DW_AT_call_data_location 37a03435ecSPavel Labath Form: DW_FORM_sec_offset 38a03435ecSPavel Labath debug_info: 3986329317SXing GUO - Version: 5 40a03435ecSPavel Labath UnitType: DW_UT_compile 41a03435ecSPavel Labath AddrSize: 4 42a03435ecSPavel Labath Entries: 43a03435ecSPavel Labath - AbbrCode: 0x00000001 44a03435ecSPavel Labath Values: 45a03435ecSPavel Labath - Value: 12 46a03435ecSPavel Labath - Value: 0x0000000000000001 47a03435ecSPavel Labath BlockData: [ 0x47 ] 48a03435ecSPavel Labath - Value: 20 49a03435ecSPavel Labath - Value: 25 505d597e20SXing GUO debug_loclists: 515d597e20SXing GUO - AddressSize: 4 525d597e20SXing GUO OffsetEntryCount: 0 535d597e20SXing GUO Lists: 545d597e20SXing GUO - Entries: 555d597e20SXing GUO - Operator: DW_LLE_start_length 565d597e20SXing GUO Values: [ 0x01, 0x02 ] 575d597e20SXing GUO - Operator: DW_LLE_end_of_list 585d597e20SXing GUO - Entries: 595d597e20SXing GUO - Operator: DW_LLE_startx_length 605d597e20SXing GUO Values: [ 0x01, 0x02 ] 615d597e20SXing GUO - Operator: DW_LLE_end_of_list 625d597e20SXing GUO - Entries: 635d597e20SXing GUO - Operator: DW_LLE_start_length 645d597e20SXing GUO Values: [ 0x01, 0x02 ] 655d597e20SXing GUO ## end_of_list intentionally missing. 66a03435ecSPavel Labath )"; 67a03435ecSPavel Labath Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections = 6892874d28SXing GUO DWARFYAML::emitDebugSections(StringRef(yamldata), 6912605bfdSXing GUO /*IsLittleEndian=*/true, 7012605bfdSXing GUO /*Is64BitAddrSize=*/false); 71a03435ecSPavel Labath ASSERT_THAT_EXPECTED(Sections, Succeeded()); 72a03435ecSPavel Labath std::unique_ptr<DWARFContext> Ctx = 73a03435ecSPavel Labath DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true); 74a03435ecSPavel Labath DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0); 75a03435ecSPavel Labath ASSERT_NE(nullptr, CU); 76a03435ecSPavel Labath DWARFDie Die = CU->getUnitDIE(); 77a03435ecSPavel Labath ASSERT_TRUE(Die.isValid()); 78a03435ecSPavel Labath 79a03435ecSPavel Labath EXPECT_THAT_EXPECTED(Die.getLocations(DW_AT_location), 80a03435ecSPavel Labath HasValue(testing::ElementsAre(DWARFLocationExpression{ 81a03435ecSPavel Labath DWARFAddressRange{1, 3}, {}}))); 82a03435ecSPavel Labath 83b6a01caaSKazu Hirata EXPECT_THAT_EXPECTED(Die.getLocations(DW_AT_data_member_location), 84b6a01caaSKazu Hirata HasValue(testing::ElementsAre( 85b6a01caaSKazu Hirata DWARFLocationExpression{std::nullopt, {0x47}}))); 86a03435ecSPavel Labath 87a03435ecSPavel Labath EXPECT_THAT_EXPECTED( 88a03435ecSPavel Labath Die.getLocations(DW_AT_vtable_elem_location), 89a03435ecSPavel Labath Failed<ErrorInfoBase>(testing::Property( 90a03435ecSPavel Labath &ErrorInfoBase::message, 914f60a428SDavid Blaikie "unable to resolve indirect address 1 for: DW_LLE_startx_length"))); 92a03435ecSPavel Labath 935754a61eSPavel Labath EXPECT_THAT_EXPECTED( 945754a61eSPavel Labath Die.getLocations(DW_AT_call_data_location), 9504aea769SPavel Labath FailedWithMessage( 9604aea769SPavel Labath "unexpected end of data at offset 0x20 while reading [0x20, 0x21)")); 97a03435ecSPavel Labath 98a03435ecSPavel Labath EXPECT_THAT_EXPECTED( 99a03435ecSPavel Labath Die.getLocations(DW_AT_call_data_value), 100a03435ecSPavel Labath Failed<ErrorInfoBase>(testing::Property(&ErrorInfoBase::message, 101a03435ecSPavel Labath "No DW_AT_call_data_value"))); 102a03435ecSPavel Labath } 103a03435ecSPavel Labath 104a58c2e4aSGreg Clayton TEST(DWARFDie, getDeclFile) { 105a58c2e4aSGreg Clayton const char *yamldata = R"( 106a58c2e4aSGreg Clayton debug_str: 107a58c2e4aSGreg Clayton - '' 108a58c2e4aSGreg Clayton debug_abbrev: 109a58c2e4aSGreg Clayton - ID: 0 110a58c2e4aSGreg Clayton Table: 111a58c2e4aSGreg Clayton - Code: 0x1 112a58c2e4aSGreg Clayton Tag: DW_TAG_compile_unit 113a58c2e4aSGreg Clayton Children: DW_CHILDREN_yes 114a58c2e4aSGreg Clayton Attributes: 115a58c2e4aSGreg Clayton - Attribute: DW_AT_stmt_list 116a58c2e4aSGreg Clayton Form: DW_FORM_sec_offset 117a58c2e4aSGreg Clayton - Code: 0x2 118a58c2e4aSGreg Clayton Tag: DW_TAG_subprogram 119a58c2e4aSGreg Clayton Children: DW_CHILDREN_no 120a58c2e4aSGreg Clayton Attributes: 121a58c2e4aSGreg Clayton - Attribute: DW_AT_decl_file 122a58c2e4aSGreg Clayton Form: DW_FORM_data1 123a58c2e4aSGreg Clayton debug_info: 124a58c2e4aSGreg Clayton - Length: 0xF 125a58c2e4aSGreg Clayton Version: 4 126a58c2e4aSGreg Clayton AbbrevTableID: 0 127a58c2e4aSGreg Clayton AbbrOffset: 0x0 128a58c2e4aSGreg Clayton AddrSize: 8 129a58c2e4aSGreg Clayton Entries: 130a58c2e4aSGreg Clayton - AbbrCode: 0x1 131a58c2e4aSGreg Clayton Values: 132a58c2e4aSGreg Clayton - Value: 0x0 133a58c2e4aSGreg Clayton - AbbrCode: 0x2 134a58c2e4aSGreg Clayton Values: 135a58c2e4aSGreg Clayton - Value: 0x1 136a58c2e4aSGreg Clayton - AbbrCode: 0x0 137a58c2e4aSGreg Clayton debug_line: 138a58c2e4aSGreg Clayton - Length: 42 139a58c2e4aSGreg Clayton Version: 2 140a58c2e4aSGreg Clayton PrologueLength: 36 141a58c2e4aSGreg Clayton MinInstLength: 1 142a58c2e4aSGreg Clayton DefaultIsStmt: 1 143a58c2e4aSGreg Clayton LineBase: 251 144a58c2e4aSGreg Clayton LineRange: 14 145a58c2e4aSGreg Clayton OpcodeBase: 13 146a58c2e4aSGreg Clayton StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ] 147a58c2e4aSGreg Clayton IncludeDirs: 148a58c2e4aSGreg Clayton - '/tmp' 149a58c2e4aSGreg Clayton Files: 150a58c2e4aSGreg Clayton - Name: main.cpp 151a58c2e4aSGreg Clayton DirIdx: 1 152a58c2e4aSGreg Clayton ModTime: 0 153a58c2e4aSGreg Clayton Length: 0 154a58c2e4aSGreg Clayton )"; 155a58c2e4aSGreg Clayton 156a58c2e4aSGreg Clayton // Given DWARF like this: 157a58c2e4aSGreg Clayton // 158a58c2e4aSGreg Clayton // 0x0000000b: DW_TAG_compile_unit 159a58c2e4aSGreg Clayton // DW_AT_stmt_list (0x00000000) 160a58c2e4aSGreg Clayton // 161a58c2e4aSGreg Clayton // 0x00000010: DW_TAG_subprogram 162a58c2e4aSGreg Clayton // DW_AT_decl_file ("/tmp/main.cpp") 163a58c2e4aSGreg Clayton // 164a58c2e4aSGreg Clayton // 0x00000012: NULL 165a58c2e4aSGreg Clayton // 166a58c2e4aSGreg Clayton // This tests that we can extract the right DW_AT_decl_file from a DIE that 167a58c2e4aSGreg Clayton // has a DW_AT_decl_file attribute. 168a58c2e4aSGreg Clayton 169a58c2e4aSGreg Clayton Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections = 170a58c2e4aSGreg Clayton DWARFYAML::emitDebugSections(StringRef(yamldata), 171a58c2e4aSGreg Clayton /*IsLittleEndian=*/true, 172a58c2e4aSGreg Clayton /*Is64BitAddrSize=*/true); 173a58c2e4aSGreg Clayton ASSERT_THAT_EXPECTED(Sections, Succeeded()); 174a58c2e4aSGreg Clayton std::unique_ptr<DWARFContext> Ctx = 175a58c2e4aSGreg Clayton DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true); 176a58c2e4aSGreg Clayton DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0); 177a58c2e4aSGreg Clayton ASSERT_NE(nullptr, CU); 178a58c2e4aSGreg Clayton DWARFDie Die = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false); 179a58c2e4aSGreg Clayton ASSERT_TRUE(Die.isValid()); 180a58c2e4aSGreg Clayton 181a58c2e4aSGreg Clayton DWARFDie MainDie = Die.getFirstChild(); 182a58c2e4aSGreg Clayton ASSERT_TRUE(MainDie.isValid()); 183a58c2e4aSGreg Clayton 184a58c2e4aSGreg Clayton std::string DeclFile = MainDie.getDeclFile( 185a58c2e4aSGreg Clayton DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath); 186a58c2e4aSGreg Clayton 187f0955922SMartin Storsjö std::string Ref = 188f0955922SMartin Storsjö ("/tmp" + llvm::sys::path::get_separator() + "main.cpp").str(); 189f0955922SMartin Storsjö EXPECT_EQ(DeclFile, Ref); 190a58c2e4aSGreg Clayton } 191a58c2e4aSGreg Clayton 192a58c2e4aSGreg Clayton TEST(DWARFDie, getDeclFileAbstractOrigin) { 193a58c2e4aSGreg Clayton const char *yamldata = R"( 194a58c2e4aSGreg Clayton debug_str: 195a58c2e4aSGreg Clayton - '' 196a58c2e4aSGreg Clayton debug_abbrev: 197a58c2e4aSGreg Clayton - ID: 0 198a58c2e4aSGreg Clayton Table: 199a58c2e4aSGreg Clayton - Code: 0x1 200a58c2e4aSGreg Clayton Tag: DW_TAG_compile_unit 201a58c2e4aSGreg Clayton Children: DW_CHILDREN_yes 202a58c2e4aSGreg Clayton Attributes: 203a58c2e4aSGreg Clayton - Attribute: DW_AT_stmt_list 204a58c2e4aSGreg Clayton Form: DW_FORM_sec_offset 205a58c2e4aSGreg Clayton - Code: 0x2 206a58c2e4aSGreg Clayton Tag: DW_TAG_subprogram 207a58c2e4aSGreg Clayton Children: DW_CHILDREN_no 208a58c2e4aSGreg Clayton Attributes: 209a58c2e4aSGreg Clayton - Attribute: DW_AT_abstract_origin 210a58c2e4aSGreg Clayton Form: DW_FORM_ref_addr 211a58c2e4aSGreg Clayton - Code: 0x3 212a58c2e4aSGreg Clayton Tag: DW_TAG_subprogram 213a58c2e4aSGreg Clayton Children: DW_CHILDREN_no 214a58c2e4aSGreg Clayton Attributes: 215a58c2e4aSGreg Clayton - Attribute: DW_AT_decl_file 216a58c2e4aSGreg Clayton Form: DW_FORM_data1 217a58c2e4aSGreg Clayton debug_info: 218a58c2e4aSGreg Clayton - Length: 0x14 219a58c2e4aSGreg Clayton Version: 4 220a58c2e4aSGreg Clayton AbbrevTableID: 0 221a58c2e4aSGreg Clayton AbbrOffset: 0x0 222a58c2e4aSGreg Clayton AddrSize: 8 223a58c2e4aSGreg Clayton Entries: 224a58c2e4aSGreg Clayton - AbbrCode: 0x1 225a58c2e4aSGreg Clayton Values: 226a58c2e4aSGreg Clayton - Value: 0x0 227a58c2e4aSGreg Clayton - AbbrCode: 0x2 228a58c2e4aSGreg Clayton Values: 229a58c2e4aSGreg Clayton - Value: 0x15 230a58c2e4aSGreg Clayton - AbbrCode: 0x3 231a58c2e4aSGreg Clayton Values: 232a58c2e4aSGreg Clayton - Value: 0x1 233a58c2e4aSGreg Clayton - AbbrCode: 0x0 234a58c2e4aSGreg Clayton debug_line: 235a58c2e4aSGreg Clayton - Length: 42 236a58c2e4aSGreg Clayton Version: 2 237a58c2e4aSGreg Clayton PrologueLength: 36 238a58c2e4aSGreg Clayton MinInstLength: 1 239a58c2e4aSGreg Clayton DefaultIsStmt: 1 240a58c2e4aSGreg Clayton LineBase: 251 241a58c2e4aSGreg Clayton LineRange: 14 242a58c2e4aSGreg Clayton OpcodeBase: 13 243a58c2e4aSGreg Clayton StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ] 244a58c2e4aSGreg Clayton IncludeDirs: 245a58c2e4aSGreg Clayton - '/tmp' 246a58c2e4aSGreg Clayton Files: 247a58c2e4aSGreg Clayton - Name: main.cpp 248a58c2e4aSGreg Clayton DirIdx: 1 249a58c2e4aSGreg Clayton ModTime: 0 250a58c2e4aSGreg Clayton Length: 0 251a58c2e4aSGreg Clayton )"; 252a58c2e4aSGreg Clayton 253a58c2e4aSGreg Clayton // Given DWARF like this: 254a58c2e4aSGreg Clayton // 255a58c2e4aSGreg Clayton // 0x0000000b: DW_TAG_compile_unit 256a58c2e4aSGreg Clayton // DW_AT_stmt_list (0x00000000) 257a58c2e4aSGreg Clayton // 258a58c2e4aSGreg Clayton // 0x00000010: DW_TAG_subprogram 259a58c2e4aSGreg Clayton // DW_AT_abstract_origin (0x0000000000000015) 260a58c2e4aSGreg Clayton // 261a58c2e4aSGreg Clayton // 0x00000015: DW_TAG_subprogram 262a58c2e4aSGreg Clayton // DW_AT_decl_file ("/tmp/main.cpp") 263a58c2e4aSGreg Clayton // 264a58c2e4aSGreg Clayton // 0x00000017: NULL 265a58c2e4aSGreg Clayton // 266a58c2e4aSGreg Clayton // 267a58c2e4aSGreg Clayton // The DIE at 0x00000010 uses a DW_AT_abstract_origin to point to the DIE at 268a58c2e4aSGreg Clayton // 0x00000015, make sure that DWARFDie::getDeclFile() succeeds by extracting 269a58c2e4aSGreg Clayton // the right file name of "/tmp/main.cpp". 270a58c2e4aSGreg Clayton // 271a58c2e4aSGreg Clayton // This tests that when we have a DW_AT_abstract_origin with a compile unit 272a58c2e4aSGreg Clayton // relative form (DW_FORM_ref4) to another DIE that we get the right 273a58c2e4aSGreg Clayton // DW_AT_decl_file value. 274a58c2e4aSGreg Clayton 275a58c2e4aSGreg Clayton Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections = 276a58c2e4aSGreg Clayton DWARFYAML::emitDebugSections(StringRef(yamldata), 277a58c2e4aSGreg Clayton /*IsLittleEndian=*/true, 278a58c2e4aSGreg Clayton /*Is64BitAddrSize=*/true); 279a58c2e4aSGreg Clayton ASSERT_THAT_EXPECTED(Sections, Succeeded()); 280a58c2e4aSGreg Clayton std::unique_ptr<DWARFContext> Ctx = 281a58c2e4aSGreg Clayton DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true); 282a58c2e4aSGreg Clayton DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0); 283a58c2e4aSGreg Clayton ASSERT_NE(nullptr, CU); 284a58c2e4aSGreg Clayton DWARFDie Die = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false); 285a58c2e4aSGreg Clayton ASSERT_TRUE(Die.isValid()); 286a58c2e4aSGreg Clayton 287a58c2e4aSGreg Clayton DWARFDie MainDie = Die.getFirstChild(); 288a58c2e4aSGreg Clayton ASSERT_TRUE(MainDie.isValid()); 289a58c2e4aSGreg Clayton 290a58c2e4aSGreg Clayton std::string DeclFile = MainDie.getDeclFile( 291a58c2e4aSGreg Clayton DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath); 292a58c2e4aSGreg Clayton 293f0955922SMartin Storsjö std::string Ref = 294f0955922SMartin Storsjö ("/tmp" + llvm::sys::path::get_separator() + "main.cpp").str(); 295f0955922SMartin Storsjö EXPECT_EQ(DeclFile, Ref); 296a58c2e4aSGreg Clayton } 297a58c2e4aSGreg Clayton 298a58c2e4aSGreg Clayton TEST(DWARFDie, getDeclFileSpecification) { 299a58c2e4aSGreg Clayton const char *yamldata = R"( 300a58c2e4aSGreg Clayton debug_str: 301a58c2e4aSGreg Clayton - '' 302a58c2e4aSGreg Clayton debug_abbrev: 303a58c2e4aSGreg Clayton - ID: 0 304a58c2e4aSGreg Clayton Table: 305a58c2e4aSGreg Clayton - Code: 0x1 306a58c2e4aSGreg Clayton Tag: DW_TAG_compile_unit 307a58c2e4aSGreg Clayton Children: DW_CHILDREN_yes 308a58c2e4aSGreg Clayton Attributes: 309a58c2e4aSGreg Clayton - Attribute: DW_AT_stmt_list 310a58c2e4aSGreg Clayton Form: DW_FORM_sec_offset 311a58c2e4aSGreg Clayton - Code: 0x2 312a58c2e4aSGreg Clayton Tag: DW_TAG_subprogram 313a58c2e4aSGreg Clayton Children: DW_CHILDREN_no 314a58c2e4aSGreg Clayton Attributes: 315a58c2e4aSGreg Clayton - Attribute: DW_AT_specification 316a58c2e4aSGreg Clayton Form: DW_FORM_ref_addr 317a58c2e4aSGreg Clayton - Code: 0x3 318a58c2e4aSGreg Clayton Tag: DW_TAG_subprogram 319a58c2e4aSGreg Clayton Children: DW_CHILDREN_no 320a58c2e4aSGreg Clayton Attributes: 321a58c2e4aSGreg Clayton - Attribute: DW_AT_decl_file 322a58c2e4aSGreg Clayton Form: DW_FORM_data1 323a58c2e4aSGreg Clayton debug_info: 324a58c2e4aSGreg Clayton - Length: 0x14 325a58c2e4aSGreg Clayton Version: 4 326a58c2e4aSGreg Clayton AbbrevTableID: 0 327a58c2e4aSGreg Clayton AbbrOffset: 0x0 328a58c2e4aSGreg Clayton AddrSize: 8 329a58c2e4aSGreg Clayton Entries: 330a58c2e4aSGreg Clayton - AbbrCode: 0x1 331a58c2e4aSGreg Clayton Values: 332a58c2e4aSGreg Clayton - Value: 0x0 333a58c2e4aSGreg Clayton - AbbrCode: 0x2 334a58c2e4aSGreg Clayton Values: 335a58c2e4aSGreg Clayton - Value: 0x15 336a58c2e4aSGreg Clayton - AbbrCode: 0x3 337a58c2e4aSGreg Clayton Values: 338a58c2e4aSGreg Clayton - Value: 0x1 339a58c2e4aSGreg Clayton - AbbrCode: 0x0 340a58c2e4aSGreg Clayton debug_line: 341a58c2e4aSGreg Clayton - Length: 42 342a58c2e4aSGreg Clayton Version: 2 343a58c2e4aSGreg Clayton PrologueLength: 36 344a58c2e4aSGreg Clayton MinInstLength: 1 345a58c2e4aSGreg Clayton DefaultIsStmt: 1 346a58c2e4aSGreg Clayton LineBase: 251 347a58c2e4aSGreg Clayton LineRange: 14 348a58c2e4aSGreg Clayton OpcodeBase: 13 349a58c2e4aSGreg Clayton StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ] 350a58c2e4aSGreg Clayton IncludeDirs: 351a58c2e4aSGreg Clayton - '/tmp' 352a58c2e4aSGreg Clayton Files: 353a58c2e4aSGreg Clayton - Name: main.cpp 354a58c2e4aSGreg Clayton DirIdx: 1 355a58c2e4aSGreg Clayton ModTime: 0 356a58c2e4aSGreg Clayton Length: 0 357a58c2e4aSGreg Clayton )"; 358a58c2e4aSGreg Clayton 359a58c2e4aSGreg Clayton // Given DWARF like this: 360a58c2e4aSGreg Clayton // 361a58c2e4aSGreg Clayton // 0x0000000b: DW_TAG_compile_unit 362a58c2e4aSGreg Clayton // DW_AT_stmt_list (0x00000000) 363a58c2e4aSGreg Clayton // 364a58c2e4aSGreg Clayton // 0x00000010: DW_TAG_subprogram 365a58c2e4aSGreg Clayton // DW_AT_specification (0x0000000000000015) 366a58c2e4aSGreg Clayton // 367a58c2e4aSGreg Clayton // 0x00000015: DW_TAG_subprogram 368a58c2e4aSGreg Clayton // DW_AT_decl_file ("/tmp/main.cpp") 369a58c2e4aSGreg Clayton // 370a58c2e4aSGreg Clayton // 0x00000017: NULL 371a58c2e4aSGreg Clayton // 372a58c2e4aSGreg Clayton // The DIE at 0x00000010 uses a DW_AT_specification to point to the DIE at 373a58c2e4aSGreg Clayton // 0x00000015, make sure that DWARFDie::getDeclFile() succeeds by extracting 374a58c2e4aSGreg Clayton // the right file name of "/tmp/main.cpp". 375a58c2e4aSGreg Clayton // 376a58c2e4aSGreg Clayton // This tests that when we have a DW_AT_specification with a compile unit 377a58c2e4aSGreg Clayton // relative form (DW_FORM_ref4) to another DIE that we get the right 378a58c2e4aSGreg Clayton // DW_AT_decl_file value. 379a58c2e4aSGreg Clayton 380a58c2e4aSGreg Clayton Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections = 381a58c2e4aSGreg Clayton DWARFYAML::emitDebugSections(StringRef(yamldata), 382a58c2e4aSGreg Clayton /*IsLittleEndian=*/true, 383a58c2e4aSGreg Clayton /*Is64BitAddrSize=*/true); 384a58c2e4aSGreg Clayton ASSERT_THAT_EXPECTED(Sections, Succeeded()); 385a58c2e4aSGreg Clayton std::unique_ptr<DWARFContext> Ctx = 386a58c2e4aSGreg Clayton DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true); 387a58c2e4aSGreg Clayton DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0); 388a58c2e4aSGreg Clayton ASSERT_NE(nullptr, CU); 389a58c2e4aSGreg Clayton DWARFDie Die = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false); 390a58c2e4aSGreg Clayton ASSERT_TRUE(Die.isValid()); 391a58c2e4aSGreg Clayton 392a58c2e4aSGreg Clayton DWARFDie MainDie = Die.getFirstChild(); 393a58c2e4aSGreg Clayton ASSERT_TRUE(MainDie.isValid()); 394a58c2e4aSGreg Clayton 395a58c2e4aSGreg Clayton std::string DeclFile = MainDie.getDeclFile( 396a58c2e4aSGreg Clayton DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath); 397a58c2e4aSGreg Clayton 398f0955922SMartin Storsjö std::string Ref = 399f0955922SMartin Storsjö ("/tmp" + llvm::sys::path::get_separator() + "main.cpp").str(); 400f0955922SMartin Storsjö EXPECT_EQ(DeclFile, Ref); 401a58c2e4aSGreg Clayton } 402a58c2e4aSGreg Clayton 403a58c2e4aSGreg Clayton TEST(DWARFDie, getDeclFileAbstractOriginAcrossCUBoundary) { 404a58c2e4aSGreg Clayton const char *yamldata = R"( 405a58c2e4aSGreg Clayton debug_str: 406a58c2e4aSGreg Clayton - '' 407a58c2e4aSGreg Clayton debug_abbrev: 408a58c2e4aSGreg Clayton - ID: 0 409a58c2e4aSGreg Clayton Table: 410a58c2e4aSGreg Clayton - Code: 0x1 411a58c2e4aSGreg Clayton Tag: DW_TAG_compile_unit 412a58c2e4aSGreg Clayton Children: DW_CHILDREN_yes 413a58c2e4aSGreg Clayton - Code: 0x2 414a58c2e4aSGreg Clayton Tag: DW_TAG_subprogram 415a58c2e4aSGreg Clayton Children: DW_CHILDREN_no 416a58c2e4aSGreg Clayton Attributes: 417a58c2e4aSGreg Clayton - Attribute: DW_AT_abstract_origin 418a58c2e4aSGreg Clayton Form: DW_FORM_ref_addr 419a58c2e4aSGreg Clayton - Code: 0x3 420a58c2e4aSGreg Clayton Tag: DW_TAG_compile_unit 421a58c2e4aSGreg Clayton Children: DW_CHILDREN_yes 422a58c2e4aSGreg Clayton Attributes: 423a58c2e4aSGreg Clayton - Attribute: DW_AT_stmt_list 424a58c2e4aSGreg Clayton Form: DW_FORM_sec_offset 425a58c2e4aSGreg Clayton - Code: 0x4 426a58c2e4aSGreg Clayton Tag: DW_TAG_subprogram 427a58c2e4aSGreg Clayton Children: DW_CHILDREN_no 428a58c2e4aSGreg Clayton Attributes: 429a58c2e4aSGreg Clayton - Attribute: DW_AT_decl_file 430a58c2e4aSGreg Clayton Form: DW_FORM_data1 431a58c2e4aSGreg Clayton debug_info: 432a58c2e4aSGreg Clayton - Length: 0xE 433a58c2e4aSGreg Clayton Version: 4 434a58c2e4aSGreg Clayton AbbrevTableID: 0 435a58c2e4aSGreg Clayton AbbrOffset: 0x0 436a58c2e4aSGreg Clayton AddrSize: 8 437a58c2e4aSGreg Clayton Entries: 438a58c2e4aSGreg Clayton - AbbrCode: 0x1 439a58c2e4aSGreg Clayton - AbbrCode: 0x2 440a58c2e4aSGreg Clayton Values: 441a58c2e4aSGreg Clayton - Value: 0x22 442a58c2e4aSGreg Clayton - AbbrCode: 0x0 443a58c2e4aSGreg Clayton - Length: 0xF 444a58c2e4aSGreg Clayton Version: 4 445a58c2e4aSGreg Clayton AbbrevTableID: 0 446a58c2e4aSGreg Clayton AbbrOffset: 0x0 447a58c2e4aSGreg Clayton AddrSize: 8 448a58c2e4aSGreg Clayton Entries: 449a58c2e4aSGreg Clayton - AbbrCode: 0x3 450a58c2e4aSGreg Clayton Values: 451a58c2e4aSGreg Clayton - Value: 0x0 452a58c2e4aSGreg Clayton - AbbrCode: 0x4 453a58c2e4aSGreg Clayton Values: 454a58c2e4aSGreg Clayton - Value: 0x1 455a58c2e4aSGreg Clayton - AbbrCode: 0x0 456a58c2e4aSGreg Clayton debug_line: 457a58c2e4aSGreg Clayton - Length: 42 458a58c2e4aSGreg Clayton Version: 2 459a58c2e4aSGreg Clayton PrologueLength: 36 460a58c2e4aSGreg Clayton MinInstLength: 1 461a58c2e4aSGreg Clayton DefaultIsStmt: 1 462a58c2e4aSGreg Clayton LineBase: 251 463a58c2e4aSGreg Clayton LineRange: 14 464a58c2e4aSGreg Clayton OpcodeBase: 13 465a58c2e4aSGreg Clayton StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ] 466a58c2e4aSGreg Clayton IncludeDirs: 467a58c2e4aSGreg Clayton - '/tmp' 468a58c2e4aSGreg Clayton Files: 469a58c2e4aSGreg Clayton - Name: main.cpp 470a58c2e4aSGreg Clayton DirIdx: 1 471a58c2e4aSGreg Clayton ModTime: 0 472a58c2e4aSGreg Clayton Length: 0 473a58c2e4aSGreg Clayton )"; 474a58c2e4aSGreg Clayton 475a58c2e4aSGreg Clayton // Given DWARF like this: 476a58c2e4aSGreg Clayton // 477a58c2e4aSGreg Clayton // 0x0000000b: DW_TAG_compile_unit 478a58c2e4aSGreg Clayton // 479a58c2e4aSGreg Clayton // 0x0000000c: DW_TAG_subprogram 480a58c2e4aSGreg Clayton // DW_AT_abstract_origin (0x0000000000000022) 481a58c2e4aSGreg Clayton // 482a58c2e4aSGreg Clayton // 0x00000011: NULL 483a58c2e4aSGreg Clayton // 484a58c2e4aSGreg Clayton // 0x0000001d: DW_TAG_compile_unit 485a58c2e4aSGreg Clayton // DW_AT_stmt_list (0x00000000) 486a58c2e4aSGreg Clayton // 487a58c2e4aSGreg Clayton // 0x00000022: DW_TAG_subprogram 488a58c2e4aSGreg Clayton // DW_AT_decl_file ("/tmp/main.cpp") 489a58c2e4aSGreg Clayton // 490a58c2e4aSGreg Clayton // 0x00000024: NULL 491a58c2e4aSGreg Clayton // 492a58c2e4aSGreg Clayton // This tests that when we have a DW_AT_abstract_origin with a 493a58c2e4aSGreg Clayton // DW_FORM_ref_addr to another DIE in another compile unit that we use the 494a58c2e4aSGreg Clayton // right file table when converting the file index of the DW_AT_decl_file. 495a58c2e4aSGreg Clayton // 496a58c2e4aSGreg Clayton // The DIE at 0x0000000c uses a DW_AT_abstract_origin to point to the DIE at 497a58c2e4aSGreg Clayton // 0x00000022, make sure that DWARFDie::getDeclFile() succeeds by extracting 498a58c2e4aSGreg Clayton // the right file name of "/tmp/main.cpp". The DW_AT_decl_file must grab the 499a58c2e4aSGreg Clayton // file from the line table prologue of the compile unit at offset 500a58c2e4aSGreg Clayton // 0x0000001d. 501a58c2e4aSGreg Clayton 502a58c2e4aSGreg Clayton Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections = 503a58c2e4aSGreg Clayton DWARFYAML::emitDebugSections(StringRef(yamldata), 504a58c2e4aSGreg Clayton /*IsLittleEndian=*/true, 505a58c2e4aSGreg Clayton /*Is64BitAddrSize=*/true); 506a58c2e4aSGreg Clayton ASSERT_THAT_EXPECTED(Sections, Succeeded()); 507a58c2e4aSGreg Clayton std::unique_ptr<DWARFContext> Ctx = 508a58c2e4aSGreg Clayton DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true); 509a58c2e4aSGreg Clayton DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0); 510a58c2e4aSGreg Clayton ASSERT_NE(nullptr, CU); 511a58c2e4aSGreg Clayton DWARFDie Die = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false); 512a58c2e4aSGreg Clayton ASSERT_TRUE(Die.isValid()); 513a58c2e4aSGreg Clayton 514a58c2e4aSGreg Clayton DWARFDie MainDie = Die.getFirstChild(); 515a58c2e4aSGreg Clayton ASSERT_TRUE(MainDie.isValid()); 516a58c2e4aSGreg Clayton 517a58c2e4aSGreg Clayton std::string DeclFile = MainDie.getDeclFile( 518a58c2e4aSGreg Clayton DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath); 519a58c2e4aSGreg Clayton 520f0955922SMartin Storsjö std::string Ref = 521f0955922SMartin Storsjö ("/tmp" + llvm::sys::path::get_separator() + "main.cpp").str(); 522f0955922SMartin Storsjö EXPECT_EQ(DeclFile, Ref); 523a58c2e4aSGreg Clayton } 524a58c2e4aSGreg Clayton 525a58c2e4aSGreg Clayton TEST(DWARFDie, getDeclFileSpecificationAcrossCUBoundary) { 526a58c2e4aSGreg Clayton const char *yamldata = R"( 527a58c2e4aSGreg Clayton debug_str: 528a58c2e4aSGreg Clayton - '' 529a58c2e4aSGreg Clayton debug_abbrev: 530a58c2e4aSGreg Clayton - ID: 0 531a58c2e4aSGreg Clayton Table: 532a58c2e4aSGreg Clayton - Code: 0x1 533a58c2e4aSGreg Clayton Tag: DW_TAG_compile_unit 534a58c2e4aSGreg Clayton Children: DW_CHILDREN_yes 535a58c2e4aSGreg Clayton - Code: 0x2 536a58c2e4aSGreg Clayton Tag: DW_TAG_subprogram 537a58c2e4aSGreg Clayton Children: DW_CHILDREN_no 538a58c2e4aSGreg Clayton Attributes: 539a58c2e4aSGreg Clayton - Attribute: DW_AT_specification 540a58c2e4aSGreg Clayton Form: DW_FORM_ref_addr 541a58c2e4aSGreg Clayton - Code: 0x3 542a58c2e4aSGreg Clayton Tag: DW_TAG_compile_unit 543a58c2e4aSGreg Clayton Children: DW_CHILDREN_yes 544a58c2e4aSGreg Clayton Attributes: 545a58c2e4aSGreg Clayton - Attribute: DW_AT_stmt_list 546a58c2e4aSGreg Clayton Form: DW_FORM_sec_offset 547a58c2e4aSGreg Clayton - Code: 0x4 548a58c2e4aSGreg Clayton Tag: DW_TAG_subprogram 549a58c2e4aSGreg Clayton Children: DW_CHILDREN_no 550a58c2e4aSGreg Clayton Attributes: 551a58c2e4aSGreg Clayton - Attribute: DW_AT_decl_file 552a58c2e4aSGreg Clayton Form: DW_FORM_data1 553a58c2e4aSGreg Clayton debug_info: 554a58c2e4aSGreg Clayton - Length: 0xE 555a58c2e4aSGreg Clayton Version: 4 556a58c2e4aSGreg Clayton AbbrevTableID: 0 557a58c2e4aSGreg Clayton AbbrOffset: 0x0 558a58c2e4aSGreg Clayton AddrSize: 8 559a58c2e4aSGreg Clayton Entries: 560a58c2e4aSGreg Clayton - AbbrCode: 0x1 561a58c2e4aSGreg Clayton - AbbrCode: 0x2 562a58c2e4aSGreg Clayton Values: 563a58c2e4aSGreg Clayton - Value: 0x22 564a58c2e4aSGreg Clayton - AbbrCode: 0x0 565a58c2e4aSGreg Clayton - Length: 0xF 566a58c2e4aSGreg Clayton Version: 4 567a58c2e4aSGreg Clayton AbbrevTableID: 0 568a58c2e4aSGreg Clayton AbbrOffset: 0x0 569a58c2e4aSGreg Clayton AddrSize: 8 570a58c2e4aSGreg Clayton Entries: 571a58c2e4aSGreg Clayton - AbbrCode: 0x3 572a58c2e4aSGreg Clayton Values: 573a58c2e4aSGreg Clayton - Value: 0x0 574a58c2e4aSGreg Clayton - AbbrCode: 0x4 575a58c2e4aSGreg Clayton Values: 576a58c2e4aSGreg Clayton - Value: 0x1 577a58c2e4aSGreg Clayton - AbbrCode: 0x0 578a58c2e4aSGreg Clayton debug_line: 579a58c2e4aSGreg Clayton - Length: 42 580a58c2e4aSGreg Clayton Version: 2 581a58c2e4aSGreg Clayton PrologueLength: 36 582a58c2e4aSGreg Clayton MinInstLength: 1 583a58c2e4aSGreg Clayton DefaultIsStmt: 1 584a58c2e4aSGreg Clayton LineBase: 251 585a58c2e4aSGreg Clayton LineRange: 14 586a58c2e4aSGreg Clayton OpcodeBase: 13 587a58c2e4aSGreg Clayton StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ] 588a58c2e4aSGreg Clayton IncludeDirs: 589a58c2e4aSGreg Clayton - '/tmp' 590a58c2e4aSGreg Clayton Files: 591a58c2e4aSGreg Clayton - Name: main.cpp 592a58c2e4aSGreg Clayton DirIdx: 1 593a58c2e4aSGreg Clayton ModTime: 0 594a58c2e4aSGreg Clayton Length: 0 595a58c2e4aSGreg Clayton )"; 596a58c2e4aSGreg Clayton 597a58c2e4aSGreg Clayton // Given DWARF like this: 598a58c2e4aSGreg Clayton // 599a58c2e4aSGreg Clayton // 0x0000000b: DW_TAG_compile_unit 600a58c2e4aSGreg Clayton // 601a58c2e4aSGreg Clayton // 0x0000000c: DW_TAG_subprogram 602a58c2e4aSGreg Clayton // DW_AT_specification (0x0000000000000022) 603a58c2e4aSGreg Clayton // 604a58c2e4aSGreg Clayton // 0x00000011: NULL 605a58c2e4aSGreg Clayton // 606a58c2e4aSGreg Clayton // 0x0000001d: DW_TAG_compile_unit 607a58c2e4aSGreg Clayton // DW_AT_stmt_list (0x00000000) 608a58c2e4aSGreg Clayton // 609a58c2e4aSGreg Clayton // 0x00000022: DW_TAG_subprogram 610a58c2e4aSGreg Clayton // DW_AT_decl_file ("/tmp/main.cpp") 611a58c2e4aSGreg Clayton // 612a58c2e4aSGreg Clayton // 0x00000024: NULL 613a58c2e4aSGreg Clayton // 614a58c2e4aSGreg Clayton // This tests that when we have a DW_AT_specification with a 615a58c2e4aSGreg Clayton // DW_FORM_ref_addr to another DIE in another compile unit that we use the 616a58c2e4aSGreg Clayton // right file table when converting the file index of the DW_AT_decl_file. 617a58c2e4aSGreg Clayton // 618a58c2e4aSGreg Clayton // The DIE at 0x0000000c uses a DW_AT_specification to point to the DIE at 619a58c2e4aSGreg Clayton // 0x00000022, make sure that DWARFDie::getDeclFile() succeeds by extracting 620a58c2e4aSGreg Clayton // the right file name of "/tmp/main.cpp". The DW_AT_decl_file must grab the 621a58c2e4aSGreg Clayton // file from the line table prologue of the compile unit at offset 622a58c2e4aSGreg Clayton // 0x0000001d. 623a58c2e4aSGreg Clayton 624a58c2e4aSGreg Clayton Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections = 625a58c2e4aSGreg Clayton DWARFYAML::emitDebugSections(StringRef(yamldata), 626a58c2e4aSGreg Clayton /*IsLittleEndian=*/true, 627a58c2e4aSGreg Clayton /*Is64BitAddrSize=*/true); 628a58c2e4aSGreg Clayton ASSERT_THAT_EXPECTED(Sections, Succeeded()); 629a58c2e4aSGreg Clayton std::unique_ptr<DWARFContext> Ctx = 630a58c2e4aSGreg Clayton DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true); 631a58c2e4aSGreg Clayton DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0); 632a58c2e4aSGreg Clayton ASSERT_NE(nullptr, CU); 633a58c2e4aSGreg Clayton DWARFDie Die = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false); 634a58c2e4aSGreg Clayton ASSERT_TRUE(Die.isValid()); 635a58c2e4aSGreg Clayton 636a58c2e4aSGreg Clayton DWARFDie MainDie = Die.getFirstChild(); 637a58c2e4aSGreg Clayton ASSERT_TRUE(MainDie.isValid()); 638a58c2e4aSGreg Clayton 639a58c2e4aSGreg Clayton std::string DeclFile = MainDie.getDeclFile( 640a58c2e4aSGreg Clayton DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath); 641a58c2e4aSGreg Clayton 642f0955922SMartin Storsjö std::string Ref = 643f0955922SMartin Storsjö ("/tmp" + llvm::sys::path::get_separator() + "main.cpp").str(); 644f0955922SMartin Storsjö EXPECT_EQ(DeclFile, Ref); 645a58c2e4aSGreg Clayton } 646a58c2e4aSGreg Clayton 647771b7af1SPavel Labath TEST(DWARFDie, getNameFromTypeUnit) { 648771b7af1SPavel Labath const char *yamldata = R"( 649771b7af1SPavel Labath debug_abbrev: 650771b7af1SPavel Labath - ID: 0 651771b7af1SPavel Labath Table: 652771b7af1SPavel Labath - Code: 0x1 653771b7af1SPavel Labath Tag: DW_TAG_compile_unit 654771b7af1SPavel Labath Children: DW_CHILDREN_yes 655771b7af1SPavel Labath - Code: 0x2 656771b7af1SPavel Labath Tag: DW_TAG_structure_type 657771b7af1SPavel Labath Children: DW_CHILDREN_no 658771b7af1SPavel Labath Attributes: 659771b7af1SPavel Labath - Attribute: DW_AT_signature 660771b7af1SPavel Labath Form: DW_FORM_ref_sig8 661771b7af1SPavel Labath - Code: 0x3 662771b7af1SPavel Labath Tag: DW_TAG_type_unit 663771b7af1SPavel Labath Children: DW_CHILDREN_yes 664771b7af1SPavel Labath - Code: 0x4 665771b7af1SPavel Labath Tag: DW_TAG_structure_type 666771b7af1SPavel Labath Children: DW_CHILDREN_no 667771b7af1SPavel Labath Attributes: 668771b7af1SPavel Labath - Attribute: DW_AT_name 669771b7af1SPavel Labath Form: DW_FORM_string 670771b7af1SPavel Labath debug_info: 671771b7af1SPavel Labath - Version: 5 672771b7af1SPavel Labath UnitType: DW_UT_compile 673771b7af1SPavel Labath AbbrevTableID: 0 674771b7af1SPavel Labath Entries: 675771b7af1SPavel Labath - AbbrCode: 0x1 676771b7af1SPavel Labath - AbbrCode: 0x2 677771b7af1SPavel Labath Values: 678771b7af1SPavel Labath - Value: 0xdeadbeefbaadf00d 679771b7af1SPavel Labath - AbbrCode: 0x0 680771b7af1SPavel Labath - Version: 5 681771b7af1SPavel Labath UnitType: DW_UT_type 682771b7af1SPavel Labath AbbrevTableID: 0 683771b7af1SPavel Labath TypeSignature: 0xdeadbeefbaadf00d 684771b7af1SPavel Labath TypeOffset: 25 685771b7af1SPavel Labath Entries: 686771b7af1SPavel Labath - AbbrCode: 0x3 687771b7af1SPavel Labath - AbbrCode: 0x4 688771b7af1SPavel Labath Values: 689771b7af1SPavel Labath - CStr: "STRUCT" 690771b7af1SPavel Labath - AbbrCode: 0x0 691771b7af1SPavel Labath )"; 692771b7af1SPavel Labath 693771b7af1SPavel Labath Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections = 694771b7af1SPavel Labath DWARFYAML::emitDebugSections(StringRef(yamldata), 695771b7af1SPavel Labath /*IsLittleEndian=*/true, 696771b7af1SPavel Labath /*Is64BitAddrSize=*/true); 697771b7af1SPavel Labath ASSERT_THAT_EXPECTED(Sections, Succeeded()); 698771b7af1SPavel Labath std::unique_ptr<DWARFContext> Ctx = 699771b7af1SPavel Labath DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true); 700771b7af1SPavel Labath DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0); 701771b7af1SPavel Labath ASSERT_NE(nullptr, CU); 702771b7af1SPavel Labath DWARFDie Die = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false).getFirstChild(); 703771b7af1SPavel Labath ASSERT_TRUE(Die.isValid()); 704771b7af1SPavel Labath 705771b7af1SPavel Labath ASSERT_STREQ(Die.getName(DINameKind::ShortName), "STRUCT"); 706771b7af1SPavel Labath } 707771b7af1SPavel Labath 708*9de73b20SZequan Wu void testAppendAndTerminateTemplateParameters(const DWARFDie &DIE, 709*9de73b20SZequan Wu const std::string &Expected) { 710*9de73b20SZequan Wu std::string TemplateName; 711*9de73b20SZequan Wu llvm::raw_string_ostream TemplateNameOS(TemplateName); 712*9de73b20SZequan Wu llvm::DWARFTypePrinter<DWARFDie> TemplateNamePrinter(TemplateNameOS); 713*9de73b20SZequan Wu TemplateNamePrinter.appendAndTerminateTemplateParameters(DIE); 714*9de73b20SZequan Wu EXPECT_THAT(TemplateName, Expected); 715*9de73b20SZequan Wu } 716*9de73b20SZequan Wu 717*9de73b20SZequan Wu void testAppendQualifiedName(const DWARFDie &DIE, const std::string &Expected) { 718*9de73b20SZequan Wu std::string QualifiedName; 719*9de73b20SZequan Wu llvm::raw_string_ostream TemplateNameOS(QualifiedName); 720*9de73b20SZequan Wu llvm::DWARFTypePrinter<DWARFDie> TemplateNamePrinter(TemplateNameOS); 721*9de73b20SZequan Wu TemplateNamePrinter.appendQualifiedName(DIE); 722*9de73b20SZequan Wu EXPECT_THAT(QualifiedName, Expected); 723*9de73b20SZequan Wu } 724*9de73b20SZequan Wu 725*9de73b20SZequan Wu TEST(DWARFDie, DWARFTypePrinterTest) { 726*9de73b20SZequan Wu // Make sure we can get template parameters and qualified names correctly with 727*9de73b20SZequan Wu // DWARFTypePrinter when using -gsimple-template-names. 728*9de73b20SZequan Wu 729*9de73b20SZequan Wu // 0x0000000b: DW_TAG_compile_unit 730*9de73b20SZequan Wu // 0x0000000c: DW_TAG_base_type 731*9de73b20SZequan Wu // DW_AT_name ("int") 732*9de73b20SZequan Wu // 0x00000011: DW_TAG_structure_type 733*9de73b20SZequan Wu // DW_AT_name ("t1") 734*9de73b20SZequan Wu // 0x00000015: DW_TAG_template_type_parameter 735*9de73b20SZequan Wu // DW_AT_type (0x0000001f "t3<int>") 736*9de73b20SZequan Wu // 0x0000001a: DW_TAG_structure_type 737*9de73b20SZequan Wu // DW_AT_name ("t2") 738*9de73b20SZequan Wu // 0x0000001e: NULL 739*9de73b20SZequan Wu // 0x0000001f: DW_TAG_structure_type 740*9de73b20SZequan Wu // DW_AT_name ("t3") 741*9de73b20SZequan Wu // 0x00000023: DW_TAG_template_type_parameter 742*9de73b20SZequan Wu // DW_AT_type (0x0000000c "int") 743*9de73b20SZequan Wu // 0x00000028: NULL 744*9de73b20SZequan Wu // 0x00000029: NULL 745*9de73b20SZequan Wu const char *yamldata = R"( 746*9de73b20SZequan Wu debug_abbrev: 747*9de73b20SZequan Wu - ID: 0 748*9de73b20SZequan Wu Table: 749*9de73b20SZequan Wu - Code: 0x1 750*9de73b20SZequan Wu Tag: DW_TAG_compile_unit 751*9de73b20SZequan Wu Children: DW_CHILDREN_yes 752*9de73b20SZequan Wu - Code: 0x2 753*9de73b20SZequan Wu Tag: DW_TAG_base_type 754*9de73b20SZequan Wu Children: DW_CHILDREN_no 755*9de73b20SZequan Wu Attributes: 756*9de73b20SZequan Wu - Attribute: DW_AT_name 757*9de73b20SZequan Wu Form: DW_FORM_string 758*9de73b20SZequan Wu - Code: 0x3 759*9de73b20SZequan Wu Tag: DW_TAG_structure_type 760*9de73b20SZequan Wu Children: DW_CHILDREN_yes 761*9de73b20SZequan Wu Attributes: 762*9de73b20SZequan Wu - Attribute: DW_AT_name 763*9de73b20SZequan Wu Form: DW_FORM_string 764*9de73b20SZequan Wu - Code: 0x4 765*9de73b20SZequan Wu Tag: DW_TAG_template_type_parameter 766*9de73b20SZequan Wu Children: DW_CHILDREN_no 767*9de73b20SZequan Wu Attributes: 768*9de73b20SZequan Wu - Attribute: DW_AT_type 769*9de73b20SZequan Wu Form: DW_FORM_ref4 770*9de73b20SZequan Wu - Code: 0x5 771*9de73b20SZequan Wu Tag: DW_TAG_structure_type 772*9de73b20SZequan Wu Children: DW_CHILDREN_no 773*9de73b20SZequan Wu Attributes: 774*9de73b20SZequan Wu - Attribute: DW_AT_name 775*9de73b20SZequan Wu Form: DW_FORM_string 776*9de73b20SZequan Wu - Code: 0x6 777*9de73b20SZequan Wu Tag: DW_TAG_structure_type 778*9de73b20SZequan Wu Children: DW_CHILDREN_yes 779*9de73b20SZequan Wu Attributes: 780*9de73b20SZequan Wu - Attribute: DW_AT_name 781*9de73b20SZequan Wu Form: DW_FORM_string 782*9de73b20SZequan Wu - Code: 0x7 783*9de73b20SZequan Wu Tag: DW_TAG_template_type_parameter 784*9de73b20SZequan Wu Children: DW_CHILDREN_no 785*9de73b20SZequan Wu Attributes: 786*9de73b20SZequan Wu - Attribute: DW_AT_type 787*9de73b20SZequan Wu Form: DW_FORM_ref4 788*9de73b20SZequan Wu - Code: 0x8 789*9de73b20SZequan Wu Tag: DW_TAG_typedef 790*9de73b20SZequan Wu Children: DW_CHILDREN_no 791*9de73b20SZequan Wu Attributes: 792*9de73b20SZequan Wu - Attribute: DW_AT_type 793*9de73b20SZequan Wu Form: DW_FORM_ref4 794*9de73b20SZequan Wu - Attribute: DW_AT_name 795*9de73b20SZequan Wu Form: DW_FORM_string 796*9de73b20SZequan Wu debug_info: 797*9de73b20SZequan Wu - Version: 4 798*9de73b20SZequan Wu AddrSize: 8 799*9de73b20SZequan Wu Entries: 800*9de73b20SZequan Wu - AbbrCode: 0x1 801*9de73b20SZequan Wu - AbbrCode: 0x2 802*9de73b20SZequan Wu Values: 803*9de73b20SZequan Wu - Value: 0xDEADBEEFDEADBEEF 804*9de73b20SZequan Wu CStr: int 805*9de73b20SZequan Wu - AbbrCode: 0x3 806*9de73b20SZequan Wu Values: 807*9de73b20SZequan Wu - Value: 0xDEADBEEFDEADBEEF 808*9de73b20SZequan Wu CStr: t1 809*9de73b20SZequan Wu - AbbrCode: 0x4 810*9de73b20SZequan Wu Values: 811*9de73b20SZequan Wu - Value: 0x0000001f # update 812*9de73b20SZequan Wu - AbbrCode: 0x5 813*9de73b20SZequan Wu Values: 814*9de73b20SZequan Wu - Value: 0xDEADBEEFDEADBEEF 815*9de73b20SZequan Wu CStr: t2 816*9de73b20SZequan Wu - AbbrCode: 0x0 817*9de73b20SZequan Wu - AbbrCode: 0x6 818*9de73b20SZequan Wu Values: 819*9de73b20SZequan Wu - Value: 0xDEADBEEFDEADBEEF 820*9de73b20SZequan Wu CStr: t3 821*9de73b20SZequan Wu - AbbrCode: 0x7 822*9de73b20SZequan Wu Values: 823*9de73b20SZequan Wu - Value: 0x0000000c # update 824*9de73b20SZequan Wu - AbbrCode: 0x8 825*9de73b20SZequan Wu Values: 826*9de73b20SZequan Wu - Value: 0x0000000c 827*9de73b20SZequan Wu - CStr: my_int 828*9de73b20SZequan Wu - AbbrCode: 0x0 829*9de73b20SZequan Wu - AbbrCode: 0x0)"; 830*9de73b20SZequan Wu Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections = 831*9de73b20SZequan Wu DWARFYAML::emitDebugSections(StringRef(yamldata), 832*9de73b20SZequan Wu /*IsLittleEndian=*/true, 833*9de73b20SZequan Wu /*Is64BitAddrSize=*/true); 834*9de73b20SZequan Wu ASSERT_THAT_EXPECTED(Sections, Succeeded()); 835*9de73b20SZequan Wu std::unique_ptr<DWARFContext> Ctx = 836*9de73b20SZequan Wu DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true); 837*9de73b20SZequan Wu testAppendAndTerminateTemplateParameters(Ctx->getDIEForOffset(0x11), 838*9de73b20SZequan Wu "<t3<int> >"); 839*9de73b20SZequan Wu testAppendQualifiedName(Ctx->getDIEForOffset(0x1a), "t1<t3<int> >::t2"); 840*9de73b20SZequan Wu testAppendQualifiedName(Ctx->getDIEForOffset(0x28), "t3<int>::my_int"); 841*9de73b20SZequan Wu } 842a03435ecSPavel Labath } // end anonymous namespace 843