Skip to content

Commit dca3538

Browse files
committed
Fix direct clang cc1 emit-pcm commands with vfs overlay on Windows
Explicit module builds currently fail on Windows because direct-clang-cc1-module-build emit-pcm commands take overlaid system module map files as inputs but miss the clang VFS overlay. This change adds the overlay and fixes explicit module builds on Windows.
1 parent 73fd67b commit dca3538

File tree

6 files changed

+87
-16
lines changed

6 files changed

+87
-16
lines changed

include/swift/ClangImporter/ClangImporter.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ namespace dependencies {
7474
namespace swift {
7575
enum class ResultConvention : uint8_t;
7676
class ASTContext;
77+
class CASOptions;
7778
class CompilerInvocation;
7879
class ClangImporterOptions;
7980
class ClangInheritanceInfo;
@@ -82,6 +83,7 @@ class ClangNode;
8283
class ConcreteDeclRef;
8384
class Decl;
8485
class DeclContext;
86+
class DiagnosticEngine;
8587
class EffectiveClangContext;
8688
class EnumDecl;
8789
class FuncDecl;
@@ -881,22 +883,41 @@ struct ClangInvocationFileMapping {
881883
bool requiresBuiltinHeadersInSystemModules;
882884
};
883885

886+
class ClangInvocationFileMappingContext {
887+
public:
888+
const LangOptions &LangOpts;
889+
SearchPathOptions &SearchPathOpts;
890+
ClangImporterOptions &ClangImporterOpts;
891+
const CASOptions &CASOpts;
892+
DiagnosticEngine &Diags;
893+
894+
ClangInvocationFileMappingContext(
895+
const LangOptions &LangOpts, SearchPathOptions &SearchPathOpts,
896+
ClangImporterOptions &ClangImporterOpts, const CASOptions &CASOpts,
897+
DiagnosticEngine &Diags)
898+
: LangOpts(LangOpts), SearchPathOpts(SearchPathOpts),
899+
ClangImporterOpts(ClangImporterOpts), CASOpts(CASOpts),
900+
Diags(Diags) {}
901+
902+
ClangInvocationFileMappingContext(const swift::ASTContext &Ctx);
903+
};
904+
884905
/// On Linux, some platform libraries (glibc, libstdc++) are not modularized.
885906
/// We inject modulemaps for those libraries into their include directories
886907
/// to allow using them from Swift.
887908
///
888909
/// `suppressDiagnostic` prevents us from emitting warning messages when we
889910
/// are unable to find headers.
890911
ClangInvocationFileMapping getClangInvocationFileMapping(
891-
const ASTContext &ctx,
912+
const ClangInvocationFileMappingContext &ctx,
892913
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs = nullptr,
893914
bool suppressDiagnostic = false);
894915

895916
/// Apply the given file mapping to the specified 'fileSystem', used
896917
/// primarily to inject modulemaps on platforms with non-modularized
897918
/// platform libraries.
898919
ClangInvocationFileMapping applyClangInvocationMapping(
899-
const ASTContext &ctx,
920+
const ClangInvocationFileMappingContext &ctx,
900921
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS,
901922
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &fileSystem,
902923
bool suppressDiagnostics = false);

lib/ClangImporter/ClangIncludePaths.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ ClangImporter::createClangArgs(const ClangImporterOptions &ClangImporterOpts,
201201
}
202202

203203
static SmallVector<std::pair<std::string, std::string>, 2>
204-
getLibcFileMapping(const ASTContext &ctx, StringRef modulemapFileName,
204+
getLibcFileMapping(const ClangInvocationFileMappingContext &ctx,
205+
StringRef modulemapFileName,
205206
std::optional<ArrayRef<StringRef>> maybeHeaderFileNames,
206207
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs,
207208
bool suppressDiagnostic) {
@@ -267,7 +268,8 @@ getLibcFileMapping(const ASTContext &ctx, StringRef modulemapFileName,
267268
}
268269

269270
static void getLibStdCxxFileMapping(
270-
ClangInvocationFileMapping &fileMapping, const ASTContext &ctx,
271+
ClangInvocationFileMapping &fileMapping,
272+
const ClangInvocationFileMappingContext &ctx,
271273
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs,
272274
bool suppressDiagnostic) {
273275
assert(ctx.LangOpts.EnableCXXInterop &&
@@ -472,7 +474,8 @@ GetPlatformAuxiliaryFile(StringRef Platform, StringRef File,
472474
}
473475

474476
void GetWindowsFileMappings(
475-
ClangInvocationFileMapping &fileMapping, const ASTContext &Context,
477+
ClangInvocationFileMapping &fileMapping,
478+
const ClangInvocationFileMappingContext &Context,
476479
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &driverVFS,
477480
bool &requiresBuiltinHeadersInSystemModules) {
478481
const llvm::Triple &Triple = Context.LangOpts.Target;
@@ -611,8 +614,14 @@ void GetWindowsFileMappings(
611614
}
612615
} // namespace
613616

617+
ClangInvocationFileMappingContext::ClangInvocationFileMappingContext(
618+
const swift::ASTContext &Ctx)
619+
: ClangInvocationFileMappingContext(Ctx.LangOpts, Ctx.SearchPathOpts,
620+
Ctx.ClangImporterOpts, Ctx.CASOpts, Ctx.Diags) {}
621+
614622
ClangInvocationFileMapping swift::getClangInvocationFileMapping(
615-
const ASTContext &ctx, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
623+
const ClangInvocationFileMappingContext &ctx,
624+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
616625
bool suppressDiagnostic) {
617626
ClangInvocationFileMapping result;
618627
if (!vfs)
@@ -683,10 +692,11 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
683692
return result;
684693
}
685694

686-
ClangInvocationFileMapping swift::applyClangInvocationMapping(const ASTContext &ctx,
687-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS,
688-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &fileSystem,
689-
bool suppressDiagnostics) {
695+
ClangInvocationFileMapping swift::applyClangInvocationMapping(
696+
const ClangInvocationFileMappingContext &ctx,
697+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS,
698+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &fileSystem,
699+
bool suppressDiagnostics) {
690700
if (ctx.CASOpts.HasImmutableFileSystem)
691701
return ClangInvocationFileMapping();
692702

@@ -715,13 +725,9 @@ ClangInvocationFileMapping swift::applyClangInvocationMapping(const ASTContext &
715725
<< "' with the following contents:\n";
716726
llvm::errs() << file.second << "\n";
717727
}
718-
auto contents = ctx.Allocate<char>(file.second.size() + 1);
719-
std::copy(file.second.begin(), file.second.end(), contents.begin());
720-
// null terminate the buffer.
721-
contents[contents.size() - 1] = '\0';
728+
// Note MemoryBuffer is guaranteeed to be null-terminated.
722729
overridenVFS->addFile(file.first, 0,
723-
llvm::MemoryBuffer::getMemBuffer(StringRef(
724-
contents.begin(), contents.size() - 1)));
730+
llvm::MemoryBuffer::getMemBufferCopy(file.second));
725731
}
726732
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
727733
new llvm::vfs::OverlayFileSystem(fileSystem);

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,6 +1992,14 @@ ModuleDependencyInfo ModuleDependencyScanner::bridgeClangModuleDependency(
19921992
}
19931993
}
19941994

1995+
// Pass the -sdk flag to make the system header VFS overlay finable
1996+
// for the -direct-clang-cc1-module-build emit-pcm command on Windows.
1997+
StringRef SDKPath = ScanASTContext.SearchPathOpts.getSDKPath();
1998+
if (!SDKPath.empty()) {
1999+
swiftArgs.push_back("-sdk");
2000+
swiftArgs.push_back(SDKPath.str());
2001+
}
2002+
19952003
// Add args reported by the scanner.
19962004
auto clangArgs = invocation.getCC1CommandLine();
19972005
llvm::for_each(clangArgs, addClangArg);

lib/Frontend/Frontend.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,25 @@ bool CompilerInstance::setUpVirtualFileSystemOverlays() {
708708
new llvm::vfs::OverlayFileSystem(MemFS);
709709
OverlayVFS->pushOverlay(SourceMgr.getFileSystem());
710710
SourceMgr.setFileSystem(std::move(OverlayVFS));
711+
} else {
712+
// For non-caching -direct-clang-cc1-module-build emit-pcm build,
713+
// setup the clang VFS so it can find system modulemap files
714+
// (like vcruntime.modulemap) as an input file.
715+
if (Invocation.getClangImporterOptions().DirectClangCC1ModuleBuild &&
716+
Invocation.getFrontendOptions().RequestedAction ==
717+
FrontendOptions::ActionType::EmitPCM) {
718+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
719+
SourceMgr.getFileSystem();
720+
ClangInvocationFileMappingContext Context(
721+
Invocation.getLangOptions(), Invocation.getSearchPathOptions(),
722+
Invocation.getClangImporterOptions(), Invocation.getCASOptions(),
723+
Diagnostics);
724+
ClangInvocationFileMapping FileMapping = applyClangInvocationMapping(
725+
Context, nullptr, VFS, /*suppressDiagnostic=*/false);
726+
if (!FileMapping.redirectedFiles.empty()) {
727+
SourceMgr.setFileSystem(std::move(VFS));
728+
}
729+
}
711730
}
712731

713732
auto ExpectedOverlay =
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module SAL [system] {
2+
header "sal.h"
3+
export *
4+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// REQUIRES: OS=windows-msvc
2+
3+
// Test that the -direct-clang-cc1-module-build is able to create a module from the VC runtime with an overlaid modulemap file
4+
5+
// RUN: %empty-directory(%t)
6+
// RUN: split-file %s %t
7+
8+
// RUN: %swift_frontend_plain -target %target-triple -module-cache-path %t/clang-module-cache -scan-dependencies -module-name Test -sdk %S/Inputs/WinSDK %t/Test.swift -o %t/deps.json
9+
// RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json clang:SAL > %t/SAL.cmd
10+
// RUN: %swift_frontend_plain @%t/SAL.cmd
11+
12+
//--- Test.swift
13+
import SAL

0 commit comments

Comments
 (0)