Skip to content

Commit a9e0a58

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 c992957 commit a9e0a58

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
@@ -873,10 +873,19 @@ struct ClangInvocationFileMapping {
873873
/// `suppressDiagnostic` prevents us from emitting warning messages when we
874874
/// are unable to find headers.
875875
ClangInvocationFileMapping getClangInvocationFileMapping(
876-
ASTContext &ctx,
876+
const ASTContext &ctx,
877877
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs = nullptr,
878878
bool suppressDiagnostic = false);
879879

880+
/// Apply the given file mapping to the specified 'fileSystem', used
881+
/// primarily to inject modulemaps on platforms with non-modularized
882+
/// platform libraries.
883+
ClangInvocationFileMapping applyClangInvocationMapping(
884+
const ASTContext &ctx,
885+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseVFS,
886+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &fileSystem,
887+
bool suppressDiagnostics = false);
888+
880889
/// Information used to compute the access level of inherited C++ members.
881890
class ClangInheritanceInfo {
882891
/// 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
@@ -1300,49 +1300,11 @@ ClangImporter::create(ASTContext &ctx,
13001300
ctx.SourceMgr.getFileSystem();
13011301

13021302
ClangInvocationFileMapping fileMapping =
1303-
getClangInvocationFileMapping(ctx, nullptr, ignoreFileMapping);
1303+
applyClangInvocationMapping(ctx, nullptr, VFS, ignoreFileMapping);
13041304

13051305
importer->requiresBuiltinHeadersInSystemModules =
13061306
fileMapping.requiresBuiltinHeadersInSystemModules;
13071307

1308-
// Avoid creating indirect file system when using include tree.
1309-
if (!ctx.CASOpts.HasImmutableFileSystem) {
1310-
// Wrap Swift's FS to allow Clang to override the working directory
1311-
VFS = llvm::vfs::RedirectingFileSystem::create(
1312-
fileMapping.redirectedFiles, true, *ctx.SourceMgr.getFileSystem());
1313-
if (importerOpts.DumpClangDiagnostics) {
1314-
llvm::errs() << "clang importer redirected file mappings:\n";
1315-
for (const auto &mapping : fileMapping.redirectedFiles) {
1316-
llvm::errs() << " mapping real file '" << mapping.second
1317-
<< "' to virtual file '" << mapping.first << "'\n";
1318-
}
1319-
llvm::errs() << "\n";
1320-
}
1321-
1322-
if (!fileMapping.overridenFiles.empty()) {
1323-
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> overridenVFS =
1324-
new llvm::vfs::InMemoryFileSystem();
1325-
for (const auto &file : fileMapping.overridenFiles) {
1326-
if (importerOpts.DumpClangDiagnostics) {
1327-
llvm::errs() << "clang importer overriding file '" << file.first
1328-
<< "' with the following contents:\n";
1329-
llvm::errs() << file.second << "\n";
1330-
}
1331-
auto contents = ctx.Allocate<char>(file.second.size() + 1);
1332-
std::copy(file.second.begin(), file.second.end(), contents.begin());
1333-
// null terminate the buffer.
1334-
contents[contents.size() - 1] = '\0';
1335-
overridenVFS->addFile(file.first, 0,
1336-
llvm::MemoryBuffer::getMemBuffer(StringRef(
1337-
contents.begin(), contents.size() - 1)));
1338-
}
1339-
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayVFS =
1340-
new llvm::vfs::OverlayFileSystem(VFS);
1341-
VFS = overlayVFS;
1342-
overlayVFS->pushOverlay(overridenVFS);
1343-
}
1344-
}
1345-
13461308
// Create a new Clang compiler invocation.
13471309
{
13481310
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)