@@ -157,6 +157,32 @@ static void optimizeCWD(CowCompilerInvocation &BuildInvocation, StringRef CWD) {
157157 }
158158}
159159
160+ // / Check a subset of invocation options to determine whether the current
161+ // / context can safely be considered as shareable.
162+ static bool areOptionsInSharedDir (CowCompilerInvocation &BuildInvocation,
163+ const ArrayRef<StringRef> SharedDirs) {
164+ const auto &HSOpts = BuildInvocation.getHeaderSearchOpts ();
165+ if (!isPathInSharedDir (SharedDirs, HSOpts.Sysroot ))
166+ return false ;
167+
168+ if (!isPathInSharedDir (SharedDirs, HSOpts.ResourceDir ))
169+ return false ;
170+
171+ for (const auto &Entry : HSOpts.UserEntries ) {
172+ if (!Entry.IgnoreSysRoot )
173+ continue ;
174+ if (!isPathInSharedDir (SharedDirs, Entry.Path ))
175+ return false ;
176+ }
177+
178+ for (const auto &SysPrefix : HSOpts.SystemHeaderPrefixes ) {
179+ if (!isPathInSharedDir (SharedDirs, SysPrefix.Prefix ))
180+ return false ;
181+ }
182+
183+ return true ;
184+ }
185+
160186static std::vector<std::string> splitString (std::string S, char Separator) {
161187 SmallVector<StringRef> Segments;
162188 StringRef (S).split (Segments, Separator, /* MaxSplit=*/ -1 , /* KeepEmpty=*/ false );
@@ -212,6 +238,25 @@ void dependencies::resetBenignCodeGenOptions(frontend::ActionKind ProgramAction,
212238 }
213239}
214240
241+ bool dependencies::isPathInSharedDir (ArrayRef<StringRef> Directories,
242+ const StringRef Input) {
243+ auto PathStartsWith = [](StringRef Prefix, StringRef Path) {
244+ auto PrefixIt = llvm::sys::path::begin (Prefix),
245+ PrefixEnd = llvm::sys::path::end (Prefix);
246+ for (auto PathIt = llvm::sys::path::begin (Path),
247+ PathEnd = llvm::sys::path::end (Path);
248+ PrefixIt != PrefixEnd && PathIt != PathEnd; ++PrefixIt, ++PathIt) {
249+ if (*PrefixIt != *PathIt)
250+ return false ;
251+ }
252+ return PrefixIt == PrefixEnd;
253+ };
254+
255+ return any_of (Directories, [&](StringRef Dir) {
256+ return !Dir.empty () && PathStartsWith (Dir, Input);
257+ });
258+ }
259+
215260static CowCompilerInvocation
216261makeCommonInvocationForModuleBuild (CompilerInvocation CI) {
217262 CI.resetNonModularOptions ();
@@ -699,13 +744,15 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
699744 MD.ID .ModuleName = M->getFullModuleName ();
700745 MD.IsSystem = M->IsSystem ;
701746
702- // Start off with the assumption that this module is in the sysroot when there
747+ // Start off with the assumption that this module is shareable when there
703748 // is a sysroot provided. As more dependencies are discovered, check if those
704- // come from the provided sysroot.
705- const StringRef CurrSysroot = MDC.ScanInstance .getHeaderSearchOpts ().Sysroot ;
706- MD.IsInSysroot =
707- !CurrSysroot.empty () &&
708- (llvm::sys::path::root_directory (CurrSysroot) != CurrSysroot);
749+ // come from the provided shared directories.
750+ const llvm::SmallVector<StringRef> SharedDirs = {
751+ MDC.ScanInstance .getHeaderSearchOpts ().Sysroot ,
752+ MDC.ScanInstance .getHeaderSearchOpts ().ResourceDir };
753+ MD.IsShareable =
754+ !SharedDirs[0 ].empty () &&
755+ (llvm::sys::path::root_directory (SharedDirs[0 ]) != SharedDirs[0 ]);
709756
710757 // For modules which use export_as link name, the linked product that of the
711758 // corresponding export_as-named module.
@@ -748,10 +795,10 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
748795 MDC.ScanInstance .getASTReader ()->visitInputFileInfos (
749796 *MF, /* IncludeSystem=*/ true ,
750797 [&](const serialization::InputFileInfo &IFI, bool IsSystem) {
751- if (MD.IsInSysroot ) {
798+ if (MD.IsShareable ) {
752799 auto FullFilePath = ASTReader::ResolveImportedPath (
753800 PathBuf, IFI.UnresolvedImportedFilename , MF->BaseDirectory );
754- MD.IsInSysroot = FullFilePath-> starts_with (CurrSysroot );
801+ MD.IsShareable = isPathInSharedDir (SharedDirs, *FullFilePath );
755802 PathBuf.resize_for_overwrite (256 );
756803 }
757804 if (!(IFI.TopLevel && IFI.ModuleMap ))
@@ -795,6 +842,10 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
795842 }
796843 });
797844
845+ // Check provided input paths from the invocation for determining IsShareable.
846+ if (MD.IsShareable )
847+ MD.IsShareable = areOptionsInSharedDir (CI, SharedDirs);
848+
798849 MDC.associateWithContextHash (CI, IgnoreCWD, MD);
799850
800851 // Finish the compiler invocation. Requires dependencies and the context hash.
@@ -836,8 +887,13 @@ void ModuleDepCollectorPP::addModulePrebuiltDeps(
836887 for (const Module *Import : M->Imports )
837888 if (Import->getTopLevelModule () != M->getTopLevelModule ())
838889 if (MDC.isPrebuiltModule (Import->getTopLevelModule ()))
839- if (SeenSubmodules.insert (Import->getTopLevelModule ()).second )
890+ if (SeenSubmodules.insert (Import->getTopLevelModule ()).second ) {
840891 MD.PrebuiltModuleDeps .emplace_back (Import->getTopLevelModule ());
892+ // Conservatively consider the module as not shareable,
893+ // as transitive dependencies from the prebuilt module have not been
894+ // determined.
895+ MD.IsShareable = false ;
896+ }
841897}
842898
843899void ModuleDepCollectorPP::addAllSubmoduleDeps (
@@ -850,11 +906,11 @@ void ModuleDepCollectorPP::addAllSubmoduleDeps(
850906 });
851907}
852908
853- void ModuleDepCollectorPP::addClangModule (const Module *M, const ModuleID ID,
854- ModuleDeps &MD) {
909+ void ModuleDepCollectorPP::addOneModuleDep (const Module *M, const ModuleID ID,
910+ ModuleDeps &MD) {
855911 MD.ClangModuleDeps .push_back (ID);
856- if (MD.IsInSysroot )
857- MD.IsInSysroot = MDC.ModularDeps [M]->IsInSysroot ;
912+ if (MD.IsShareable )
913+ MD.IsShareable = MDC.ModularDeps [M]->IsShareable ;
858914}
859915
860916void ModuleDepCollectorPP::addModuleDep (
@@ -865,7 +921,7 @@ void ModuleDepCollectorPP::addModuleDep(
865921 !MDC.isPrebuiltModule (Import)) {
866922 if (auto ImportID = handleTopLevelModule (Import->getTopLevelModule ()))
867923 if (AddedModules.insert (Import->getTopLevelModule ()).second )
868- addClangModule (Import->getTopLevelModule (), *ImportID, MD);
924+ addOneModuleDep (Import->getTopLevelModule (), *ImportID, MD);
869925 }
870926 }
871927}
@@ -889,7 +945,7 @@ void ModuleDepCollectorPP::addAffectingClangModule(
889945 !MDC.isPrebuiltModule (Affecting)) {
890946 if (auto ImportID = handleTopLevelModule (Affecting))
891947 if (AddedModules.insert (Affecting).second )
892- addClangModule (Affecting, *ImportID, MD);
948+ addOneModuleDep (Affecting, *ImportID, MD);
893949 }
894950 }
895951}
0 commit comments