diff --git a/include/swift/AST/ModuleDependencies.h b/include/swift/AST/ModuleDependencies.h index 1b47cdafea1..86e8071aad3 100644 --- a/include/swift/AST/ModuleDependencies.h +++ b/include/swift/AST/ModuleDependencies.h @@ -1097,13 +1097,8 @@ public: return SwiftDependencyTracker(CAS, Mapper.get(), CI); } - llvm::IntrusiveRefCntPtr getClangScanningFS() const { - if (CAS) - return llvm::cas::createCASProvidingFileSystem( - CAS, llvm::vfs::createPhysicalFileSystem()); - - return llvm::vfs::createPhysicalFileSystem(); - } + llvm::IntrusiveRefCntPtr + getClangScanningFS(ASTContext &ctx) const; bool hasPathMapping() const { return Mapper && !Mapper->getMappings().empty(); diff --git a/include/swift/ClangImporter/ClangImporter.h b/include/swift/ClangImporter/ClangImporter.h index 0862c3c94df..74514879e7b 100644 --- a/include/swift/ClangImporter/ClangImporter.h +++ b/include/swift/ClangImporter/ClangImporter.h @@ -873,10 +873,19 @@ struct ClangInvocationFileMapping { /// `suppressDiagnostic` prevents us from emitting warning messages when we /// are unable to find headers. ClangInvocationFileMapping getClangInvocationFileMapping( - ASTContext &ctx, + const ASTContext &ctx, llvm::IntrusiveRefCntPtr vfs = nullptr, bool suppressDiagnostic = false); +/// Apply the given file mapping to the specified 'fileSystem', used +/// primarily to inject modulemaps on platforms with non-modularized +/// platform libraries. +ClangInvocationFileMapping applyClangInvocationMapping( + const ASTContext &ctx, + llvm::IntrusiveRefCntPtr baseVFS, + llvm::IntrusiveRefCntPtr &fileSystem, + bool suppressDiagnostics = false); + /// Information used to compute the access level of inherited C++ members. class ClangInheritanceInfo { /// The cumulative inheritance access specifier, that is used to compute the diff --git a/lib/AST/ModuleDependencies.cpp b/lib/AST/ModuleDependencies.cpp index 149a85e514e..dbd5e44c65f 100644 --- a/lib/AST/ModuleDependencies.cpp +++ b/lib/AST/ModuleDependencies.cpp @@ -499,6 +499,18 @@ SwiftDependencyScanningService::SwiftDependencyScanningService() { SharedFilesystemCache.emplace(); } +llvm::IntrusiveRefCntPtr +SwiftDependencyScanningService::getClangScanningFS(ASTContext &ctx) const { + llvm::IntrusiveRefCntPtr baseFileSystem = + llvm::vfs::createPhysicalFileSystem(); + ClangInvocationFileMapping fileMapping = + applyClangInvocationMapping(ctx, nullptr, baseFileSystem, false); + + if (CAS) + return llvm::cas::createCASProvidingFileSystem(CAS, baseFileSystem); + return baseFileSystem; +} + bool swift::dependencies::checkImportNotTautological(const ImportPath::Module modulePath, const SourceLoc importLoc, diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 04616e20531..05f382fef9b 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -1300,49 +1300,11 @@ ClangImporter::create(ASTContext &ctx, ctx.SourceMgr.getFileSystem(); ClangInvocationFileMapping fileMapping = - getClangInvocationFileMapping(ctx, nullptr, ignoreFileMapping); + applyClangInvocationMapping(ctx, nullptr, VFS, ignoreFileMapping); importer->requiresBuiltinHeadersInSystemModules = fileMapping.requiresBuiltinHeadersInSystemModules; - // Avoid creating indirect file system when using include tree. - if (!ctx.CASOpts.HasImmutableFileSystem) { - // 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 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(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 overlayVFS = - new llvm::vfs::OverlayFileSystem(VFS); - VFS = overlayVFS; - overlayVFS->pushOverlay(overridenVFS); - } - } - // Create a new Clang compiler invocation. { if (auto ClangArgs = importer->getClangCC1Arguments(ctx, VFS)) diff --git a/lib/ClangImporter/ClangIncludePaths.cpp b/lib/ClangImporter/ClangIncludePaths.cpp index 0bcb3e4e88e..99393334434 100644 --- a/lib/ClangImporter/ClangIncludePaths.cpp +++ b/lib/ClangImporter/ClangIncludePaths.cpp @@ -200,7 +200,7 @@ ClangImporter::createClangArgs(const ClangImporterOptions &ClangImporterOpts, } static SmallVector, 2> -getLibcFileMapping(ASTContext &ctx, StringRef modulemapFileName, +getLibcFileMapping(const ASTContext &ctx, StringRef modulemapFileName, std::optional> maybeHeaderFileNames, const llvm::IntrusiveRefCntPtr &vfs, bool suppressDiagnostic) { @@ -266,7 +266,7 @@ getLibcFileMapping(ASTContext &ctx, StringRef modulemapFileName, } static void getLibStdCxxFileMapping( - ClangInvocationFileMapping &fileMapping, ASTContext &ctx, + ClangInvocationFileMapping &fileMapping, const ASTContext &ctx, const llvm::IntrusiveRefCntPtr &vfs, bool suppressDiagnostic) { assert(ctx.LangOpts.EnableCXXInterop && @@ -457,7 +457,7 @@ GetPlatformAuxiliaryFile(StringRef Platform, StringRef File, } void GetWindowsFileMappings( - ClangInvocationFileMapping &fileMapping, ASTContext &Context, + ClangInvocationFileMapping &fileMapping, const ASTContext &Context, const llvm::IntrusiveRefCntPtr &driverVFS, bool &requiresBuiltinHeadersInSystemModules) { const llvm::Triple &Triple = Context.LangOpts.Target; @@ -588,7 +588,7 @@ void GetWindowsFileMappings( } // namespace ClangInvocationFileMapping swift::getClangInvocationFileMapping( - ASTContext &ctx, llvm::IntrusiveRefCntPtr vfs, + const ASTContext &ctx, llvm::IntrusiveRefCntPtr vfs, bool suppressDiagnostic) { ClangInvocationFileMapping result; if (!vfs) @@ -658,3 +658,52 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping( result.requiresBuiltinHeadersInSystemModules); return result; } + +ClangInvocationFileMapping swift::applyClangInvocationMapping(const ASTContext &ctx, + llvm::IntrusiveRefCntPtr baseVFS, + llvm::IntrusiveRefCntPtr &fileSystem, + bool suppressDiagnostics) { + if (ctx.CASOpts.HasImmutableFileSystem) + return ClangInvocationFileMapping(); + + ClangInvocationFileMapping fileMapping = + getClangInvocationFileMapping(ctx, baseVFS, suppressDiagnostics); + + auto importerOpts = ctx.ClangImporterOpts; + // Wrap Swift's FS to allow Clang to override the working directory + fileSystem = llvm::vfs::RedirectingFileSystem::create( + fileMapping.redirectedFiles, true, *fileSystem); + 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 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(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 overlayVFS = + new llvm::vfs::OverlayFileSystem(fileSystem); + fileSystem = overlayVFS; + overlayVFS->pushOverlay(overridenVFS); + } + + return fileMapping; +} diff --git a/lib/DependencyScan/ModuleDependencyScanner.cpp b/lib/DependencyScan/ModuleDependencyScanner.cpp index 5e0848c7760..b7f7529d881 100644 --- a/lib/DependencyScan/ModuleDependencyScanner.cpp +++ b/lib/DependencyScan/ModuleDependencyScanner.cpp @@ -31,6 +31,7 @@ #include "swift/Frontend/ModuleInterfaceLoader.h" #include "swift/Serialization/SerializedModuleLoader.h" #include "swift/Subsystems.h" +#include "clang/Frontend/CompilerInstance.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/SetOperations.h" #include "llvm/CAS/CachingOnDiskFileSystem.h" @@ -267,7 +268,7 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker( const SILOptions &SILOptions, ASTContext &ScanASTContext, swift::DependencyTracker &DependencyTracker, DiagnosticEngine &Diagnostics) : clangScanningTool(*globalScanningService.ClangScanningService, - globalScanningService.getClangScanningFS()) { + globalScanningService.getClangScanningFS(ScanASTContext)) { // Create a scanner-specific Invocation and ASTContext. workerCompilerInvocation = std::make_unique(ScanCompilerInvocation); diff --git a/test/ScanDependencies/cxx-overlay-underlying-module-lookup.swift b/test/ScanDependencies/cxx-overlay-underlying-module-lookup.swift index 26605cd9747..d509ab559c3 100644 --- a/test/ScanDependencies/cxx-overlay-underlying-module-lookup.swift +++ b/test/ScanDependencies/cxx-overlay-underlying-module-lookup.swift @@ -3,9 +3,6 @@ // 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 // RUN: %validate-json %t/deps.json | %FileCheck %s -// rdar://151780437: libstdc++ VFS modulemap redirects not functioning with EBM enabled -// REQUIRES: OS=macosx - import CxxStdlib // CHECK: "mainModuleName": "deps"