diff --git a/include/swift/ClangImporter/ClangImporter.h b/include/swift/ClangImporter/ClangImporter.h index 81da1291ff293..8eeaa0303e3a7 100644 --- a/include/swift/ClangImporter/ClangImporter.h +++ b/include/swift/ClangImporter/ClangImporter.h @@ -148,6 +148,17 @@ typedef llvm::PointerUnion ImportDiagnosticTarget; +/// Addition file mapping information for ClangImporter. +struct ClangInvocationFileMapping { + /// Mapping from a file name to an existing file path. + SmallVector, 2> redirectedFiles; + + /// MemoryBuffer that represents the file name and content to overload. + SmallVector, 2> overridenFiles; + + bool requiresBuiltinHeadersInSystemModules = false; +}; + /// Class that imports Clang modules into Swift, mapping directly /// from Clang ASTs over to Swift ASTs. class ClangImporter final : public ClangModuleLoader { @@ -166,7 +177,7 @@ class ClangImporter final : public ClangModuleLoader { private: Implementation &Impl; - bool requiresBuiltinHeadersInSystemModules = false; + ClangInvocationFileMapping clangFileMapping; ClangImporter(ASTContext &ctx, DependencyTracker *tracker, DWARFImporterDelegate *dwarfImporterDelegate); @@ -205,6 +216,14 @@ class ClangImporter final : public ClangModuleLoader { DWARFImporterDelegate *dwarfImporterDelegate = nullptr, bool ignoreFileMapping = false); + static std::string getClangSystemOverlayFile(const SearchPathOptions &Opts); + + static llvm::IntrusiveRefCntPtr + computeClangImporterFileSystem( + const ASTContext &ctx, const ClangInvocationFileMapping &fileMapping, + llvm::IntrusiveRefCntPtr baseFS, + bool suppressDiagnostics = false); + std::vector getClangDriverArguments(ASTContext &ctx, bool ignoreClangTarget = false); @@ -531,6 +550,11 @@ class ClangImporter final : public ClangModuleLoader { std::string getClangModuleHash() const; + /// Get clang file mapping. + const ClangInvocationFileMapping &getClangFileMapping() const { + return clangFileMapping; + } + /// Get clang import creation cc1 args for swift explicit module build. std::vector getSwiftExplicitModuleDirectCC1Args() const; @@ -883,36 +907,6 @@ std::optional getCxxRefConventionWithAttrs(const clang::Decl *decl); } // namespace importer -struct ClangInvocationFileMapping { - /// Mapping from a file name to an existing file path. - SmallVector, 2> redirectedFiles; - - /// Mapping from a file name to a string of characters that represents the - /// contents of the file. - SmallVector, 1> overridenFiles; - - bool requiresBuiltinHeadersInSystemModules; -}; - -class ClangInvocationFileMappingContext { -public: - const LangOptions &LangOpts; - SearchPathOptions &SearchPathOpts; - ClangImporterOptions &ClangImporterOpts; - const CASOptions &CASOpts; - DiagnosticEngine &Diags; - - ClangInvocationFileMappingContext( - const LangOptions &LangOpts, SearchPathOptions &SearchPathOpts, - ClangImporterOptions &ClangImporterOpts, const CASOptions &CASOpts, - DiagnosticEngine &Diags) - : LangOpts(LangOpts), SearchPathOpts(SearchPathOpts), - ClangImporterOpts(ClangImporterOpts), CASOpts(CASOpts), - Diags(Diags) {} - - ClangInvocationFileMappingContext(const swift::ASTContext &Ctx); -}; - /// On Linux, some platform libraries (glibc, libstdc++) are not modularized. /// We inject modulemaps for those libraries into their include directories /// to allow using them from Swift. @@ -920,19 +914,10 @@ class ClangInvocationFileMappingContext { /// `suppressDiagnostic` prevents us from emitting warning messages when we /// are unable to find headers. ClangInvocationFileMapping getClangInvocationFileMapping( - const ClangInvocationFileMappingContext &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 ClangInvocationFileMappingContext &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/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index ba291e66c3db9..880e8590ad20c 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -828,10 +828,9 @@ getEmbedBitcodeInvocationArguments(std::vector &invocationArgStrs, }); } -void -importer::addCommonInvocationArguments( - std::vector &invocationArgStrs, - ASTContext &ctx, bool requiresBuiltinHeadersInSystemModules, +void importer::addCommonInvocationArguments( + std::vector &invocationArgStrs, ASTContext &ctx, + bool requiresBuiltinHeadersInSystemModules, bool needSystemVFSOverlay, bool ignoreClangTarget) { using ImporterImpl = ClangImporter::Implementation; llvm::Triple triple = ctx.LangOpts.Target; @@ -1003,6 +1002,12 @@ importer::addCommonInvocationArguments( invocationArgStrs.push_back("-Xclang"); invocationArgStrs.push_back("-fbuiltin-headers-in-system-modules"); } + + if (needSystemVFSOverlay) { + invocationArgStrs.push_back("-ivfsoverlay"); + invocationArgStrs.push_back( + ClangImporter::getClangSystemOverlayFile(ctx.SearchPathOpts)); + } } bool ClangImporter::canReadPCH(StringRef PCHFilename) { @@ -1151,6 +1156,85 @@ ClangImporter::getOrCreatePCH(const ClangImporterOptions &ImporterOptions, return PCHFilename.value(); } +std::string +ClangImporter::getClangSystemOverlayFile(const SearchPathOptions &Opts) { + llvm::SmallString<256> overlayPath(Opts.RuntimeResourcePath); + llvm::sys::path::append(overlayPath, + Implementation::clangSystemVFSOverlayName); + return overlayPath.str().str(); +} + +llvm::IntrusiveRefCntPtr +ClangImporter::computeClangImporterFileSystem( + const ASTContext &ctx, const ClangInvocationFileMapping &fileMapping, + llvm::IntrusiveRefCntPtr baseFS, + bool suppressDiagnostics) { + // Configure ClangImporter file system. There are two situations: + // * If caching is used, thus file system is immutable, the one immutable file + // system is shared between swift frontend and ClangImporter. + // * Otherwise, ClangImporter file system is configure from scratch from + // VFS in SourceMgr using ivfsoverlay options. + if (ctx.CASOpts.HasImmutableFileSystem) + return baseFS; + + auto importerOpts = ctx.ClangImporterOpts; + auto fileSystem = baseFS; + std::unique_ptr redirectYAMLFile; + if (!fileMapping.redirectedFiles.empty()) { + 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"; + } + // Create a vfs overlay map for all redirects. + llvm::vfs::YAMLVFSWriter vfsWriter; + vfsWriter.setUseExternalNames(true); + for (const auto &mapping : fileMapping.redirectedFiles) + vfsWriter.addFileMapping(mapping.first, mapping.second); + + std::string vfsYAML; + llvm::raw_string_ostream os(vfsYAML); + vfsWriter.write(os); + + redirectYAMLFile = llvm::MemoryBuffer::getMemBufferCopy( + vfsYAML, getClangSystemOverlayFile(ctx.SearchPathOpts)); + } + + if (!fileMapping.overridenFiles.empty() || redirectYAMLFile) { + auto overridenVFS = + llvm::makeIntrusiveRefCnt(); + for (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"; + } + // Note MemoryBuffer is guaranteeed to be null-terminated. + overridenVFS->addFile(file.first, 0, + llvm::MemoryBuffer::getMemBufferCopy(file.second)); + } + if (redirectYAMLFile) { + if (importerOpts.DumpClangDiagnostics) { + llvm::errs() << "clang importer overriding file for redirects'" + << redirectYAMLFile->getBufferIdentifier() + << "' with the following contents:\n"; + llvm::errs() << redirectYAMLFile->getBuffer() << "\n"; + } + std::string yamlFile = redirectYAMLFile->getBufferIdentifier().str(); + overridenVFS->addFile(yamlFile, 0, std::move(redirectYAMLFile)); + } + auto overlayVFS = + llvm::makeIntrusiveRefCnt(fileSystem); + overlayVFS->pushOverlay(std::move(overridenVFS)); + fileSystem = std::move(overlayVFS); + } + + return fileSystem; +} + std::vector ClangImporter::getClangDriverArguments(ASTContext &ctx, bool ignoreClangTarget) { assert(!ctx.ClangImporterOpts.DirectClangCC1ModuleBuild && @@ -1168,8 +1252,10 @@ ClangImporter::getClangDriverArguments(ASTContext &ctx, bool ignoreClangTarget) getEmbedBitcodeInvocationArguments(invocationArgStrs, ctx); break; } - addCommonInvocationArguments(invocationArgStrs, ctx, - requiresBuiltinHeadersInSystemModules, ignoreClangTarget); + addCommonInvocationArguments( + invocationArgStrs, ctx, + clangFileMapping.requiresBuiltinHeadersInSystemModules, + !clangFileMapping.redirectedFiles.empty(), ignoreClangTarget); return invocationArgStrs; } @@ -1235,6 +1321,10 @@ std::optional> ClangImporter::getClangCC1Arguments( CI->getTargetOpts().DarwinTargetVariantTriple = ctx.LangOpts.TargetVariant->str(); } + if (!clangFileMapping.redirectedFiles.empty()) + CI->getHeaderSearchOpts().AddVFSOverlayFile( + getClangSystemOverlayFile(ctx.SearchPathOpts)); + // Forward the index store path. That information is not passed to scanner // and it is cached invariant so we don't want to re-scan if that changed. CI->getFrontendOpts().IndexStorePath = ctx.ClangImporterOpts.IndexStorePath; @@ -1348,18 +1438,16 @@ std::unique_ptr ClangImporter::create( } } - llvm::IntrusiveRefCntPtr VFS = - ctx.SourceMgr.getFileSystem(); - - ClangInvocationFileMapping fileMapping = - applyClangInvocationMapping(ctx, nullptr, VFS, ignoreFileMapping); - - importer->requiresBuiltinHeadersInSystemModules = - fileMapping.requiresBuiltinHeadersInSystemModules; + importer->clangFileMapping = getClangInvocationFileMapping( + ctx, ctx.SourceMgr.getFileSystem(), ignoreFileMapping); + llvm::IntrusiveRefCntPtr vfs = + computeClangImporterFileSystem(ctx, importer->clangFileMapping, + ctx.SourceMgr.getFileSystem(), + ignoreFileMapping); // Create a new Clang compiler invocation. { - if (auto ClangArgs = importer->getClangCC1Arguments(ctx, VFS)) + if (auto ClangArgs = importer->getClangCC1Arguments(ctx, vfs)) importer->Impl.ClangArgs = *ClangArgs; else return nullptr; @@ -1373,7 +1461,7 @@ std::unique_ptr ClangImporter::create( llvm::errs() << "'\n"; } importer->Impl.Invocation = createClangInvocation( - importer.get(), importerOpts, VFS, importer->Impl.ClangArgs); + importer.get(), importerOpts, vfs, importer->Impl.ClangArgs); if (!importer->Impl.Invocation) return nullptr; } @@ -1424,7 +1512,7 @@ std::unique_ptr ClangImporter::create( auto actualDiagClient = std::make_unique( importer->Impl, instance.getDiagnosticOpts(), importerOpts.DumpClangDiagnostics); - instance.createVirtualFileSystem(std::move(VFS), actualDiagClient.get()); + instance.createVirtualFileSystem(std::move(vfs), actualDiagClient.get()); instance.createFileManager(); instance.createDiagnostics(actualDiagClient.release()); diff --git a/lib/ClangImporter/ClangIncludePaths.cpp b/lib/ClangImporter/ClangIncludePaths.cpp index 1f25e1d2657a6..810cf76be0105 100644 --- a/lib/ClangImporter/ClangIncludePaths.cpp +++ b/lib/ClangImporter/ClangIncludePaths.cpp @@ -202,8 +202,7 @@ ClangImporter::createClangArgs(const ClangImporterOptions &ClangImporterOpts, } static SmallVector, 2> -getLibcFileMapping(const ClangInvocationFileMappingContext &ctx, - StringRef modulemapFileName, +getLibcFileMapping(const ASTContext &ctx, StringRef modulemapFileName, std::optional> maybeHeaderFileNames, const llvm::IntrusiveRefCntPtr &vfs, bool suppressDiagnostic) { @@ -270,8 +269,7 @@ getLibcFileMapping(const ClangInvocationFileMappingContext &ctx, } static void getLibStdCxxFileMapping( - ClangInvocationFileMapping &fileMapping, - const ClangInvocationFileMappingContext &ctx, + ClangInvocationFileMapping &fileMapping, const ASTContext &ctx, const llvm::IntrusiveRefCntPtr &vfs, bool suppressDiagnostic) { assert(ctx.LangOpts.EnableCXXInterop && @@ -450,26 +448,27 @@ static void getLibStdCxxFileMapping( includeHeaderInModuleMap(additionalFile); os << contents.substr(headerInjectionPoint); - fileMapping.overridenFiles.push_back( - {std::string(injectedModuleMapPath), std::move(os.str())}); + fileMapping.overridenFiles.emplace_back( + std::string(injectedModuleMapPath), + std::move(additionalHeaderDirectives)); } namespace { -std::string -GetPlatformAuxiliaryFile(StringRef Platform, StringRef File, - const SearchPathOptions &Options) { +std::string GetPlatformAuxiliaryFile(StringRef Platform, StringRef File, + llvm::vfs::FileSystem &VFS, + const SearchPathOptions &Options) { StringRef SDKPath = Options.getSDKPath(); if (!SDKPath.empty()) { llvm::SmallString<261> path{SDKPath}; llvm::sys::path::append(path, "usr", "share", File); - if (llvm::sys::fs::exists(path)) + if (VFS.exists(path)) return path.str().str(); } if (!Options.RuntimeResourcePath.empty()) { llvm::SmallString<261> path{Options.RuntimeResourcePath}; llvm::sys::path::append(path, Platform, File); - if (llvm::sys::fs::exists(path)) + if (VFS.exists(path)) return path.str().str(); } @@ -477,8 +476,7 @@ GetPlatformAuxiliaryFile(StringRef Platform, StringRef File, } void GetWindowsFileMappings( - ClangInvocationFileMapping &fileMapping, - const ClangInvocationFileMappingContext &Context, + ClangInvocationFileMapping &fileMapping, const ASTContext &Context, const llvm::IntrusiveRefCntPtr &driverVFS, bool &requiresBuiltinHeadersInSystemModules) { const llvm::Triple &Triple = Context.LangOpts.Target; @@ -514,7 +512,7 @@ void GetWindowsFileMappings( llvm::sys::path::append(WinSDKInjection, "module.modulemap"); AuxiliaryFile = GetPlatformAuxiliaryFile("windows", "winsdk_um.modulemap", - SearchPathOpts); + VFS, SearchPathOpts); if (!AuxiliaryFile.empty()) fileMapping.redirectedFiles.emplace_back(std::string(WinSDKInjection), AuxiliaryFile); @@ -523,7 +521,7 @@ void GetWindowsFileMappings( llvm::sys::path::remove_filename(WinSDKInjection); llvm::sys::path::append(WinSDKInjection, "shared", "module.modulemap"); AuxiliaryFile = GetPlatformAuxiliaryFile( - "windows", "winsdk_shared.modulemap", SearchPathOpts); + "windows", "winsdk_shared.modulemap", VFS, SearchPathOpts); if (!AuxiliaryFile.empty()) fileMapping.redirectedFiles.emplace_back(std::string(WinSDKInjection), AuxiliaryFile); @@ -540,8 +538,8 @@ void GetWindowsFileMappings( llvm::sys::path::append(UCRTInjection, "Include", UCRTSDK.Version, "ucrt"); llvm::sys::path::append(UCRTInjection, "module.modulemap"); - AuxiliaryFile = - GetPlatformAuxiliaryFile("windows", "ucrt.modulemap", SearchPathOpts); + AuxiliaryFile = GetPlatformAuxiliaryFile("windows", "ucrt.modulemap", VFS, + SearchPathOpts); if (!AuxiliaryFile.empty()) { // The ucrt module map has the C standard library headers all together. // That leads to module cycles with the clang _Builtin_ modules. e.g. @@ -578,18 +576,16 @@ void GetWindowsFileMappings( llvm::sys::path::append(VCToolsInjection, "include"); llvm::sys::path::append(VCToolsInjection, "module.modulemap"); - AuxiliaryFile = - GetPlatformAuxiliaryFile("windows", "vcruntime.modulemap", - SearchPathOpts); + AuxiliaryFile = GetPlatformAuxiliaryFile("windows", "vcruntime.modulemap", + VFS, SearchPathOpts); if (!AuxiliaryFile.empty()) fileMapping.redirectedFiles.emplace_back(std::string(VCToolsInjection), AuxiliaryFile); llvm::sys::path::remove_filename(VCToolsInjection); llvm::sys::path::append(VCToolsInjection, "vcruntime.apinotes"); - AuxiliaryFile = - GetPlatformAuxiliaryFile("windows", "vcruntime.apinotes", - SearchPathOpts); + AuxiliaryFile = GetPlatformAuxiliaryFile("windows", "vcruntime.apinotes", + VFS, SearchPathOpts); if (!AuxiliaryFile.empty()) fileMapping.redirectedFiles.emplace_back(std::string(VCToolsInjection), AuxiliaryFile); @@ -610,23 +606,16 @@ void GetWindowsFileMappings( for (const char * const header : kInjectedHeaders) { llvm::sys::path::remove_filename(VCToolsInjection); llvm::sys::path::append(VCToolsInjection, header); - if (!llvm::sys::fs::exists(VCToolsInjection)) - fileMapping.overridenFiles.emplace_back(std::string{VCToolsInjection}, - ""); + if (!VFS.exists(VCToolsInjection)) + fileMapping.overridenFiles.emplace_back(VCToolsInjection, ""); } } } } // namespace -ClangInvocationFileMappingContext::ClangInvocationFileMappingContext( - const swift::ASTContext &Ctx) - : ClangInvocationFileMappingContext(Ctx.LangOpts, Ctx.SearchPathOpts, - Ctx.ClangImporterOpts, Ctx.CASOpts, Ctx.Diags) {} - ClangInvocationFileMapping swift::getClangInvocationFileMapping( - const ClangInvocationFileMappingContext &ctx, - llvm::IntrusiveRefCntPtr vfs, - bool suppressDiagnostic) { + const ASTContext &ctx, llvm::IntrusiveRefCntPtr vfs, + bool suppressDiagnostic) { ClangInvocationFileMapping result; if (!vfs) vfs = llvm::vfs::getRealFileSystem(); @@ -693,51 +682,6 @@ ClangInvocationFileMapping swift::getClangInvocationFileMapping( GetWindowsFileMappings(result, ctx, vfs, result.requiresBuiltinHeadersInSystemModules); - return result; -} - -ClangInvocationFileMapping swift::applyClangInvocationMapping( - const ClangInvocationFileMappingContext &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"; - } - // Note MemoryBuffer is guaranteeed to be null-terminated. - overridenVFS->addFile(file.first, 0, - llvm::MemoryBuffer::getMemBufferCopy(file.second)); - } - llvm::IntrusiveRefCntPtr overlayVFS = - new llvm::vfs::OverlayFileSystem(fileSystem); - fileSystem = overlayVFS; - overlayVFS->pushOverlay(overridenVFS); - } - - return fileMapping; + return result; } diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h index ab596c6359299..c1bc5a0b114d6 100644 --- a/lib/ClangImporter/ImporterImpl.h +++ b/lib/ClangImporter/ImporterImpl.h @@ -490,10 +490,13 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation const Version CurrentVersion; - constexpr static const char * const moduleImportBufferName = - ""; - constexpr static const char * const bridgingHeaderBufferName = - ""; + constexpr static const char *const moduleImportBufferName = + ""; + constexpr static const char *const bridgingHeaderBufferName = + ""; + /// The name of system vfsoverlay. + constexpr static const char *const clangSystemVFSOverlayName = + ""; private: DiagnosticWalker Walker; @@ -2012,6 +2015,7 @@ void getNormalInvocationArguments(std::vector &invocationArgStrs, void addCommonInvocationArguments(std::vector &invocationArgStrs, ASTContext &ctx, bool requiresBuiltinHeadersInSystemModules, + bool needSystemVFSOverlay, bool ignoreClangTarget); /// Finds a particular kind of nominal by looking through typealiases. diff --git a/lib/DependencyScan/ModuleDependencyScanner.cpp b/lib/DependencyScan/ModuleDependencyScanner.cpp index 6d492ae752e89..f84e82d801535 100644 --- a/lib/DependencyScan/ModuleDependencyScanner.cpp +++ b/lib/DependencyScan/ModuleDependencyScanner.cpp @@ -196,14 +196,15 @@ static std::vector inputSpecificClangScannerCommand( static llvm::IntrusiveRefCntPtr getClangScanningFS(std::shared_ptr cas, ASTContext &ctx) { - llvm::IntrusiveRefCntPtr baseFileSystem = - llvm::vfs::createPhysicalFileSystem(); - ClangInvocationFileMapping fileMapping = - applyClangInvocationMapping(ctx, nullptr, baseFileSystem, false); + auto *importer = static_cast(ctx.getClangModuleLoader()); + // Dependency scanner needs to create its own file system per worker. + auto fs = ClangImporter::computeClangImporterFileSystem( + ctx, importer->getClangFileMapping(), + llvm::vfs::createPhysicalFileSystem(), true); if (cas) - return llvm::cas::createCASProvidingFileSystem(cas, baseFileSystem); - return baseFileSystem; + return llvm::cas::createCASProvidingFileSystem(cas, fs); + return fs; } ModuleDependencyScanningWorker::ModuleDependencyScanningWorker( @@ -2038,10 +2039,16 @@ ModuleDependencyInfo ModuleDependencyScanner::bridgeClangModuleDependency( invocation.getMutCASOpts() = clang::CASOptions(); invocation.getMutFrontendOpts().CASIncludeTreeID.clear(); - // FIXME: workaround for rdar://105684525: find the -ivfsoverlay option - // from clang scanner and pass to swift. if (!ScanASTContext.CASOpts.EnableCaching) { auto &overlayFiles = invocation.getMutHeaderSearchOpts().VFSOverlayFiles; + + // clang system overlay file is a virtual file that is not an actual file. + auto clangSystemOverlayFile = + ClangImporter::getClangSystemOverlayFile(ScanASTContext.SearchPathOpts); + llvm::erase(overlayFiles, clangSystemOverlayFile); + + // FIXME: workaround for rdar://105684525: find the -ivfsoverlay option + // from clang scanner and pass to swift. for (auto overlay : overlayFiles) { swiftArgs.push_back("-vfsoverlay"); swiftArgs.push_back(overlay); diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 4fb3c0e114ea0..178b3f1356808 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -711,25 +711,6 @@ bool CompilerInstance::setUpVirtualFileSystemOverlays() { new llvm::vfs::OverlayFileSystem(MemFS); OverlayVFS->pushOverlay(SourceMgr.getFileSystem()); SourceMgr.setFileSystem(std::move(OverlayVFS)); - } else { - // For non-caching -direct-clang-cc1-module-build emit-pcm build, - // setup the clang VFS so it can find system modulemap files - // (like vcruntime.modulemap) as an input file. - if (Invocation.getClangImporterOptions().DirectClangCC1ModuleBuild && - Invocation.getFrontendOptions().RequestedAction == - FrontendOptions::ActionType::EmitPCM) { - llvm::IntrusiveRefCntPtr VFS = - SourceMgr.getFileSystem(); - ClangInvocationFileMappingContext Context( - Invocation.getLangOptions(), Invocation.getSearchPathOptions(), - Invocation.getClangImporterOptions(), Invocation.getCASOptions(), - Diagnostics); - ClangInvocationFileMapping FileMapping = applyClangInvocationMapping( - Context, nullptr, VFS, /*suppressDiagnostic=*/false); - if (!FileMapping.redirectedFiles.empty()) { - SourceMgr.setFileSystem(std::move(VFS)); - } - } } auto ExpectedOverlay = @@ -991,10 +972,10 @@ std::string CompilerInstance::getBridgingHeaderPath() const { } bool CompilerInstance::setUpInputs() { - // There is no input file when building PCM using Caching. + // There is no need to setup input when emit PCM. Let ClangImporter and the + // underlying clang CompilerInstance to handle inputs. if (Invocation.getFrontendOptions().RequestedAction == - FrontendOptions::ActionType::EmitPCM && - Invocation.getCASOptions().EnableCaching) + FrontendOptions::ActionType::EmitPCM) return false; // Adds to InputSourceCodeBufferIDs, so may need to happen before the diff --git a/test/ClangImporter/print-module-map-paths.swift b/test/ClangImporter/print-module-map-paths.swift index d5fac537f2679..20966ce6e2b1e 100644 --- a/test/ClangImporter/print-module-map-paths.swift +++ b/test/ClangImporter/print-module-map-paths.swift @@ -28,11 +28,13 @@ // RUN: cp %S/../../stdlib/public/Cxx/cxxshim/libcxxshim.modulemap %t/sdk/usr/lib/swift/android // RUN: %swift %s -typecheck -parse-stdlib -dump-clang-diagnostics -target aarch64-unknown-linux-android -sdk %t/sdk -resource-dir %t/resources -cxx-interoperability-mode=default 2>&1 | %FileCheck -check-prefix=CHECK-ANDROID-CXX %s +// CHECK-macosx-CXX-NOT: clang importer redirected file mappings: + // CHECK-LINUX: clang importer redirected file mappings: // CHECK-LINUX-NEXT: mapping real file '{{.*}}{{/|\\}}resources{{/|\\}}linux{{/|\\}}armv7{{/|\\}}glibc.modulemap' to virtual file '{{.*}}{{/|\\}}sdk{{/|\\}}usr{{/|\\}}include{{/|\\}}module.modulemap' // CHECK-LINUX-NEXT: mapping real file '{{.*}}{{/|\\}}resources{{/|\\}}linux{{/|\\}}armv7{{/|\\}}SwiftGlibc.h' to virtual file '{{.*}}{{/|\\}}sdk{{/|\\}}usr{{/|\\}}include{{/|\\}}SwiftGlibc.h' -// CHECK-CXX: clang importer redirected file mappings: +// CHECK-linux-gnu-CXX: clang importer redirected file mappings: // CHECK-linux-gnu-CXX: mapping real file '{{.*}}/resources/linux/libstdcxx.h' to virtual file '{{.*}}/usr/include/c++/{{.*}}/libstdcxx.h' // CHECK-linux-gnu-CXX: clang importer overriding file '{{.*}}/usr/include/c++/{{.*}}/module.modulemap' with the following contents: // CHECK-linux-gnu-CXX-NEXT: --- libstdcxx.modulemap --- @@ -46,4 +48,8 @@ // CHECK-ANDROID-NEXT: mapping real file '{{.*}}{{/|\\}}resources{{/|\\}}android{{/|\\}}aarch64{{/|\\}}SwiftAndroidNDK.h' to virtual file '{{.*}}{{/|\\}}sdk{{/|\\}}usr{{/|\\}}include{{/|\\}}SwiftAndroidNDK.h' // CHECK-ANDROID-NEXT: mapping real file '{{.*}}{{/|\\}}resources{{/|\\}}android{{/|\\}}aarch64{{/|\\}}SwiftBionic.h' to virtual file '{{.*}}{{/|\\}}sdk{{/|\\}}usr{{/|\\}}include{{/|\\}}SwiftBionic.h' +// CHECK-windows-msvc-CXX: clang importer file mappings: + // CHECK-ANDROID-CXX: clang importer driver args: {{.*}}'-fmodule-map-file={{.*}}resources{{/|\\}}android{{/|\\}}libcxxshim.modulemap' + +// CHECK-CXX: clang importer cc1 args: