mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[ModuleInterfaces] Add adjacent swiftmodule to dependencies
If there’s a `.swiftmodule` corresponding to the `.swiftinterface` we’re loading, but it’s out of date or otherwise unusable, still make it a dependency of the cached module. The general assumption with cached modules is that, by virtue of them being in the cache, they have a more up-to-date view of the world than the adjacent compiled module. However, if a new `.swiftmodule` comes along that’s totally valid, we should consider it as having a newer view of the world than the cached one, so we should use it instead. Fixes rdar://51959788
This commit is contained in:
@@ -284,6 +284,7 @@ class swift::ParseableInterfaceBuilder {
|
||||
const SourceLoc diagnosticLoc;
|
||||
DependencyTracker *const dependencyTracker;
|
||||
CompilerInvocation subInvocation;
|
||||
SmallVector<StringRef, 3> extraDependencies;
|
||||
|
||||
void configureSubInvocationInputsAndOutputs(StringRef OutPath) {
|
||||
auto &SubFEOpts = subInvocation.getFrontendOptions();
|
||||
@@ -397,6 +398,8 @@ class swift::ParseableInterfaceBuilder {
|
||||
auto DTDeps = SubInstance.getDependencyTracker()->getDependencies();
|
||||
SmallVector<StringRef, 16> InitialDepNames(DTDeps.begin(), DTDeps.end());
|
||||
InitialDepNames.push_back(interfacePath);
|
||||
InitialDepNames.insert(InitialDepNames.end(),
|
||||
extraDependencies.begin(), extraDependencies.end());
|
||||
llvm::StringSet<> AllDepNames;
|
||||
SmallString<128> Scratch;
|
||||
|
||||
@@ -487,6 +490,12 @@ public:
|
||||
return subInvocation;
|
||||
}
|
||||
|
||||
/// Ensures the requested file name is added as a dependency of the resulting
|
||||
/// module.
|
||||
void addExtraDependency(StringRef path) {
|
||||
extraDependencies.push_back(path);
|
||||
}
|
||||
|
||||
bool buildSwiftModule(StringRef OutPath, bool ShouldSerializeDeps,
|
||||
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer) {
|
||||
bool SubError = false;
|
||||
@@ -672,6 +681,15 @@ struct ModuleRebuildInfo {
|
||||
.missingDependencies.push_back(depPath);
|
||||
}
|
||||
|
||||
/// Determines if we saw the given module path and registered is as out of
|
||||
/// date.
|
||||
bool sawOutOfDateModule(StringRef modulePath) {
|
||||
for (auto &mod : outOfDateModules)
|
||||
if (mod.path == modulePath)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *invalidModuleReason(serialization::Status status) {
|
||||
using namespace serialization;
|
||||
switch (status) {
|
||||
@@ -1319,6 +1337,14 @@ class ParseableInterfaceModuleLoaderImpl {
|
||||
interfacePath);
|
||||
}
|
||||
|
||||
// If we found an out-of-date .swiftmodule, we still want to add it as
|
||||
// a dependency of the .swiftinterface. That way if it's updated, but
|
||||
// the .swiftinterface remains the same, we invalidate the cache and
|
||||
// check the new .swiftmodule, because it likely has more information
|
||||
// about the state of the world.
|
||||
if (rebuildInfo.sawOutOfDateModule(modulePath))
|
||||
builder.addExtraDependency(modulePath);
|
||||
|
||||
if (builder.buildSwiftModule(cachedOutputPath, /*shouldSerializeDeps*/true,
|
||||
&moduleBuffer))
|
||||
return std::make_error_code(std::errc::invalid_argument);
|
||||
|
||||
Reference in New Issue
Block a user