@@ -828,10 +828,9 @@ getEmbedBitcodeInvocationArguments(std::vector<std::string> &invocationArgStrs,
828828 });
829829}
830830
831- void
832- importer::addCommonInvocationArguments (
833- std::vector<std::string> &invocationArgStrs,
834- ASTContext &ctx, bool requiresBuiltinHeadersInSystemModules,
831+ void importer::addCommonInvocationArguments (
832+ std::vector<std::string> &invocationArgStrs, ASTContext &ctx,
833+ bool requiresBuiltinHeadersInSystemModules, bool needSystemVFSOverlay,
835834 bool ignoreClangTarget) {
836835 using ImporterImpl = ClangImporter::Implementation;
837836 llvm::Triple triple = ctx.LangOpts .Target ;
@@ -1003,6 +1002,12 @@ importer::addCommonInvocationArguments(
10031002 invocationArgStrs.push_back (" -Xclang" );
10041003 invocationArgStrs.push_back (" -fbuiltin-headers-in-system-modules" );
10051004 }
1005+
1006+ if (needSystemVFSOverlay) {
1007+ invocationArgStrs.push_back (" -ivfsoverlay" );
1008+ invocationArgStrs.push_back (
1009+ ClangImporter::getClangSystemOverlayFile (ctx.SearchPathOpts ));
1010+ }
10061011}
10071012
10081013bool ClangImporter::canReadPCH (StringRef PCHFilename) {
@@ -1151,6 +1156,85 @@ ClangImporter::getOrCreatePCH(const ClangImporterOptions &ImporterOptions,
11511156 return PCHFilename.value ();
11521157}
11531158
1159+ std::string
1160+ ClangImporter::getClangSystemOverlayFile (const SearchPathOptions &Opts) {
1161+ llvm::SmallString<256 > overlayPath (Opts.RuntimeResourcePath );
1162+ llvm::sys::path::append (overlayPath,
1163+ Implementation::clangSystemVFSOverlayName);
1164+ return overlayPath.str ().str ();
1165+ }
1166+
1167+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
1168+ ClangImporter::computeClangImporterFileSystem (
1169+ const ASTContext &ctx,
1170+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseFS,
1171+ ClangImporter *importer, bool suppressDiagnostics) {
1172+ // Configure ClangImporter file system. There are two situations:
1173+ // * If caching is used, thus file system is immutable, the one immutable file
1174+ // system is shared between swift frontend and ClangImporter.
1175+ // * Otherwise, ClangImporter file system is configure from scratch from
1176+ // VFS in SourceMgr using ivfsoverlay options.
1177+ if (ctx.CASOpts .HasImmutableFileSystem )
1178+ return baseFS;
1179+
1180+ ClangInvocationFileMapping fileMapping =
1181+ getClangInvocationFileMapping (ctx, baseFS, suppressDiagnostics);
1182+
1183+ auto importerOpts = ctx.ClangImporterOpts ;
1184+ if (importer)
1185+ importer->requiresBuiltinHeadersInSystemModules =
1186+ fileMapping.requiresBuiltinHeadersInSystemModules ;
1187+
1188+ auto fileSystem = baseFS;
1189+ if (!fileMapping.redirectedFiles .empty ()) {
1190+ if (importerOpts.DumpClangDiagnostics ) {
1191+ llvm::errs () << " clang importer redirected file mappings:\n " ;
1192+ for (const auto &mapping : fileMapping.redirectedFiles ) {
1193+ llvm::errs () << " mapping real file '" << mapping.second
1194+ << " ' to virtual file '" << mapping.first << " '\n " ;
1195+ }
1196+ llvm::errs () << " \n " ;
1197+ }
1198+ // Create a vfs overlay map for all redirects.
1199+ llvm::vfs::YAMLVFSWriter vfsWriter;
1200+ vfsWriter.setUseExternalNames (true );
1201+ for (const auto &mapping : fileMapping.redirectedFiles )
1202+ vfsWriter.addFileMapping (mapping.first , mapping.second );
1203+
1204+ std::string vfsYAML;
1205+ llvm::raw_string_ostream os (vfsYAML);
1206+ vfsWriter.write (os);
1207+
1208+ fileMapping.overridenFiles .push_back (llvm::MemoryBuffer::getMemBufferCopy (
1209+ vfsYAML, getClangSystemOverlayFile (ctx.SearchPathOpts )));
1210+
1211+ if (importer)
1212+ importer->needSystemVFSOverlay = true ;
1213+ }
1214+
1215+ if (!fileMapping.overridenFiles .empty ()) {
1216+ auto overridenVFS =
1217+ llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
1218+ for (auto &file : fileMapping.overridenFiles ) {
1219+ if (importerOpts.DumpClangDiagnostics ) {
1220+ llvm::errs () << " clang importer overriding file '"
1221+ << file->getBufferIdentifier ()
1222+ << " ' with the following contents:\n " ;
1223+ llvm::errs () << file->getBuffer () << " \n " ;
1224+ }
1225+ // Note MemoryBuffer is guaranteeed to be null-terminated.
1226+ std::string filePath = file->getBufferIdentifier ().str ();
1227+ overridenVFS->addFile (filePath, 0 , std::move (file));
1228+ }
1229+ auto overlayVFS =
1230+ llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>(fileSystem);
1231+ overlayVFS->pushOverlay (std::move (overridenVFS));
1232+ fileSystem = std::move (overlayVFS);
1233+ }
1234+
1235+ return fileSystem;
1236+ }
1237+
11541238std::vector<std::string>
11551239ClangImporter::getClangDriverArguments (ASTContext &ctx, bool ignoreClangTarget) {
11561240 assert (!ctx.ClangImporterOpts .DirectClangCC1ModuleBuild &&
@@ -1169,7 +1253,8 @@ ClangImporter::getClangDriverArguments(ASTContext &ctx, bool ignoreClangTarget)
11691253 break ;
11701254 }
11711255 addCommonInvocationArguments (invocationArgStrs, ctx,
1172- requiresBuiltinHeadersInSystemModules, ignoreClangTarget);
1256+ requiresBuiltinHeadersInSystemModules,
1257+ needSystemVFSOverlay, ignoreClangTarget);
11731258 return invocationArgStrs;
11741259}
11751260
@@ -1235,6 +1320,10 @@ std::optional<std::vector<std::string>> ClangImporter::getClangCC1Arguments(
12351320 CI->getTargetOpts ().DarwinTargetVariantTriple = ctx.LangOpts .TargetVariant ->str ();
12361321 }
12371322
1323+ if (needSystemVFSOverlay)
1324+ CI->getHeaderSearchOpts ().AddVFSOverlayFile (
1325+ getClangSystemOverlayFile (ctx.SearchPathOpts ));
1326+
12381327 // Forward the index store path. That information is not passed to scanner
12391328 // and it is cached invariant so we don't want to re-scan if that changed.
12401329 CI->getFrontendOpts ().IndexStorePath = ctx.ClangImporterOpts .IndexStorePath ;
@@ -1348,18 +1437,13 @@ std::unique_ptr<ClangImporter> ClangImporter::create(
13481437 }
13491438 }
13501439
1351- llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
1352- ctx.SourceMgr .getFileSystem ();
1353-
1354- ClangInvocationFileMapping fileMapping =
1355- applyClangInvocationMapping (ctx, nullptr , VFS, ignoreFileMapping);
1356-
1357- importer->requiresBuiltinHeadersInSystemModules =
1358- fileMapping.requiresBuiltinHeadersInSystemModules ;
1440+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs =
1441+ computeClangImporterFileSystem (ctx, ctx.SourceMgr .getFileSystem (),
1442+ importer.get (), ignoreFileMapping);
13591443
13601444 // Create a new Clang compiler invocation.
13611445 {
1362- if (auto ClangArgs = importer->getClangCC1Arguments (ctx, VFS ))
1446+ if (auto ClangArgs = importer->getClangCC1Arguments (ctx, vfs ))
13631447 importer->Impl .ClangArgs = *ClangArgs;
13641448 else
13651449 return nullptr ;
@@ -1373,7 +1457,7 @@ std::unique_ptr<ClangImporter> ClangImporter::create(
13731457 llvm::errs () << " '\n " ;
13741458 }
13751459 importer->Impl .Invocation = createClangInvocation (
1376- importer.get (), importerOpts, VFS , importer->Impl .ClangArgs );
1460+ importer.get (), importerOpts, vfs , importer->Impl .ClangArgs );
13771461 if (!importer->Impl .Invocation )
13781462 return nullptr ;
13791463 }
@@ -1424,7 +1508,7 @@ std::unique_ptr<ClangImporter> ClangImporter::create(
14241508 auto actualDiagClient = std::make_unique<ClangDiagnosticConsumer>(
14251509 importer->Impl , instance.getDiagnosticOpts (),
14261510 importerOpts.DumpClangDiagnostics );
1427- instance.createVirtualFileSystem (std::move (VFS ), actualDiagClient.get ());
1511+ instance.createVirtualFileSystem (std::move (vfs ), actualDiagClient.get ());
14281512 instance.createFileManager ();
14291513 instance.createDiagnostics (actualDiagClient.release ());
14301514
0 commit comments