Skip to content

Commit b20e9cf

Browse files
Adjust to the new clang builtin modules
<__stddef_size_t.h> is now a modular header, and so will not be absorbed into Darwin. When that happens, Darwin.C.stddef no longer has a size_t declaration, instead it imports the declaration from _Builtin_stddef.size_t. Darwin still has its other size_t declaration though, Darwin.POSIX._types._size_t, and that's the one that will be found currently. If that one ever goes away though, allow for _Builtin_stddef.size_t being found in C-typedef-Darwin.
1 parent e45afd3 commit b20e9cf

File tree

9 files changed

+96
-21
lines changed

9 files changed

+96
-21
lines changed

include/swift/ClangImporter/ClangImporter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ bool isCxxConstReferenceType(const clang::Type *type);
647647
struct ClangInvocationFileMapping {
648648
SmallVector<std::pair<std::string, std::string>, 2> redirectedFiles;
649649
SmallVector<std::pair<std::string, std::string>, 1> overridenFiles;
650+
bool requiresBuiltinHeadersInSystemModules;
650651
};
651652

652653
/// On Linux, some platform libraries (glibc, libstdc++) are not modularized.

lib/ClangImporter/ClangImporter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,11 @@ ClangImporter::create(ASTContext &ctx,
12041204
// Create a new Clang compiler invocation.
12051205
{
12061206
importer->Impl.ClangArgs = getClangArguments(ctx);
1207+
if (fileMapping.requiresBuiltinHeadersInSystemModules) {
1208+
if (!importerOpts.DirectClangCC1ModuleBuild)
1209+
importer->Impl.ClangArgs.push_back("-Xclang");
1210+
importer->Impl.ClangArgs.push_back("-fbuiltin-headers-in-system-modules");
1211+
}
12071212
ArrayRef<std::string> invocationArgStrs = importer->Impl.ClangArgs;
12081213
if (importerOpts.DumpClangDiagnostics) {
12091214
llvm::errs() << "'";

lib/ClangImporter/ClangIncludePaths.cpp

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,8 @@ static void getLibStdCxxFileMapping(
398398
}
399399

400400
namespace {
401-
std::string
402-
GetWindowsAuxiliaryFile(StringRef modulemap, const SearchPathOptions &Options) {
401+
std::string GetWindowsAuxiliaryFile(StringRef modulemap,
402+
const SearchPathOptions &Options) {
403403
StringRef SDKPath = Options.getSDKPath();
404404
if (!SDKPath.empty()) {
405405
llvm::SmallString<261> path{SDKPath};
@@ -420,7 +420,8 @@ GetWindowsAuxiliaryFile(StringRef modulemap, const SearchPathOptions &Options) {
420420

421421
SmallVector<std::pair<std::string, std::string>, 2> GetWindowsFileMappings(
422422
ASTContext &Context,
423-
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &driverVFS) {
423+
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &driverVFS,
424+
bool &requiresBuiltinHeadersInSystemModules) {
424425
const llvm::Triple &Triple = Context.LangOpts.Target;
425426
const SearchPathOptions &SearchPathOpts = Context.SearchPathOpts;
426427
SmallVector<std::pair<std::string, std::string>, 2> Mappings;
@@ -468,8 +469,21 @@ SmallVector<std::pair<std::string, std::string>, 2> GetWindowsFileMappings(
468469
llvm::sys::path::append(UCRTInjection, "module.modulemap");
469470

470471
AuxiliaryFile = GetWindowsAuxiliaryFile("ucrt.modulemap", SearchPathOpts);
471-
if (!AuxiliaryFile.empty())
472+
if (!AuxiliaryFile.empty()) {
473+
// The ucrt module map has the C standard library headers all together.
474+
// That leads to module cycles with the clang _Builtin_ modules. e.g.
475+
// <fenv.h> on ucrt includes <float.h>. The clang builtin <float.h>
476+
// include-nexts <float.h>. When both of those UCRT headers are in the
477+
// ucrt module, there's a module cycle ucrt -> _Builtin_float -> ucrt
478+
// (i.e. fenv.h (ucrt) -> float.h (builtin) -> float.h (ucrt)). Until the
479+
// ucrt module map is updated, the builtin headers need to join the system
480+
// modules. i.e. when the builtin float.h is in the ucrt module too, the
481+
// cycle goes away. Note that -fbuiltin-headers-in-system-modules does
482+
// nothing to fix the same problem with C++ headers, and is generally
483+
// fragile.
472484
Mappings.emplace_back(std::string(UCRTInjection), AuxiliaryFile);
485+
requiresBuiltinHeadersInSystemModules = true;
486+
}
473487
}
474488

475489
struct {
@@ -515,20 +529,36 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
515529

516530
const llvm::Triple &triple = ctx.LangOpts.Target;
517531

532+
SmallVector<std::pair<std::string, std::string>, 2> libcFileMapping;
518533
if (triple.isOSWASI()) {
519534
// WASI Mappings
520-
result.redirectedFiles.append(
521-
getLibcFileMapping(ctx, "wasi-libc.modulemap", std::nullopt, vfs));
535+
libcFileMapping =
536+
getLibcFileMapping(ctx, "wasi-libc.modulemap", std::nullopt, vfs);
522537
} else {
523538
// Android/BSD/Linux Mappings
524-
result.redirectedFiles.append(getLibcFileMapping(
525-
ctx, "glibc.modulemap", StringRef("SwiftGlibc.h"), vfs));
539+
libcFileMapping = getLibcFileMapping(ctx, "glibc.modulemap",
540+
StringRef("SwiftGlibc.h"), vfs);
526541
}
542+
result.redirectedFiles.append(libcFileMapping);
543+
// Both libc module maps have the C standard library headers all together in a
544+
// SwiftLibc module. That leads to module cycles with the clang _Builtin_
545+
// modules. e.g. <inttypes.h> includes <stdint.h> on these platforms. The
546+
// clang builtin <stdint.h> include-nexts <stdint.h>. When both of those
547+
// platform headers are in the SwiftLibc module, there's a module cycle
548+
// SwiftLibc -> _Builtin_stdint -> SwiftLibc (i.e. inttypes.h (platform) ->
549+
// stdint.h (builtin) -> stdint.h (platform)). Until this can be fixed in
550+
// these module maps, the clang builtin headers need to join the "system"
551+
// modules (SwiftLibc). i.e. when the clang builtin stdint.h is in the
552+
// SwiftLibc module too, the cycle goes away. Note that
553+
// -fbuiltin-headers-in-system-modules does nothing to fix the same problem
554+
// with C++ headers, and is generally fragile.
555+
result.requiresBuiltinHeadersInSystemModules = !libcFileMapping.empty();
527556

528557
if (ctx.LangOpts.EnableCXXInterop)
529558
getLibStdCxxFileMapping(result, ctx, vfs);
530559

531-
result.redirectedFiles.append(GetWindowsFileMappings(ctx, vfs));
560+
result.redirectedFiles.append(GetWindowsFileMappings(
561+
ctx, vfs, result.requiresBuiltinHeadersInSystemModules));
532562

533563
return result;
534564
}

lib/DriverTool/sil_opt_main.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,8 @@ struct SILOptOptions {
518518
swift::UnavailableDeclOptimization::Complete, "complete",
519519
"Eliminate unavailable decls from lowered SIL/IR")),
520520
llvm::cl::init(swift::UnavailableDeclOptimization::None));
521+
522+
llvm::cl::list<std::string> ClangXCC = llvm::cl::list<std::string>("Xcc", llvm::cl::desc("option to pass to clang"));
521523
};
522524

523525
/// Regular expression corresponding to the value given in one of the
@@ -671,6 +673,11 @@ int sil_opt_main(ArrayRef<const char *> argv, void *MainAddr) {
671673
Invocation.getDiagnosticOptions().VerifyMode =
672674
options.VerifyMode ? DiagnosticOptions::Verify : DiagnosticOptions::NoVerify;
673675

676+
auto ExtraArgs = Invocation.getClangImporterOptions().ExtraArgs;
677+
for (const auto &xcc : options.ClangXCC) {
678+
ExtraArgs.push_back(xcc);
679+
}
680+
674681
// Setup the SIL Options.
675682
SILOptions &SILOpts = Invocation.getSILOptions();
676683
SILOpts.InlineThreshold = options.SILInlineThreshold;

stdlib/public/Backtracing/SymbolicatedBacktrace.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717

1818
import Swift
1919

20-
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
21-
@_implementationOnly import OS.Darwin
22-
#endif
23-
24-
@_implementationOnly import OS.Libc
20+
@_implementationOnly import CompressionLibs
21+
@_implementationOnly import FixedLayout
22+
@_implementationOnly import ImageFormats
23+
@_implementationOnly import OS
2524
@_implementationOnly import Runtime
25+
@_implementationOnly import _SwiftConcurrencyShims
26+
@_implementationOnly import SwiftShims
27+
@_implementationOnly import SwiftOverlayShims
2628

2729
/// A symbolicated backtrace
2830
public struct SymbolicatedBacktrace: CustomStringConvertible {

test/DebugInfo/C-typedef-Darwin.swift

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,32 @@ let blah = size_t(1024)
99
use(blah)
1010
// CHECK: !DIDerivedType(tag: DW_TAG_typedef,
1111
// CHECK-SAME: scope: ![[DARWIN_MODULE:[0-9]+]],
12-
// CHECK: ![[DARWIN_MODULE]] = !DIModule({{.*}}, name: "stddef"
12+
// size_t is defined in clang, originally by <stddef.h>, and later split out to
13+
// <__stddef_size_t.h>. clang's original behavior, which is kept up via clang's
14+
// Darwin toolchain adding -fbuiltin-headers-in-system-modules, makes clang'e
15+
// <stddef.h> a part of the Darwin.C.stddef module. There are a few different
16+
// things that can happen depending on the situation.
17+
// 1. <__stddef_size_t.h> doesn't exist and everything is in clang's <stddef.h>,
18+
// -fbuiltin-headers-in-system-modules is in use. Darwin.C.stddef precompiles
19+
// clang's <stddef.h> and has size_t.
20+
// 2. <__stddef_size_t.h> but doesn't have a module,
21+
// -fbuiltin-headers-in-system-modules is still in use. This is basically the
22+
// same as #1 with the added detail that <__stddef_size_t.h> gets absorbed by
23+
// Darwin.C.stddef
24+
// 3. <__stddef_size_t.h> does have a module,
25+
// -fbuiltin-headers-in-system-modules is still in use. Darwin.C.stddef
26+
// precompiles clang's <stddef.h>, but no longer absorbs <__stddef_size_t.h> and
27+
// no longer has size_t. Instead _Builtin_stddef.size_t has size_t.
28+
// 4. -fbuiltin-headers-in-system-modules is no longer used. clang's <stddef.h>
29+
// is now in _Builtin_stddef which will be imported by Darwin.
30+
// _Builtin_stddef.size_t still has size_t.
31+
// There's one more wrinkle: size_t is also defined in macOS by
32+
// <sys/_types/_size_t.h> currently. That means that Darwin.POSIX._types._size_t
33+
// also has size_t. That means there are currently two valid modules for size_t.
34+
// 1. Darwin.C.stddef or _Builtin_stddef.size_t, depending on the state of
35+
// clang's builtin modules and whether -fbuiltin-headers-in-system-modules is
36+
// used
37+
// 2. Darwin.POSIX._types._size_t, as long as <sys/_types/_size_t.h> declares
38+
// size_t, which is shouldn't do.
39+
// All all three modules
40+
// CHECK: ![[DARWIN_MODULE]] = !DIModule({{.*}}, name: "{{stddef|size_t|_size_t}}"

test/Interop/lit.local.cfg

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ if get_target_os() in ['windows-msvc']:
3333
# Clang should build object files with link settings equivalent to -libc MD
3434
# when building for the MSVC target.
3535
clang_opt = clang_compile_opt + '-D_MT -D_DLL -Xclang --dependent-lib=msvcrt -Xclang --dependent-lib=oldnames '
36-
config.substitutions.insert(0, ('%target-swift-flags', '-vfsoverlay {}'.format(os.path.join(config.swift_obj_root,
37-
'stdlib',
38-
'windows-vfs-overlay.yaml'))))
36+
# ucrt.modulemap currently requires -fbuiltin-headers-in-system-modules
37+
config.substitutions.insert(0, ('%target-swift-flags', '-vfsoverlay {} -Xcc -Xclang -Xcc -fbuiltin-headers-in-system-modules'.format(
38+
os.path.join(config.swift_obj_root,
39+
'stdlib',
40+
'windows-vfs-overlay.yaml'))))
3941
else:
4042
# FIXME(compnerd) do all the targets we currently support use SysV ABI?
4143
config.substitutions.insert(0, ('%target-abi', 'SYSV'))

test/lit.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,10 +374,10 @@ else:
374374
config.swift_system_overlay_opt = ""
375375
config.clang_system_overlay_opt = ""
376376
if kIsWindows:
377-
config.swift_system_overlay_opt = "-vfsoverlay {}".format(
377+
config.swift_system_overlay_opt = "-vfsoverlay {} -Xcc -Xclang -Xcc -fbuiltin-headers-in-system-modules".format(
378378
os.path.join(config.swift_obj_root, "stdlib", "windows-vfs-overlay.yaml")
379379
)
380-
config.clang_system_overlay_opt = "-Xcc -ivfsoverlay -Xcc {}".format(
380+
config.clang_system_overlay_opt = "-Xcc -ivfsoverlay -Xcc {} -Xcc -Xclang -Xcc -fbuiltin-headers-in-system-modules".format(
381381
os.path.join(config.swift_obj_root, "stdlib", "windows-vfs-overlay.yaml")
382382
)
383383
stdlib_resource_dir_opt = config.resource_dir_opt

utils/build.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ function Build-CMakeProject {
608608

609609
$SwiftArgs += @("-resource-dir", "$SwiftResourceDir")
610610
$SwiftArgs += @("-L", "$SwiftResourceDir\windows")
611-
$SwiftArgs += @("-vfsoverlay", "$RuntimeBinaryCache\stdlib\windows-vfs-overlay.yaml")
611+
$SwiftArgs += @("-vfsoverlay", "$RuntimeBinaryCache\stdlib\windows-vfs-overlay.yaml", "-Xcc", "-Xclang", "-Xcc", "-fbuiltin-headers-in-system-modules")
612612
}
613613
} else {
614614
$SwiftArgs += @("-sdk", "$BinaryCache\toolchains\$PinnedToolchain\Library\Developer\Platforms\Windows.platform\Developer\SDKs\Windows.sdk")

0 commit comments

Comments
 (0)