xref: /llvm-project/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp (revision 081723b9db84e78d7dd240b46af2aeb3b51b00be)
1 //===-- DWARFASTParserClangTests.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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
10 #include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h"
11 #include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
12 #include "TestingSupport/Symbol/ClangTestUtils.h"
13 #include "TestingSupport/Symbol/YAMLModuleTester.h"
14 #include "lldb/Core/Debugger.h"
15 #include "gmock/gmock.h"
16 #include "gtest/gtest.h"
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 using namespace lldb_private::dwarf;
21 using namespace lldb_private::plugin::dwarf;
22 
23 namespace {
24 static std::once_flag debugger_initialize_flag;
25 
26 class DWARFASTParserClangTests : public testing::Test {
27   void SetUp() override {
28     std::call_once(debugger_initialize_flag,
29                    []() { Debugger::Initialize(nullptr); });
30   }
31 };
32 
33 class DWARFASTParserClangStub : public DWARFASTParserClang {
34 public:
35   using DWARFASTParserClang::DWARFASTParserClang;
36   using DWARFASTParserClang::LinkDeclContextToDIE;
37 
38   std::vector<const clang::DeclContext *> GetDeclContextToDIEMapKeys() {
39     std::vector<const clang::DeclContext *> keys;
40     for (const auto &it : m_decl_ctx_to_die)
41       keys.push_back(it.first);
42     return keys;
43   }
44 };
45 } // namespace
46 
47 // If your implementation needs to dereference the dummy pointers we are
48 // defining here, causing this test to fail, feel free to delete it.
49 TEST_F(DWARFASTParserClangTests,
50        EnsureAllDIEsInDeclContextHaveBeenParsedParsesOnlyMatchingEntries) {
51 
52   /// Auxiliary debug info.
53   const char *yamldata = R"(
54 --- !ELF
55 FileHeader:
56   Class:   ELFCLASS64
57   Data:    ELFDATA2LSB
58   Type:    ET_EXEC
59   Machine: EM_386
60 DWARF:
61   debug_abbrev:
62     - Table:
63         - Code:            0x00000001
64           Tag:             DW_TAG_compile_unit
65           Children:        DW_CHILDREN_yes
66           Attributes:
67             - Attribute:       DW_AT_language
68               Form:            DW_FORM_data2
69         - Code:            0x00000002
70           Tag:             DW_TAG_base_type
71           Children:        DW_CHILDREN_no
72           Attributes:
73             - Attribute:       DW_AT_encoding
74               Form:            DW_FORM_data1
75             - Attribute:       DW_AT_byte_size
76               Form:            DW_FORM_data1
77   debug_info:
78     - Version:         4
79       AddrSize:        8
80       Entries:
81         - AbbrCode:        0x00000001
82           Values:
83             - Value:           0x000000000000000C
84         - AbbrCode:        0x00000002
85           Values:
86             - Value:           0x0000000000000007 # DW_ATE_unsigned
87             - Value:           0x0000000000000004
88         - AbbrCode:        0x00000002
89           Values:
90             - Value:           0x0000000000000007 # DW_ATE_unsigned
91             - Value:           0x0000000000000008
92         - AbbrCode:        0x00000002
93           Values:
94             - Value:           0x0000000000000005 # DW_ATE_signed
95             - Value:           0x0000000000000008
96         - AbbrCode:        0x00000002
97           Values:
98             - Value:           0x0000000000000008 # DW_ATE_unsigned_char
99             - Value:           0x0000000000000001
100         - AbbrCode:        0x00000000
101 )";
102 
103   YAMLModuleTester t(yamldata);
104   ASSERT_TRUE((bool)t.GetDwarfUnit());
105 
106   auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
107   auto &ast_ctx = *holder->GetAST();
108 
109   DWARFASTParserClangStub ast_parser(ast_ctx);
110 
111   DWARFUnit *unit = t.GetDwarfUnit();
112   const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE();
113   const DWARFDebugInfoEntry *die_child0 = die_first->GetFirstChild();
114   const DWARFDebugInfoEntry *die_child1 = die_child0->GetSibling();
115   const DWARFDebugInfoEntry *die_child2 = die_child1->GetSibling();
116   const DWARFDebugInfoEntry *die_child3 = die_child2->GetSibling();
117   std::vector<DWARFDIE> dies = {
118       DWARFDIE(unit, die_child0), DWARFDIE(unit, die_child1),
119       DWARFDIE(unit, die_child2), DWARFDIE(unit, die_child3)};
120   std::vector<clang::DeclContext *> decl_ctxs = {
121       (clang::DeclContext *)1LL, (clang::DeclContext *)2LL,
122       (clang::DeclContext *)2LL, (clang::DeclContext *)3LL};
123   for (int i = 0; i < 4; ++i)
124     ast_parser.LinkDeclContextToDIE(decl_ctxs[i], dies[i]);
125   ast_parser.EnsureAllDIEsInDeclContextHaveBeenParsed(
126       CompilerDeclContext(nullptr, decl_ctxs[1]));
127 
128   EXPECT_THAT(ast_parser.GetDeclContextToDIEMapKeys(),
129               testing::UnorderedElementsAre(decl_ctxs[0], decl_ctxs[3]));
130 }
131 
132 TEST_F(DWARFASTParserClangTests, TestCallingConventionParsing) {
133   // Tests parsing DW_AT_calling_convention values.
134 
135   // The DWARF below just declares a list of function types with
136   // DW_AT_calling_convention on them.
137   const char *yamldata = R"(
138 --- !ELF
139 FileHeader:
140   Class:   ELFCLASS32
141   Data:    ELFDATA2LSB
142   Type:    ET_EXEC
143   Machine: EM_386
144 DWARF:
145   debug_str:
146     - func1
147     - func2
148     - func3
149     - func4
150     - func5
151     - func6
152     - func7
153     - func8
154     - func9
155   debug_abbrev:
156     - ID:              0
157       Table:
158         - Code:            0x1
159           Tag:             DW_TAG_compile_unit
160           Children:        DW_CHILDREN_yes
161           Attributes:
162             - Attribute:       DW_AT_language
163               Form:            DW_FORM_data2
164         - Code:            0x2
165           Tag:             DW_TAG_subprogram
166           Children:        DW_CHILDREN_no
167           Attributes:
168             - Attribute:       DW_AT_low_pc
169               Form:            DW_FORM_addr
170             - Attribute:       DW_AT_high_pc
171               Form:            DW_FORM_data4
172             - Attribute:       DW_AT_name
173               Form:            DW_FORM_strp
174             - Attribute:       DW_AT_calling_convention
175               Form:            DW_FORM_data1
176             - Attribute:       DW_AT_external
177               Form:            DW_FORM_flag_present
178   debug_info:
179     - Version:         4
180       AddrSize:        4
181       Entries:
182         - AbbrCode:        0x1
183           Values:
184             - Value:           0xC
185         - AbbrCode:        0x2
186           Values:
187             - Value:           0x0
188             - Value:           0x5
189             - Value:           0x00
190             - Value:           0xCB
191             - Value:           0x1
192         - AbbrCode:        0x2
193           Values:
194             - Value:           0x10
195             - Value:           0x5
196             - Value:           0x06
197             - Value:           0xB3
198             - Value:           0x1
199         - AbbrCode:        0x2
200           Values:
201             - Value:           0x20
202             - Value:           0x5
203             - Value:           0x0C
204             - Value:           0xB1
205             - Value:           0x1
206         - AbbrCode:        0x2
207           Values:
208             - Value:           0x30
209             - Value:           0x5
210             - Value:           0x12
211             - Value:           0xC0
212             - Value:           0x1
213         - AbbrCode:        0x2
214           Values:
215             - Value:           0x40
216             - Value:           0x5
217             - Value:           0x18
218             - Value:           0xB2
219             - Value:           0x1
220         - AbbrCode:        0x2
221           Values:
222             - Value:           0x50
223             - Value:           0x5
224             - Value:           0x1E
225             - Value:           0xC1
226             - Value:           0x1
227         - AbbrCode:        0x2
228           Values:
229             - Value:           0x60
230             - Value:           0x5
231             - Value:           0x24
232             - Value:           0xC2
233             - Value:           0x1
234         - AbbrCode:        0x2
235           Values:
236             - Value:           0x70
237             - Value:           0x5
238             - Value:           0x2a
239             - Value:           0xEE
240             - Value:           0x1
241         - AbbrCode:        0x2
242           Values:
243             - Value:           0x80
244             - Value:           0x5
245             - Value:           0x30
246             - Value:           0x01
247             - Value:           0x1
248         - AbbrCode:        0x0
249 ...
250 )";
251   YAMLModuleTester t(yamldata);
252 
253   DWARFUnit *unit = t.GetDwarfUnit();
254   ASSERT_NE(unit, nullptr);
255   const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
256   ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
257   DWARFDIE cu_die(unit, cu_entry);
258 
259   auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
260   auto &ast_ctx = *holder->GetAST();
261   DWARFASTParserClangStub ast_parser(ast_ctx);
262 
263   std::vector<std::string> found_function_types;
264   // The DWARF above is just a list of functions. Parse all of them to
265   // extract the function types and their calling convention values.
266   for (DWARFDIE func : cu_die.children()) {
267     ASSERT_EQ(func.Tag(), DW_TAG_subprogram);
268     SymbolContext sc;
269     bool new_type = false;
270     lldb::TypeSP type = ast_parser.ParseTypeFromDWARF(sc, func, &new_type);
271     found_function_types.push_back(
272         type->GetForwardCompilerType().GetTypeName().AsCString());
273   }
274 
275   // Compare the parsed function types against the expected list of types.
276   const std::vector<std::string> expected_function_types = {
277       "void () __attribute__((regcall))",
278       "void () __attribute__((fastcall))",
279       "void () __attribute__((stdcall))",
280       "void () __attribute__((vectorcall))",
281       "void () __attribute__((pascal))",
282       "void () __attribute__((ms_abi))",
283       "void () __attribute__((sysv_abi))",
284       "void ()", // invalid calling convention.
285       "void ()", // DW_CC_normal -> no attribute
286   };
287   ASSERT_EQ(found_function_types, expected_function_types);
288 }
289 
290 TEST_F(DWARFASTParserClangTests, TestPtrAuthParsing) {
291   // Tests parsing values with type DW_TAG_LLVM_ptrauth_type corresponding to
292   // explicitly signed raw function pointers
293 
294   // This is Dwarf for the following C code:
295   // ```
296   // void (*__ptrauth(0, 0, 42) a)();
297   // ```
298 
299   const char *yamldata = R"(
300 --- !ELF
301 FileHeader:
302   Class:   ELFCLASS64
303   Data:    ELFDATA2LSB
304   Type:    ET_EXEC
305   Machine: EM_AARCH64
306 DWARF:
307   debug_str:
308     - a
309   debug_abbrev:
310     - ID:              0
311       Table:
312         - Code:            0x01
313           Tag:             DW_TAG_compile_unit
314           Children:        DW_CHILDREN_yes
315           Attributes:
316             - Attribute:       DW_AT_language
317               Form:            DW_FORM_data2
318         - Code:            0x02
319           Tag:             DW_TAG_variable
320           Children:        DW_CHILDREN_no
321           Attributes:
322             - Attribute:       DW_AT_name
323               Form:            DW_FORM_strp
324             - Attribute:       DW_AT_type
325               Form:            DW_FORM_ref4
326             - Attribute:       DW_AT_external
327               Form:            DW_FORM_flag_present
328         - Code:            0x03
329           Tag:             DW_TAG_LLVM_ptrauth_type
330           Children:        DW_CHILDREN_no
331           Attributes:
332             - Attribute:       DW_AT_type
333               Form:            DW_FORM_ref4
334             - Attribute:       DW_AT_LLVM_ptrauth_key
335               Form:            DW_FORM_data1
336             - Attribute:       DW_AT_LLVM_ptrauth_extra_discriminator
337               Form:            DW_FORM_data2
338         - Code:            0x04
339           Tag:             DW_TAG_pointer_type
340           Children:        DW_CHILDREN_no
341           Attributes:
342             - Attribute:       DW_AT_type
343               Form:            DW_FORM_ref4
344         - Code:            0x05
345           Tag:             DW_TAG_subroutine_type
346           Children:        DW_CHILDREN_yes
347         - Code:            0x06
348           Tag:             DW_TAG_unspecified_parameters
349           Children:        DW_CHILDREN_no
350 
351   debug_info:
352     - Version:         5
353       UnitType:        DW_UT_compile
354       AddrSize:        8
355       Entries:
356 # 0x0c: DW_TAG_compile_unit
357 #         DW_AT_language [DW_FORM_data2]    (DW_LANG_C99)
358         - AbbrCode:        0x01
359           Values:
360             - Value:           0x0c
361 
362 # 0x0f:   DW_TAG_variable
363 #           DW_AT_name [DW_FORM_strp]       (\"a\")
364 #           DW_AT_type [DW_FORM_ref4]       (0x00000018 \"void (*__ptrauth(0, 0, 0x02a)\")
365 #           DW_AT_external [DW_FORM_flag_present]   (true)
366         - AbbrCode:        0x02
367           Values:
368             - Value:           0x00
369             - Value:           0x18
370 
371 # 0x18:   DW_TAG_LLVM_ptrauth_type
372 #           DW_AT_type [DW_FORM_ref4]       (0x00000020 \"void (*)(...)\")
373 #           DW_AT_LLVM_ptrauth_key [DW_FORM_data1]  (0x00)
374 #           DW_AT_LLVM_ptrauth_extra_discriminator [DW_FORM_data2]  (0x002a)
375         - AbbrCode:        0x03
376           Values:
377             - Value:           0x20
378             - Value:           0x00
379             - Value:           0x2a
380 
381 # 0x20:   DW_TAG_pointer_type
382 #           DW_AT_type [DW_AT_type [DW_FORM_ref4]       (0x00000025 \"void (...)\")
383         - AbbrCode:        0x04
384           Values:
385             - Value:           0x25
386 
387 # 0x25:   DW_TAG_subroutine_type
388         - AbbrCode:        0x05
389 
390 # 0x26:     DW_TAG_unspecified_parameters
391         - AbbrCode:        0x06
392 
393         - AbbrCode:        0x00 # end of child tags of 0x25
394         - AbbrCode:        0x00 # end of child tags of 0x0c
395 ...
396 )";
397   YAMLModuleTester t(yamldata);
398 
399   DWARFUnit *unit = t.GetDwarfUnit();
400   ASSERT_NE(unit, nullptr);
401   const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
402   ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
403   DWARFDIE cu_die(unit, cu_entry);
404 
405   auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
406   auto &ast_ctx = *holder->GetAST();
407   DWARFASTParserClangStub ast_parser(ast_ctx);
408 
409   DWARFDIE ptrauth_variable = cu_die.GetFirstChild();
410   ASSERT_EQ(ptrauth_variable.Tag(), DW_TAG_variable);
411   DWARFDIE ptrauth_type =
412       ptrauth_variable.GetAttributeValueAsReferenceDIE(DW_AT_type);
413   ASSERT_EQ(ptrauth_type.Tag(), DW_TAG_LLVM_ptrauth_type);
414 
415   SymbolContext sc;
416   bool new_type = false;
417   lldb::TypeSP type_sp =
418       ast_parser.ParseTypeFromDWARF(sc, ptrauth_type, &new_type);
419   CompilerType compiler_type = type_sp->GetForwardCompilerType();
420   ASSERT_EQ(compiler_type.GetPtrAuthKey(), 0U);
421   ASSERT_EQ(compiler_type.GetPtrAuthAddressDiversity(), false);
422   ASSERT_EQ(compiler_type.GetPtrAuthDiscriminator(), 42U);
423 }
424 
425 struct ExtractIntFromFormValueTest : public testing::Test {
426   SubsystemRAII<FileSystem, HostInfo> subsystems;
427   clang_utils::TypeSystemClangHolder holder;
428   TypeSystemClang &ts;
429 
430   DWARFASTParserClang parser;
431   ExtractIntFromFormValueTest()
432       : holder("dummy ASTContext"), ts(*holder.GetAST()), parser(ts) {}
433 
434   /// Takes the given integer value, stores it in a DWARFFormValue and then
435   /// tries to extract the value back via
436   /// DWARFASTParserClang::ExtractIntFromFormValue.
437   /// Returns the string representation of the extracted value or the error
438   /// that was returned from ExtractIntFromFormValue.
439   llvm::Expected<std::string> Extract(clang::QualType qt, uint64_t value) {
440     DWARFFormValue form_value;
441     form_value.SetUnsigned(value);
442     llvm::Expected<llvm::APInt> result =
443         parser.ExtractIntFromFormValue(ts.GetType(qt), form_value);
444     if (!result)
445       return result.takeError();
446     llvm::SmallString<16> result_str;
447     result->toStringUnsigned(result_str);
448     return std::string(result_str.str());
449   }
450 
451   /// Same as ExtractIntFromFormValueTest::Extract but takes a signed integer
452   /// and treats the result as a signed integer.
453   llvm::Expected<std::string> ExtractS(clang::QualType qt, int64_t value) {
454     DWARFFormValue form_value;
455     form_value.SetSigned(value);
456     llvm::Expected<llvm::APInt> result =
457         parser.ExtractIntFromFormValue(ts.GetType(qt), form_value);
458     if (!result)
459       return result.takeError();
460     llvm::SmallString<16> result_str;
461     result->toStringSigned(result_str);
462     return std::string(result_str.str());
463   }
464 };
465 
466 TEST_F(ExtractIntFromFormValueTest, TestBool) {
467   using namespace llvm;
468   clang::ASTContext &ast = ts.getASTContext();
469 
470   EXPECT_THAT_EXPECTED(Extract(ast.BoolTy, 0), HasValue("0"));
471   EXPECT_THAT_EXPECTED(Extract(ast.BoolTy, 1), HasValue("1"));
472   EXPECT_THAT_EXPECTED(Extract(ast.BoolTy, 2), Failed());
473   EXPECT_THAT_EXPECTED(Extract(ast.BoolTy, 3), Failed());
474 }
475 
476 TEST_F(ExtractIntFromFormValueTest, TestInt) {
477   using namespace llvm;
478 
479   clang::ASTContext &ast = ts.getASTContext();
480 
481   // Find the min/max values for 'int' on the current host target.
482   constexpr int64_t int_max = std::numeric_limits<int>::max();
483   constexpr int64_t int_min = std::numeric_limits<int>::min();
484 
485   // Check that the bit width of int matches the int width in our type system.
486   ASSERT_EQ(sizeof(int) * 8, ast.getIntWidth(ast.IntTy));
487 
488   // Check values around int_min.
489   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_min - 2), llvm::Failed());
490   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_min - 1), llvm::Failed());
491   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_min),
492                        HasValue(std::to_string(int_min)));
493   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_min + 1),
494                        HasValue(std::to_string(int_min + 1)));
495   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_min + 2),
496                        HasValue(std::to_string(int_min + 2)));
497 
498   // Check values around 0.
499   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, -128), HasValue("-128"));
500   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, -10), HasValue("-10"));
501   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, -1), HasValue("-1"));
502   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, 0), HasValue("0"));
503   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, 1), HasValue("1"));
504   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, 10), HasValue("10"));
505   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, 128), HasValue("128"));
506 
507   // Check values around int_max.
508   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_max - 2),
509                        HasValue(std::to_string(int_max - 2)));
510   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_max - 1),
511                        HasValue(std::to_string(int_max - 1)));
512   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_max),
513                        HasValue(std::to_string(int_max)));
514   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_max + 1), llvm::Failed());
515   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_max + 5), llvm::Failed());
516 
517   // Check some values not near an edge case.
518   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_max / 2),
519                        HasValue(std::to_string(int_max / 2)));
520   EXPECT_THAT_EXPECTED(ExtractS(ast.IntTy, int_min / 2),
521                        HasValue(std::to_string(int_min / 2)));
522 }
523 
524 TEST_F(ExtractIntFromFormValueTest, TestUnsignedInt) {
525   using namespace llvm;
526 
527   clang::ASTContext &ast = ts.getASTContext();
528   constexpr uint64_t uint_max = std::numeric_limits<uint32_t>::max();
529 
530   // Check values around 0.
531   EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, 0), HasValue("0"));
532   EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, 1), HasValue("1"));
533   EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, 1234), HasValue("1234"));
534 
535   // Check some values not near an edge case.
536   EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, uint_max / 2),
537                        HasValue(std::to_string(uint_max / 2)));
538 
539   // Check values around uint_max.
540   EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, uint_max - 2),
541                        HasValue(std::to_string(uint_max - 2)));
542   EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, uint_max - 1),
543                        HasValue(std::to_string(uint_max - 1)));
544   EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, uint_max),
545                        HasValue(std::to_string(uint_max)));
546   EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, uint_max + 1),
547                        llvm::Failed());
548   EXPECT_THAT_EXPECTED(Extract(ast.UnsignedIntTy, uint_max + 2),
549                        llvm::Failed());
550 }
551 
552 TEST_F(DWARFASTParserClangTests, TestDefaultTemplateParamParsing) {
553   // Tests parsing DW_AT_default_value for template parameters.
554   auto BufferOrError = llvm::MemoryBuffer::getFile(
555       GetInputFilePath("DW_AT_default_value-test.yaml"), /*IsText=*/true);
556   ASSERT_TRUE(BufferOrError);
557   YAMLModuleTester t(BufferOrError.get()->getBuffer());
558 
559   DWARFUnit *unit = t.GetDwarfUnit();
560   ASSERT_NE(unit, nullptr);
561   const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
562   ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
563   DWARFDIE cu_die(unit, cu_entry);
564 
565   auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
566   auto &ast_ctx = *holder->GetAST();
567   DWARFASTParserClangStub ast_parser(ast_ctx);
568 
569   llvm::SmallVector<lldb::TypeSP, 2> types;
570   for (DWARFDIE die : cu_die.children()) {
571     if (die.Tag() == DW_TAG_class_type) {
572       SymbolContext sc;
573       bool new_type = false;
574       types.push_back(ast_parser.ParseTypeFromDWARF(sc, die, &new_type));
575     }
576   }
577 
578   ASSERT_EQ(types.size(), 3U);
579 
580   auto check_decl = [](auto const *decl) {
581     clang::ClassTemplateSpecializationDecl const *ctsd =
582         llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>(decl);
583     ASSERT_NE(ctsd, nullptr);
584 
585     auto const &args = ctsd->getTemplateArgs();
586     ASSERT_GT(args.size(), 0U);
587 
588     for (auto const &arg : args.asArray()) {
589       EXPECT_TRUE(arg.getIsDefaulted());
590     }
591   };
592 
593   for (auto const &type_sp : types) {
594     ASSERT_NE(type_sp, nullptr);
595     auto const *decl = ClangUtil::GetAsTagDecl(type_sp->GetFullCompilerType());
596     if (decl->getName() == "bar" || decl->getName() == "baz") {
597       check_decl(decl);
598     }
599   }
600 }
601 
602 TEST_F(DWARFASTParserClangTests, TestUniqueDWARFASTTypeMap_CppInsertMapFind) {
603   // This tests the behaviour of UniqueDWARFASTTypeMap under
604   // following scenario:
605   // 1. DWARFASTParserClang parses a forward declaration and
606   // inserts it into the UniqueDWARFASTTypeMap.
607   // 2. We then MapDeclDIEToDefDIE which updates the map
608   // entry with the line number/file information of the definition.
609   // 3. Parse the definition DIE, which should return the previously
610   // parsed type from the UniqueDWARFASTTypeMap.
611 
612   const char *yamldata = R"(
613 --- !ELF
614 FileHeader:
615   Class:   ELFCLASS64
616   Data:    ELFDATA2LSB
617   Type:    ET_EXEC
618   Machine: EM_AARCH64
619 DWARF:
620   debug_str:
621     - Foo
622 
623   debug_line:
624     - Version:         4
625       MinInstLength:   1
626       MaxOpsPerInst:   1
627       DefaultIsStmt:   1
628       LineBase:        0
629       LineRange:       0
630       Files:
631         - Name:            main.cpp
632           DirIdx:          0
633           ModTime:         0
634           Length:          0
635 
636   debug_abbrev:
637     - ID:              0
638       Table:
639         - Code:            0x01
640           Tag:             DW_TAG_compile_unit
641           Children:        DW_CHILDREN_yes
642           Attributes:
643             - Attribute:       DW_AT_language
644               Form:            DW_FORM_data2
645             - Attribute:       DW_AT_stmt_list
646               Form:            DW_FORM_sec_offset
647         - Code:            0x02
648           Tag:             DW_TAG_structure_type
649           Children:        DW_CHILDREN_no
650           Attributes:
651             - Attribute:       DW_AT_name
652               Form:            DW_FORM_strp
653             - Attribute:       DW_AT_declaration
654               Form:            DW_FORM_flag_present
655         - Code:            0x03
656           Tag:             DW_TAG_structure_type
657           Children:        DW_CHILDREN_no
658           Attributes:
659             - Attribute:       DW_AT_name
660               Form:            DW_FORM_strp
661             - Attribute:       DW_AT_decl_file
662               Form:            DW_FORM_data1
663             - Attribute:       DW_AT_decl_line
664               Form:            DW_FORM_data1
665 
666   debug_info:
667     - Version:         5
668       UnitType:        DW_UT_compile
669       AddrSize:        8
670       Entries:
671 # 0x0c: DW_TAG_compile_unit
672 #         DW_AT_language [DW_FORM_data2]    (DW_LANG_C_plus_plus)
673 #         DW_AT_stmt_list [DW_FORM_sec_offset]
674         - AbbrCode:        0x01
675           Values:
676             - Value:           0x04
677             - Value:           0x0000000000000000
678 
679 # 0x0d:   DW_TAG_structure_type
680 #           DW_AT_name [DW_FORM_strp]       (\"Foo\")
681 #           DW_AT_declaration [DW_FORM_flag_present] (true)
682         - AbbrCode:        0x02
683           Values:
684             - Value:           0x00
685 
686 # 0x0f:   DW_TAG_structure_type
687 #           DW_AT_name [DW_FORM_strp]       (\"Foo\")
688 #           DW_AT_decl_file [DW_FORM_data1] (main.cpp)
689 #           DW_AT_decl_line [DW_FORM_data1] (3)
690         - AbbrCode:        0x03
691           Values:
692             - Value:           0x00
693             - Value:           0x01
694             - Value:           0x03
695 
696         - AbbrCode:        0x00 # end of child tags of 0x0c
697 ...
698 )";
699   YAMLModuleTester t(yamldata);
700 
701   DWARFUnit *unit = t.GetDwarfUnit();
702   ASSERT_NE(unit, nullptr);
703   const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
704   ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
705   ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
706   DWARFDIE cu_die(unit, cu_entry);
707 
708   auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
709   auto &ast_ctx = *holder->GetAST();
710   DWARFASTParserClangStub ast_parser(ast_ctx);
711 
712   DWARFDIE decl_die;
713   DWARFDIE def_die;
714   for (auto const &die : cu_die.children()) {
715     if (die.Tag() != DW_TAG_structure_type)
716       continue;
717 
718     if (die.GetAttributeValueAsOptionalUnsigned(llvm::dwarf::DW_AT_declaration))
719       decl_die = die;
720     else
721       def_die = die;
722   }
723 
724   ASSERT_TRUE(decl_die.IsValid());
725   ASSERT_TRUE(def_die.IsValid());
726   ASSERT_NE(decl_die, def_die);
727 
728   ParsedDWARFTypeAttributes attrs(def_die);
729   ASSERT_TRUE(attrs.decl.IsValid());
730 
731   SymbolContext sc;
732   bool new_type = false;
733   lldb::TypeSP type_sp = ast_parser.ParseTypeFromDWARF(sc, decl_die, &new_type);
734   ASSERT_NE(type_sp, nullptr);
735 
736   ast_parser.MapDeclDIEToDefDIE(decl_die, def_die);
737 
738   lldb::TypeSP reparsed_type_sp =
739       ast_parser.ParseTypeFromDWARF(sc, def_die, &new_type);
740   ASSERT_NE(reparsed_type_sp, nullptr);
741 
742   ASSERT_EQ(type_sp, reparsed_type_sp);
743 }
744 
745 TEST_F(DWARFASTParserClangTests, TestParseDWARFAttributes_ObjectPointer) {
746   // This tests the behaviour of ParsedDWARFTypeAttributes
747   // for DW_TAG_subprogram definitions which have a DW_AT_object_pointer
748   // *and* a DW_AT_specification that also has a DW_AT_object_pointer.
749   // We don't want the declaration DW_AT_object_pointer to overwrite the
750   // one from the more specific definition's.
751 
752   const char *yamldata = R"(
753 --- !ELF
754 FileHeader:
755   Class:   ELFCLASS64
756   Data:    ELFDATA2LSB
757   Type:    ET_EXEC
758   Machine: EM_AARCH64
759 DWARF:
760   debug_str:
761     - Context
762     - func
763     - this
764   debug_abbrev:
765     - ID:              0
766       Table:
767         - Code:            0x1
768           Tag:             DW_TAG_compile_unit
769           Children:        DW_CHILDREN_yes
770           Attributes:
771             - Attribute:       DW_AT_language
772               Form:            DW_FORM_data2
773         - Code:            0x2
774           Tag:             DW_TAG_structure_type
775           Children:        DW_CHILDREN_yes
776           Attributes:
777             - Attribute:       DW_AT_name
778               Form:            DW_FORM_strp
779         - Code:            0x3
780           Tag:             DW_TAG_subprogram
781           Children:        DW_CHILDREN_yes
782           Attributes:
783             - Attribute:       DW_AT_name
784               Form:            DW_FORM_strp
785             - Attribute:       DW_AT_declaration
786               Form:            DW_FORM_flag_present
787             - Attribute:       DW_AT_object_pointer
788               Form:            DW_FORM_ref4
789             - Attribute:       DW_AT_artificial
790               Form:            DW_FORM_flag_present
791             - Attribute:       DW_AT_external
792               Form:            DW_FORM_flag_present
793         - Code:            0x4
794           Tag:             DW_TAG_formal_parameter
795           Children:        DW_CHILDREN_no
796           Attributes:
797             - Attribute:       DW_AT_artificial
798               Form:            DW_FORM_flag_present
799         - Code:            0x5
800           Tag:             DW_TAG_subprogram
801           Children:        DW_CHILDREN_yes
802           Attributes:
803             - Attribute:       DW_AT_object_pointer
804               Form:            DW_FORM_ref4
805             - Attribute:       DW_AT_specification
806               Form:            DW_FORM_ref4
807         - Code:            0x6
808           Tag:             DW_TAG_formal_parameter
809           Children:        DW_CHILDREN_no
810           Attributes:
811             - Attribute:       DW_AT_name
812               Form:            DW_FORM_strp
813             - Attribute:       DW_AT_artificial
814               Form:            DW_FORM_flag_present
815   debug_info:
816      - Version:         5
817        UnitType:        DW_UT_compile
818        AddrSize:        8
819        Entries:
820 
821 # DW_TAG_compile_unit
822 #   DW_AT_language [DW_FORM_data2]    (DW_LANG_C_plus_plus)
823 
824         - AbbrCode:        0x1
825           Values:
826             - Value:           0x04
827 
828 #   DW_TAG_structure_type
829 #     DW_AT_name [DW_FORM_strp] ("Context")
830 
831         - AbbrCode:        0x2
832           Values:
833             - Value:           0x0
834 
835 #     DW_TAG_subprogram
836 #       DW_AT_name [DW_FORM_strp] ("func")
837 #       DW_AT_object_pointer [DW_FORM_ref4]
838         - AbbrCode:        0x3
839           Values:
840             - Value:           0x8
841             - Value:           0x1
842             - Value:           0x1d
843             - Value:           0x1
844             - Value:           0x1
845 
846 #       DW_TAG_formal_parameter
847 #         DW_AT_artificial
848         - AbbrCode:        0x4
849           Values:
850           - Value: 0x1
851 
852         - AbbrCode: 0x0
853         - AbbrCode: 0x0
854 
855 #     DW_TAG_subprogram
856 #       DW_AT_object_pointer [DW_FORM_ref4] ("this")
857 #       DW_AT_specification [DW_FORM_ref4] ("func")
858         - AbbrCode:        0x5
859           Values:
860             - Value:           0x29
861             - Value:           0x14
862 
863 #       DW_TAG_formal_parameter
864 #         DW_AT_name [DW_FORM_strp] ("this")
865 #         DW_AT_artificial
866         - AbbrCode:        0x6
867           Values:
868             - Value:           0xd
869             - Value:           0x1
870 
871         - AbbrCode: 0x0
872         - AbbrCode: 0x0
873 ...
874 )";
875   YAMLModuleTester t(yamldata);
876 
877   DWARFUnit *unit = t.GetDwarfUnit();
878   ASSERT_NE(unit, nullptr);
879   const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
880   ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
881   ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
882   DWARFDIE cu_die(unit, cu_entry);
883 
884   auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
885   auto &ast_ctx = *holder->GetAST();
886   DWARFASTParserClangStub ast_parser(ast_ctx);
887 
888   auto context_die = cu_die.GetFirstChild();
889   ASSERT_TRUE(context_die.IsValid());
890   ASSERT_EQ(context_die.Tag(), DW_TAG_structure_type);
891 
892   auto subprogram_definition = context_die.GetSibling();
893   ASSERT_TRUE(subprogram_definition.IsValid());
894   ASSERT_EQ(subprogram_definition.Tag(), DW_TAG_subprogram);
895   ASSERT_FALSE(subprogram_definition.GetAttributeValueAsOptionalUnsigned(
896       DW_AT_external));
897 
898   auto param_die = subprogram_definition.GetFirstChild();
899   ASSERT_TRUE(param_die.IsValid());
900 
901   ParsedDWARFTypeAttributes attrs(subprogram_definition);
902   EXPECT_TRUE(attrs.object_pointer.IsValid());
903   EXPECT_EQ(attrs.object_pointer, param_die);
904 }
905 
906 TEST_F(DWARFASTParserClangTests, TestParseSubroutine_ExplicitObjectParameter) {
907   // Tests parsing of a C++ non-static member function with an explicit object
908   // parameter that isn't called "this" and is not a pointer (but a CV-qualified
909   // rvalue reference instead).
910 
911   const char *yamldata = R"(
912 --- !ELF
913 FileHeader:
914   Class:   ELFCLASS64
915   Data:    ELFDATA2LSB
916   Type:    ET_EXEC
917   Machine: EM_AARCH64
918 DWARF:
919   debug_str:
920     - Context
921     - func
922     - mySelf
923   debug_abbrev:
924     - ID:              0
925       Table:
926         - Code:            0x1
927           Tag:             DW_TAG_compile_unit
928           Children:        DW_CHILDREN_yes
929           Attributes:
930             - Attribute:       DW_AT_language
931               Form:            DW_FORM_data2
932         - Code:            0x2
933           Tag:             DW_TAG_structure_type
934           Children:        DW_CHILDREN_yes
935           Attributes:
936             - Attribute:       DW_AT_name
937               Form:            DW_FORM_strp
938         - Code:            0x3
939           Tag:             DW_TAG_subprogram
940           Children:        DW_CHILDREN_yes
941           Attributes:
942             - Attribute:       DW_AT_name
943               Form:            DW_FORM_strp
944             - Attribute:       DW_AT_declaration
945               Form:            DW_FORM_flag_present
946             - Attribute:       DW_AT_object_pointer
947               Form:            DW_FORM_ref4
948             - Attribute:       DW_AT_external
949               Form:            DW_FORM_flag_present
950         - Code:            0x4
951           Tag:             DW_TAG_formal_parameter
952           Children:        DW_CHILDREN_no
953           Attributes:
954             - Attribute:       DW_AT_name
955               Form:            DW_FORM_strp
956             - Attribute:       DW_AT_type
957               Form:            DW_FORM_ref4
958         - Code:            0x5
959           Tag:             DW_TAG_rvalue_reference_type
960           Children:        DW_CHILDREN_no
961           Attributes:
962             - Attribute:       DW_AT_type
963               Form:            DW_FORM_ref4
964         - Code:            0x6
965           Tag:             DW_TAG_const_type
966           Children:        DW_CHILDREN_no
967           Attributes:
968             - Attribute:       DW_AT_type
969               Form:            DW_FORM_ref4
970         - Code:            0x7
971           Tag:             DW_TAG_volatile_type
972           Children:        DW_CHILDREN_no
973           Attributes:
974             - Attribute:       DW_AT_type
975               Form:            DW_FORM_ref4
976   debug_info:
977      - Version:         5
978        UnitType:        DW_UT_compile
979        AddrSize:        8
980        Entries:
981 
982 # DW_TAG_compile_unit
983 #   DW_AT_language [DW_FORM_data2]    (DW_LANG_C_plus_plus)
984 
985         - AbbrCode:        0x1
986           Values:
987             - Value:           0x04
988 
989 #   DW_TAG_structure_type
990 #     DW_AT_name [DW_FORM_strp] ("Context")
991 
992         - AbbrCode:        0x2
993           Values:
994             - Value:           0x0
995 
996 #     DW_TAG_subprogram
997 #       DW_AT_name [DW_FORM_strp] ("func")
998 #       DW_AT_object_pointer [DW_FORM_ref4]
999         - AbbrCode:        0x3
1000           Values:
1001             - Value:           0x8
1002             - Value:           0x1
1003             - Value:           0x1d
1004             - Value:           0x1
1005 
1006 #       DW_TAG_formal_parameter
1007 #         DW_AT_name [DW_FORM_strp] ("mySelf")
1008 #         DW_AT_type [DW_FORM_ref4] (const volatile Context &&)
1009         - AbbrCode:        0x4
1010           Values:
1011             - Value: 0xd
1012             - Value: 0x28
1013 
1014         - AbbrCode: 0x0
1015         - AbbrCode: 0x0
1016 
1017 #   DW_TAG_rvalue_reference_type
1018 #     DW_AT_type [DW_FORM_ref4] ("const volatile Context")
1019 
1020         - AbbrCode:        0x5
1021           Values:
1022             - Value:           0x2d
1023 
1024 #   DW_TAG_const_type
1025 #     DW_AT_type [DW_FORM_ref4] ("volatile Context")
1026 
1027         - AbbrCode:        0x6
1028           Values:
1029             - Value:           0x32
1030 
1031 #   DW_TAG_volatile_type
1032 #     DW_AT_type [DW_FORM_ref4] ("Context")
1033 
1034         - AbbrCode:        0x7
1035           Values:
1036             - Value:           0xf
1037 
1038         - AbbrCode: 0x0
1039 ...
1040 )";
1041   YAMLModuleTester t(yamldata);
1042 
1043   DWARFUnit *unit = t.GetDwarfUnit();
1044   ASSERT_NE(unit, nullptr);
1045   const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
1046   ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
1047   ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
1048   DWARFDIE cu_die(unit, cu_entry);
1049 
1050   auto ts_or_err =
1051       cu_die.GetDWARF()->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
1052   ASSERT_TRUE(static_cast<bool>(ts_or_err));
1053   llvm::consumeError(ts_or_err.takeError());
1054   auto *parser =
1055       static_cast<DWARFASTParserClang *>((*ts_or_err)->GetDWARFParser());
1056 
1057   auto context_die = cu_die.GetFirstChild();
1058   ASSERT_TRUE(context_die.IsValid());
1059   ASSERT_EQ(context_die.Tag(), DW_TAG_structure_type);
1060 
1061   SymbolContext sc;
1062   bool new_type;
1063   auto context_type_sp = parser->ParseTypeFromDWARF(sc, context_die, &new_type);
1064   ASSERT_NE(context_type_sp, nullptr);
1065 
1066   ASSERT_TRUE(
1067       parser->CompleteTypeFromDWARF(context_die, context_type_sp.get(),
1068                                     context_type_sp->GetForwardCompilerType()));
1069 
1070   auto *record_decl = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(
1071       ClangUtil::GetAsTagDecl(context_type_sp->GetForwardCompilerType()));
1072   ASSERT_NE(record_decl, nullptr);
1073 
1074   auto method_it = record_decl->method_begin();
1075   ASSERT_NE(method_it, record_decl->method_end());
1076 
1077   // Check that we didn't parse the function as static.
1078   EXPECT_FALSE(method_it->isStatic());
1079 
1080   // Check that method qualifiers were correctly set.
1081   EXPECT_EQ(method_it->getMethodQualifiers(),
1082             clang::Qualifiers::fromCVRMask(clang::Qualifiers::Const |
1083                                            clang::Qualifiers::Volatile));
1084 }
1085 
1086 TEST_F(DWARFASTParserClangTests, TestParseSubroutine_ParameterCreation) {
1087   // Tests parsing of a C++ free function will create clang::ParmVarDecls with
1088   // the correct clang::DeclContext.
1089   //
1090   // Also ensures we attach names to the ParmVarDecls (even when DWARF contains
1091   // a mix of named/unnamed parameters).
1092 
1093   const char *yamldata = R"(
1094 --- !ELF
1095 FileHeader:
1096   Class:   ELFCLASS64
1097   Data:    ELFDATA2LSB
1098   Type:    ET_EXEC
1099   Machine: EM_AARCH64
1100 DWARF:
1101   debug_str:
1102     - func
1103     - int
1104     - short
1105     - namedParam
1106   debug_abbrev:
1107     - ID:              0
1108       Table:
1109         - Code:            0x1
1110           Tag:             DW_TAG_compile_unit
1111           Children:        DW_CHILDREN_yes
1112           Attributes:
1113             - Attribute:       DW_AT_language
1114               Form:            DW_FORM_data2
1115         - Code:            0x2
1116           Tag:             DW_TAG_structure_type
1117           Children:        DW_CHILDREN_yes
1118           Attributes:
1119             - Attribute:       DW_AT_name
1120               Form:            DW_FORM_strp
1121         - Code:            0x3
1122           Tag:             DW_TAG_subprogram
1123           Children:        DW_CHILDREN_yes
1124           Attributes:
1125             - Attribute:       DW_AT_name
1126               Form:            DW_FORM_strp
1127             - Attribute:       DW_AT_declaration
1128               Form:            DW_FORM_flag_present
1129             - Attribute:       DW_AT_external
1130               Form:            DW_FORM_flag_present
1131         - Code:            0x4
1132           Tag:             DW_TAG_formal_parameter
1133           Children:        DW_CHILDREN_no
1134           Attributes:
1135             - Attribute:       DW_AT_type
1136               Form:            DW_FORM_ref4
1137         - Code:            0x5
1138           Tag:             DW_TAG_formal_parameter
1139           Children:        DW_CHILDREN_no
1140           Attributes:
1141             - Attribute:       DW_AT_type
1142               Form:            DW_FORM_ref4
1143             - Attribute:       DW_AT_name
1144               Form:            DW_FORM_strp
1145         - Code:            0x6
1146           Tag:             DW_TAG_base_type
1147           Children:        DW_CHILDREN_no
1148           Attributes:
1149             - Attribute:       DW_AT_name
1150               Form:            DW_FORM_strp
1151             - Attribute:       DW_AT_encoding
1152               Form:            DW_FORM_data1
1153             - Attribute:       DW_AT_byte_size
1154               Form:            DW_FORM_data1
1155   debug_info:
1156      - Version:         5
1157        UnitType:        DW_UT_compile
1158        AddrSize:        8
1159        Entries:
1160 
1161 # DW_TAG_compile_unit
1162 #   DW_AT_language [DW_FORM_data2]    (DW_LANG_C_plus_plus)
1163 
1164         - AbbrCode:        0x1
1165           Values:
1166             - Value:           0x04
1167 
1168 #     DW_TAG_subprogram
1169 #       DW_AT_name [DW_FORM_strp] ("func")
1170         - AbbrCode:        0x3
1171           Values:
1172             - Value:           0x0
1173             - Value:           0x1
1174             - Value:           0x1
1175 
1176 #       DW_TAG_formal_parameter
1177 #         DW_AT_type [DW_FORM_ref4] (int)
1178         - AbbrCode:        0x4
1179           Values:
1180             - Value: 0x23
1181 
1182 #       DW_TAG_formal_parameter
1183 #         DW_AT_type [DW_FORM_ref4] (short)
1184 #         DW_AT_name [DW_FORM_strp] ("namedParam")
1185         - AbbrCode:        0x5
1186           Values:
1187             - Value: 0x2a
1188             - Value: 0xf
1189 
1190         - AbbrCode: 0x0
1191 
1192 #   DW_TAG_base_type
1193 #     DW_AT_name      [DW_FORM_strp] ("int")
1194 #     DW_AT_encoding  [DW_FORM_data1]
1195 #     DW_AT_byte_size [DW_FORM_data1]
1196 
1197         - AbbrCode:        0x6
1198           Values:
1199             - Value:           0x0000000000000005
1200             - Value:           0x0000000000000005 # DW_ATE_signed
1201             - Value:           0x0000000000000004
1202 
1203 #   DW_TAG_base_type
1204 #     DW_AT_name      [DW_FORM_strp] ("short")
1205 #     DW_AT_encoding  [DW_FORM_data1]
1206 #     DW_AT_byte_size [DW_FORM_data1]
1207 
1208         - AbbrCode:        0x6
1209           Values:
1210             - Value:           0x0000000000000009
1211             - Value:           0x0000000000000005 # DW_ATE_signed
1212             - Value:           0x0000000000000004
1213 
1214         - AbbrCode: 0x0
1215 ...
1216 )";
1217   YAMLModuleTester t(yamldata);
1218 
1219   DWARFUnit *unit = t.GetDwarfUnit();
1220   ASSERT_NE(unit, nullptr);
1221   const DWARFDebugInfoEntry *cu_entry = unit->DIE().GetDIE();
1222   ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
1223   ASSERT_EQ(unit->GetDWARFLanguageType(), DW_LANG_C_plus_plus);
1224   DWARFDIE cu_die(unit, cu_entry);
1225 
1226   auto ts_or_err =
1227       cu_die.GetDWARF()->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
1228   ASSERT_TRUE(static_cast<bool>(ts_or_err));
1229   llvm::consumeError(ts_or_err.takeError());
1230 
1231   auto *ts = static_cast<TypeSystemClang *>(ts_or_err->get());
1232   auto *parser = static_cast<DWARFASTParserClang *>(ts->GetDWARFParser());
1233 
1234   auto subprogram = cu_die.GetFirstChild();
1235   ASSERT_TRUE(subprogram.IsValid());
1236   ASSERT_EQ(subprogram.Tag(), DW_TAG_subprogram);
1237 
1238   SymbolContext sc;
1239   bool new_type;
1240   auto type_sp = parser->ParseTypeFromDWARF(sc, subprogram, &new_type);
1241   ASSERT_NE(type_sp, nullptr);
1242 
1243   auto result = ts->GetTranslationUnitDecl()->lookup(
1244       clang_utils::getDeclarationName(*ts, "func"));
1245   ASSERT_TRUE(result.isSingleResult());
1246 
1247   auto const *func = llvm::cast<clang::FunctionDecl>(result.front());
1248 
1249   EXPECT_EQ(func->getNumParams(), 2U);
1250   EXPECT_EQ(func->getParamDecl(0)->getDeclContext(), func);
1251   EXPECT_TRUE(func->getParamDecl(0)->getName().empty());
1252   EXPECT_EQ(func->getParamDecl(1)->getDeclContext(), func);
1253   EXPECT_EQ(func->getParamDecl(1)->getName(), "namedParam");
1254 }
1255