Skip to content

[scanner] setup the clang importer injected redirecting overlay vfs f… #78184

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/swift/ClangImporter/ClangImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,14 @@ ClangInvocationFileMapping getClangInvocationFileMapping(
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs = nullptr,
bool suppressDiagnostic = false);

/// Construct the clang overlay VFS that's needed for the clang instance
/// used by the clang importer to find injected platform-specific modulemaps
/// that are created by `getClangInvocationFileMapping`.
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
createClangInvocationFileMappingVFS(
const ClangInvocationFileMapping &fileMapping, ASTContext &ctx,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS);

} // end namespace swift

#endif
35 changes: 2 additions & 33 deletions lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1333,39 +1333,8 @@ ClangImporter::create(ASTContext &ctx,
// Avoid creating indirect file system when using include tree.
if (!ctx.ClangImporterOpts.HasClangIncludeTreeRoot) {
// Wrap Swift's FS to allow Clang to override the working directory
VFS = llvm::vfs::RedirectingFileSystem::create(
fileMapping.redirectedFiles, true, *ctx.SourceMgr.getFileSystem());
if (importerOpts.DumpClangDiagnostics) {
llvm::errs() << "clang importer redirected file mappings:\n";
for (const auto &mapping : fileMapping.redirectedFiles) {
llvm::errs() << " mapping real file '" << mapping.second
<< "' to virtual file '" << mapping.first << "'\n";
}
llvm::errs() << "\n";
}

if (!fileMapping.overridenFiles.empty()) {
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> overridenVFS =
new llvm::vfs::InMemoryFileSystem();
for (const auto &file : fileMapping.overridenFiles) {
if (importerOpts.DumpClangDiagnostics) {
llvm::errs() << "clang importer overriding file '" << file.first
<< "' with the following contents:\n";
llvm::errs() << file.second << "\n";
}
auto contents = ctx.Allocate<char>(file.second.size() + 1);
std::copy(file.second.begin(), file.second.end(), contents.begin());
// null terminate the buffer.
contents[contents.size() - 1] = '\0';
overridenVFS->addFile(file.first, 0,
llvm::MemoryBuffer::getMemBuffer(StringRef(
contents.begin(), contents.size() - 1)));
}
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
new llvm::vfs::OverlayFileSystem(VFS);
VFS = overlayVFS;
overlayVFS->pushOverlay(overridenVFS);
}
VFS = createClangInvocationFileMappingVFS(fileMapping, ctx,
ctx.SourceMgr.getFileSystem());
}

// Create a new Clang compiler invocation.
Expand Down
40 changes: 40 additions & 0 deletions lib/ClangImporter/ClangIncludePaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -655,3 +655,43 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
result.requiresBuiltinHeadersInSystemModules);
return result;
}

llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
swift::createClangInvocationFileMappingVFS(
const ClangInvocationFileMapping &fileMapping, ASTContext &ctx,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS) {
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> redirectedVFS =
llvm::vfs::RedirectingFileSystem::create(fileMapping.redirectedFiles,
true, *baseVFS);
if (ctx.ClangImporterOpts.DumpClangDiagnostics) {
llvm::errs() << "clang importer redirected file mappings:\n";
for (const auto &mapping : fileMapping.redirectedFiles) {
llvm::errs() << " mapping real file '" << mapping.second
<< "' to virtual file '" << mapping.first << "'\n";
}
llvm::errs() << "\n";
}

if (fileMapping.overridenFiles.empty())
return redirectedVFS;
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> overridenVFS =
new llvm::vfs::InMemoryFileSystem();
for (const auto &file : fileMapping.overridenFiles) {
if (ctx.ClangImporterOpts.DumpClangDiagnostics) {
llvm::errs() << "clang importer overriding file '" << file.first
<< "' with the following contents:\n";
llvm::errs() << file.second << "\n";
}
auto contents = ctx.Allocate<char>(file.second.size() + 1);
std::copy(file.second.begin(), file.second.end(), contents.begin());
// null terminate the buffer.
contents[contents.size() - 1] = '\0';
overridenVFS->addFile(file.first, 0,
llvm::MemoryBuffer::getMemBuffer(StringRef(
contents.begin(), contents.size() - 1)));
}
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
new llvm::vfs::OverlayFileSystem(redirectedVFS);
overlayVFS->pushOverlay(overridenVFS);
return overlayVFS;
}
16 changes: 14 additions & 2 deletions lib/DependencyScan/ModuleDependencyScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,13 +179,25 @@ static bool isSwiftDependencyKind(ModuleDependencyKind Kind) {
Kind == ModuleDependencyKind::SwiftPlaceholder;
}

static llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
getClangInvocationOverlayScanningVFS(
ASTContext &ctx, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseFS) {
auto fileMapping = swift::getClangInvocationFileMapping(
ctx, baseFS, /*suppressDiagnostic=*/true);
if (fileMapping.redirectedFiles.empty())
return baseFS;
return createClangInvocationFileMappingVFS(fileMapping, ctx, baseFS);
}

ModuleDependencyScanningWorker::ModuleDependencyScanningWorker(
SwiftDependencyScanningService &globalScanningService,
const CompilerInvocation &ScanCompilerInvocation,
const SILOptions &SILOptions, ASTContext &ScanASTContext,
swift::DependencyTracker &DependencyTracker, DiagnosticEngine &Diagnostics)
: clangScanningTool(*globalScanningService.ClangScanningService,
globalScanningService.getClangScanningFS()) {
: clangScanningTool(
*globalScanningService.ClangScanningService,
getClangInvocationOverlayScanningVFS(
ScanASTContext, globalScanningService.getClangScanningFS())) {
// Create a scanner-specific Invocation and ASTContext.
workerCompilerInvocation =
std::make_unique<CompilerInvocation>(ScanCompilerInvocation);
Expand Down
11 changes: 11 additions & 0 deletions test/ScanDependencies/win-crt.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -scan-dependencies -Xcc -v %s -o - | %validate-json | %FileCheck %s

// We want to explicitly import WinSDK's CRT.
// REQUIRES: OS=windows-msvc

import CRT

// CHECK: "modulePath": "{{.*}}\\ucrt-{{.*}}.pcm",
// CHECK-NEXT: "sourceFiles": [
// CHECK-NEXT: "{{.*}}\\ucrt\\module.modulemap"