Skip to content

Commit ca59242

Browse files
committed
[Dependency Scanning] Add ClangImporter's mandatory path remaps to dependency scanning query filesystem
On creation, 'ClangImporter' adds overlay modulemap files for non-modular platform libraries (e.g. glibc, libstdc++), which allows Swift code to import and use those libraries. This change adds the same filesystem overlay to dependency scanning queries by applying them to the filesystem instantiated for each depndency scanning worker. Without these overlays EBM builds cannot discover and use non-modular system libraries on non-Darwin platforms. Resolves rdar://151780437
1 parent 17d8955 commit ca59242

File tree

7 files changed

+80
-55
lines changed

7 files changed

+80
-55
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,13 +1097,8 @@ class SwiftDependencyScanningService {
10971097
return SwiftDependencyTracker(CAS, Mapper.get(), CI);
10981098
}
10991099

1100-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> getClangScanningFS() const {
1101-
if (CAS)
1102-
return llvm::cas::createCASProvidingFileSystem(
1103-
CAS, llvm::vfs::createPhysicalFileSystem());
1104-
1105-
return llvm::vfs::createPhysicalFileSystem();
1106-
}
1100+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
1101+
getClangScanningFS(ASTContext &ctx) const;
11071102

11081103
bool hasPathMapping() const {
11091104
return Mapper && !Mapper->getMappings().empty();

include/swift/ClangImporter/ClangImporter.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,10 +795,19 @@ struct ClangInvocationFileMapping {
795795
/// `suppressDiagnostic` prevents us from emitting warning messages when we
796796
/// are unable to find headers.
797797
ClangInvocationFileMapping getClangInvocationFileMapping(
798-
ASTContext &ctx,
798+
const ASTContext &ctx,
799799
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs = nullptr,
800800
bool suppressDiagnostic = false);
801801

802+
/// Apply the given file mapping to the specified 'fileSystem', used
803+
/// primarily to inject modulemaps on platforms with non-modularized
804+
/// platform libraries.
805+
ClangInvocationFileMapping applyClangInvocationMapping(
806+
const ASTContext &ctx,
807+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS,
808+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &fileSystem,
809+
bool suppressDiagnostics = false);
810+
802811
/// Information used to compute the access level of inherited C++ members.
803812
class ClangInheritanceInfo {
804813
/// The cumulative inheritance access specifier, that is used to compute the

lib/AST/ModuleDependencies.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,18 @@ SwiftDependencyScanningService::SwiftDependencyScanningService() {
499499
SharedFilesystemCache.emplace();
500500
}
501501

502+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
503+
SwiftDependencyScanningService::getClangScanningFS(ASTContext &ctx) const {
504+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseFileSystem =
505+
llvm::vfs::createPhysicalFileSystem();
506+
ClangInvocationFileMapping fileMapping =
507+
applyClangInvocationMapping(ctx, nullptr, baseFileSystem, false);
508+
509+
if (CAS)
510+
return llvm::cas::createCASProvidingFileSystem(CAS, baseFileSystem);
511+
return baseFileSystem;
512+
}
513+
502514
bool
503515
swift::dependencies::checkImportNotTautological(const ImportPath::Module modulePath,
504516
const SourceLoc importLoc,

lib/ClangImporter/ClangImporter.cpp

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,49 +1324,11 @@ ClangImporter::create(ASTContext &ctx,
13241324
ctx.SourceMgr.getFileSystem();
13251325

13261326
ClangInvocationFileMapping fileMapping =
1327-
getClangInvocationFileMapping(ctx, nullptr, ignoreFileMapping);
1327+
applyClangInvocationMapping(ctx, nullptr, VFS, ignoreFileMapping);
13281328

13291329
importer->requiresBuiltinHeadersInSystemModules =
13301330
fileMapping.requiresBuiltinHeadersInSystemModules;
13311331

1332-
// Avoid creating indirect file system when using include tree.
1333-
if (!ctx.CASOpts.HasImmutableFileSystem) {
1334-
// Wrap Swift's FS to allow Clang to override the working directory
1335-
VFS = llvm::vfs::RedirectingFileSystem::create(
1336-
fileMapping.redirectedFiles, true, *ctx.SourceMgr.getFileSystem());
1337-
if (importerOpts.DumpClangDiagnostics) {
1338-
llvm::errs() << "clang importer redirected file mappings:\n";
1339-
for (const auto &mapping : fileMapping.redirectedFiles) {
1340-
llvm::errs() << " mapping real file '" << mapping.second
1341-
<< "' to virtual file '" << mapping.first << "'\n";
1342-
}
1343-
llvm::errs() << "\n";
1344-
}
1345-
1346-
if (!fileMapping.overridenFiles.empty()) {
1347-
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> overridenVFS =
1348-
new llvm::vfs::InMemoryFileSystem();
1349-
for (const auto &file : fileMapping.overridenFiles) {
1350-
if (importerOpts.DumpClangDiagnostics) {
1351-
llvm::errs() << "clang importer overriding file '" << file.first
1352-
<< "' with the following contents:\n";
1353-
llvm::errs() << file.second << "\n";
1354-
}
1355-
auto contents = ctx.Allocate<char>(file.second.size() + 1);
1356-
std::copy(file.second.begin(), file.second.end(), contents.begin());
1357-
// null terminate the buffer.
1358-
contents[contents.size() - 1] = '\0';
1359-
overridenVFS->addFile(file.first, 0,
1360-
llvm::MemoryBuffer::getMemBuffer(StringRef(
1361-
contents.begin(), contents.size() - 1)));
1362-
}
1363-
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
1364-
new llvm::vfs::OverlayFileSystem(VFS);
1365-
VFS = overlayVFS;
1366-
overlayVFS->pushOverlay(overridenVFS);
1367-
}
1368-
}
1369-
13701332
// Create a new Clang compiler invocation.
13711333
{
13721334
if (auto ClangArgs = importer->getClangCC1Arguments(ctx, VFS))

lib/ClangImporter/ClangIncludePaths.cpp

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ ClangImporter::createClangArgs(const ClangImporterOptions &ClangImporterOpts,
197197
}
198198

199199
static SmallVector<std::pair<std::string, std::string>, 2>
200-
getLibcFileMapping(ASTContext &ctx, StringRef modulemapFileName,
200+
getLibcFileMapping(const ASTContext &ctx, StringRef modulemapFileName,
201201
std::optional<ArrayRef<StringRef>> maybeHeaderFileNames,
202202
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs,
203203
bool suppressDiagnostic) {
@@ -263,7 +263,7 @@ getLibcFileMapping(ASTContext &ctx, StringRef modulemapFileName,
263263
}
264264

265265
static void getLibStdCxxFileMapping(
266-
ClangInvocationFileMapping &fileMapping, ASTContext &ctx,
266+
ClangInvocationFileMapping &fileMapping, const ASTContext &ctx,
267267
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &vfs,
268268
bool suppressDiagnostic) {
269269
assert(ctx.LangOpts.EnableCXXInterop &&
@@ -454,7 +454,7 @@ GetPlatformAuxiliaryFile(StringRef Platform, StringRef File,
454454
}
455455

456456
void GetWindowsFileMappings(
457-
ClangInvocationFileMapping &fileMapping, ASTContext &Context,
457+
ClangInvocationFileMapping &fileMapping, const ASTContext &Context,
458458
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &driverVFS,
459459
bool &requiresBuiltinHeadersInSystemModules) {
460460
const llvm::Triple &Triple = Context.LangOpts.Target;
@@ -585,7 +585,7 @@ void GetWindowsFileMappings(
585585
} // namespace
586586

587587
ClangInvocationFileMapping swift::getClangInvocationFileMapping(
588-
ASTContext &ctx, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
588+
const ASTContext &ctx, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
589589
bool suppressDiagnostic) {
590590
ClangInvocationFileMapping result;
591591
if (!vfs)
@@ -655,3 +655,52 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping(
655655
result.requiresBuiltinHeadersInSystemModules);
656656
return result;
657657
}
658+
659+
ClangInvocationFileMapping swift::applyClangInvocationMapping(const ASTContext &ctx,
660+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS,
661+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &fileSystem,
662+
bool suppressDiagnostics) {
663+
if (ctx.CASOpts.HasImmutableFileSystem)
664+
return ClangInvocationFileMapping();
665+
666+
ClangInvocationFileMapping fileMapping =
667+
getClangInvocationFileMapping(ctx, baseVFS, suppressDiagnostics);
668+
669+
auto importerOpts = ctx.ClangImporterOpts;
670+
// Wrap Swift's FS to allow Clang to override the working directory
671+
fileSystem = llvm::vfs::RedirectingFileSystem::create(
672+
fileMapping.redirectedFiles, true, *fileSystem);
673+
if (importerOpts.DumpClangDiagnostics) {
674+
llvm::errs() << "clang importer redirected file mappings:\n";
675+
for (const auto &mapping : fileMapping.redirectedFiles) {
676+
llvm::errs() << " mapping real file '" << mapping.second
677+
<< "' to virtual file '" << mapping.first << "'\n";
678+
}
679+
llvm::errs() << "\n";
680+
}
681+
682+
if (!fileMapping.overridenFiles.empty()) {
683+
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> overridenVFS =
684+
new llvm::vfs::InMemoryFileSystem();
685+
for (const auto &file : fileMapping.overridenFiles) {
686+
if (importerOpts.DumpClangDiagnostics) {
687+
llvm::errs() << "clang importer overriding file '" << file.first
688+
<< "' with the following contents:\n";
689+
llvm::errs() << file.second << "\n";
690+
}
691+
auto contents = ctx.Allocate<char>(file.second.size() + 1);
692+
std::copy(file.second.begin(), file.second.end(), contents.begin());
693+
// null terminate the buffer.
694+
contents[contents.size() - 1] = '\0';
695+
overridenVFS->addFile(file.first, 0,
696+
llvm::MemoryBuffer::getMemBuffer(StringRef(
697+
contents.begin(), contents.size() - 1)));
698+
}
699+
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
700+
new llvm::vfs::OverlayFileSystem(fileSystem);
701+
fileSystem = overlayVFS;
702+
overlayVFS->pushOverlay(overridenVFS);
703+
}
704+
705+
return fileMapping;
706+
}

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "swift/Frontend/ModuleInterfaceLoader.h"
3232
#include "swift/Serialization/SerializedModuleLoader.h"
3333
#include "swift/Subsystems.h"
34+
#include "clang/Frontend/CompilerInstance.h"
3435
#include "llvm/ADT/IntrusiveRefCntPtr.h"
3536
#include "llvm/ADT/SetOperations.h"
3637
#include "llvm/CAS/CachingOnDiskFileSystem.h"
@@ -267,7 +268,7 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker(
267268
const SILOptions &SILOptions, ASTContext &ScanASTContext,
268269
swift::DependencyTracker &DependencyTracker, DiagnosticEngine &Diagnostics)
269270
: clangScanningTool(*globalScanningService.ClangScanningService,
270-
globalScanningService.getClangScanningFS()) {
271+
globalScanningService.getClangScanningFS(ScanASTContext)) {
271272
// Create a scanner-specific Invocation and ASTContext.
272273
workerCompilerInvocation =
273274
std::make_unique<CompilerInvocation>(ScanCompilerInvocation);

test/ScanDependencies/cxx-overlay-underlying-module-lookup.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
// RUN: %target-swift-frontend -scan-dependencies -o %t/deps.json %s -cxx-interoperability-mode=default -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import
44
// RUN: %validate-json %t/deps.json | %FileCheck %s
55

6-
// rdar://151780437: libstdc++ VFS modulemap redirects not functioning with EBM enabled
7-
// REQUIRES: OS=macosx
8-
96
import CxxStdlib
107

118
// CHECK: "mainModuleName": "deps"

0 commit comments

Comments
 (0)