[ExplicitModule] Fix canImport lookup for swift explicit module build

Previously, canImport lookup is not completely working with explicit
module due to two issues:
* For clang modules, canImport check still do a full modulemap lookup
  which is repeated work from scanner. For caching builds, this lookup
  cannot be performed because all modulemap and search path are dropped
  after scanning.
* For swift module, if the canImport module was never actually imported
  later, this canImport check will fail during the actual compilation,
  causing different dependencies in the actual compilation.

To fix the problem, first unified the lookup method for clang and swift
module, which will only lookup the module dependencies reported by
scanner to determine if `canImport` succeed or not. Secondly, add all
the successful `canImport` check modules into the dependency of the
current module so this information can be used during actual
compilation.

Note the behavior change here is that if a module is only checked in
`canImport` but never imported still needs to be built. Comparing to
implicit module build, this can bring in additional clang modules if
they are only check inside `canImport` but should not increase work for
swift modules (where binary module needs to be on disk anyway) or the
most common usecase for `canImport` which is to check the same module
before importing.

rdar://121082031
This commit is contained in:
Steven Wu
2024-01-17 11:11:35 -08:00
parent 517d187a83
commit 4fb7abc9f9
8 changed files with 226 additions and 23 deletions

View File

@@ -428,10 +428,18 @@ ModuleDependencyScanner::getMainModuleDependencyInfo(
for (auto fileUnit : mainModule->getFiles()) {
auto sf = dyn_cast<SourceFile>(fileUnit);
if (!sf)
continue;
continue;
mainDependencies.addModuleImport(*sf, alreadyAddedModules);
}
// Add all the successful canImport checks from the ASTContext as part of
// the dependency since only mainModule can have `canImport` check. This
// needs to happen after visiting all the top-level decls from all
// SourceFiles.
for (auto &Module :
mainModule->getASTContext().getSuccessfulCanImportCheckNames())
mainDependencies.addModuleImport(Module.first(), &alreadyAddedModules);
}
return mainDependencies;