843 lines · cpp
1//===- llvm/unittest/DebugInfo/DWARFDieTest.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 "llvm/BinaryFormat/Dwarf.h"10#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"11#include "llvm/DebugInfo/DWARF/DWARFContext.h"12#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"13#include "llvm/ObjectYAML/DWARFEmitter.h"14#include "llvm/Testing/Support/Error.h"15#include "gtest/gtest.h"16 17using namespace llvm;18using namespace llvm::dwarf;19 20namespace {21 22TEST(DWARFDie, getLocations) {23 const char *yamldata = R"(24 debug_abbrev:25 - Table:26 - Code: 0x0000000127 Tag: DW_TAG_compile_unit28 Children: DW_CHILDREN_no29 Attributes:30 - Attribute: DW_AT_location31 Form: DW_FORM_sec_offset32 - Attribute: DW_AT_data_member_location33 Form: DW_FORM_exprloc34 - Attribute: DW_AT_vtable_elem_location35 Form: DW_FORM_sec_offset36 - Attribute: DW_AT_call_data_location37 Form: DW_FORM_sec_offset38 debug_info:39 - Version: 540 UnitType: DW_UT_compile41 AddrSize: 442 Entries:43 - AbbrCode: 0x0000000144 Values:45 - Value: 1246 - Value: 0x000000000000000147 BlockData: [ 0x47 ]48 - Value: 2049 - Value: 2550 debug_loclists:51 - AddressSize: 452 OffsetEntryCount: 053 Lists:54 - Entries:55 - Operator: DW_LLE_start_length56 Values: [ 0x01, 0x02 ]57 - Operator: DW_LLE_end_of_list58 - Entries:59 - Operator: DW_LLE_startx_length60 Values: [ 0x01, 0x02 ]61 - Operator: DW_LLE_end_of_list62 - Entries:63 - Operator: DW_LLE_start_length64 Values: [ 0x01, 0x02 ]65 ## end_of_list intentionally missing.66 )";67 Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections =68 DWARFYAML::emitDebugSections(StringRef(yamldata),69 /*IsLittleEndian=*/true,70 /*Is64BitAddrSize=*/false);71 ASSERT_THAT_EXPECTED(Sections, Succeeded());72 std::unique_ptr<DWARFContext> Ctx =73 DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true);74 DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0);75 ASSERT_NE(nullptr, CU);76 DWARFDie Die = CU->getUnitDIE();77 ASSERT_TRUE(Die.isValid());78 79 EXPECT_THAT_EXPECTED(Die.getLocations(DW_AT_location),80 HasValue(testing::ElementsAre(DWARFLocationExpression{81 DWARFAddressRange{1, 3}, {}})));82 83 EXPECT_THAT_EXPECTED(Die.getLocations(DW_AT_data_member_location),84 HasValue(testing::ElementsAre(85 DWARFLocationExpression{std::nullopt, {0x47}})));86 87 EXPECT_THAT_EXPECTED(88 Die.getLocations(DW_AT_vtable_elem_location),89 Failed<ErrorInfoBase>(testing::Property(90 &ErrorInfoBase::message,91 "unable to resolve indirect address 1 for: DW_LLE_startx_length")));92 93 EXPECT_THAT_EXPECTED(94 Die.getLocations(DW_AT_call_data_location),95 FailedWithMessage(96 "unexpected end of data at offset 0x20 while reading [0x20, 0x21)"));97 98 EXPECT_THAT_EXPECTED(99 Die.getLocations(DW_AT_call_data_value),100 Failed<ErrorInfoBase>(testing::Property(&ErrorInfoBase::message,101 "No DW_AT_call_data_value")));102}103 104TEST(DWARFDie, getDeclFile) {105 const char *yamldata = R"(106 debug_str:107 - ''108 debug_abbrev:109 - ID: 0110 Table:111 - Code: 0x1112 Tag: DW_TAG_compile_unit113 Children: DW_CHILDREN_yes114 Attributes:115 - Attribute: DW_AT_stmt_list116 Form: DW_FORM_sec_offset117 - Code: 0x2118 Tag: DW_TAG_subprogram119 Children: DW_CHILDREN_no120 Attributes:121 - Attribute: DW_AT_decl_file122 Form: DW_FORM_data1123 debug_info:124 - Length: 0xF125 Version: 4126 AbbrevTableID: 0127 AbbrOffset: 0x0128 AddrSize: 8129 Entries:130 - AbbrCode: 0x1131 Values:132 - Value: 0x0133 - AbbrCode: 0x2134 Values:135 - Value: 0x1136 - AbbrCode: 0x0137 debug_line:138 - Length: 42139 Version: 2140 PrologueLength: 36141 MinInstLength: 1142 DefaultIsStmt: 1143 LineBase: 251144 LineRange: 14145 OpcodeBase: 13146 StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]147 IncludeDirs:148 - '/tmp'149 Files:150 - Name: main.cpp151 DirIdx: 1152 ModTime: 0153 Length: 0154 )";155 156 // Given DWARF like this:157 //158 // 0x0000000b: DW_TAG_compile_unit159 // DW_AT_stmt_list (0x00000000)160 //161 // 0x00000010: DW_TAG_subprogram162 // DW_AT_decl_file ("/tmp/main.cpp")163 //164 // 0x00000012: NULL165 //166 // This tests that we can extract the right DW_AT_decl_file from a DIE that167 // has a DW_AT_decl_file attribute.168 169 Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections =170 DWARFYAML::emitDebugSections(StringRef(yamldata),171 /*IsLittleEndian=*/true,172 /*Is64BitAddrSize=*/true);173 ASSERT_THAT_EXPECTED(Sections, Succeeded());174 std::unique_ptr<DWARFContext> Ctx =175 DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true);176 DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0);177 ASSERT_NE(nullptr, CU);178 DWARFDie Die = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false);179 ASSERT_TRUE(Die.isValid());180 181 DWARFDie MainDie = Die.getFirstChild();182 ASSERT_TRUE(MainDie.isValid());183 184 std::string DeclFile = MainDie.getDeclFile(185 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath);186 187 std::string Ref =188 ("/tmp" + llvm::sys::path::get_separator() + "main.cpp").str();189 EXPECT_EQ(DeclFile, Ref);190}191 192TEST(DWARFDie, getDeclFileAbstractOrigin) {193 const char *yamldata = R"(194 debug_str:195 - ''196 debug_abbrev:197 - ID: 0198 Table:199 - Code: 0x1200 Tag: DW_TAG_compile_unit201 Children: DW_CHILDREN_yes202 Attributes:203 - Attribute: DW_AT_stmt_list204 Form: DW_FORM_sec_offset205 - Code: 0x2206 Tag: DW_TAG_subprogram207 Children: DW_CHILDREN_no208 Attributes:209 - Attribute: DW_AT_abstract_origin210 Form: DW_FORM_ref_addr211 - Code: 0x3212 Tag: DW_TAG_subprogram213 Children: DW_CHILDREN_no214 Attributes:215 - Attribute: DW_AT_decl_file216 Form: DW_FORM_data1217 debug_info:218 - Length: 0x14219 Version: 4220 AbbrevTableID: 0221 AbbrOffset: 0x0222 AddrSize: 8223 Entries:224 - AbbrCode: 0x1225 Values:226 - Value: 0x0227 - AbbrCode: 0x2228 Values:229 - Value: 0x15230 - AbbrCode: 0x3231 Values:232 - Value: 0x1233 - AbbrCode: 0x0234 debug_line:235 - Length: 42236 Version: 2237 PrologueLength: 36238 MinInstLength: 1239 DefaultIsStmt: 1240 LineBase: 251241 LineRange: 14242 OpcodeBase: 13243 StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]244 IncludeDirs:245 - '/tmp'246 Files:247 - Name: main.cpp248 DirIdx: 1249 ModTime: 0250 Length: 0251 )";252 253 // Given DWARF like this:254 //255 // 0x0000000b: DW_TAG_compile_unit256 // DW_AT_stmt_list (0x00000000)257 //258 // 0x00000010: DW_TAG_subprogram259 // DW_AT_abstract_origin (0x0000000000000015)260 //261 // 0x00000015: DW_TAG_subprogram262 // DW_AT_decl_file ("/tmp/main.cpp")263 //264 // 0x00000017: NULL265 //266 //267 // The DIE at 0x00000010 uses a DW_AT_abstract_origin to point to the DIE at268 // 0x00000015, make sure that DWARFDie::getDeclFile() succeeds by extracting269 // the right file name of "/tmp/main.cpp".270 //271 // This tests that when we have a DW_AT_abstract_origin with a compile unit272 // relative form (DW_FORM_ref4) to another DIE that we get the right273 // DW_AT_decl_file value.274 275 Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections =276 DWARFYAML::emitDebugSections(StringRef(yamldata),277 /*IsLittleEndian=*/true,278 /*Is64BitAddrSize=*/true);279 ASSERT_THAT_EXPECTED(Sections, Succeeded());280 std::unique_ptr<DWARFContext> Ctx =281 DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true);282 DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0);283 ASSERT_NE(nullptr, CU);284 DWARFDie Die = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false);285 ASSERT_TRUE(Die.isValid());286 287 DWARFDie MainDie = Die.getFirstChild();288 ASSERT_TRUE(MainDie.isValid());289 290 std::string DeclFile = MainDie.getDeclFile(291 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath);292 293 std::string Ref =294 ("/tmp" + llvm::sys::path::get_separator() + "main.cpp").str();295 EXPECT_EQ(DeclFile, Ref);296}297 298TEST(DWARFDie, getDeclFileSpecification) {299 const char *yamldata = R"(300 debug_str:301 - ''302 debug_abbrev:303 - ID: 0304 Table:305 - Code: 0x1306 Tag: DW_TAG_compile_unit307 Children: DW_CHILDREN_yes308 Attributes:309 - Attribute: DW_AT_stmt_list310 Form: DW_FORM_sec_offset311 - Code: 0x2312 Tag: DW_TAG_subprogram313 Children: DW_CHILDREN_no314 Attributes:315 - Attribute: DW_AT_specification316 Form: DW_FORM_ref_addr317 - Code: 0x3318 Tag: DW_TAG_subprogram319 Children: DW_CHILDREN_no320 Attributes:321 - Attribute: DW_AT_decl_file322 Form: DW_FORM_data1323 debug_info:324 - Length: 0x14325 Version: 4326 AbbrevTableID: 0327 AbbrOffset: 0x0328 AddrSize: 8329 Entries:330 - AbbrCode: 0x1331 Values:332 - Value: 0x0333 - AbbrCode: 0x2334 Values:335 - Value: 0x15336 - AbbrCode: 0x3337 Values:338 - Value: 0x1339 - AbbrCode: 0x0340 debug_line:341 - Length: 42342 Version: 2343 PrologueLength: 36344 MinInstLength: 1345 DefaultIsStmt: 1346 LineBase: 251347 LineRange: 14348 OpcodeBase: 13349 StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]350 IncludeDirs:351 - '/tmp'352 Files:353 - Name: main.cpp354 DirIdx: 1355 ModTime: 0356 Length: 0357 )";358 359 // Given DWARF like this:360 //361 // 0x0000000b: DW_TAG_compile_unit362 // DW_AT_stmt_list (0x00000000)363 //364 // 0x00000010: DW_TAG_subprogram365 // DW_AT_specification (0x0000000000000015)366 //367 // 0x00000015: DW_TAG_subprogram368 // DW_AT_decl_file ("/tmp/main.cpp")369 //370 // 0x00000017: NULL371 //372 // The DIE at 0x00000010 uses a DW_AT_specification to point to the DIE at373 // 0x00000015, make sure that DWARFDie::getDeclFile() succeeds by extracting374 // the right file name of "/tmp/main.cpp".375 //376 // This tests that when we have a DW_AT_specification with a compile unit377 // relative form (DW_FORM_ref4) to another DIE that we get the right378 // DW_AT_decl_file value.379 380 Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections =381 DWARFYAML::emitDebugSections(StringRef(yamldata),382 /*IsLittleEndian=*/true,383 /*Is64BitAddrSize=*/true);384 ASSERT_THAT_EXPECTED(Sections, Succeeded());385 std::unique_ptr<DWARFContext> Ctx =386 DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true);387 DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0);388 ASSERT_NE(nullptr, CU);389 DWARFDie Die = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false);390 ASSERT_TRUE(Die.isValid());391 392 DWARFDie MainDie = Die.getFirstChild();393 ASSERT_TRUE(MainDie.isValid());394 395 std::string DeclFile = MainDie.getDeclFile(396 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath);397 398 std::string Ref =399 ("/tmp" + llvm::sys::path::get_separator() + "main.cpp").str();400 EXPECT_EQ(DeclFile, Ref);401}402 403TEST(DWARFDie, getDeclFileAbstractOriginAcrossCUBoundary) {404 const char *yamldata = R"(405 debug_str:406 - ''407 debug_abbrev:408 - ID: 0409 Table:410 - Code: 0x1411 Tag: DW_TAG_compile_unit412 Children: DW_CHILDREN_yes413 - Code: 0x2414 Tag: DW_TAG_subprogram415 Children: DW_CHILDREN_no416 Attributes:417 - Attribute: DW_AT_abstract_origin418 Form: DW_FORM_ref_addr419 - Code: 0x3420 Tag: DW_TAG_compile_unit421 Children: DW_CHILDREN_yes422 Attributes:423 - Attribute: DW_AT_stmt_list424 Form: DW_FORM_sec_offset425 - Code: 0x4426 Tag: DW_TAG_subprogram427 Children: DW_CHILDREN_no428 Attributes:429 - Attribute: DW_AT_decl_file430 Form: DW_FORM_data1431 debug_info:432 - Length: 0xE433 Version: 4434 AbbrevTableID: 0435 AbbrOffset: 0x0436 AddrSize: 8437 Entries:438 - AbbrCode: 0x1439 - AbbrCode: 0x2440 Values:441 - Value: 0x22442 - AbbrCode: 0x0443 - Length: 0xF444 Version: 4445 AbbrevTableID: 0446 AbbrOffset: 0x0447 AddrSize: 8448 Entries:449 - AbbrCode: 0x3450 Values:451 - Value: 0x0452 - AbbrCode: 0x4453 Values:454 - Value: 0x1455 - AbbrCode: 0x0456 debug_line:457 - Length: 42458 Version: 2459 PrologueLength: 36460 MinInstLength: 1461 DefaultIsStmt: 1462 LineBase: 251463 LineRange: 14464 OpcodeBase: 13465 StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]466 IncludeDirs:467 - '/tmp'468 Files:469 - Name: main.cpp470 DirIdx: 1471 ModTime: 0472 Length: 0473 )";474 475 // Given DWARF like this:476 //477 // 0x0000000b: DW_TAG_compile_unit478 //479 // 0x0000000c: DW_TAG_subprogram480 // DW_AT_abstract_origin (0x0000000000000022)481 //482 // 0x00000011: NULL483 //484 // 0x0000001d: DW_TAG_compile_unit485 // DW_AT_stmt_list (0x00000000)486 //487 // 0x00000022: DW_TAG_subprogram488 // DW_AT_decl_file ("/tmp/main.cpp")489 //490 // 0x00000024: NULL491 //492 // This tests that when we have a DW_AT_abstract_origin with a493 // DW_FORM_ref_addr to another DIE in another compile unit that we use the494 // right file table when converting the file index of the DW_AT_decl_file.495 //496 // The DIE at 0x0000000c uses a DW_AT_abstract_origin to point to the DIE at497 // 0x00000022, make sure that DWARFDie::getDeclFile() succeeds by extracting498 // the right file name of "/tmp/main.cpp". The DW_AT_decl_file must grab the499 // file from the line table prologue of the compile unit at offset500 // 0x0000001d.501 502 Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections =503 DWARFYAML::emitDebugSections(StringRef(yamldata),504 /*IsLittleEndian=*/true,505 /*Is64BitAddrSize=*/true);506 ASSERT_THAT_EXPECTED(Sections, Succeeded());507 std::unique_ptr<DWARFContext> Ctx =508 DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true);509 DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0);510 ASSERT_NE(nullptr, CU);511 DWARFDie Die = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false);512 ASSERT_TRUE(Die.isValid());513 514 DWARFDie MainDie = Die.getFirstChild();515 ASSERT_TRUE(MainDie.isValid());516 517 std::string DeclFile = MainDie.getDeclFile(518 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath);519 520 std::string Ref =521 ("/tmp" + llvm::sys::path::get_separator() + "main.cpp").str();522 EXPECT_EQ(DeclFile, Ref);523}524 525TEST(DWARFDie, getDeclFileSpecificationAcrossCUBoundary) {526 const char *yamldata = R"(527 debug_str:528 - ''529 debug_abbrev:530 - ID: 0531 Table:532 - Code: 0x1533 Tag: DW_TAG_compile_unit534 Children: DW_CHILDREN_yes535 - Code: 0x2536 Tag: DW_TAG_subprogram537 Children: DW_CHILDREN_no538 Attributes:539 - Attribute: DW_AT_specification540 Form: DW_FORM_ref_addr541 - Code: 0x3542 Tag: DW_TAG_compile_unit543 Children: DW_CHILDREN_yes544 Attributes:545 - Attribute: DW_AT_stmt_list546 Form: DW_FORM_sec_offset547 - Code: 0x4548 Tag: DW_TAG_subprogram549 Children: DW_CHILDREN_no550 Attributes:551 - Attribute: DW_AT_decl_file552 Form: DW_FORM_data1553 debug_info:554 - Length: 0xE555 Version: 4556 AbbrevTableID: 0557 AbbrOffset: 0x0558 AddrSize: 8559 Entries:560 - AbbrCode: 0x1561 - AbbrCode: 0x2562 Values:563 - Value: 0x22564 - AbbrCode: 0x0565 - Length: 0xF566 Version: 4567 AbbrevTableID: 0568 AbbrOffset: 0x0569 AddrSize: 8570 Entries:571 - AbbrCode: 0x3572 Values:573 - Value: 0x0574 - AbbrCode: 0x4575 Values:576 - Value: 0x1577 - AbbrCode: 0x0578 debug_line:579 - Length: 42580 Version: 2581 PrologueLength: 36582 MinInstLength: 1583 DefaultIsStmt: 1584 LineBase: 251585 LineRange: 14586 OpcodeBase: 13587 StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]588 IncludeDirs:589 - '/tmp'590 Files:591 - Name: main.cpp592 DirIdx: 1593 ModTime: 0594 Length: 0595 )";596 597 // Given DWARF like this:598 //599 // 0x0000000b: DW_TAG_compile_unit600 //601 // 0x0000000c: DW_TAG_subprogram602 // DW_AT_specification (0x0000000000000022)603 //604 // 0x00000011: NULL605 //606 // 0x0000001d: DW_TAG_compile_unit607 // DW_AT_stmt_list (0x00000000)608 //609 // 0x00000022: DW_TAG_subprogram610 // DW_AT_decl_file ("/tmp/main.cpp")611 //612 // 0x00000024: NULL613 //614 // This tests that when we have a DW_AT_specification with a615 // DW_FORM_ref_addr to another DIE in another compile unit that we use the616 // right file table when converting the file index of the DW_AT_decl_file.617 //618 // The DIE at 0x0000000c uses a DW_AT_specification to point to the DIE at619 // 0x00000022, make sure that DWARFDie::getDeclFile() succeeds by extracting620 // the right file name of "/tmp/main.cpp". The DW_AT_decl_file must grab the621 // file from the line table prologue of the compile unit at offset622 // 0x0000001d.623 624 Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections =625 DWARFYAML::emitDebugSections(StringRef(yamldata),626 /*IsLittleEndian=*/true,627 /*Is64BitAddrSize=*/true);628 ASSERT_THAT_EXPECTED(Sections, Succeeded());629 std::unique_ptr<DWARFContext> Ctx =630 DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true);631 DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0);632 ASSERT_NE(nullptr, CU);633 DWARFDie Die = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false);634 ASSERT_TRUE(Die.isValid());635 636 DWARFDie MainDie = Die.getFirstChild();637 ASSERT_TRUE(MainDie.isValid());638 639 std::string DeclFile = MainDie.getDeclFile(640 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath);641 642 std::string Ref =643 ("/tmp" + llvm::sys::path::get_separator() + "main.cpp").str();644 EXPECT_EQ(DeclFile, Ref);645}646 647TEST(DWARFDie, getNameFromTypeUnit) {648 const char *yamldata = R"(649 debug_abbrev:650 - ID: 0651 Table:652 - Code: 0x1653 Tag: DW_TAG_compile_unit654 Children: DW_CHILDREN_yes655 - Code: 0x2656 Tag: DW_TAG_structure_type657 Children: DW_CHILDREN_no658 Attributes:659 - Attribute: DW_AT_signature660 Form: DW_FORM_ref_sig8661 - Code: 0x3662 Tag: DW_TAG_type_unit663 Children: DW_CHILDREN_yes664 - Code: 0x4665 Tag: DW_TAG_structure_type666 Children: DW_CHILDREN_no667 Attributes:668 - Attribute: DW_AT_name669 Form: DW_FORM_string670 debug_info:671 - Version: 5672 UnitType: DW_UT_compile673 AbbrevTableID: 0674 Entries:675 - AbbrCode: 0x1676 - AbbrCode: 0x2677 Values:678 - Value: 0xdeadbeefbaadf00d679 - AbbrCode: 0x0680 - Version: 5681 UnitType: DW_UT_type682 AbbrevTableID: 0683 TypeSignature: 0xdeadbeefbaadf00d684 TypeOffset: 25685 Entries:686 - AbbrCode: 0x3687 - AbbrCode: 0x4688 Values:689 - CStr: "STRUCT"690 - AbbrCode: 0x0691 )";692 693 Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections =694 DWARFYAML::emitDebugSections(StringRef(yamldata),695 /*IsLittleEndian=*/true,696 /*Is64BitAddrSize=*/true);697 ASSERT_THAT_EXPECTED(Sections, Succeeded());698 std::unique_ptr<DWARFContext> Ctx =699 DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true);700 DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0);701 ASSERT_NE(nullptr, CU);702 DWARFDie Die = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false).getFirstChild();703 ASSERT_TRUE(Die.isValid());704 705 ASSERT_STREQ(Die.getName(DINameKind::ShortName), "STRUCT");706}707 708void testAppendAndTerminateTemplateParameters(const DWARFDie &DIE,709 const std::string &Expected) {710 std::string TemplateName;711 llvm::raw_string_ostream TemplateNameOS(TemplateName);712 llvm::DWARFTypePrinter<DWARFDie> TemplateNamePrinter(TemplateNameOS);713 TemplateNamePrinter.appendAndTerminateTemplateParameters(DIE);714 EXPECT_THAT(TemplateName, Expected);715}716 717void testAppendQualifiedName(const DWARFDie &DIE, const std::string &Expected) {718 std::string QualifiedName;719 llvm::raw_string_ostream TemplateNameOS(QualifiedName);720 llvm::DWARFTypePrinter<DWARFDie> TemplateNamePrinter(TemplateNameOS);721 TemplateNamePrinter.appendQualifiedName(DIE);722 EXPECT_THAT(QualifiedName, Expected);723}724 725TEST(DWARFDie, DWARFTypePrinterTest) {726 // Make sure we can get template parameters and qualified names correctly with727 // DWARFTypePrinter when using -gsimple-template-names.728 729 // 0x0000000b: DW_TAG_compile_unit730 // 0x0000000c: DW_TAG_base_type731 // DW_AT_name ("int")732 // 0x00000011: DW_TAG_structure_type733 // DW_AT_name ("t1")734 // 0x00000015: DW_TAG_template_type_parameter735 // DW_AT_type (0x0000001f "t3<int>")736 // 0x0000001a: DW_TAG_structure_type737 // DW_AT_name ("t2")738 // 0x0000001e: NULL739 // 0x0000001f: DW_TAG_structure_type740 // DW_AT_name ("t3")741 // 0x00000023: DW_TAG_template_type_parameter742 // DW_AT_type (0x0000000c "int")743 // 0x00000028: NULL744 // 0x00000029: NULL745 const char *yamldata = R"(746 debug_abbrev:747 - ID: 0748 Table:749 - Code: 0x1750 Tag: DW_TAG_compile_unit751 Children: DW_CHILDREN_yes752 - Code: 0x2753 Tag: DW_TAG_base_type754 Children: DW_CHILDREN_no755 Attributes:756 - Attribute: DW_AT_name757 Form: DW_FORM_string758 - Code: 0x3759 Tag: DW_TAG_structure_type760 Children: DW_CHILDREN_yes761 Attributes:762 - Attribute: DW_AT_name763 Form: DW_FORM_string764 - Code: 0x4765 Tag: DW_TAG_template_type_parameter766 Children: DW_CHILDREN_no767 Attributes:768 - Attribute: DW_AT_type769 Form: DW_FORM_ref4770 - Code: 0x5771 Tag: DW_TAG_structure_type772 Children: DW_CHILDREN_no773 Attributes:774 - Attribute: DW_AT_name775 Form: DW_FORM_string776 - Code: 0x6777 Tag: DW_TAG_structure_type778 Children: DW_CHILDREN_yes779 Attributes:780 - Attribute: DW_AT_name781 Form: DW_FORM_string782 - Code: 0x7783 Tag: DW_TAG_template_type_parameter784 Children: DW_CHILDREN_no785 Attributes:786 - Attribute: DW_AT_type787 Form: DW_FORM_ref4788 - Code: 0x8789 Tag: DW_TAG_typedef790 Children: DW_CHILDREN_no791 Attributes:792 - Attribute: DW_AT_type793 Form: DW_FORM_ref4794 - Attribute: DW_AT_name795 Form: DW_FORM_string796 debug_info:797 - Version: 4798 AddrSize: 8799 Entries:800 - AbbrCode: 0x1801 - AbbrCode: 0x2802 Values:803 - Value: 0xDEADBEEFDEADBEEF804 CStr: int805 - AbbrCode: 0x3806 Values:807 - Value: 0xDEADBEEFDEADBEEF808 CStr: t1809 - AbbrCode: 0x4810 Values:811 - Value: 0x0000001f # update812 - AbbrCode: 0x5813 Values:814 - Value: 0xDEADBEEFDEADBEEF815 CStr: t2816 - AbbrCode: 0x0817 - AbbrCode: 0x6818 Values:819 - Value: 0xDEADBEEFDEADBEEF820 CStr: t3821 - AbbrCode: 0x7822 Values:823 - Value: 0x0000000c # update824 - AbbrCode: 0x8825 Values:826 - Value: 0x0000000c827 - CStr: my_int828 - AbbrCode: 0x0829 - AbbrCode: 0x0)";830 Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections =831 DWARFYAML::emitDebugSections(StringRef(yamldata),832 /*IsLittleEndian=*/true,833 /*Is64BitAddrSize=*/true);834 ASSERT_THAT_EXPECTED(Sections, Succeeded());835 std::unique_ptr<DWARFContext> Ctx =836 DWARFContext::create(*Sections, 4, /*isLittleEndian=*/true);837 testAppendAndTerminateTemplateParameters(Ctx->getDIEForOffset(0x11),838 "<t3<int> >");839 testAppendQualifiedName(Ctx->getDIEForOffset(0x1a), "t1<t3<int> >::t2");840 testAppendQualifiedName(Ctx->getDIEForOffset(0x28), "t3<int>::my_int");841}842} // end anonymous namespace843