@@ -356,48 +356,39 @@ class swift::ParseableInterfaceBuilder {
356356 return false ;
357357 }
358358
359- // / Populate the provided \p Deps with \c FileDependency entries including:
360- // /
361- // / - All the dependencies mentioned by \p SubInstance's DependencyTracker,
362- // / that were read while compiling the module.
363- // /
364- // / - For any file in the latter set that is itself a .swiftmodule
365- // / living in \p cachePath, all of _its_ dependencies, copied
366- // / out to avoid having to do recursive scanning when rechecking this
367- // / dependency in the future.
359+ // / Determines if the dependency with the provided path is a swiftmodule in
360+ // / either the module cache or prebuilt module cache
361+ bool isCachedModule (StringRef DepName) const {
362+ if (moduleCachePath.empty () && prebuiltCachePath.empty ())
363+ return false ;
364+
365+ auto Ext = llvm::sys::path::extension (DepName);
366+ auto Ty = file_types::lookupTypeForExtension (Ext);
367+
368+ if (Ty != file_types::TY_SwiftModuleFile)
369+ return false ;
370+ if (!moduleCachePath.empty () && DepName.startswith (moduleCachePath))
371+ return true ;
372+ return !prebuiltCachePath.empty () && DepName.startswith (prebuiltCachePath);
373+ }
374+
375+ // / Populate the provided \p Deps with \c FileDependency entries for all
376+ // / dependencies \p SubInstance's DependencyTracker recorded while compiling
377+ // / the module, excepting .swiftmodules in \p moduleCachePath or
378+ // / \p prebuiltCachePath. Those have _their_ dependencies added instead, both
379+ // / to avoid having to do recursive scanning when rechecking this dependency
380+ // / in future and to make the module caches relocatable.
368381 bool collectDepsForSerialization (CompilerInstance &SubInstance,
369382 SmallVectorImpl<FileDependency> &Deps,
370383 bool IsHashBased) {
371384 StringRef SDKPath = SubInstance.getASTContext ().SearchPathOpts .SDKPath ;
372-
373385 auto DTDeps = SubInstance.getDependencyTracker ()->getDependencies ();
374386 SmallVector<StringRef, 16 > InitialDepNames (DTDeps.begin (), DTDeps.end ());
375387 InitialDepNames.push_back (interfacePath);
376388 llvm::StringSet<> AllDepNames;
377- for (auto const &DepName : InitialDepNames) {
378- if (AllDepNames.insert (DepName).second && dependencyTracker) {
379- dependencyTracker->addDependency (DepName, /* isSystem*/ false );
380- }
381-
382- // / Lazily load the dependency buffer if we need it. If we're not
383- // / dealing with a hash-based dependencies, and if the dependency is
384- // / not a .swiftmodule, we can avoid opening the buffer.
385- std::unique_ptr<llvm::MemoryBuffer> DepBuf = nullptr ;
386- auto getDepBuf = [&]() -> llvm::MemoryBuffer * {
387- if (DepBuf) return DepBuf.get ();
388- if (auto Buf = getBufferOfDependency (fs, DepName, interfacePath,
389- diags, diagnosticLoc)) {
390- DepBuf = std::move (Buf);
391- return DepBuf.get ();
392- }
393- return nullptr ;
394- };
395-
396- auto Status = getStatusOfDependency (fs, DepName, interfacePath,
397- diags, diagnosticLoc);
398- if (!Status)
399- return true ;
400389
390+ for (auto const &DepName : InitialDepNames) {
391+ // Adjust the paths of dependences in the SDK to be relative to it
401392 bool IsSDKRelative = false ;
402393 StringRef DepNameToStore = DepName;
403394 if (SDKPath.size () > 1 && DepName.startswith (SDKPath)) {
@@ -418,32 +409,29 @@ class swift::ParseableInterfaceBuilder {
418409 }
419410 }
420411
421- if (IsHashBased) {
422- auto buf = getDepBuf ();
423- if (!buf) return true ;
424- uint64_t hash = xxHash64 (buf->getBuffer ());
425- Deps.push_back (
426- FileDependency::hashBased (DepNameToStore, IsSDKRelative,
427- Status->getSize (), hash));
428- } else {
429- uint64_t mtime =
430- Status->getLastModificationTime ().time_since_epoch ().count ();
431- Deps.push_back (
432- FileDependency::modTimeBased (DepNameToStore, IsSDKRelative,
433- Status->getSize (), mtime));
412+ if (AllDepNames.insert (DepName).second && dependencyTracker) {
413+ dependencyTracker->addDependency (DepName, /* isSystem*/ IsSDKRelative);
434414 }
435415
436- if (moduleCachePath.empty ())
437- continue ;
416+ // / Lazily load the dependency buffer if we need it. If we're not
417+ // / dealing with a hash-based dependencies, and if the dependency is
418+ // / not a .swiftmodule, we can avoid opening the buffer.
419+ std::unique_ptr<llvm::MemoryBuffer> DepBuf = nullptr ;
420+ auto getDepBuf = [&]() -> llvm::MemoryBuffer * {
421+ if (DepBuf) return DepBuf.get ();
422+ if (auto Buf = getBufferOfDependency (fs, DepName, interfacePath,
423+ diags, diagnosticLoc)) {
424+ DepBuf = std::move (Buf);
425+ return DepBuf.get ();
426+ }
427+ return nullptr ;
428+ };
438429
439- // If Dep is itself a .swiftmodule in the cache dir, pull out its deps
440- // and include them in our own, so we have a single-file view of
441- // transitive deps: removes redundancies, and avoids opening and reading
442- // multiple swiftmodules during future loads.
443- auto Ext = llvm::sys::path::extension (DepName);
444- auto Ty = file_types::lookupTypeForExtension (Ext);
445- if (Ty == file_types::TY_SwiftModuleFile &&
446- DepName.startswith (moduleCachePath)) {
430+ // If Dep is itself a cached .swiftmodule, pull out its deps and include
431+ // them in our own, so we have a single-file view of transitive deps:
432+ // removes redundancies, makes the cache more relocatable, and avoids
433+ // opening and reading multiple swiftmodules during future loads.
434+ if (isCachedModule (DepName)) {
447435 auto buf = getDepBuf ();
448436 if (!buf) return true ;
449437 SmallVector<FileDependency, 16 > SubDeps;
@@ -459,10 +447,32 @@ class swift::ParseableInterfaceBuilder {
459447 if (AllDepNames.insert (SubDep.getPath ()).second ) {
460448 Deps.push_back (SubDep);
461449 if (dependencyTracker)
462- dependencyTracker->addDependency (SubDep. getPath (),
463- /* IsSystem=*/ false );
450+ dependencyTracker->addDependency (
451+ SubDep. getPath (), /* IsSystem=*/ SubDep. isSDKRelative () );
464452 }
465453 }
454+ continue ;
455+ }
456+
457+ // Otherwise, include this dependency directly
458+ auto Status = getStatusOfDependency (fs, DepName, interfacePath,
459+ diags, diagnosticLoc);
460+ if (!Status)
461+ return true ;
462+
463+ if (IsHashBased) {
464+ auto buf = getDepBuf ();
465+ if (!buf) return true ;
466+ uint64_t hash = xxHash64 (buf->getBuffer ());
467+ Deps.push_back (
468+ FileDependency::hashBased (DepNameToStore, IsSDKRelative,
469+ Status->getSize (), hash));
470+ } else {
471+ uint64_t mtime =
472+ Status->getLastModificationTime ().time_since_epoch ().count ();
473+ Deps.push_back (
474+ FileDependency::modTimeBased (DepNameToStore, IsSDKRelative,
475+ Status->getSize (), mtime));
466476 }
467477 }
468478 return false ;
0 commit comments