@@ -392,29 +392,13 @@ std::error_code SerializedModuleLoaderBase::openModuleFile(
392392 return std::error_code ();
393393}
394394
395- llvm::ErrorOr< SerializedModuleLoaderBase::BinaryModuleImports>
395+ SerializedModuleLoaderBase::BinaryModuleImports
396396SerializedModuleLoaderBase::getImportsOfModule (
397- Twine modulePath, ModuleLoadingBehavior transitiveBehavior,
398- bool isFramework, bool isRequiredOSSAModules, StringRef SDKName,
399- StringRef packageName, llvm::vfs::FileSystem *fileSystem,
400- PathObfuscator &recoverer) {
401- auto moduleBuf = fileSystem->getBufferForFile (modulePath);
402- if (!moduleBuf)
403- return moduleBuf.getError ();
404-
397+ const ModuleFileSharedCore &loadedModuleFile,
398+ ModuleLoadingBehavior transitiveBehavior, StringRef packageName) {
405399 llvm::StringSet<> importedModuleNames;
406400 std::string importedHeader = " " ;
407- std::shared_ptr<const ModuleFileSharedCore> loadedModuleFile;
408- serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load (
409- " " , " " , std::move (moduleBuf.get ()), nullptr , nullptr , isFramework,
410- isRequiredOSSAModules,
411- SDKName, recoverer, loadedModuleFile);
412-
413- // If failed to load, just ignore and return do not found.
414- if (loadInfo.status != serialization::Status::Valid)
415- return std::make_error_code (std::errc::no_such_file_or_directory);
416-
417- for (const auto &dependency : loadedModuleFile->getDependencies ()) {
401+ for (const auto &dependency : loadedModuleFile.getDependencies ()) {
418402 if (dependency.isHeader ()) {
419403 assert (importedHeader.empty () &&
420404 " Unexpected more than one header dependency" );
@@ -423,11 +407,11 @@ SerializedModuleLoaderBase::getImportsOfModule(
423407 }
424408
425409 ModuleLoadingBehavior dependencyTransitiveBehavior =
426- loadedModuleFile-> getTransitiveLoadingBehavior (
410+ loadedModuleFile. getTransitiveLoadingBehavior (
427411 dependency,
428412 /* debuggerMode*/ false ,
429413 /* isPartialModule*/ false , packageName,
430- loadedModuleFile-> isTestable ());
414+ loadedModuleFile. isTestable ());
431415 if (dependencyTransitiveBehavior > transitiveBehavior)
432416 continue ;
433417
@@ -441,41 +425,60 @@ SerializedModuleLoaderBase::getImportsOfModule(
441425 importedModuleNames.insert (moduleName);
442426 }
443427
444- return SerializedModuleLoaderBase::BinaryModuleImports{importedModuleNames, importedHeader};
428+ return SerializedModuleLoaderBase::BinaryModuleImports{importedModuleNames,
429+ importedHeader};
445430}
446431
447432llvm::ErrorOr<ModuleDependencyInfo>
448- SerializedModuleLoaderBase::scanModuleFile (Twine modulePath, bool isFramework) {
433+ SerializedModuleLoaderBase::scanModuleFile (Twine modulePath, bool isFramework,
434+ bool isTestableImport) {
449435 const std::string moduleDocPath;
450436 const std::string sourceInfoPath;
437+
438+ // Read and valid module.
439+ auto moduleBuf = Ctx.SourceMgr .getFileSystem ()->getBufferForFile (modulePath);
440+ if (!moduleBuf)
441+ return moduleBuf.getError ();
442+
443+ std::shared_ptr<const ModuleFileSharedCore> loadedModuleFile;
444+ serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load (
445+ " " , " " , std::move (moduleBuf.get ()), nullptr , nullptr , isFramework,
446+ isRequiredOSSAModules (), Ctx.LangOpts .SDKName ,
447+ Ctx.SearchPathOpts .DeserializedPathRecoverer , loadedModuleFile);
448+
449+ if (!Ctx.SearchPathOpts .NoScannerModuleValidation ) {
450+ // If failed to load, just ignore and return do not found.
451+ if (loadInfo.status != serialization::Status::Valid) {
452+ if (Ctx.LangOpts .EnableModuleLoadingRemarks )
453+ Ctx.Diags .diagnose (SourceLoc (), diag::skip_module_invalid,
454+ modulePath.str ());
455+ return std::make_error_code (std::errc::no_such_file_or_directory);
456+ }
457+
458+ if (loadedModuleFile->isTestable () && !isTestableImport) {
459+ if (Ctx.LangOpts .EnableModuleLoadingRemarks )
460+ Ctx.Diags .diagnose (SourceLoc (), diag::skip_module_testable,
461+ modulePath.str ());
462+ return std::make_error_code (std::errc::no_such_file_or_directory);
463+ }
464+ }
465+
451466 // Some transitive dependencies of binary modules are not required to be
452467 // imported during normal builds.
453468 // TODO: This is worth revisiting for debugger purposes where
454469 // loading the module is optional, and implementation-only imports
455470 // from modules with testing enabled where the dependency is
456471 // optional.
457- ModuleLoadingBehavior transitiveLoadingBehavior =
458- ModuleLoadingBehavior::Required;
459- auto binaryModuleImports = getImportsOfModule (
460- modulePath, transitiveLoadingBehavior, isFramework,
461- isRequiredOSSAModules (),
462- Ctx.LangOpts .SDKName , Ctx.LangOpts .PackageName ,
463- Ctx.SourceMgr .getFileSystem ().get (),
464- Ctx.SearchPathOpts .DeserializedPathRecoverer );
465- if (!binaryModuleImports)
466- return binaryModuleImports.getError ();
472+ auto binaryModuleImports =
473+ getImportsOfModule (*loadedModuleFile, ModuleLoadingBehavior::Required,
474+ Ctx.LangOpts .PackageName );
467475
468476 // Lookup optional imports of this module also
469- auto binaryModuleOptionalImports = getImportsOfModule (
470- modulePath, ModuleLoadingBehavior::Optional, isFramework,
471- isRequiredOSSAModules (),
472- Ctx.LangOpts .SDKName , Ctx.LangOpts .PackageName ,
473- Ctx.SourceMgr .getFileSystem ().get (),
474- Ctx.SearchPathOpts .DeserializedPathRecoverer );
475- if (!binaryModuleOptionalImports)
476- return binaryModuleImports.getError ();
477+ auto binaryModuleOptionalImports =
478+ getImportsOfModule (*loadedModuleFile, ModuleLoadingBehavior::Optional,
479+ Ctx.LangOpts .PackageName );
477480
478- auto importedModuleSet = binaryModuleImports.get (). moduleImports ;
481+ auto importedModuleSet = binaryModuleImports.moduleImports ;
479482 std::vector<std::string> importedModuleNames;
480483 importedModuleNames.reserve (importedModuleSet.size ());
481484 llvm::transform (importedModuleSet.keys (),
@@ -484,8 +487,8 @@ SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework) {
484487 return N.str ();
485488 });
486489
487- auto importedHeader = binaryModuleImports.get (). headerImport ;
488- auto &importedOptionalModuleSet = binaryModuleOptionalImports.get (). moduleImports ;
490+ auto importedHeader = binaryModuleImports.headerImport ;
491+ auto &importedOptionalModuleSet = binaryModuleOptionalImports.moduleImports ;
489492 std::vector<std::string> importedOptionalModuleNames;
490493 for (const auto optionalImportedModule : importedOptionalModuleSet.keys ())
491494 if (!importedModuleSet.contains (optionalImportedModule))
@@ -794,7 +797,8 @@ bool SerializedModuleLoaderBase::findModule(
794797 auto result = findModuleFilesInDirectory (
795798 moduleID, absoluteBaseName, moduleInterfacePath,
796799 moduleInterfaceSourcePath, moduleBuffer, moduleDocBuffer,
797- moduleSourceInfoBuffer, skipBuildingInterface, isFramework);
800+ moduleSourceInfoBuffer, skipBuildingInterface, isFramework,
801+ isTestableDependencyLookup);
798802 if (!result)
799803 return true ;
800804 if (result == std::errc::not_supported)
0 commit comments