1 //===-- DWARFASTParserClangTests.cpp --------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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/YAMLModuleTester.h"
13 #include "gmock/gmock.h"
14 #include "gtest/gtest.h"
17 using namespace lldb_private
;
20 class DWARFASTParserClangTests
: public testing::Test
{};
22 class DWARFASTParserClangStub
: public DWARFASTParserClang
{
24 using DWARFASTParserClang::DWARFASTParserClang
;
25 using DWARFASTParserClang::LinkDeclContextToDIE
;
27 std::vector
<const clang::DeclContext
*> GetDeclContextToDIEMapKeys() {
28 std::vector
<const clang::DeclContext
*> keys
;
29 for (const auto &it
: m_decl_ctx_to_die
)
30 keys
.push_back(it
.first
);
36 // If your implementation needs to dereference the dummy pointers we are
37 // defining here, causing this test to fail, feel free to delete it.
38 TEST_F(DWARFASTParserClangTests
,
39 EnsureAllDIEsInDeclContextHaveBeenParsedParsesOnlyMatchingEntries
) {
41 /// Auxiliary debug info.
42 const char *yamldata
= R
"(
53 Tag: DW_TAG_compile_unit
54 Children: DW_CHILDREN_yes
56 - Attribute: DW_AT_language
60 Children: DW_CHILDREN_no
62 - Attribute: DW_AT_encoding
64 - Attribute: DW_AT_byte_size
70 - AbbrCode: 0x00000001
72 - Value: 0x000000000000000C
73 - AbbrCode: 0x00000002
75 - Value: 0x0000000000000007 # DW_ATE_unsigned
76 - Value: 0x0000000000000004
77 - AbbrCode: 0x00000002
79 - Value: 0x0000000000000007 # DW_ATE_unsigned
80 - Value: 0x0000000000000008
81 - AbbrCode: 0x00000002
83 - Value: 0x0000000000000005 # DW_ATE_signed
84 - Value: 0x0000000000000008
85 - AbbrCode: 0x00000002
87 - Value: 0x0000000000000008 # DW_ATE_unsigned_char
88 - Value: 0x0000000000000001
89 - AbbrCode: 0x00000000
92 YAMLModuleTester
t(yamldata
);
93 ASSERT_TRUE((bool)t
.GetDwarfUnit());
95 TypeSystemClang
ast_ctx("dummy ASTContext", HostInfoBase::GetTargetTriple());
96 DWARFASTParserClangStub
ast_parser(ast_ctx
);
98 DWARFUnit
*unit
= t
.GetDwarfUnit();
99 const DWARFDebugInfoEntry
*die_first
= unit
->DIE().GetDIE();
100 const DWARFDebugInfoEntry
*die_child0
= die_first
->GetFirstChild();
101 const DWARFDebugInfoEntry
*die_child1
= die_child0
->GetSibling();
102 const DWARFDebugInfoEntry
*die_child2
= die_child1
->GetSibling();
103 const DWARFDebugInfoEntry
*die_child3
= die_child2
->GetSibling();
104 std::vector
<DWARFDIE
> dies
= {
105 DWARFDIE(unit
, die_child0
), DWARFDIE(unit
, die_child1
),
106 DWARFDIE(unit
, die_child2
), DWARFDIE(unit
, die_child3
)};
107 std::vector
<clang::DeclContext
*> decl_ctxs
= {
108 (clang::DeclContext
*)1LL, (clang::DeclContext
*)2LL,
109 (clang::DeclContext
*)2LL, (clang::DeclContext
*)3LL};
110 for (int i
= 0; i
< 4; ++i
)
111 ast_parser
.LinkDeclContextToDIE(decl_ctxs
[i
], dies
[i
]);
112 ast_parser
.EnsureAllDIEsInDeclContextHaveBeenParsed(
113 CompilerDeclContext(nullptr, decl_ctxs
[1]));
115 EXPECT_THAT(ast_parser
.GetDeclContextToDIEMapKeys(),
116 testing::UnorderedElementsAre(decl_ctxs
[0], decl_ctxs
[3]));
119 TEST_F(DWARFASTParserClangTests
, TestCallingConventionParsing
) {
120 // Tests parsing DW_AT_calling_convention values.
122 // The DWARF below just declares a list of function types with
123 // DW_AT_calling_convention on them.
124 const char *yamldata
= R
"(
146 Tag: DW_TAG_compile_unit
147 Children: DW_CHILDREN_yes
149 - Attribute: DW_AT_language
152 Tag: DW_TAG_subprogram
153 Children: DW_CHILDREN_no
155 - Attribute: DW_AT_low_pc
157 - Attribute: DW_AT_high_pc
159 - Attribute: DW_AT_name
161 - Attribute: DW_AT_calling_convention
163 - Attribute: DW_AT_external
164 Form: DW_FORM_flag_present
238 YAMLModuleTester
t(yamldata
);
240 DWARFUnit
*unit
= t
.GetDwarfUnit();
241 ASSERT_NE(unit
, nullptr);
242 const DWARFDebugInfoEntry
*cu_entry
= unit
->DIE().GetDIE();
243 ASSERT_EQ(cu_entry
->Tag(), DW_TAG_compile_unit
);
244 DWARFDIE
cu_die(unit
, cu_entry
);
246 TypeSystemClang
ast_ctx("dummy ASTContext", HostInfoBase::GetTargetTriple());
247 DWARFASTParserClangStub
ast_parser(ast_ctx
);
249 std::vector
<std::string
> found_function_types
;
250 // The DWARF above is just a list of functions. Parse all of them to
251 // extract the function types and their calling convention values.
252 for (DWARFDIE func
: cu_die
.children()) {
253 ASSERT_EQ(func
.Tag(), DW_TAG_subprogram
);
255 bool new_type
= false;
256 lldb::TypeSP type
= ast_parser
.ParseTypeFromDWARF(sc
, func
, &new_type
);
257 found_function_types
.push_back(
258 type
->GetForwardCompilerType().GetTypeName().AsCString());
261 // Compare the parsed function types against the expected list of types.
262 const std::vector
<std::string
> expected_function_types
= {
263 "void () __attribute__((regcall))",
264 "void () __attribute__((fastcall))",
265 "void () __attribute__((stdcall))",
266 "void () __attribute__((vectorcall))",
267 "void () __attribute__((pascal))",
268 "void () __attribute__((ms_abi))",
269 "void () __attribute__((sysv_abi))",
270 "void ()", // invalid calling convention.
271 "void ()", // DW_CC_normal -> no attribute
273 ASSERT_EQ(found_function_types
, expected_function_types
);