@@ -162,6 +162,32 @@ static void optimizeCWD(CowCompilerInvocation &BuildInvocation, StringRef CWD) {
162
162
}
163
163
}
164
164
165
+ // / Check a subset of invocation options to determine whether the current
166
+ // / context can safely be considered as stable.
167
+ static bool areOptionsInStableDir (CowCompilerInvocation &BuildInvocation,
168
+ const ArrayRef<StringRef> StableDirs) {
169
+ const auto &HSOpts = BuildInvocation.getHeaderSearchOpts ();
170
+ assert (isPathInStableDir (StableDirs, HSOpts.Sysroot ) &&
171
+ " Sysroots differ between module dependencies and current TU" );
172
+
173
+ assert (isPathInStableDir (StableDirs, HSOpts.ResourceDir ) &&
174
+ " ResourceDirs differ between module dependencies and current TU" );
175
+
176
+ for (const auto &Entry : HSOpts.UserEntries ) {
177
+ if (!Entry.IgnoreSysRoot )
178
+ continue ;
179
+ if (!isPathInStableDir (StableDirs, Entry.Path ))
180
+ return false ;
181
+ }
182
+
183
+ for (const auto &SysPrefix : HSOpts.SystemHeaderPrefixes ) {
184
+ if (!isPathInStableDir (StableDirs, SysPrefix.Prefix ))
185
+ return false ;
186
+ }
187
+
188
+ return true ;
189
+ }
190
+
165
191
static std::vector<std::string> splitString (std::string S, char Separator) {
166
192
SmallVector<StringRef> Segments;
167
193
StringRef (S).split (Segments, Separator, /* MaxSplit=*/ -1 , /* KeepEmpty=*/ false );
@@ -217,6 +243,25 @@ void dependencies::resetBenignCodeGenOptions(frontend::ActionKind ProgramAction,
217
243
}
218
244
}
219
245
246
+ bool dependencies::isPathInStableDir (const ArrayRef<StringRef> Directories,
247
+ const StringRef Input) {
248
+ auto PathStartsWith = [](StringRef Prefix, StringRef Path) {
249
+ auto PrefixIt = llvm::sys::path::begin (Prefix),
250
+ PrefixEnd = llvm::sys::path::end (Prefix);
251
+ for (auto PathIt = llvm::sys::path::begin (Path),
252
+ PathEnd = llvm::sys::path::end (Path);
253
+ PrefixIt != PrefixEnd && PathIt != PathEnd; ++PrefixIt, ++PathIt) {
254
+ if (*PrefixIt != *PathIt)
255
+ return false ;
256
+ }
257
+ return PrefixIt == PrefixEnd;
258
+ };
259
+
260
+ return any_of (Directories, [&](StringRef Dir) {
261
+ return !Dir.empty () && PathStartsWith (Dir, Input);
262
+ });
263
+ }
264
+
220
265
static CowCompilerInvocation
221
266
makeCommonInvocationForModuleBuild (CompilerInvocation CI) {
222
267
CI.resetNonModularOptions ();
@@ -770,6 +815,17 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
770
815
771
816
MD.ID .ModuleName = M->getFullModuleName ();
772
817
MD.IsSystem = M->IsSystem ;
818
+
819
+ // Start off with the assumption that this module is shareable when there
820
+ // is a sysroot provided. As more dependencies are discovered, check if those
821
+ // come from the provided shared directories.
822
+ const llvm::SmallVector<StringRef> StableDirs = {
823
+ MDC.ScanInstance .getHeaderSearchOpts ().Sysroot ,
824
+ MDC.ScanInstance .getHeaderSearchOpts ().ResourceDir };
825
+ MD.IsInStableDirectories =
826
+ !StableDirs[0 ].empty () &&
827
+ (llvm::sys::path::root_directory (StableDirs[0 ]) != StableDirs[0 ]);
828
+
773
829
// For modules which use export_as link name, the linked product that of the
774
830
// corresponding export_as-named module.
775
831
if (!M->UseExportAsModuleLinkName )
@@ -811,6 +867,12 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
811
867
MDC.ScanInstance .getASTReader ()->visitInputFileInfos (
812
868
*MF, /* IncludeSystem=*/ true ,
813
869
[&](const serialization::InputFileInfo &IFI, bool IsSystem) {
870
+ if (MD.IsInStableDirectories ) {
871
+ auto FullFilePath = ASTReader::ResolveImportedPath (
872
+ PathBuf, IFI.UnresolvedImportedFilename , MF->BaseDirectory );
873
+ MD.IsInStableDirectories =
874
+ isPathInStableDir (StableDirs, *FullFilePath);
875
+ }
814
876
if (!(IFI.TopLevel && IFI.ModuleMap ))
815
877
return ;
816
878
if (IFI.UnresolvedImportedFilenameAsRequested .ends_with (
@@ -878,6 +940,11 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
878
940
}
879
941
880
942
MD.IgnoreCWD = IgnoreCWD;
943
+ // Check provided input paths from the invocation for determining
944
+ // IsInStableDirectories.
945
+ if (MD.IsInStableDirectories )
946
+ MD.IsInStableDirectories = areOptionsInStableDir (CI, StableDirs);
947
+
881
948
MDC.associateWithContextHash (CI, IgnoreCWD, MD);
882
949
883
950
// Finish the compiler invocation. Requires dependencies and the context hash.
@@ -929,8 +996,13 @@ void ModuleDepCollectorPP::addModulePrebuiltDeps(
929
996
for (const Module *Import : M->Imports )
930
997
if (Import->getTopLevelModule () != M->getTopLevelModule ())
931
998
if (MDC.isPrebuiltModule (Import->getTopLevelModule ()))
932
- if (SeenSubmodules.insert (Import->getTopLevelModule ()).second )
999
+ if (SeenSubmodules.insert (Import->getTopLevelModule ()).second ) {
933
1000
MD.PrebuiltModuleDeps .emplace_back (Import->getTopLevelModule ());
1001
+ // Conservatively consider the module as not coming from stable
1002
+ // directories, as transitive dependencies from the prebuilt module
1003
+ // have not been determined.
1004
+ MD.IsInStableDirectories = false ;
1005
+ }
934
1006
}
935
1007
936
1008
void ModuleDepCollectorPP::addAllSubmoduleDeps (
@@ -943,6 +1015,13 @@ void ModuleDepCollectorPP::addAllSubmoduleDeps(
943
1015
});
944
1016
}
945
1017
1018
+ void ModuleDepCollectorPP::addOneModuleDep (const Module *M, const ModuleID ID,
1019
+ ModuleDeps &MD) {
1020
+ MD.ClangModuleDeps .push_back (ID);
1021
+ if (MD.IsInStableDirectories )
1022
+ MD.IsInStableDirectories = MDC.ModularDeps [M]->IsInStableDirectories ;
1023
+ }
1024
+
946
1025
void ModuleDepCollectorPP::addModuleDep (
947
1026
const Module *M, ModuleDeps &MD,
948
1027
llvm::DenseSet<const Module *> &AddedModules) {
@@ -951,7 +1030,7 @@ void ModuleDepCollectorPP::addModuleDep(
951
1030
!MDC.isPrebuiltModule (Import)) {
952
1031
if (auto ImportID = handleTopLevelModule (Import->getTopLevelModule ()))
953
1032
if (AddedModules.insert (Import->getTopLevelModule ()).second )
954
- MD. ClangModuleDeps . push_back ( *ImportID);
1033
+ addOneModuleDep (Import-> getTopLevelModule (), *ImportID, MD );
955
1034
}
956
1035
}
957
1036
}
@@ -975,7 +1054,7 @@ void ModuleDepCollectorPP::addAffectingClangModule(
975
1054
!MDC.isPrebuiltModule (Affecting)) {
976
1055
if (auto ImportID = handleTopLevelModule (Affecting))
977
1056
if (AddedModules.insert (Affecting).second )
978
- MD. ClangModuleDeps . push_back ( *ImportID);
1057
+ addOneModuleDep (Affecting, *ImportID, MD );
979
1058
}
980
1059
}
981
1060
}
0 commit comments