Skip to content

Commit 1cbcf74

Browse files
authored
[lldb][ClangExpressionParser] Set BuiltinHeadersInSystemModules depending on SDK version (#102309)
This patch changes the way we initialize `BuiltinHeadersInSystemModules` which is one of the flags controlling Clang's behaviour when the Darwin module is split into more fine-grained modules. The ClangExpressionParser currently unconditionally sets `-fbuiltin-headers-in-system-modules` when evaluating expressions with the `target.import-std-module` setting. This flag should, however, be set depending on the SDK version (which is what the Clang Darwin toolchain does). Unfortunately, the compiler instance that we create with `ClangExpressionParser` never consults the Clang driver, and thus doesn't correctly infer `BuiltinHeadersInSystemModules`. Note, this isn't an issue with the `CompilerInstance` that the `ClangModulesDeclVendor` creates because it uses the `createInovcation` API, which calls into `Darwin::addClangTargetOptions`. This patch mimicks how `sdkSupportsBuiltinModules` is used in `Darwin::addClangTargetOptions`. This ensures that the `import-std-module` API tests run cleanly regardless of SDK version. The plan is to eventually make the `CompilerInstance` construction in `ClangExpressionParser` go through the driver, so we can avoid duplicating the logic in LLDB. But we aren't there yet. **Implementation** * We look for the `SDKSettings.json` in the sysroot directory that we found in DWARF (via `DW_AT_LLVM_sysroot`) * Then parse this file and extract the SDK version number out of it * Then mimick `sdkSupportsBuiltinModules` from `Toolchains/Darwin.cpp` and set `BuiltinHeadersInSystemModules` based on it rdar://116490281
1 parent e9c9fde commit 1cbcf74

File tree

3 files changed

+94
-3
lines changed

3 files changed

+94
-3
lines changed

lldb/include/lldb/Utility/XcodeSDK.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ class XcodeSDK {
8585
/// Whether LLDB feels confident importing Clang modules from this SDK.
8686
static bool SDKSupportsModules(Type type, llvm::VersionTuple version);
8787
static bool SDKSupportsModules(Type desired_type, const FileSpec &sdk_path);
88+
89+
/// Returns true if the SDK for the specified triple supports
90+
/// builtin modules in system headers.
91+
///
92+
/// NOTE: should be kept in sync with sdkSupportsBuiltinModules in
93+
/// Toolchains/Darwin.cpp
94+
///
95+
/// FIXME: this function will be removed once LLDB's ClangExpressionParser
96+
/// constructs the compiler instance through the driver/toolchain. See \ref
97+
/// SetupImportStdModuleLangOpts
98+
///
99+
static bool SDKSupportsBuiltinModules(const llvm::Triple &target_triple,
100+
llvm::VersionTuple sdk_version);
101+
88102
/// Return the canonical SDK name, such as "macosx" for the macOS SDK.
89103
static std::string GetCanonicalName(Info info);
90104
/// Return the best-matching SDK type for a specific triple.

lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "clang/AST/ExternalASTSource.h"
1212
#include "clang/AST/PrettyPrinter.h"
1313
#include "clang/Basic/Builtins.h"
14+
#include "clang/Basic/DarwinSDKInfo.h"
1415
#include "clang/Basic/DiagnosticIDs.h"
1516
#include "clang/Basic/SourceLocation.h"
1617
#include "clang/Basic/TargetInfo.h"
@@ -39,6 +40,7 @@
3940
#include "llvm/ExecutionEngine/ExecutionEngine.h"
4041
#include "llvm/Support/CrashRecoveryContext.h"
4142
#include "llvm/Support/Debug.h"
43+
#include "llvm/Support/Error.h"
4244
#include "llvm/Support/FileSystem.h"
4345
#include "llvm/Support/TargetSelect.h"
4446

@@ -91,6 +93,8 @@
9193
#include "lldb/Utility/StringList.h"
9294

9395
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
96+
#include "Plugins/Platform/MacOSX/PlatformDarwin.h"
97+
#include "lldb/Utility/XcodeSDK.h"
9498

9599
#include <cctype>
96100
#include <memory>
@@ -279,6 +283,49 @@ class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
279283
std::string m_output;
280284
};
281285

286+
/// Returns true if the SDK for the specified triple supports
287+
/// builtin modules in system headers. This is used to decide
288+
/// whether to pass -fbuiltin-headers-in-system-modules to
289+
/// the compiler instance when compiling the `std` module.
290+
static llvm::Expected<bool>
291+
sdkSupportsBuiltinModules(lldb_private::Target &target) {
292+
#ifndef __APPLE__
293+
return false;
294+
#else
295+
auto arch_spec = target.GetArchitecture();
296+
auto const &triple = arch_spec.GetTriple();
297+
auto module_sp = target.GetExecutableModule();
298+
if (!module_sp)
299+
return llvm::createStringError("Executable module not found.");
300+
301+
// Get SDK path that the target was compiled against.
302+
auto sdk_or_err = PlatformDarwin::GetSDKPathFromDebugInfo(*module_sp);
303+
if (!sdk_or_err)
304+
return sdk_or_err.takeError();
305+
306+
// Use the SDK path from debug-info to find a local matching SDK directory.
307+
auto sdk_path_or_err =
308+
HostInfo::GetSDKRoot(HostInfo::SDKOptions{std::move(sdk_or_err->first)});
309+
if (!sdk_path_or_err)
310+
return sdk_path_or_err.takeError();
311+
312+
auto VFS = FileSystem::Instance().GetVirtualFileSystem();
313+
if (!VFS)
314+
return llvm::createStringError("No virtual filesystem available.");
315+
316+
// Extract SDK version from the /path/to/some.sdk/SDKSettings.json
317+
auto parsed_or_err = clang::parseDarwinSDKInfo(*VFS, *sdk_path_or_err);
318+
if (!parsed_or_err)
319+
return parsed_or_err.takeError();
320+
321+
auto maybe_sdk = *parsed_or_err;
322+
if (!maybe_sdk)
323+
return llvm::createStringError("Couldn't find Darwin SDK info.");
324+
325+
return XcodeSDK::SDKSupportsBuiltinModules(triple, maybe_sdk->getVersion());
326+
#endif
327+
}
328+
282329
static void SetupModuleHeaderPaths(CompilerInstance *compiler,
283330
std::vector<std::string> include_directories,
284331
lldb::TargetSP target_sp) {
@@ -561,7 +608,9 @@ static void SetupLangOpts(CompilerInstance &compiler,
561608
lang_opts.NoBuiltin = true;
562609
}
563610

564-
static void SetupImportStdModuleLangOpts(CompilerInstance &compiler) {
611+
static void SetupImportStdModuleLangOpts(CompilerInstance &compiler,
612+
lldb_private::Target &target) {
613+
Log *log = GetLog(LLDBLog::Expressions);
565614
LangOptions &lang_opts = compiler.getLangOpts();
566615
lang_opts.Modules = true;
567616
// We want to implicitly build modules.
@@ -578,7 +627,14 @@ static void SetupImportStdModuleLangOpts(CompilerInstance &compiler) {
578627
lang_opts.GNUMode = true;
579628
lang_opts.GNUKeywords = true;
580629
lang_opts.CPlusPlus11 = true;
581-
lang_opts.BuiltinHeadersInSystemModules = true;
630+
631+
auto supported_or_err = sdkSupportsBuiltinModules(target);
632+
if (supported_or_err)
633+
lang_opts.BuiltinHeadersInSystemModules = !*supported_or_err;
634+
else
635+
LLDB_LOG_ERROR(log, supported_or_err.takeError(),
636+
"Failed to determine BuiltinHeadersInSystemModules when "
637+
"setting up import-std-module: {0}");
582638

583639
// The Darwin libc expects this macro to be set.
584640
lang_opts.GNUCVersion = 40201;
@@ -659,7 +715,7 @@ ClangExpressionParser::ClangExpressionParser(
659715
if (auto *clang_expr = dyn_cast<ClangUserExpression>(&m_expr);
660716
clang_expr && clang_expr->DidImportCxxModules()) {
661717
LLDB_LOG(log, "Adding lang options for importing C++ modules");
662-
SetupImportStdModuleLangOpts(*m_compiler);
718+
SetupImportStdModuleLangOpts(*m_compiler, *target_sp);
663719
SetupModuleHeaderPaths(m_compiler.get(), m_include_directories, target_sp);
664720
}
665721

lldb/source/Utility/XcodeSDK.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,27 @@ bool XcodeSDK::SupportsSwift() const {
259259
}
260260
}
261261

262+
bool XcodeSDK::SDKSupportsBuiltinModules(const llvm::Triple &target_triple,
263+
llvm::VersionTuple sdk_version) {
264+
using namespace llvm;
265+
266+
switch (target_triple.getOS()) {
267+
case Triple::OSType::MacOSX:
268+
return sdk_version >= VersionTuple(15U);
269+
case Triple::OSType::IOS:
270+
return sdk_version >= VersionTuple(18U);
271+
case Triple::OSType::TvOS:
272+
return sdk_version >= VersionTuple(18U);
273+
case Triple::OSType::WatchOS:
274+
return sdk_version >= VersionTuple(11U);
275+
case Triple::OSType::XROS:
276+
return sdk_version >= VersionTuple(2U);
277+
default:
278+
// New SDKs support builtin modules from the start.
279+
return true;
280+
}
281+
}
282+
262283
bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type desired_type,
263284
const FileSpec &sdk_path) {
264285
ConstString last_path_component = sdk_path.GetFilename();

0 commit comments

Comments
 (0)