|
11 | 11 | #include "clang/AST/ExternalASTSource.h"
|
12 | 12 | #include "clang/AST/PrettyPrinter.h"
|
13 | 13 | #include "clang/Basic/Builtins.h"
|
| 14 | +#include "clang/Basic/DarwinSDKInfo.h" |
14 | 15 | #include "clang/Basic/DiagnosticIDs.h"
|
15 | 16 | #include "clang/Basic/SourceLocation.h"
|
16 | 17 | #include "clang/Basic/TargetInfo.h"
|
@@ -352,6 +353,73 @@ static void SetupDefaultClangDiagnostics(CompilerInstance &compiler) {
|
352 | 353 | }
|
353 | 354 | }
|
354 | 355 |
|
| 356 | +// NOTE: should be kept in sync with sdkSupportsBuiltinModules in |
| 357 | +// Toolchains/Darwin.cpp |
| 358 | +static bool |
| 359 | +sdkSupportsBuiltinModulesImpl(const llvm::Triple &triple, |
| 360 | + const std::optional<DarwinSDKInfo> &SDKInfo) { |
| 361 | + if (!SDKInfo) |
| 362 | + return false; |
| 363 | + |
| 364 | + VersionTuple SDKVersion = SDKInfo->getVersion(); |
| 365 | + switch (triple.getOS()) { |
| 366 | + case Triple::OSType::MacOSX: |
| 367 | + return SDKVersion >= VersionTuple(15U); |
| 368 | + case Triple::OSType::IOS: |
| 369 | + return SDKVersion >= VersionTuple(18U); |
| 370 | + case Triple::OSType::TvOS: |
| 371 | + return SDKVersion >= VersionTuple(18U); |
| 372 | + case Triple::OSType::WatchOS: |
| 373 | + return SDKVersion >= VersionTuple(11U); |
| 374 | + case Triple::OSType::XROS: |
| 375 | + return SDKVersion >= VersionTuple(2U); |
| 376 | + default: |
| 377 | + // New SDKs support builtin modules from the start. |
| 378 | + return true; |
| 379 | + } |
| 380 | +} |
| 381 | + |
| 382 | +/// Returns true if the SDK for the specified triple supports |
| 383 | +/// builtin modules in system headers. This is used to decide |
| 384 | +/// whether to pass -fbuiltin-headers-in-system-modules to |
| 385 | +/// the compiler instance when compiling the `std` module. |
| 386 | +/// |
| 387 | +/// This function assumes one of the directories in \ref include_dirs |
| 388 | +/// is an SDK path that exists on the host. The SDK version is |
| 389 | +/// read from the SDKSettings.json in that directory. |
| 390 | +/// |
| 391 | +/// \param[in] triple The target triple. |
| 392 | +/// \param[in] include_dirs The include directories the compiler will use |
| 393 | +/// during header search. |
| 394 | +/// |
| 395 | +static bool |
| 396 | +sdkSupportsBuiltinModules(llvm::Triple const &triple, |
| 397 | + std::vector<std::string> const &include_dirs) { |
| 398 | + // Find an SDK directory. |
| 399 | + static constexpr std::string_view s_sdk_suffix = ".sdk"; |
| 400 | + auto it = llvm::find_if(include_dirs, [](std::string const &path) { |
| 401 | + return path.find(s_sdk_suffix) != std::string::npos; |
| 402 | + }); |
| 403 | + if (it == include_dirs.end()) |
| 404 | + return false; |
| 405 | + |
| 406 | + auto VFS = FileSystem::Instance().GetVirtualFileSystem(); |
| 407 | + if (!VFS) |
| 408 | + return false; |
| 409 | + |
| 410 | + // Extract: /path/to/some.sdk |
| 411 | + size_t suffix = it->find(s_sdk_suffix); |
| 412 | + assert(suffix != std::string::npos); |
| 413 | + std::string sdk_path = it->substr(0, suffix + s_sdk_suffix.size()); |
| 414 | + |
| 415 | + // Extract SDK version from the /path/to/some.sdk/SDKSettings.json |
| 416 | + auto parsed = clang::parseDarwinSDKInfo(*VFS, sdk_path); |
| 417 | + if (!parsed) |
| 418 | + return false; |
| 419 | + |
| 420 | + return sdkSupportsBuiltinModulesImpl(triple, *parsed); |
| 421 | +} |
| 422 | + |
355 | 423 | //===----------------------------------------------------------------------===//
|
356 | 424 | // Implementation of ClangExpressionParser
|
357 | 425 | //===----------------------------------------------------------------------===//
|
@@ -576,7 +644,8 @@ ClangExpressionParser::ClangExpressionParser(
|
576 | 644 | lang_opts.GNUMode = true;
|
577 | 645 | lang_opts.GNUKeywords = true;
|
578 | 646 | lang_opts.CPlusPlus11 = true;
|
579 |
| - lang_opts.BuiltinHeadersInSystemModules = true; |
| 647 | + lang_opts.BuiltinHeadersInSystemModules = !sdkSupportsBuiltinModules( |
| 648 | + target_sp->GetArchitecture().GetTriple(), m_include_directories); |
580 | 649 |
|
581 | 650 | // The Darwin libc expects this macro to be set.
|
582 | 651 | lang_opts.GNUCVersion = 40201;
|
|
0 commit comments