@@ -222,27 +222,19 @@ static bool serializedASTLooksValid(const llvm::MemoryBuffer &buf) {
222
222
}
223
223
224
224
static std::unique_ptr<llvm::MemoryBuffer> getBufferOfDependency (
225
- llvm::vfs::FileSystem &fs, StringRef depPath, StringRef interfacePath,
226
- DiagnosticEngine &diags, SourceLoc diagnosticLoc) {
225
+ llvm::vfs::FileSystem &fs, StringRef depPath) {
227
226
auto depBuf = fs.getBufferForFile (depPath, /* FileSize=*/ -1 ,
228
227
/* RequiresNullTerminator=*/ false );
229
228
if (!depBuf) {
230
- diags.diagnose (diagnosticLoc,
231
- diag::missing_dependency_of_module_interface,
232
- depPath, interfacePath, depBuf.getError ().message ());
233
229
return nullptr ;
234
230
}
235
231
return std::move (depBuf.get ());
236
232
}
237
233
238
234
static Optional<llvm::vfs::Status> getStatusOfDependency (
239
- llvm::vfs::FileSystem &fs, StringRef depPath, StringRef interfacePath,
240
- DiagnosticEngine &diags, SourceLoc diagnosticLoc) {
235
+ llvm::vfs::FileSystem &fs, StringRef depPath) {
241
236
auto status = fs.status (depPath);
242
237
if (!status) {
243
- diags.diagnose (diagnosticLoc,
244
- diag::missing_dependency_of_module_interface,
245
- depPath, interfacePath, status.getError ().message ());
246
238
return None;
247
239
}
248
240
return status.get ();
@@ -432,8 +424,7 @@ class swift::ParseableInterfaceBuilder {
432
424
if (DepName.startswith (ResourcePath))
433
425
continue ;
434
426
435
- auto Status = getStatusOfDependency (fs, DepName, interfacePath,
436
- diags, diagnosticLoc);
427
+ auto Status = getStatusOfDependency (fs, DepName);
437
428
if (!Status)
438
429
return true ;
439
430
@@ -443,8 +434,7 @@ class swift::ParseableInterfaceBuilder {
443
434
std::unique_ptr<llvm::MemoryBuffer> DepBuf = nullptr ;
444
435
auto getDepBuf = [&]() -> llvm::MemoryBuffer * {
445
436
if (DepBuf) return DepBuf.get ();
446
- if (auto Buf = getBufferOfDependency (fs, DepName, interfacePath,
447
- diags, diagnosticLoc)) {
437
+ if (auto Buf = getBufferOfDependency (fs, DepName)) {
448
438
DepBuf = std::move (Buf);
449
439
return DepBuf.get ();
450
440
}
@@ -644,14 +634,15 @@ struct ModuleRebuildInfo {
644
634
Optional<serialization::Status> serializationStatus;
645
635
ModuleKind kind;
646
636
SmallVector<std::string, 10 > outOfDateDependencies;
637
+ SmallVector<std::string, 10 > missingDependencies;
647
638
};
648
639
SmallVector<OutOfDateModule, 3 > outOfDateModules;
649
640
650
641
OutOfDateModule &getOrInsertOutOfDateModule (StringRef path) {
651
642
for (auto &mod : outOfDateModules) {
652
643
if (mod.path == path) return mod;
653
644
}
654
- outOfDateModules.push_back ({path, None, ModuleKind::Normal, {}});
645
+ outOfDateModules.push_back ({path, None, ModuleKind::Normal, {}, {} });
655
646
return outOfDateModules.back ();
656
647
}
657
648
@@ -674,6 +665,13 @@ struct ModuleRebuildInfo {
674
665
.outOfDateDependencies .push_back (depPath);
675
666
}
676
667
668
+ // / Registers a missing dependency at \c depPath for the module
669
+ // / at \c modulePath.
670
+ void addMissingDependency (StringRef modulePath, StringRef depPath) {
671
+ getOrInsertOutOfDateModule (modulePath)
672
+ .missingDependencies .push_back (depPath);
673
+ }
674
+
677
675
const char *invalidModuleReason (serialization::Status status) {
678
676
using namespace serialization ;
679
677
switch (status) {
@@ -710,6 +708,11 @@ struct ModuleRebuildInfo {
710
708
dep);
711
709
}
712
710
711
+ // Diagnose any missing dependencies in this module.
712
+ for (auto &dep : mod.missingDependencies ) {
713
+ ctx.Diags .diagnose (loc, diag::module_interface_dependency_missing, dep);
714
+ }
715
+
713
716
// If there was a compiled module that wasn't able to be read, diagnose
714
717
// the reason we couldn't read it.
715
718
if (auto status = mod.serializationStatus ) {
@@ -823,31 +826,44 @@ class ParseableInterfaceModuleLoaderImpl {
823
826
return StringRef (scratch.data (), scratch.size ());
824
827
}
825
828
829
+ enum class DependencyStatus {
830
+ UpToDate,
831
+ OutOfDate,
832
+ Missing
833
+ };
834
+
826
835
// Checks that a dependency read from the cached module is up to date compared
827
836
// to the interface file it represents.
828
- bool dependencyIsUpToDate (const FileDependency &dep, StringRef fullPath) {
829
- auto status = getStatusOfDependency (fs, fullPath, interfacePath,
830
- diags, diagnosticLoc);
831
- if (!status) return false ;
837
+ DependencyStatus checkDependency (StringRef modulePath,
838
+ const FileDependency &dep,
839
+ StringRef fullPath) {
840
+ auto status = getStatusOfDependency (fs, fullPath);
841
+ if (!status)
842
+ return DependencyStatus::Missing;
832
843
833
844
// If the sizes differ, then we know the file has changed.
834
- if (status->getSize () != dep.getSize ()) return false ;
845
+ if (status->getSize () != dep.getSize ())
846
+ return DependencyStatus::OutOfDate;
835
847
836
848
// Otherwise, if this dependency is verified by modification time, check
837
849
// it vs. the modification time of the file.
838
850
if (dep.isModificationTimeBased ()) {
839
851
uint64_t mtime =
840
852
status->getLastModificationTime ().time_since_epoch ().count ();
841
- return mtime == dep.getModificationTime ();
853
+ return mtime == dep.getModificationTime () ?
854
+ DependencyStatus::UpToDate :
855
+ DependencyStatus::OutOfDate;
842
856
}
843
857
844
858
// Slow path: if the dependency is verified by content hash, check it vs.
845
859
// the hash of the file.
846
- auto buf = getBufferOfDependency (fs, fullPath, interfacePath,
847
- diags, diagnosticLoc);
848
- if (!buf) return false ;
860
+ auto buf = getBufferOfDependency (fs, fullPath);
861
+ if (!buf)
862
+ return DependencyStatus::Missing ;
849
863
850
- return xxHash64 (buf->getBuffer ()) == dep.getContentHash ();
864
+ return xxHash64 (buf->getBuffer ()) == dep.getContentHash () ?
865
+ DependencyStatus::UpToDate :
866
+ DependencyStatus::OutOfDate;
851
867
}
852
868
853
869
// Check if all the provided file dependencies are up-to-date compared to
@@ -857,13 +873,19 @@ class ParseableInterfaceModuleLoaderImpl {
857
873
SmallString<128 > SDKRelativeBuffer;
858
874
for (auto &in : deps) {
859
875
StringRef fullPath = getFullDependencyPath (in, SDKRelativeBuffer);
860
- if (!dependencyIsUpToDate (in, fullPath)) {
861
- LLVM_DEBUG (llvm::dbgs () << " Dep " << fullPath
862
- << " is directly out of date\n " );
876
+ switch (checkDependency (modulePath, in, fullPath)) {
877
+ case DependencyStatus::UpToDate:
878
+ LLVM_DEBUG (llvm::dbgs () << " Dep " << fullPath << " is up to date\n " );
879
+ break ;
880
+ case DependencyStatus::OutOfDate:
881
+ LLVM_DEBUG (llvm::dbgs () << " Dep " << fullPath << " is out of date\n " );
863
882
rebuildInfo.addOutOfDateDependency (modulePath, fullPath);
864
883
return false ;
884
+ case DependencyStatus::Missing:
885
+ LLVM_DEBUG (llvm::dbgs () << " Dep " << fullPath << " is missing\n " );
886
+ rebuildInfo.addMissingDependency (modulePath, fullPath);
887
+ return false ;
865
888
}
866
- LLVM_DEBUG (llvm::dbgs () << " Dep " << fullPath << " is up to date\n " );
867
889
}
868
890
return true ;
869
891
}
@@ -1148,6 +1170,9 @@ class ParseableInterfaceModuleLoaderImpl {
1148
1170
ModuleRebuildInfo::ModuleKind::Normal);
1149
1171
}
1150
1172
} else if (adjacentModuleBuffer.getError () != notFoundError) {
1173
+ LLVM_DEBUG (llvm::dbgs () << " Found unreadable module at "
1174
+ << modulePath
1175
+ << " ; deferring to serialized module loader\n " );
1151
1176
return std::make_error_code (std::errc::not_supported);
1152
1177
}
1153
1178
0 commit comments