@@ -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, const ClangInvocationFileMapping &fileMapping,
1170+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> baseFS,
1171+ 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+ auto importerOpts = ctx.ClangImporterOpts ;
1181+ auto fileSystem = baseFS;
1182+ std::unique_ptr<llvm::MemoryBuffer> redirectYAMLFile;
1183+ if (!fileMapping.redirectedFiles .empty ()) {
1184+ if (importerOpts.DumpClangDiagnostics ) {
1185+ llvm::errs () << " clang importer redirected file mappings:\n " ;
1186+ for (const auto &mapping : fileMapping.redirectedFiles ) {
1187+ llvm::errs () << " mapping real file '" << mapping.second
1188+ << " ' to virtual file '" << mapping.first << " '\n " ;
1189+ }
1190+ llvm::errs () << " \n " ;
1191+ }
1192+ // Create a vfs overlay map for all redirects.
1193+ llvm::vfs::YAMLVFSWriter vfsWriter;
1194+ vfsWriter.setUseExternalNames (true );
1195+ for (const auto &mapping : fileMapping.redirectedFiles )
1196+ vfsWriter.addFileMapping (mapping.first , mapping.second );
1197+
1198+ std::string vfsYAML;
1199+ llvm::raw_string_ostream os (vfsYAML);
1200+ vfsWriter.write (os);
1201+
1202+ redirectYAMLFile = llvm::MemoryBuffer::getMemBufferCopy (
1203+ vfsYAML, getClangSystemOverlayFile (ctx.SearchPathOpts ));
1204+ }
1205+
1206+ if (!fileMapping.overridenFiles .empty () || redirectYAMLFile) {
1207+ auto overridenVFS =
1208+ llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
1209+ for (auto &file : fileMapping.overridenFiles ) {
1210+ if (importerOpts.DumpClangDiagnostics ) {
1211+ llvm::errs () << " clang importer overriding file '" << file.first
1212+ << " ' with the following contents:\n " ;
1213+ llvm::errs () << file.second << " \n " ;
1214+ }
1215+ // Note MemoryBuffer is guaranteeed to be null-terminated.
1216+ overridenVFS->addFile (file.first , 0 ,
1217+ llvm::MemoryBuffer::getMemBufferCopy (file.second ));
1218+ }
1219+ if (redirectYAMLFile) {
1220+ if (importerOpts.DumpClangDiagnostics ) {
1221+ llvm::errs () << " clang importer overriding file for redirects'"
1222+ << redirectYAMLFile->getBufferIdentifier ()
1223+ << " ' with the following contents:\n " ;
1224+ llvm::errs () << redirectYAMLFile->getBuffer () << " \n " ;
1225+ }
1226+ std::string yamlFile = redirectYAMLFile->getBufferIdentifier ().str ();
1227+ overridenVFS->addFile (yamlFile, 0 , std::move (redirectYAMLFile));
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 &&
@@ -1168,8 +1252,10 @@ ClangImporter::getClangDriverArguments(ASTContext &ctx, bool ignoreClangTarget)
11681252 getEmbedBitcodeInvocationArguments (invocationArgStrs, ctx);
11691253 break ;
11701254 }
1171- addCommonInvocationArguments (invocationArgStrs, ctx,
1172- requiresBuiltinHeadersInSystemModules, ignoreClangTarget);
1255+ addCommonInvocationArguments (
1256+ invocationArgStrs, ctx,
1257+ clangFileMapping.requiresBuiltinHeadersInSystemModules ,
1258+ clangFileMapping.needSystemVFSOverlay , ignoreClangTarget);
11731259 return invocationArgStrs;
11741260}
11751261
@@ -1235,6 +1321,10 @@ std::optional<std::vector<std::string>> ClangImporter::getClangCC1Arguments(
12351321 CI->getTargetOpts ().DarwinTargetVariantTriple = ctx.LangOpts .TargetVariant ->str ();
12361322 }
12371323
1324+ if (clangFileMapping.needSystemVFSOverlay )
1325+ CI->getHeaderSearchOpts ().AddVFSOverlayFile (
1326+ getClangSystemOverlayFile (ctx.SearchPathOpts ));
1327+
12381328 // Forward the index store path. That information is not passed to scanner
12391329 // and it is cached invariant so we don't want to re-scan if that changed.
12401330 CI->getFrontendOpts ().IndexStorePath = ctx.ClangImporterOpts .IndexStorePath ;
@@ -1348,18 +1438,16 @@ std::unique_ptr<ClangImporter> ClangImporter::create(
13481438 }
13491439 }
13501440
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 ;
1441+ importer->clangFileMapping = getClangInvocationFileMapping (
1442+ ctx, ctx.SourceMgr .getFileSystem (), ignoreFileMapping);
1443+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs =
1444+ computeClangImporterFileSystem (ctx, importer->clangFileMapping ,
1445+ ctx.SourceMgr .getFileSystem (),
1446+ ignoreFileMapping);
13591447
13601448 // Create a new Clang compiler invocation.
13611449 {
1362- if (auto ClangArgs = importer->getClangCC1Arguments (ctx, VFS ))
1450+ if (auto ClangArgs = importer->getClangCC1Arguments (ctx, vfs ))
13631451 importer->Impl .ClangArgs = *ClangArgs;
13641452 else
13651453 return nullptr ;
@@ -1373,7 +1461,7 @@ std::unique_ptr<ClangImporter> ClangImporter::create(
13731461 llvm::errs () << " '\n " ;
13741462 }
13751463 importer->Impl .Invocation = createClangInvocation (
1376- importer.get (), importerOpts, VFS , importer->Impl .ClangArgs );
1464+ importer.get (), importerOpts, vfs , importer->Impl .ClangArgs );
13771465 if (!importer->Impl .Invocation )
13781466 return nullptr ;
13791467 }
@@ -1424,7 +1512,7 @@ std::unique_ptr<ClangImporter> ClangImporter::create(
14241512 auto actualDiagClient = std::make_unique<ClangDiagnosticConsumer>(
14251513 importer->Impl , instance.getDiagnosticOpts (),
14261514 importerOpts.DumpClangDiagnostics );
1427- instance.createVirtualFileSystem (std::move (VFS ), actualDiagClient.get ());
1515+ instance.createVirtualFileSystem (std::move (vfs ), actualDiagClient.get ());
14281516 instance.createFileManager ();
14291517 instance.createDiagnostics (actualDiagClient.release ());
14301518
0 commit comments