@@ -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 stable.
162+ static bool areOptionsInStableDir (CowCompilerInvocation &BuildInvocation,
163+ const ArrayRef<StringRef> StableDirs) {
164+ const auto &HSOpts = BuildInvocation.getHeaderSearchOpts ();
165+ assert (isPathInStableDir (StableDirs, HSOpts.Sysroot ) &&
166+ " Sysroots differ between module dependencies and current TU" );
167+
168+ assert (isPathInStableDir (StableDirs, HSOpts.ResourceDir ) &&
169+ " ResourceDirs differ between module dependencies and current TU" );
170+
171+ for (const auto &Entry : HSOpts.UserEntries ) {
172+ if (!Entry.IgnoreSysRoot )
173+ continue ;
174+ if (!isPathInStableDir (StableDirs, Entry.Path ))
175+ return false ;
176+ }
177+
178+ for (const auto &SysPrefix : HSOpts.SystemHeaderPrefixes ) {
179+ if (!isPathInStableDir (StableDirs, 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::isPathInStableDir (const 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 ();
@@ -698,6 +743,17 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
698743
699744 MD.ID .ModuleName = M->getFullModuleName ();
700745 MD.IsSystem = M->IsSystem ;
746+
747+ // Start off with the assumption that this module is shareable when there
748+ // is a sysroot provided. As more dependencies are discovered, check if those
749+ // come from the provided shared directories.
750+ const llvm::SmallVector<StringRef> StableDirs = {
751+ MDC.ScanInstance .getHeaderSearchOpts ().Sysroot ,
752+ MDC.ScanInstance .getHeaderSearchOpts ().ResourceDir };
753+ MD.IsInStableDirectories =
754+ !StableDirs[0 ].empty () &&
755+ (llvm::sys::path::root_directory (StableDirs[0 ]) != StableDirs[0 ]);
756+
701757 // For modules which use export_as link name, the linked product that of the
702758 // corresponding export_as-named module.
703759 if (!M->UseExportAsModuleLinkName )
@@ -739,6 +795,12 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
739795 MDC.ScanInstance .getASTReader ()->visitInputFileInfos (
740796 *MF, /* IncludeSystem=*/ true ,
741797 [&](const serialization::InputFileInfo &IFI, bool IsSystem) {
798+ if (MD.IsInStableDirectories ) {
799+ auto FullFilePath = ASTReader::ResolveImportedPath (
800+ PathBuf, IFI.UnresolvedImportedFilename , MF->BaseDirectory );
801+ MD.IsInStableDirectories =
802+ isPathInStableDir (StableDirs, *FullFilePath);
803+ }
742804 if (!(IFI.TopLevel && IFI.ModuleMap ))
743805 return ;
744806 if (IFI.UnresolvedImportedFilenameAsRequested .ends_with (
@@ -780,6 +842,11 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
780842 }
781843 });
782844
845+ // Check provided input paths from the invocation for determining
846+ // IsInStableDirectories.
847+ if (MD.IsInStableDirectories )
848+ MD.IsInStableDirectories = areOptionsInStableDir (CI, StableDirs);
849+
783850 MDC.associateWithContextHash (CI, IgnoreCWD, MD);
784851
785852 // Finish the compiler invocation. Requires dependencies and the context hash.
@@ -821,8 +888,13 @@ void ModuleDepCollectorPP::addModulePrebuiltDeps(
821888 for (const Module *Import : M->Imports )
822889 if (Import->getTopLevelModule () != M->getTopLevelModule ())
823890 if (MDC.isPrebuiltModule (Import->getTopLevelModule ()))
824- if (SeenSubmodules.insert (Import->getTopLevelModule ()).second )
891+ if (SeenSubmodules.insert (Import->getTopLevelModule ()).second ) {
825892 MD.PrebuiltModuleDeps .emplace_back (Import->getTopLevelModule ());
893+ // Conservatively consider the module as not coming from stable
894+ // directories, as transitive dependencies from the prebuilt module
895+ // have not been determined.
896+ MD.IsInStableDirectories = false ;
897+ }
826898}
827899
828900void ModuleDepCollectorPP::addAllSubmoduleDeps (
@@ -835,6 +907,13 @@ void ModuleDepCollectorPP::addAllSubmoduleDeps(
835907 });
836908}
837909
910+ void ModuleDepCollectorPP::addOneModuleDep (const Module *M, const ModuleID ID,
911+ ModuleDeps &MD) {
912+ MD.ClangModuleDeps .push_back (ID);
913+ if (MD.IsInStableDirectories )
914+ MD.IsInStableDirectories = MDC.ModularDeps [M]->IsInStableDirectories ;
915+ }
916+
838917void ModuleDepCollectorPP::addModuleDep (
839918 const Module *M, ModuleDeps &MD,
840919 llvm::DenseSet<const Module *> &AddedModules) {
@@ -843,7 +922,7 @@ void ModuleDepCollectorPP::addModuleDep(
843922 !MDC.isPrebuiltModule (Import)) {
844923 if (auto ImportID = handleTopLevelModule (Import->getTopLevelModule ()))
845924 if (AddedModules.insert (Import->getTopLevelModule ()).second )
846- MD. ClangModuleDeps . push_back ( *ImportID);
925+ addOneModuleDep (Import-> getTopLevelModule (), *ImportID, MD );
847926 }
848927 }
849928}
@@ -867,7 +946,7 @@ void ModuleDepCollectorPP::addAffectingClangModule(
867946 !MDC.isPrebuiltModule (Affecting)) {
868947 if (auto ImportID = handleTopLevelModule (Affecting))
869948 if (AddedModules.insert (Affecting).second )
870- MD. ClangModuleDeps . push_back ( *ImportID);
949+ addOneModuleDep (Affecting, *ImportID, MD );
871950 }
872951 }
873952}
0 commit comments