1 //===-- XcodeSDKModuleTests.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/Platform/MacOSX/PlatformMacOSX.h"
10 #include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h"
11 #include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
12 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
13 #include "TestingSupport/Symbol/YAMLModuleTester.h"
14 #include "lldb/Core/PluginManager.h"
15 #include "llvm/Support/Error.h"
16 #include "llvm/Support/Path.h"
17 #include "gmock/gmock.h"
18 #include "gtest/gtest.h"
21 using namespace lldb_private
;
22 using namespace lldb_private::plugin::dwarf
;
26 class XcodeSDKModuleTests
: public testing::Test
{
27 SubsystemRAII
<HostInfoBase
, PlatformMacOSX
> subsystems
;
30 struct SDKPathParsingTestData
{
31 /// Each path will be put into a new CU's
32 /// DW_AT_LLVM_sysroot.
33 std::vector
<llvm::StringRef
> input_sdk_paths
;
35 /// 'true' if we expect \ref GetSDKPathFromDebugInfo
36 /// to notify us about an SDK mismatch.
39 /// 'true if the test expects the parsed SDK to
40 /// be an internal one.
41 bool expect_internal_sdk
;
43 /// A substring that the final parsed sdk
44 /// is expected to contain.
45 llvm::StringRef expect_sdk_path_pattern
;
48 struct SDKPathParsingMultiparamTests
49 : public XcodeSDKModuleTests
,
50 public testing::WithParamInterface
<SDKPathParsingTestData
> {
51 std::vector
<std::string
>
52 createCompileUnits(std::vector
<llvm::StringRef
> const &sdk_paths
) {
53 std::vector
<std::string
> compile_units
;
55 for (auto sdk_path
: sdk_paths
) {
56 compile_units
.emplace_back(llvm::formatv(
63 - AbbrCode: 0x00000001
65 - Value: 0x000000000000000C
68 - AbbrCode: 0x00000000
70 llvm::sys::path::filename(sdk_path
, llvm::sys::path::Style::posix
),
79 TEST_F(XcodeSDKModuleTests
, TestModuleGetXcodeSDK
) {
80 const char *yamldata
= R
"(
93 Tag: DW_TAG_compile_unit
94 Children: DW_CHILDREN_no
96 - Attribute: DW_AT_language
98 - Attribute: DW_AT_APPLE_sdk
104 - AbbrCode: 0x00000001
106 - Value: 0x000000000000000C
107 - Value: 0x0000000000000000
108 - AbbrCode: 0x00000000
112 YAMLModuleTester
t(yamldata
);
113 DWARFUnit
*dwarf_unit
= t
.GetDwarfUnit();
114 auto *dwarf_cu
= llvm::cast
<DWARFCompileUnit
>(dwarf_unit
);
115 ASSERT_TRUE(static_cast<bool>(dwarf_cu
));
116 SymbolFileDWARF
&sym_file
= dwarf_cu
->GetSymbolFileDWARF();
117 CompUnitSP comp_unit
= sym_file
.GetCompileUnitAtIndex(0);
118 ASSERT_TRUE(static_cast<bool>(comp_unit
.get()));
119 ModuleSP module
= t
.GetModule();
120 ASSERT_EQ(module
->GetSourceMappingList().GetSize(), 0u);
121 XcodeSDK sdk
= sym_file
.ParseXcodeSDK(*comp_unit
);
122 ASSERT_EQ(sdk
.GetType(), XcodeSDK::Type::MacOSX
);
123 ASSERT_EQ(module
->GetSourceMappingList().GetSize(), 1u);
126 TEST_F(XcodeSDKModuleTests
, TestSDKPathFromDebugInfo_InvalidSDKPath
) {
127 // Tests that parsing a CU with an invalid SDK directory name fails.
129 const char *yamldata
= R
"(
140 Tag: DW_TAG_compile_unit
141 Children: DW_CHILDREN_no
143 - Attribute: DW_AT_language
145 - Attribute: DW_AT_APPLE_sdk
153 - AbbrCode: 0x00000001
155 - Value: 0x000000000000000C
156 - CStr: "1abc@defgh2
"
157 - AbbrCode: 0x00000000
161 YAMLModuleTester
t(yamldata
);
162 ModuleSP module
= t
.GetModule();
163 ASSERT_NE(module
, nullptr);
165 auto path_or_err
= PlatformDarwin::ResolveSDKPathFromDebugInfo(*module
);
166 EXPECT_FALSE(static_cast<bool>(path_or_err
));
167 llvm::consumeError(path_or_err
.takeError());
170 TEST_F(XcodeSDKModuleTests
, TestSDKPathFromDebugInfo_No_DW_AT_APPLE_sdk
) {
171 // Tests that parsing a CU without a DW_AT_APPLE_sdk fails.
173 const char *yamldata
= R
"(
184 Tag: DW_TAG_compile_unit
185 Children: DW_CHILDREN_no
187 - Attribute: DW_AT_language
189 - Attribute: DW_AT_LLVM_sysroot
197 - AbbrCode: 0x00000001
199 - Value: 0x000000000000000C
200 - CStr: "/Library
/Developer
/CommandLineTools
/SDKs
/iPhoneOS14
.0
.Internal
.sdk
"
201 - AbbrCode: 0x00000000
205 YAMLModuleTester
t(yamldata
);
206 ModuleSP module
= t
.GetModule();
207 ASSERT_NE(module
, nullptr);
209 auto path_or_err
= PlatformDarwin::ResolveSDKPathFromDebugInfo(*module
);
210 EXPECT_FALSE(static_cast<bool>(path_or_err
));
211 llvm::consumeError(path_or_err
.takeError());
214 TEST_P(SDKPathParsingMultiparamTests
, TestSDKPathFromDebugInfo
) {
215 // Tests that we can parse the SDK path from debug-info.
216 // In the presence of multiple compile units, one of which
217 // points to an internal SDK, we should pick the internal SDK.
219 std::string yamldata
= R
"(
230 Tag: DW_TAG_compile_unit
231 Children: DW_CHILDREN_no
233 - Attribute: DW_AT_language
235 - Attribute: DW_AT_APPLE_sdk
237 - Attribute: DW_AT_LLVM_sysroot
242 auto [input_sdk_paths
, expect_mismatch
, expect_internal_sdk
,
243 expect_sdk_path_pattern
] = GetParam();
245 for (auto &&sdk
: createCompileUnits(input_sdk_paths
))
246 yamldata
+= std::move(sdk
);
248 YAMLModuleTester
t(yamldata
);
249 DWARFUnit
*dwarf_unit
= t
.GetDwarfUnit();
250 auto *dwarf_cu
= llvm::cast
<DWARFCompileUnit
>(dwarf_unit
);
251 ASSERT_TRUE(static_cast<bool>(dwarf_cu
));
252 SymbolFileDWARF
&sym_file
= dwarf_cu
->GetSymbolFileDWARF();
253 ASSERT_EQ(sym_file
.GetNumCompileUnits(), input_sdk_paths
.size());
254 ModuleSP module
= t
.GetModule();
255 ASSERT_NE(module
, nullptr);
257 auto sdk_or_err
= PlatformDarwin::GetSDKPathFromDebugInfo(*module
);
258 ASSERT_TRUE(static_cast<bool>(sdk_or_err
));
260 auto [sdk
, found_mismatch
] = *sdk_or_err
;
262 EXPECT_EQ(found_mismatch
, expect_mismatch
);
263 EXPECT_EQ(sdk
.IsAppleInternalSDK(), expect_internal_sdk
);
264 EXPECT_NE(sdk
.GetString().find(expect_sdk_path_pattern
), std::string::npos
);
267 SDKPathParsingTestData sdkPathParsingTestCases
[] = {
268 /// Multiple CUs with a mix of internal and public SDKs
270 {"/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk",
271 "/invalid/path/to/something.invalid.sdk",
272 "/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk",
273 "/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk"},
274 .expect_mismatch
= true,
275 .expect_internal_sdk
= true,
276 .expect_sdk_path_pattern
= "Internal.sdk"},
278 /// Single CU with a public SDK
280 {"/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk"},
281 .expect_mismatch
= false,
282 .expect_internal_sdk
= false,
283 .expect_sdk_path_pattern
= "MacOSX10.9.sdk"},
285 /// Single CU with an internal SDK
287 {"/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk"},
288 .expect_mismatch
= false,
289 .expect_internal_sdk
= true,
290 .expect_sdk_path_pattern
= "Internal.sdk"},
292 /// Two CUs with an internal SDK each
294 {"/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk",
295 "/Library/Developer/CommandLineTools/SDKs/iPhoneOS12.9.Internal.sdk"},
296 .expect_mismatch
= false,
297 .expect_internal_sdk
= true,
298 .expect_sdk_path_pattern
= "Internal.sdk"},
300 /// Two CUs with an internal SDK each
302 {"/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.1.sdk",
303 "/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk"},
304 .expect_mismatch
= false,
305 .expect_internal_sdk
= false,
306 .expect_sdk_path_pattern
= "iPhoneOS14.1.sdk"},
309 INSTANTIATE_TEST_CASE_P(SDKPathParsingTests
, SDKPathParsingMultiparamTests
,
310 ::testing::ValuesIn(sdkPathParsingTestCases
));