xref: /llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDieTest.cpp (revision 9de73b20404f0b2db1cbf70d164cfe0789d5bb94)
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