Skip to content

Commit 8237e1b

Browse files
committed
[scanner] setup the clang importer injected redirecting overlay vfs for correct clang dependency scanning
This makes its possible to use -explicit-module-build to correctly find 'crt' swift module on windows
1 parent 71dfdcf commit 8237e1b

File tree

5 files changed

+75
-35
lines changed

5 files changed

+75
-35
lines changed

include/swift/ClangImporter/ClangImporter.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,14 @@ ClangInvocationFileMapping getClangInvocationFileMapping(
767767
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs = nullptr,
768768
bool suppressDiagnostic = false);
769769

770+
/// Construct the clang overlay VFS that's needed for the clang instance
771+
/// used by the clang importer to find injected platform-specific modulemaps
772+
/// that are created by `getClangInvocationFileMapping`.
773+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
774+
createClangInvocationFileMappingVFS(
775+
const ClangInvocationFileMapping &fileMapping, ASTContext &ctx,
776+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS);
777+
770778
} // end namespace swift
771779

772780
#endif

lib/ClangImporter/ClangImporter.cpp

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,39 +1333,8 @@ ClangImporter::create(ASTContext &ctx,
13331333
// Avoid creating indirect file system when using include tree.
13341334
if (!ctx.ClangImporterOpts.HasClangIncludeTreeRoot) {
13351335
// Wrap Swift's FS to allow Clang to override the working directory
1336-
VFS = llvm::vfs::RedirectingFileSystem::create(
1337-
fileMapping.redirectedFiles, true, *ctx.SourceMgr.getFileSystem());
1338-
if (importerOpts.DumpClangDiagnostics) {
1339-
llvm::errs() << "clang importer redirected file mappings:\n";
1340-
for (const auto &mapping : fileMapping.redirectedFiles) {
1341-
llvm::errs() << " mapping real file '" << mapping.second
1342-
<< "' to virtual file '" << mapping.first << "'\n";
1343-
}
1344-
llvm::errs() << "\n";
1345-
}
1346-
1347-
if (!fileMapping.overridenFiles.empty()) {
1348-
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> overridenVFS =
1349-
new llvm::vfs::InMemoryFileSystem();
1350-
for (const auto &file : fileMapping.overridenFiles) {
1351-
if (importerOpts.DumpClangDiagnostics) {
1352-
llvm::errs() << "clang importer overriding file '" << file.first
1353-
<< "' with the following contents:\n";
1354-
llvm::errs() << file.second << "\n";
1355-
}
1356-
auto contents = ctx.Allocate<char>(file.second.size() + 1);
1357-
std::copy(file.second.begin(), file.second.end(), contents.begin());
1358-
// null terminate the buffer.
1359-
contents[contents.size() - 1] = '\0';
1360-
overridenVFS->addFile(file.first, 0,
1361-
llvm::MemoryBuffer::getMemBuffer(StringRef(
1362-
contents.begin(), contents.size() - 1)));
1363-
}
1364-
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
1365-
new llvm::vfs::OverlayFileSystem(VFS);
1366-
VFS = overlayVFS;
1367-
overlayVFS->pushOverlay(overridenVFS);
1368-
}
1336+
VFS = createClangInvocationFileMappingVFS(fileMapping, ctx,
1337+
ctx.SourceMgr.getFileSystem());
13691338
}
13701339

13711340
// Create a new Clang compiler invocation.

lib/ClangImporter/ClangIncludePaths.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,3 +655,43 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
655655
result.requiresBuiltinHeadersInSystemModules);
656656
return result;
657657
}
658+
659+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
660+
swift::createClangInvocationFileMappingVFS(
661+
const ClangInvocationFileMapping &fileMapping, ASTContext &ctx,
662+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS) {
663+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> redirectedVFS =
664+
llvm::vfs::RedirectingFileSystem::create(fileMapping.redirectedFiles,
665+
true, *baseVFS);
666+
if (ctx.ClangImporterOpts.DumpClangDiagnostics) {
667+
llvm::errs() << "clang importer redirected file mappings:\n";
668+
for (const auto &mapping : fileMapping.redirectedFiles) {
669+
llvm::errs() << " mapping real file '" << mapping.second
670+
<< "' to virtual file '" << mapping.first << "'\n";
671+
}
672+
llvm::errs() << "\n";
673+
}
674+
675+
if (fileMapping.overridenFiles.empty())
676+
return redirectedVFS;
677+
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> overridenVFS =
678+
new llvm::vfs::InMemoryFileSystem();
679+
for (const auto &file : fileMapping.overridenFiles) {
680+
if (ctx.ClangImporterOpts.DumpClangDiagnostics) {
681+
llvm::errs() << "clang importer overriding file '" << file.first
682+
<< "' with the following contents:\n";
683+
llvm::errs() << file.second << "\n";
684+
}
685+
auto contents = ctx.Allocate<char>(file.second.size() + 1);
686+
std::copy(file.second.begin(), file.second.end(), contents.begin());
687+
// null terminate the buffer.
688+
contents[contents.size() - 1] = '\0';
689+
overridenVFS->addFile(file.first, 0,
690+
llvm::MemoryBuffer::getMemBuffer(StringRef(
691+
contents.begin(), contents.size() - 1)));
692+
}
693+
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
694+
new llvm::vfs::OverlayFileSystem(redirectedVFS);
695+
overlayVFS->pushOverlay(overridenVFS);
696+
return overlayVFS;
697+
}

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,25 @@ static bool isSwiftDependencyKind(ModuleDependencyKind Kind) {
179179
Kind == ModuleDependencyKind::SwiftPlaceholder;
180180
}
181181

182+
static llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
183+
getClangInvocationOverlayScanningVFS(
184+
ASTContext &ctx, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseFS) {
185+
auto fileMapping = swift::getClangInvocationFileMapping(
186+
ctx, baseFS, /*suppressDiagnostic=*/true);
187+
if (fileMapping.redirectedFiles.empty())
188+
return baseFS;
189+
return createClangInvocationFileMappingVFS(fileMapping, ctx, baseFS);
190+
}
191+
182192
ModuleDependencyScanningWorker::ModuleDependencyScanningWorker(
183193
SwiftDependencyScanningService &globalScanningService,
184194
const CompilerInvocation &ScanCompilerInvocation,
185195
const SILOptions &SILOptions, ASTContext &ScanASTContext,
186196
swift::DependencyTracker &DependencyTracker, DiagnosticEngine &Diagnostics)
187-
: clangScanningTool(*globalScanningService.ClangScanningService,
188-
globalScanningService.getClangScanningFS()) {
197+
: clangScanningTool(
198+
*globalScanningService.ClangScanningService,
199+
getClangInvocationOverlayScanningVFS(
200+
ScanASTContext, globalScanningService.getClangScanningFS())) {
189201
// Create a scanner-specific Invocation and ASTContext.
190202
workerCompilerInvocation =
191203
std::make_unique<CompilerInvocation>(ScanCompilerInvocation);

test/ScanDependencies/win-crt.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -scan-dependencies -Xcc -v %s -o - | %validate-json | %FileCheck %s
3+
4+
// We want to explicitly import WinSDK's CRT.
5+
// REQUIRES: OS=windows-msvc
6+
7+
import CRT
8+
9+
// CHECK: "modulePath": "{{.*}}\\ucrt-{{.*}}.pcm",
10+
// CHECK-NEXT: "sourceFiles": [
11+
// CHECK-NEXT: "{{.*}}\\ucrt\\module.modulemap"

0 commit comments

Comments
 (0)