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 platform_sp
= Platform::GetHostPlatform();
166 ASSERT_TRUE(platform_sp
);
167 auto path_or_err
= platform_sp
->ResolveSDKPathFromDebugInfo(*module
);
168 EXPECT_FALSE(static_cast<bool>(path_or_err
));
169 llvm::consumeError(path_or_err
.takeError());
172 TEST_F(XcodeSDKModuleTests
, TestSDKPathFromDebugInfo_No_DW_AT_APPLE_sdk
) {
173 // Tests that parsing a CU without a DW_AT_APPLE_sdk fails.
175 const char *yamldata
= R
"(
186 Tag: DW_TAG_compile_unit
187 Children: DW_CHILDREN_no
189 - Attribute: DW_AT_language
191 - Attribute: DW_AT_LLVM_sysroot
199 - AbbrCode: 0x00000001
201 - Value: 0x000000000000000C
202 - CStr: "/Library
/Developer
/CommandLineTools
/SDKs
/iPhoneOS14
.0
.Internal
.sdk
"
203 - AbbrCode: 0x00000000
207 YAMLModuleTester
t(yamldata
);
208 ModuleSP module
= t
.GetModule();
209 ASSERT_NE(module
, nullptr);
211 auto platform_sp
= Platform::GetHostPlatform();
212 ASSERT_TRUE(platform_sp
);
213 auto path_or_err
= platform_sp
->ResolveSDKPathFromDebugInfo(*module
);
214 EXPECT_FALSE(static_cast<bool>(path_or_err
));
215 llvm::consumeError(path_or_err
.takeError());
218 TEST_P(SDKPathParsingMultiparamTests
, TestSDKPathFromDebugInfo
) {
219 // Tests that we can parse the SDK path from debug-info.
220 // In the presence of multiple compile units, one of which
221 // points to an internal SDK, we should pick the internal SDK.
223 std::string yamldata
= R
"(
234 Tag: DW_TAG_compile_unit
235 Children: DW_CHILDREN_no
237 - Attribute: DW_AT_language
239 - Attribute: DW_AT_APPLE_sdk
241 - Attribute: DW_AT_LLVM_sysroot
246 auto [input_sdk_paths
, expect_mismatch
, expect_internal_sdk
,
247 expect_sdk_path_pattern
] = GetParam();
249 for (auto &&sdk
: createCompileUnits(input_sdk_paths
))
250 yamldata
+= std::move(sdk
);
252 YAMLModuleTester
t(yamldata
);
253 DWARFUnit
*dwarf_unit
= t
.GetDwarfUnit();
254 auto *dwarf_cu
= llvm::cast
<DWARFCompileUnit
>(dwarf_unit
);
255 ASSERT_TRUE(static_cast<bool>(dwarf_cu
));
256 SymbolFileDWARF
&sym_file
= dwarf_cu
->GetSymbolFileDWARF();
257 ASSERT_EQ(sym_file
.GetNumCompileUnits(), input_sdk_paths
.size());
258 ModuleSP module
= t
.GetModule();
259 ASSERT_NE(module
, nullptr);
261 auto platform_sp
= Platform::GetHostPlatform();
262 ASSERT_TRUE(platform_sp
);
263 auto sdk_or_err
= platform_sp
->GetSDKPathFromDebugInfo(*module
);
264 ASSERT_TRUE(static_cast<bool>(sdk_or_err
));
266 auto [sdk
, found_mismatch
] = *sdk_or_err
;
268 EXPECT_EQ(found_mismatch
, expect_mismatch
);
269 EXPECT_EQ(sdk
.IsAppleInternalSDK(), expect_internal_sdk
);
270 EXPECT_NE(sdk
.GetString().find(expect_sdk_path_pattern
), std::string::npos
);
273 SDKPathParsingTestData sdkPathParsingTestCases
[] = {
274 /// Multiple CUs with a mix of internal and public SDKs
276 {"/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk",
277 "/invalid/path/to/something.invalid.sdk",
278 "/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk",
279 "/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk"},
280 .expect_mismatch
= true,
281 .expect_internal_sdk
= true,
282 .expect_sdk_path_pattern
= "Internal.sdk"},
284 /// Single CU with a public SDK
286 {"/Library/Developer/CommandLineTools/SDKs/MacOSX10.9.sdk"},
287 .expect_mismatch
= false,
288 .expect_internal_sdk
= false,
289 .expect_sdk_path_pattern
= "MacOSX10.9.sdk"},
291 /// Single CU with an internal SDK
293 {"/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk"},
294 .expect_mismatch
= false,
295 .expect_internal_sdk
= true,
296 .expect_sdk_path_pattern
= "Internal.sdk"},
298 /// Two CUs with an internal SDK each
300 {"/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.0.Internal.sdk",
301 "/Library/Developer/CommandLineTools/SDKs/iPhoneOS12.9.Internal.sdk"},
302 .expect_mismatch
= false,
303 .expect_internal_sdk
= true,
304 .expect_sdk_path_pattern
= "Internal.sdk"},
306 /// Two CUs with an internal SDK each
308 {"/Library/Developer/CommandLineTools/SDKs/iPhoneOS14.1.sdk",
309 "/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk"},
310 .expect_mismatch
= false,
311 .expect_internal_sdk
= false,
312 .expect_sdk_path_pattern
= "iPhoneOS14.1.sdk"},
315 INSTANTIATE_TEST_SUITE_P(SDKPathParsingTests
, SDKPathParsingMultiparamTests
,
316 ::testing::ValuesIn(sdkPathParsingTestCases
));