diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index dfcaadeac7533..cc99b57120491 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -1074,6 +1074,9 @@ class ASTContext final { /// Does any proper bookkeeping to keep all module loaders up to date as well. void addSearchPath(StringRef searchPath, bool isFramework, bool isSystem); + /// Adds the path to the explicitly built module \c name. + void addExplicitModulePath(StringRef name, std::string path); + /// Adds a module loader to this AST context. /// /// \param loader The new module loader, which will be added after any @@ -1087,7 +1090,7 @@ class ASTContext final { /// interface. void addModuleLoader(std::unique_ptr loader, bool isClang = false, bool isDWARF = false, - bool IsInterface = false); + bool IsInterface = false, bool IsExplicit = false); /// Add a module interface checker to use for this AST context. void addModuleInterfaceChecker(std::unique_ptr checker); diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h index 39091dcd3ad78..70774ef3bdaa7 100644 --- a/include/swift/AST/Module.h +++ b/include/swift/AST/Module.h @@ -858,6 +858,13 @@ class ModuleDecl /// returns true. bool isSubmoduleOf(const ModuleDecl *M) const; +private: + std::string CacheKey; + +public: + void setCacheKey(const std::string &key) { CacheKey = key; } + StringRef getCacheKey() const { return CacheKey; } + bool isResilient() const { return getResilienceStrategy() != ResilienceStrategy::Default; } diff --git a/include/swift/AST/SearchPathOptions.h b/include/swift/AST/SearchPathOptions.h index f8101fe93db68..f6fd586b2f5ec 100644 --- a/include/swift/AST/SearchPathOptions.h +++ b/include/swift/AST/SearchPathOptions.h @@ -45,7 +45,7 @@ enum class ModuleLoadingMode { PreferInterface, PreferSerialized, OnlyInterface, - OnlySerialized + OnlySerialized, }; /// A single module search path that can come from different sources, e.g. diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index 3e89fc1062711..8c4eb2475fbc5 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -459,6 +459,9 @@ namespace swift { bool EnableDeserializationSafety = ::getenv("SWIFT_ENABLE_DESERIALIZATION_SAFETY"); + /// Disable injecting deserializes module paths into the explict module map. + bool DisableDeserializationOfExplicitPaths = false; + /// Attempt to recover for imported modules with broken modularization /// in an unsafe way. Currently applies only to xrefs where the target /// decl moved to a different module that is already loaded. diff --git a/include/swift/Frontend/ModuleInterfaceLoader.h b/include/swift/Frontend/ModuleInterfaceLoader.h index c1cbdb7ed7d85..a5fadd951074b 100644 --- a/include/swift/Frontend/ModuleInterfaceLoader.h +++ b/include/swift/Frontend/ModuleInterfaceLoader.h @@ -152,8 +152,9 @@ class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase { std::unique_ptr *moduleBuffer, std::unique_ptr *moduleDocBuffer, std::unique_ptr *moduleSourceInfoBuffer, - bool isCanImportLookup, bool isTestableDependencyLookup, - bool &isFramework, bool &isSystemModule) override; + std::string *cacheKey, bool isCanImportLookup, + bool isTestableDependencyLookup, bool &isFramework, + bool &isSystemModule) override; std::error_code findModuleFilesInDirectory( ImportPath::Element ModuleID, const SerializedModuleBaseName &BaseName, @@ -181,6 +182,7 @@ class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase { const llvm::StringMap &ExplicitSwiftModuleInputs, bool IgnoreSwiftSourceInfoFile); + void addExplicitModulePath(StringRef name, std::string path) override; /// Append visible module names to \p names. Note that names are possibly /// duplicated, and not guaranteed to be ordered in any way. void collectVisibleTopLevelModuleNames( @@ -201,8 +203,9 @@ class ExplicitCASModuleLoader : public SerializedModuleLoaderBase { std::unique_ptr *moduleBuffer, std::unique_ptr *moduleDocBuffer, std::unique_ptr *moduleSourceInfoBuffer, - bool isCanImportLookup, bool isTestableDependencyLookup, - bool &isFramework, bool &isSystemModule) override; + std::string *cacheKey, bool isCanImportLookup, + bool isTestableDependencyLookup, bool &isFramework, + bool &isSystemModule) override; std::error_code findModuleFilesInDirectory( ImportPath::Element ModuleID, const SerializedModuleBaseName &BaseName, diff --git a/include/swift/Serialization/SerializedModuleLoader.h b/include/swift/Serialization/SerializedModuleLoader.h index c137370177bdf..5e1231640c8a3 100644 --- a/include/swift/Serialization/SerializedModuleLoader.h +++ b/include/swift/Serialization/SerializedModuleLoader.h @@ -103,8 +103,8 @@ class SerializedModuleLoaderBase : public ModuleLoader { std::unique_ptr *moduleBuffer, std::unique_ptr *moduleDocBuffer, std::unique_ptr *moduleSourceInfoBuffer, - bool isCanImportLookup, bool isTestableDependencyLookup, - bool &isFramework, bool &isSystemModule); + std::string *CacheKey, bool isCanImportLookup, + bool isTestableDependencyLookup, bool &isFramework, bool &isSystemModule); /// Attempts to search the provided directory for a loadable serialized /// .swiftmodule with the provided `ModuleFilename`. Subclasses must @@ -268,6 +268,8 @@ class SerializedModuleLoaderBase : public ModuleLoader { /// A textual reason why the compiler rejected a binary module load /// attempt with a given status, to be used for diagnostic output. static std::optional invalidModuleReason(serialization::Status status); + + virtual void addExplicitModulePath(StringRef name, std::string path) {}; }; /// Imports serialized Swift modules into an ASTContext. diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 0acc541f5eff9..91765c5271b33 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -19,8 +19,8 @@ #include "ClangTypeConverter.h" #include "ForeignRepresentationInfo.h" #include "SubstitutionMapStorage.h" -#include "swift/AST/ASTContextGlobalCache.h" #include "swift/ABI/MetadataValues.h" +#include "swift/AST/ASTContextGlobalCache.h" #include "swift/AST/AvailabilityContextStorage.h" #include "swift/AST/ClangModuleLoader.h" #include "swift/AST/ConcreteDeclRef.h" @@ -67,6 +67,8 @@ #include "swift/Basic/Statistic.h" #include "swift/Basic/StringExtras.h" #include "swift/ClangImporter/ClangModule.h" +#include "swift/Frontend/ModuleInterfaceLoader.h" +#include "swift/Serialization/SerializedModuleLoader.h" #include "swift/Strings.h" #include "swift/Subsystems.h" #include "swift/SymbolGraphGen/SymbolGraphOptions.h" @@ -445,6 +447,9 @@ struct ASTContext::Implementation { /// Singleton used to cache the import graph. swift::namelookup::ImportCache TheImportCache; + /// The module loader used to load explicit Swift modules. + SerializedModuleLoaderBase *TheExplicitSwiftModuleLoader = nullptr; + /// The module loader used to load Clang modules. ClangModuleLoader *TheClangModuleLoader = nullptr; @@ -2159,14 +2164,23 @@ void ASTContext::addSearchPath(StringRef searchPath, bool isFramework, clangLoader->addSearchPath(searchPath, isFramework, isSystem); } +void ASTContext::addExplicitModulePath(StringRef name, std::string path) { + if (getImpl().TheExplicitSwiftModuleLoader) + getImpl().TheExplicitSwiftModuleLoader->addExplicitModulePath(name, path); +} + void ASTContext::addModuleLoader(std::unique_ptr loader, - bool IsClang, bool IsDwarf, bool IsInterface) { + bool IsClang, bool IsDwarf, bool IsInterface, + bool IsExplicit) { if (IsClang && !IsDwarf && !getImpl().TheClangModuleLoader) getImpl().TheClangModuleLoader = static_cast(loader.get()); if (IsClang && IsDwarf && !getImpl().TheDWARFModuleLoader) getImpl().TheDWARFModuleLoader = static_cast(loader.get()); + if (IsExplicit && !getImpl().TheExplicitSwiftModuleLoader) + getImpl().TheExplicitSwiftModuleLoader = + static_cast(loader.get()); getImpl().ModuleLoaders.push_back(std::move(loader)); } diff --git a/lib/DependencyScan/ScanDependencies.cpp b/lib/DependencyScan/ScanDependencies.cpp index 934076ae9961f..ad22f0cbb089b 100644 --- a/lib/DependencyScan/ScanDependencies.cpp +++ b/lib/DependencyScan/ScanDependencies.cpp @@ -1497,7 +1497,6 @@ bool swift::dependencies::scanDependencies(CompilerInstance &CI) { ctx.Allocate(); ModuleDependenciesCache cache(CI.getMainModule()->getNameStr().str(), CI.getInvocation().getModuleScanningHash()); - if (service->setupCachingDependencyScanningService(CI)) return true; diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 89e0e7238ffeb..7e196020dfe4c 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -870,7 +870,7 @@ bool CompilerInstance::setUpModuleLoaders() { // Install an explicit module loader if it was created earlier. if (ESML) { this->DefaultSerializedLoader = ESML.get(); - Context->addModuleLoader(std::move(ESML)); + Context->addModuleLoader(std::move(ESML), false, false, false, true); } if (!ExplicitModuleBuild) { diff --git a/lib/Frontend/ModuleInterfaceLoader.cpp b/lib/Frontend/ModuleInterfaceLoader.cpp index ec3a53d8ec57f..1f5343d664380 100644 --- a/lib/Frontend/ModuleInterfaceLoader.cpp +++ b/lib/Frontend/ModuleInterfaceLoader.cpp @@ -2304,8 +2304,8 @@ bool ExplicitSwiftModuleLoader::findModule( std::unique_ptr *ModuleBuffer, std::unique_ptr *ModuleDocBuffer, std::unique_ptr *ModuleSourceInfoBuffer, - bool IsCanImportLookup, bool isTestableDependencyLookup, - bool &IsFramework, bool &IsSystemModule) { + std::string *cacheKey, bool IsCanImportLookup, + bool isTestableDependencyLookup, bool &IsFramework, bool &IsSystemModule) { // Find a module with an actual, physical name on disk, in case // -module-alias is used (otherwise same). // @@ -2473,6 +2473,12 @@ ExplicitSwiftModuleLoader::create(ASTContext &ctx, return result; } +void ExplicitSwiftModuleLoader::addExplicitModulePath(StringRef name, + std::string path) { + ExplicitSwiftModuleInputInfo entry(path, {}, {}, {}); + Impl.ExplicitModuleMap.try_emplace(name, std::move(entry)); +} + struct ExplicitCASModuleLoader::Implementation { ASTContext &Ctx; llvm::BumpPtrAllocator Allocator; @@ -2660,8 +2666,8 @@ bool ExplicitCASModuleLoader::findModule( std::unique_ptr *ModuleBuffer, std::unique_ptr *ModuleDocBuffer, std::unique_ptr *ModuleSourceInfoBuffer, - bool IsCanImportLookup, bool IsTestableDependencyLookup, - bool &IsFramework, bool &IsSystemModule) { + std::string *CacheKey, bool IsCanImportLookup, + bool IsTestableDependencyLookup, bool &IsFramework, bool &IsSystemModule) { // Find a module with an actual, physical name on disk, in case // -module-alias is used (otherwise same). // @@ -2681,6 +2687,8 @@ bool ExplicitCASModuleLoader::findModule( // Set IsFramework bit according to the moduleInfo IsFramework = moduleInfo.isFramework; IsSystemModule = moduleInfo.isSystem; + if (CacheKey && moduleInfo.moduleCacheKey) + *CacheKey = *moduleInfo.moduleCacheKey; // Fallback check for module cache key passed on command-line as module path. std::string moduleCASID = moduleInfo.moduleCacheKey diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp index e08c44ec0cd0f..2f8a847cf5bbb 100644 --- a/lib/Serialization/ModuleFile.cpp +++ b/lib/Serialization/ModuleFile.cpp @@ -210,6 +210,10 @@ ModuleFile::loadDependenciesForFileContext(const FileUnit *file, auto importPath = builder.copyTo(ctx); auto modulePath = importPath.getModulePath(dependency.isScoped()); auto accessPath = importPath.getAccessPath(dependency.isScoped()); + if (!getContext().LangOpts.DisableDeserializationOfExplicitPaths && + !dependency.Core.BinaryModulePath.empty()) + ctx.addExplicitModulePath(modulePath.front().Item.str(), + dependency.Core.BinaryModulePath.str()); auto module = getModule(modulePath, /*allowLoading*/true); if (!module || module->failedToLoad()) { diff --git a/lib/Serialization/ModuleFileSharedCore.cpp b/lib/Serialization/ModuleFileSharedCore.cpp index 98dca3cfdf402..77ca9daa48c90 100644 --- a/lib/Serialization/ModuleFileSharedCore.cpp +++ b/lib/Serialization/ModuleFileSharedCore.cpp @@ -1561,9 +1561,9 @@ ModuleFileSharedCore::ModuleFileSharedCore( unsigned rawImportControl; bool scoped; bool hasSPI; - input_block::ImportedModuleLayout::readRecord(scratch, - rawImportControl, - scoped, hasSPI); + bool hasPath; + input_block::ImportedModuleLayout::readRecord( + scratch, rawImportControl, scoped, hasSPI, hasPath); auto importKind = getActualImportControl(rawImportControl); if (!importKind) { // We don't know how to import this dependency. @@ -1580,14 +1580,25 @@ ModuleFileSharedCore::ModuleFileSharedCore( unsigned recordID = fatalIfUnexpected( cursor.readRecord(entry.ID, scratch, &spiBlob)); assert(recordID == input_block::IMPORTED_MODULE_SPIS); - input_block::ImportedModuleLayoutSPI::readRecord(scratch); - (void) recordID; - } else { - spiBlob = StringRef(); + input_block::ImportedModuleSPILayout::readRecord(scratch); + (void)recordID; + } + + StringRef pathBlob; + if (hasPath) { + scratch.clear(); + + llvm::BitstreamEntry entry = + fatalIfUnexpected(cursor.advance(AF_DontPopBlockAtEnd)); + unsigned recordID = fatalIfUnexpected( + cursor.readRecord(entry.ID, scratch, &pathBlob)); + assert(recordID == input_block::IMPORTED_MODULE_PATH); + input_block::ImportedModulePathLayout::readRecord(scratch); + (void)recordID; } Dependencies.push_back( - {blobData, spiBlob, importKind.value(), scoped}); + {blobData, spiBlob, pathBlob, importKind.value(), scoped}); break; } case input_block::LINK_LIBRARY: { diff --git a/lib/Serialization/ModuleFileSharedCore.h b/lib/Serialization/ModuleFileSharedCore.h index ca0a132e82bb0..32c213d8ac853 100644 --- a/lib/Serialization/ModuleFileSharedCore.h +++ b/lib/Serialization/ModuleFileSharedCore.h @@ -123,6 +123,7 @@ class ModuleFileSharedCore { public: const StringRef RawPath; const StringRef RawSPIs; + const StringRef BinaryModulePath; private: using ImportFilterKind = ModuleDecl::ImportFilterKind; @@ -137,27 +138,26 @@ class ModuleFileSharedCore { return static_cast(1 << RawImportControl); } - Dependency(StringRef path, StringRef spiGroups, bool isHeader, - ImportFilterKind importControl, bool isScoped) - : RawPath(path), - RawSPIs(spiGroups), + Dependency(StringRef path, StringRef spiGroups, StringRef binaryModulePath, + bool isHeader, ImportFilterKind importControl, bool isScoped) + : RawPath(path), RawSPIs(spiGroups), BinaryModulePath(binaryModulePath), RawImportControl(rawControlFromKind(importControl)), - IsHeader(isHeader), - IsScoped(isScoped) { + IsHeader(isHeader), IsScoped(isScoped) { assert(llvm::popcount(static_cast(importControl)) == 1 && "must be a particular filter option, not a bitset"); assert(getImportControl() == importControl && "not enough bits"); } public: - Dependency(StringRef path, StringRef spiGroups, - ImportFilterKind importControl, bool isScoped) - : Dependency(path, spiGroups, false, importControl, isScoped) {} - - static Dependency forHeader(StringRef headerPath, bool exported) { - auto importControl = - exported ? ImportFilterKind::Exported : ImportFilterKind::Default; - return Dependency(headerPath, StringRef(), true, importControl, false); + Dependency(StringRef path, StringRef spiGroups, StringRef binaryModulePath, + ImportFilterKind importControl, bool isScoped) + : Dependency(path, spiGroups, binaryModulePath, false, importControl, + isScoped) {} + + static Dependency forHeader(StringRef headerPath, bool exported) { + auto importControl = + exported ? ImportFilterKind::Exported : ImportFilterKind::Default; + return Dependency(headerPath, {}, {}, true, importControl, false); } bool isExported() const { diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index b2d9408be5655..fcd082d0c3b29 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 968; // @inout result convention +const uint16_t SWIFTMODULE_VERSION_MINOR = 969; // Module import paths /// A standard hash seed used for all string hashes in a serialized module. /// @@ -1131,6 +1131,7 @@ namespace input_block { DEPENDENCY_DIRECTORY, MODULE_INTERFACE_PATH, IMPORTED_MODULE_SPIS, + IMPORTED_MODULE_PATH, EXTERNAL_MACRO, }; @@ -1139,16 +1140,22 @@ namespace input_block { ImportControlField, // import kind BCFixed<1>, // scoped? BCFixed<1>, // has spis? - BCBlob // module name, with submodule path pieces separated by \0s. - // If the 'scoped' flag is set, the final path piece is an access - // path within the module. + BCFixed<1>, // has path? + BCBlob // module name, with submodule path pieces separated by \0s. If the + // 'scoped' flag is set, the final path piece is an access path + // within the module. >; - using ImportedModuleLayoutSPI = BCRecordLayout< + using ImportedModuleSPILayout = BCRecordLayout< IMPORTED_MODULE_SPIS, BCBlob // SPI names, separated by \0s >; + using ImportedModulePathLayout = BCRecordLayout< + IMPORTED_MODULE_PATH, + BCBlob // Module file path + >; + using ExternalMacroLayout = BCRecordLayout< EXTERNAL_MACRO, ImportControlField, // import kind diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 0ccab47c9e0d7..be73cfa600ddf 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -884,6 +884,7 @@ void Serializer::writeBlockInfoBlock() { BLOCK_RECORD(input_block, DEPENDENCY_DIRECTORY); BLOCK_RECORD(input_block, MODULE_INTERFACE_PATH); BLOCK_RECORD(input_block, IMPORTED_MODULE_SPIS); + BLOCK_RECORD(input_block, IMPORTED_MODULE_PATH); BLOCK_RECORD(input_block, EXTERNAL_MACRO); BLOCK(DECLS_AND_TYPES_BLOCK); @@ -1334,7 +1335,8 @@ static ImportSet getImportsAsSet(const ModuleDecl *M, void Serializer::writeInputBlock() { BCBlockRAII restoreBlock(Out, INPUT_BLOCK_ID, 4); input_block::ImportedModuleLayout importedModule(Out); - input_block::ImportedModuleLayoutSPI ImportedModuleSPI(Out); + input_block::ImportedModuleSPILayout ImportedModuleSPI(Out); + input_block::ImportedModulePathLayout ImportedModulePath(Out); input_block::LinkLibraryLayout LinkLibrary(Out); input_block::ImportedHeaderLayout ImportedHeader(Out); input_block::ImportedHeaderContentsLayout ImportedHeaderContents(Out); @@ -1510,9 +1512,17 @@ void Serializer::writeInputBlock() { llvm::SmallSetVector spis; M->lookupImportedSPIGroups(import.importedModule, spis); - importedModule.emit(ScratchRecord, - static_cast(stableImportControl), - !import.accessPath.empty(), !spis.empty(), importPath); + StringRef path; + if (Options.ExplicitModuleBuild && import.importedModule && + !import.importedModule->isNonSwiftModule()) { + path = import.importedModule->getCacheKey(); + if (path.empty()) + path = import.importedModule->getModuleLoadedFilename(); + } + + importedModule.emit( + ScratchRecord, static_cast(stableImportControl), + !import.accessPath.empty(), !spis.empty(), !path.empty(), importPath); if (!spis.empty()) { SmallString<64> out; @@ -1522,6 +1532,9 @@ void Serializer::writeInputBlock() { [&outStream] { outStream << StringRef("\0", 1); }); ImportedModuleSPI.emit(ScratchRecord, out); } + + if (!path.empty()) + ImportedModulePath.emit(ScratchRecord, path); } if (!Options.ModuleLinkName.empty()) diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index bcedbc8d0471e..31753a574d8e6 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -732,8 +732,8 @@ bool SerializedModuleLoaderBase::findModule( std::unique_ptr *moduleBuffer, std::unique_ptr *moduleDocBuffer, std::unique_ptr *moduleSourceInfoBuffer, - bool isCanImportLookup, bool isTestableDependencyLookup, - bool &isFramework, bool &isSystemModule) { + std::string *cacheKey, bool isCanImportLookup, + bool isTestableDependencyLookup, bool &isFramework, bool &isSystemModule) { // Find a module with an actual, physical name on disk, in case // -module-alias is used (otherwise same). // @@ -1508,12 +1508,13 @@ bool SerializedModuleLoaderBase::canImportModule( bool isSystemModule = false; auto mID = path[0]; - auto found = findModule( - mID, /*moduleInterfacePath=*/nullptr, &moduleInterfaceSourcePath, - &moduleInputBuffer, - /*moduleDocBuffer=*/nullptr, /*moduleSourceInfoBuffer=*/nullptr, - /*isCanImportLookup=*/true, isTestableDependencyLookup, - isFramework, isSystemModule); + auto found = + findModule(mID, /*moduleInterfacePath=*/nullptr, + &moduleInterfaceSourcePath, &moduleInputBuffer, + /*moduleDocBuffer=*/nullptr, + /*moduleSourceInfoBuffer=*/nullptr, /*cacheKey=*/nullptr, + /*isCanImportLookup=*/true, isTestableDependencyLookup, + isFramework, isSystemModule); // If we cannot find the module, don't continue. if (!found) return false; @@ -1597,6 +1598,7 @@ SerializedModuleLoaderBase::loadModule(SourceLoc importLoc, bool isFramework = false; bool isSystemModule = false; + std::string cacheKey; llvm::SmallString<256> moduleInterfacePath; llvm::SmallString<256> moduleInterfaceSourcePath; std::unique_ptr moduleInputBuffer; @@ -1606,10 +1608,9 @@ SerializedModuleLoaderBase::loadModule(SourceLoc importLoc, // Look on disk. if (!findModule(moduleID, &moduleInterfacePath, &moduleInterfaceSourcePath, &moduleInputBuffer, &moduleDocInputBuffer, - &moduleSourceInfoInputBuffer, + &moduleSourceInfoInputBuffer, &cacheKey, /*isCanImportLookup=*/false, - /*isTestableDependencyLookup=*/false, - isFramework, + /*isTestableDependencyLookup=*/false, isFramework, isSystemModule)) { return nullptr; } @@ -1635,6 +1636,7 @@ SerializedModuleLoaderBase::loadModule(SourceLoc importLoc, } M->setHasResolvedImports(); }); + M->setCacheKey(cacheKey); if (dependencyTracker && file) { auto DepPath = file->getFilename(); diff --git a/test/ScanDependencies/optional_transitive_dep_load_fail.swift b/test/ScanDependencies/optional_transitive_dep_load_fail.swift index 6b5ccbb2df19a..698ae416944e9 100644 --- a/test/ScanDependencies/optional_transitive_dep_load_fail.swift +++ b/test/ScanDependencies/optional_transitive_dep_load_fail.swift @@ -37,7 +37,7 @@ // Step 1: build Foo Swift module // RUN: %target-swift-frontend -emit-module %t/Foo.swift -emit-module-path %t/Foo.swiftmodule/%target-swiftmodule-name -module-name Foo -emit-module-interface-path %t/Foo.swiftmodule/%target-swiftinterface-name -enable-library-evolution -I %S/Inputs/CHeaders -I %S/Inputs/Swift -enable-testing -swift-version 5 -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -// Step 2: scan dependencies and ensure the transitive dependency on "A" is misssing +// Step 2: scan dependencies and ensure the transitive dependency on "A" is missing // RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -sdk %t -prebuilt-module-cache-path %t/clang-module-cache // RUN: %validate-json %t/deps.json | %FileCheck -check-prefix CHECK_SCAN %s // CHECK_SCAN-NOT: "swift": "A" diff --git a/test/Serialization/Inputs/a.swift b/test/Serialization/Inputs/a.swift new file mode 100644 index 0000000000000..2028afdf91aa9 --- /dev/null +++ b/test/Serialization/Inputs/a.swift @@ -0,0 +1 @@ +@_exported import B diff --git a/test/Serialization/external_macros.swift b/test/Serialization/external_macros.swift index a497e1cafa1db..27b1594aea762 100644 --- a/test/Serialization/external_macros.swift +++ b/test/Serialization/external_macros.swift @@ -12,15 +12,15 @@ // RUN: -swift-version 5 -external-plugin-path %t#%swift-plugin-server // RUN: llvm-bcanalyzer -dump %t/Test.swiftmodule | %FileCheck %s -// CHECK-COUNT-1: blob data = 'MacroOne' -// CHECK-COUNT-1: blob data = 'MacroTwo' +// CHECK-COUNT-1: blob data = 'MacroOne' +// CHECK-COUNT-1: blob data = 'MacroTwo' // RUN: %target-swift-frontend -emit-module %t/test2.swift -module-name Test2 -o %t/Test2.swiftmodule \ // RUN: -swift-version 5 -external-plugin-path %t#%swift-plugin-server -package-name Test // RUN: llvm-bcanalyzer -dump %t/Test2.swiftmodule | %FileCheck %s --check-prefix CHECK2 -// CHECK2-COUNT-1: blob data = 'MacroOne' -// CHECK2-COUNT-1: blob data = 'MacroTwo' +// CHECK2-COUNT-1: blob data = 'MacroOne' +// CHECK2-COUNT-1: blob data = 'MacroTwo' //--- macro-1.swift import SwiftSyntax diff --git a/test/Serialization/module-dependencies.swift b/test/Serialization/module-dependencies.swift new file mode 100644 index 0000000000000..cc1d0e7de29e6 --- /dev/null +++ b/test/Serialization/module-dependencies.swift @@ -0,0 +1,9 @@ +// RUN: %empty-directory(%t) +// RUN: mkdir %t/a %t/b +// RUN: %target-swift-frontend -emit-module -o %t/b/B.swiftmodule %S/../Inputs/empty.swift -disable-implicit-swift-modules -parse-stdlib +//-no-serialize-debugging-options +// RUN: %target-swift-frontend -emit-module -o %t/a/A.swiftmodule %S/Inputs/a.swift -swift-module-file=B=%t/b/B.swiftmodule -disable-implicit-swift-modules -parse-stdlib + +// Not passing in path to b/B.swiftmodule -- it should be found in the INPUT block. +// RUN: %target-swift-frontend -emit-module -o %t/Library.swiftmodule %s -swift-module-file=A=%t/a/A.swiftmodule -disable-implicit-swift-modules -parse-stdlib +import A