Skip to content

Commit 2f70fc4

Browse files
hjyamauchijunov
authored andcommitted
Fix direct clang cc1 emit-pcm commands with vfs overlay on Windows (swiftlang#85325)
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 5a10be6 commit 2f70fc4

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
@@ -75,6 +75,7 @@ namespace dependencies {
7575
namespace swift {
7676
enum class ResultConvention : uint8_t;
7777
class ASTContext;
78+
class CASOptions;
7879
class CompilerInvocation;
7980
class ClangImporterOptions;
8081
class ClangInheritanceInfo;
@@ -83,6 +84,7 @@ class ClangNode;
8384
class ConcreteDeclRef;
8485
class Decl;
8586
class DeclContext;
87+
class DiagnosticEngine;
8688
class EffectiveClangContext;
8789
class EnumDecl;
8890
class FuncDecl;
@@ -878,22 +880,41 @@ struct ClangInvocationFileMapping {
878880
bool requiresBuiltinHeadersInSystemModules;
879881
};
880882

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

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

lib/ClangImporter/ClangIncludePaths.cpp

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

204204
static SmallVector<std::pair<std::string, std::string>, 2>
205-
getLibcFileMapping(const ASTContext &ctx, StringRef modulemapFileName,
205+
getLibcFileMapping(const ClangInvocationFileMappingContext &ctx,
206+
StringRef modulemapFileName,
206207
std::optional<ArrayRef<StringRef>> maybeHeaderFileNames,
207208
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs,
208209
bool suppressDiagnostic) {
@@ -269,7 +270,8 @@ getLibcFileMapping(const ASTContext &ctx, StringRef modulemapFileName,
269270
}
270271

271272
static void getLibStdCxxFileMapping(
272-
ClangInvocationFileMapping &fileMapping, const ASTContext &ctx,
273+
ClangInvocationFileMapping &fileMapping,
274+
const ClangInvocationFileMappingContext &ctx,
273275
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs,
274276
bool suppressDiagnostic) {
275277
assert(ctx.LangOpts.EnableCXXInterop &&
@@ -475,7 +477,8 @@ GetPlatformAuxiliaryFile(StringRef Platform, StringRef File,
475477
}
476478

477479
void GetWindowsFileMappings(
478-
ClangInvocationFileMapping &fileMapping, const ASTContext &Context,
480+
ClangInvocationFileMapping &fileMapping,
481+
const ClangInvocationFileMappingContext &Context,
479482
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &driverVFS,
480483
bool &requiresBuiltinHeadersInSystemModules) {
481484
const llvm::Triple &Triple = Context.LangOpts.Target;
@@ -615,8 +618,14 @@ void GetWindowsFileMappings(
615618
}
616619
} // namespace
617620

621+
ClangInvocationFileMappingContext::ClangInvocationFileMappingContext(
622+
const swift::ASTContext &Ctx)
623+
: ClangInvocationFileMappingContext(Ctx.LangOpts, Ctx.SearchPathOpts,
624+
Ctx.ClangImporterOpts, Ctx.CASOpts, Ctx.Diags) {}
625+
618626
ClangInvocationFileMapping swift::getClangInvocationFileMapping(
619-
const ASTContext &ctx, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
627+
const ClangInvocationFileMappingContext &ctx,
628+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
620629
bool suppressDiagnostic) {
621630
ClangInvocationFileMapping result;
622631
if (!vfs)
@@ -687,10 +696,11 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
687696
return result;
688697
}
689698

690-
ClangInvocationFileMapping swift::applyClangInvocationMapping(const ASTContext &ctx,
691-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS,
692-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &fileSystem,
693-
bool suppressDiagnostics) {
699+
ClangInvocationFileMapping swift::applyClangInvocationMapping(
700+
const ClangInvocationFileMappingContext &ctx,
701+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS,
702+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &fileSystem,
703+
bool suppressDiagnostics) {
694704
if (ctx.CASOpts.HasImmutableFileSystem)
695705
return ClangInvocationFileMapping();
696706

@@ -719,13 +729,9 @@ ClangInvocationFileMapping swift::applyClangInvocationMapping(const ASTContext &
719729
<< "' with the following contents:\n";
720730
llvm::errs() << file.second << "\n";
721731
}
722-
auto contents = ctx.Allocate<char>(file.second.size() + 1);
723-
std::copy(file.second.begin(), file.second.end(), contents.begin());
724-
// null terminate the buffer.
725-
contents[contents.size() - 1] = '\0';
732+
// Note MemoryBuffer is guaranteeed to be null-terminated.
726733
overridenVFS->addFile(file.first, 0,
727-
llvm::MemoryBuffer::getMemBuffer(StringRef(
728-
contents.begin(), contents.size() - 1)));
734+
llvm::MemoryBuffer::getMemBufferCopy(file.second));
729735
}
730736
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
731737
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
@@ -711,6 +711,25 @@ bool CompilerInstance::setUpVirtualFileSystemOverlays() {
711711
new llvm::vfs::OverlayFileSystem(MemFS);
712712
OverlayVFS->pushOverlay(SourceMgr.getFileSystem());
713713
SourceMgr.setFileSystem(std::move(OverlayVFS));
714+
} else {
715+
// For non-caching -direct-clang-cc1-module-build emit-pcm build,
716+
// setup the clang VFS so it can find system modulemap files
717+
// (like vcruntime.modulemap) as an input file.
718+
if (Invocation.getClangImporterOptions().DirectClangCC1ModuleBuild &&
719+
Invocation.getFrontendOptions().RequestedAction ==
720+
FrontendOptions::ActionType::EmitPCM) {
721+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
722+
SourceMgr.getFileSystem();
723+
ClangInvocationFileMappingContext Context(
724+
Invocation.getLangOptions(), Invocation.getSearchPathOptions(),
725+
Invocation.getClangImporterOptions(), Invocation.getCASOptions(),
726+
Diagnostics);
727+
ClangInvocationFileMapping FileMapping = applyClangInvocationMapping(
728+
Context, nullptr, VFS, /*suppressDiagnostic=*/false);
729+
if (!FileMapping.redirectedFiles.empty()) {
730+
SourceMgr.setFileSystem(std::move(VFS));
731+
}
732+
}
714733
}
715734

716735
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)