@@ -420,7 +420,8 @@ GetWindowsAuxiliaryFile(StringRef modulemap, const SearchPathOptions &Options) {
420
420
421
421
SmallVector<std::pair<std::string, std::string>, 2 > GetWindowsFileMappings (
422
422
ASTContext &Context,
423
- const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &driverVFS) {
423
+ const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &driverVFS,
424
+ bool &requiresBuiltinHeadersInSystemModules) {
424
425
const llvm::Triple &Triple = Context.LangOpts .Target ;
425
426
const SearchPathOptions &SearchPathOpts = Context.SearchPathOpts ;
426
427
SmallVector<std::pair<std::string, std::string>, 2 > Mappings;
@@ -468,8 +469,21 @@ SmallVector<std::pair<std::string, std::string>, 2> GetWindowsFileMappings(
468
469
llvm::sys::path::append (UCRTInjection, " module.modulemap" );
469
470
470
471
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.
472
484
Mappings.emplace_back (std::string (UCRTInjection), AuxiliaryFile);
485
+ requiresBuiltinHeadersInSystemModules = true ;
486
+ }
473
487
}
474
488
475
489
struct {
@@ -515,20 +529,36 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
515
529
516
530
const llvm::Triple &triple = ctx.LangOpts .Target ;
517
531
532
+ SmallVector<std::pair<std::string, std::string>, 2 > libcFileMapping;
518
533
if (triple.isOSWASI ()) {
519
534
// 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);
522
537
} else {
523
538
// 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);
526
541
}
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 ();
527
556
528
557
if (ctx.LangOpts .EnableCXXInterop )
529
558
getLibStdCxxFileMapping (result, ctx, vfs);
530
559
531
- result.redirectedFiles .append (GetWindowsFileMappings (ctx, vfs));
560
+ result.redirectedFiles .append (GetWindowsFileMappings (
561
+ ctx, vfs, result.requiresBuiltinHeadersInSystemModules ));
532
562
533
563
return result;
534
564
}
0 commit comments