diff --git a/include/swift/AST/DiagnosticsClangImporter.def b/include/swift/AST/DiagnosticsClangImporter.def index 600709b3f2805..288f23b9d4c5d 100644 --- a/include/swift/AST/DiagnosticsClangImporter.def +++ b/include/swift/AST/DiagnosticsClangImporter.def @@ -42,6 +42,8 @@ WARNING(could_not_rewrite_bridging_header,none, ERROR(bridging_header_pch_error,Fatal, "failed to emit precompiled header '%0' for bridging header '%1'", (StringRef, StringRef)) +ERROR(err_rewrite_bridging_header,none, + "failed to serialize bridging header: '%0'", (StringRef)) ERROR(emit_pcm_error,Fatal, "failed to emit precompiled module '%0' for module map '%1'", diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 2905dcdd2d2ed..94006af84f9e5 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -1193,6 +1193,9 @@ REMARK(module_api_import_aliases,none, "%select{, which reexports definition from %2|}3", (const Decl *, ModuleDecl *, ModuleDecl *, bool)) +REMARK(skip_module_invalid,none,"skip invalid swiftmodule: %0", (StringRef)) +REMARK(skip_module_testable,none,"skip swiftmodule built with '-enable-testing': %0", (StringRef)) + REMARK(macro_loaded,none, "loaded macro implementation module %0 from " "%select{shared library '%2'|executable '%2'|" diff --git a/include/swift/AST/ModuleDependencies.h b/include/swift/AST/ModuleDependencies.h index a20807d09c081..c3d6bae702397 100644 --- a/include/swift/AST/ModuleDependencies.h +++ b/include/swift/AST/ModuleDependencies.h @@ -1097,6 +1097,12 @@ class ModuleDependenciesCache { std::optional findDependency(StringRef moduleName) const; + /// Look for known existing dependencies. + /// + /// \returns the cached result. + const ModuleDependencyInfo & + findKnownDependency(const ModuleDependencyID &moduleID) const; + /// Record dependencies for the given module. void recordDependency(StringRef moduleName, ModuleDependencyInfo dependencies); diff --git a/include/swift/AST/SearchPathOptions.h b/include/swift/AST/SearchPathOptions.h index 14ed706c67a95..dd7debcce1351 100644 --- a/include/swift/AST/SearchPathOptions.h +++ b/include/swift/AST/SearchPathOptions.h @@ -38,6 +38,15 @@ enum class ModuleSearchPathKind { RuntimeLibrary, }; +/// Specifies how to load modules when both a module interface and serialized +/// AST are present, or whether to disallow one format or the other altogether. +enum class ModuleLoadingMode { + PreferInterface, + PreferSerialized, + OnlyInterface, + OnlySerialized +}; + /// A single module search path that can come from different sources, e.g. /// framework search paths, import search path etc. class ModuleSearchPath : public llvm::RefCountedBase { @@ -499,6 +508,12 @@ class SearchPathOptions { /// original form. PathObfuscator DeserializedPathRecoverer; + /// Specify the module loading behavior of the compilation. + ModuleLoadingMode ModuleLoadMode = ModuleLoadingMode::PreferSerialized; + + /// Legacy scanner search behavior. + bool NoScannerModuleValidation = false; + /// Return all module search paths that (non-recursively) contain a file whose /// name is in \p Filenames. SmallVector @@ -546,7 +561,9 @@ class SearchPathOptions { RuntimeResourcePath, hash_combine_range(RuntimeLibraryImportPaths.begin(), RuntimeLibraryImportPaths.end()), - DisableModulesValidateSystemDependencies); + DisableModulesValidateSystemDependencies, + NoScannerModuleValidation, + ModuleLoadMode); } /// Return a hash code of any components from these options that should diff --git a/include/swift/ClangImporter/ClangImporter.h b/include/swift/ClangImporter/ClangImporter.h index e5fc22588da83..01d6415d525d1 100644 --- a/include/swift/ClangImporter/ClangImporter.h +++ b/include/swift/ClangImporter/ClangImporter.h @@ -402,8 +402,10 @@ class ClangImporter final : public ClangModuleLoader { getWrapperForModule(const clang::Module *mod, bool returnOverlayIfPossible = false) const override; - std::string getBridgingHeaderContents(StringRef headerPath, off_t &fileSize, - time_t &fileModTime); + std::string + getBridgingHeaderContents(StringRef headerPath, off_t &fileSize, + time_t &fileModTime, + StringRef pchIncludeTree); /// Makes a temporary replica of the ClangImporter's CompilerInstance, reads /// an Objective-C header file into the replica and emits a PCH file of its diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index f30e8b1ede5a1..27098b7cd1a37 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -1337,4 +1337,10 @@ def disable_strict_concurrency_region_based_isolation : Flag<["-"], HelpText<"Disable region based isolation when running with strict concurrency enabled. Only enabled with asserts">, Flags<[HelpHidden]>; +def no_scanner_module_validation: Flag<["-"], "no-scanner-module-validation">, + HelpText<"Do not validate binary modules in scanner and delegate the validation to swift-frontend">; +def module_load_mode: Separate<["-"], "module-load-mode">, + MetaVarName<"only-interface|prefer-interface|prefer-serialized|only-serialized">, + HelpText<"Module loading mode">; + } // end let Flags = [FrontendOption, NoDriverOption, HelpHidden] diff --git a/include/swift/Serialization/ScanningLoaders.h b/include/swift/Serialization/ScanningLoaders.h index 12698ce2af8ce..d3419e1269233 100644 --- a/include/swift/Serialization/ScanningLoaders.h +++ b/include/swift/Serialization/ScanningLoaders.h @@ -34,7 +34,8 @@ class SwiftModuleScanner : public SerializedModuleLoaderBase { /// Scan the given interface file to determine dependencies. llvm::ErrorOr - scanInterfaceFile(Twine moduleInterfacePath, bool isFramework); + scanInterfaceFile(Twine moduleInterfacePath, bool isFramework, + bool isTestableImport); InterfaceSubContextDelegate &astDelegate; diff --git a/include/swift/Serialization/SerializedModuleLoader.h b/include/swift/Serialization/SerializedModuleLoader.h index a51f85d918c8c..8e32a130a7979 100644 --- a/include/swift/Serialization/SerializedModuleLoader.h +++ b/include/swift/Serialization/SerializedModuleLoader.h @@ -16,6 +16,7 @@ #include "swift/AST/FileUnit.h" #include "swift/AST/Module.h" #include "swift/AST/ModuleLoader.h" +#include "swift/AST/SearchPathOptions.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PrefixMapper.h" #include "llvm/TargetParser/Triple.h" @@ -23,20 +24,12 @@ namespace swift { class ModuleFile; class PathObfuscator; +class ModuleFileSharedCore; enum class ModuleLoadingBehavior; namespace file_types { enum ID : uint8_t; } -/// Specifies how to load modules when both a module interface and serialized -/// AST are present, or whether to disallow one format or the other altogether. -enum class ModuleLoadingMode { - PreferInterface, - PreferSerialized, - OnlyInterface, - OnlySerialized -}; - /// How a dependency should be loaded. /// /// \sa getTransitiveLoadingBehavior @@ -170,22 +163,18 @@ class SerializedModuleLoaderBase : public ModuleLoader { } /// Scan the given serialized module file to determine dependencies. - llvm::ErrorOr scanModuleFile(Twine modulePath, bool isFramework); + llvm::ErrorOr + scanModuleFile(Twine modulePath, bool isFramework, bool isTestableImport); struct BinaryModuleImports { llvm::StringSet<> moduleImports; std::string headerImport; }; - static llvm::ErrorOr - getImportsOfModule(Twine modulePath, + static BinaryModuleImports + getImportsOfModule(const ModuleFileSharedCore &loadedModule, ModuleLoadingBehavior transitiveBehavior, - bool isFramework, - bool isRequiredOSSAModules, - StringRef SDKName, - StringRef packageName, - llvm::vfs::FileSystem *fileSystem, - PathObfuscator &recoverer); + StringRef packageName, bool isTestableImport); /// Load the module file into a buffer and also collect its module name. static std::unique_ptr diff --git a/lib/AST/ModuleDependencies.cpp b/lib/AST/ModuleDependencies.cpp index 0a26a5bac8848..8f425281e69e5 100644 --- a/lib/AST/ModuleDependencies.cpp +++ b/lib/AST/ModuleDependencies.cpp @@ -21,6 +21,7 @@ #include "swift/Frontend/Frontend.h" #include "llvm/CAS/CASProvidingFileSystem.h" #include "llvm/CAS/CachingOnDiskFileSystem.h" +#include "llvm/Config/config.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/PrefixMapper.h" @@ -480,6 +481,58 @@ void SwiftDependencyTracker::addCommonSearchPathDeps( // Add VFSOverlay file. for (auto &Overlay: Opts.VFSOverlayFiles) FS->status(Overlay); + + // Add plugin dylibs from the toolchain only by look through the plugin search + // directory. + auto recordFiles = [&](StringRef Path) { + std::error_code EC; + for (auto I = FS->dir_begin(Path, EC); + !EC && I != llvm::vfs::directory_iterator(); I = I.increment(EC)) { + if (I->type() != llvm::sys::fs::file_type::regular_file) + continue; +#if defined(_WIN32) + constexpr StringRef libPrefix{}; + constexpr StringRef libSuffix = ".dll"; +#else + constexpr StringRef libPrefix = "lib"; + constexpr StringRef libSuffix = LTDL_SHLIB_EXT; +#endif + StringRef filename = llvm::sys::path::filename(I->path()); + if (filename.starts_with(libPrefix) && filename.ends_with(libSuffix)) + FS->status(I->path()); + } + }; + for (auto &entry : Opts.PluginSearchOpts) { + switch (entry.getKind()) { + + // '-load-plugin-library '. + case PluginSearchOption::Kind::LoadPluginLibrary: { + auto &val = entry.get(); + FS->status(val.LibraryPath); + break; + } + + // '-load-plugin-executable #, ...'. + case PluginSearchOption::Kind::LoadPluginExecutable: { + // We don't have executable plugin in toolchain. + break; + } + + // '-plugin-path '. + case PluginSearchOption::Kind::PluginPath: { + auto &val = entry.get(); + recordFiles(val.SearchPath); + break; + } + + // '-external-plugin-path #'. + case PluginSearchOption::Kind::ExternalPluginPath: { + auto &val = entry.get(); + recordFiles(val.SearchPath); + break; + } + } + } } void SwiftDependencyTracker::startTracking() { @@ -739,6 +792,13 @@ ModuleDependenciesCache::findDependency(StringRef moduleName) const { return std::nullopt; } +const ModuleDependencyInfo &ModuleDependenciesCache::findKnownDependency( + const ModuleDependencyID &moduleID) const { + auto dep = findDependency(moduleID); + assert(dep && "dependency unknown"); + return **dep; +} + bool ModuleDependenciesCache::hasDependency(const ModuleDependencyID &moduleID) const { return hasDependency(moduleID.ModuleName, moduleID.Kind); } diff --git a/lib/AST/PluginLoader.cpp b/lib/AST/PluginLoader.cpp index 658b28348e1d4..95f1b01ed24a8 100644 --- a/lib/AST/PluginLoader.cpp +++ b/lib/AST/PluginLoader.cpp @@ -17,6 +17,7 @@ #include "swift/Basic/SourceManager.h" #include "swift/Parse/Lexer.h" #include "llvm/Config/config.h" +#include "llvm/Support/VirtualFileSystem.h" using namespace swift; @@ -59,6 +60,15 @@ static StringRef pluginModuleNameStringFromPath(StringRef path) { return ""; } +static llvm::IntrusiveRefCntPtr +getPluginLoadingFS(ASTContext &Ctx) { + // If there is a clang include tree FS, using real file system to load plugin + // as the FS in SourceMgr doesn't support directory iterator. + if (Ctx.ClangImporterOpts.HasClangIncludeTreeRoot) + return llvm::vfs::getRealFileSystem(); + return Ctx.SourceMgr.getFileSystem(); +} + llvm::DenseMap & PluginLoader::getPluginMap() { if (PluginMap.has_value()) { @@ -86,7 +96,7 @@ PluginLoader::getPluginMap() { (void)result; }; - auto fs = Ctx.SourceMgr.getFileSystem(); + auto fs = getPluginLoadingFS(Ctx); std::error_code ec; for (auto &entry : Ctx.SearchPathOpts.PluginSearchOpts) { @@ -162,7 +172,7 @@ PluginLoader::lookupPluginByModuleName(Identifier moduleName) { llvm::Expected PluginLoader::loadLibraryPlugin(StringRef path) { - auto fs = Ctx.SourceMgr.getFileSystem(); + auto fs = getPluginLoadingFS(Ctx); SmallString<128> resolvedPath; if (auto err = fs->getRealPath(path, resolvedPath)) { return llvm::createStringError(err, err.message()); @@ -186,7 +196,7 @@ PluginLoader::loadLibraryPlugin(StringRef path) { llvm::Expected PluginLoader::loadExecutablePlugin(StringRef path) { - auto fs = Ctx.SourceMgr.getFileSystem(); + auto fs = getPluginLoadingFS(Ctx); SmallString<128> resolvedPath; if (auto err = fs->getRealPath(path, resolvedPath)) { return llvm::createStringError(err, err.message()); diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index a9b15c6871231..ec580ce31c305 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -55,13 +55,16 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileEntry.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LangStandard.h" #include "clang/Basic/Module.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" #include "clang/CAS/CASOptions.h" +#include "clang/CAS/IncludeTree.h" #include "clang/CodeGen/ObjectFilePCHContainerOperations.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/FrontendActions.h" +#include "clang/Frontend/IncludeTreePPActions.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Frontend/Utils.h" #include "clang/Index/IndexingAction.h" @@ -80,7 +83,11 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/CAS/CASReference.h" +#include "llvm/CAS/ObjectStore.h" #include "llvm/Support/CrashRecoveryContext.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileCollector.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Memory.h" @@ -1696,8 +1703,13 @@ bool ClangImporter::importHeader(StringRef header, ModuleDecl *adapter, StringRef cachedContents, SourceLoc diagLoc) { clang::FileManager &fileManager = Impl.Instance->getFileManager(); auto headerFile = fileManager.getFile(header, /*OpenFile=*/true); + // Prefer importing the header directly if the header content matches by + // checking size and mod time. This allows correct import if some no-modular + // headers are already imported into clang importer. If mod time is zero, then + // the module should be built from CAS and there is no mod time to verify. if (headerFile && (*headerFile)->getSize() == expectedSize && - (*headerFile)->getModificationTime() == expectedModTime) { + (expectedModTime == 0 || + (*headerFile)->getModificationTime() == expectedModTime)) { return importBridgingHeader(header, adapter, diagLoc, false, true); } @@ -1752,16 +1764,46 @@ bool ClangImporter::importBridgingHeader(StringRef header, ModuleDecl *adapter, std::move(sourceBuffer), implicitImport); } -std::string ClangImporter::getBridgingHeaderContents(StringRef headerPath, - off_t &fileSize, - time_t &fileModTime) { +static llvm::Expected +setupIncludeTreeInput(clang::CompilerInvocation &invocation, + StringRef headerPath, StringRef pchIncludeTree) { + auto DB = invocation.getCASOpts().getOrCreateDatabases(); + if (!DB) + return DB.takeError(); + auto CAS = DB->first; + auto ID = CAS->parseID(pchIncludeTree); + if (!ID) + return ID.takeError(); + auto includeTreeRef = CAS->getReference(*ID); + if (!includeTreeRef) + return llvm::cas::ObjectStore::createUnknownObjectError(*ID); + + invocation.getFrontendOpts().Inputs.push_back(clang::FrontendInputFile( + *includeTreeRef, headerPath, clang::Language::ObjC)); + + return *includeTreeRef; +} + +std::string ClangImporter::getBridgingHeaderContents( + StringRef headerPath, off_t &fileSize, time_t &fileModTime, + StringRef pchIncludeTree) { auto invocation = std::make_shared(*Impl.Invocation); invocation->getFrontendOpts().DisableFree = false; invocation->getFrontendOpts().Inputs.clear(); - invocation->getFrontendOpts().Inputs.push_back( - clang::FrontendInputFile(headerPath, clang::Language::ObjC)); + + std::optional includeTreeRef; + if (pchIncludeTree.empty()) + invocation->getFrontendOpts().Inputs.push_back( + clang::FrontendInputFile(headerPath, clang::Language::ObjC)); + else if (auto err = + setupIncludeTreeInput(*invocation, headerPath, pchIncludeTree) + .moveInto(includeTreeRef)) { + Impl.diagnose({}, diag::err_rewrite_bridging_header, + toString(std::move(err))); + return ""; + } invocation->getPreprocessorOpts().resetNonModularOptions(); @@ -1782,18 +1824,36 @@ std::string ClangImporter::getBridgingHeaderContents(StringRef headerPath, // write to an in-memory buffer. class RewriteIncludesAction : public clang::PreprocessorFrontendAction { raw_ostream &OS; + std::optional includeTreeRef; void ExecuteAction() override { clang::CompilerInstance &compiler = getCompilerInstance(); + // If the input is include tree, setup the IncludeTreePPAction. + if (includeTreeRef) { + auto IncludeTreeRoot = clang::cas::IncludeTreeRoot::get( + compiler.getOrCreateObjectStore(), *includeTreeRef); + if (!IncludeTreeRoot) + llvm::report_fatal_error(IncludeTreeRoot.takeError()); + auto PPCachedAct = + clang::createPPActionsFromIncludeTree(*IncludeTreeRoot); + if (!PPCachedAct) + llvm::report_fatal_error(PPCachedAct.takeError()); + compiler.getPreprocessor().setPPCachedActions( + std::move(*PPCachedAct)); + } + clang::RewriteIncludesInInput(compiler.getPreprocessor(), &OS, compiler.getPreprocessorOutputOpts()); } + public: - explicit RewriteIncludesAction(raw_ostream &os) : OS(os) {} + explicit RewriteIncludesAction( + raw_ostream &os, std::optional includeTree) + : OS(os), includeTreeRef(includeTree) {} }; llvm::raw_string_ostream os(result); - RewriteIncludesAction action(os); + RewriteIncludesAction action(os, includeTreeRef); rewriteInstance.ExecuteAction(action); }); @@ -2514,6 +2574,7 @@ ClangImporter::Implementation::Implementation( !ctx.ClangImporterOpts.BridgingHeader.empty()), DisableOverlayModules(ctx.ClangImporterOpts.DisableOverlayModules), EnableClangSPI(ctx.ClangImporterOpts.EnableClangSPI), + UseClangIncludeTree(ctx.ClangImporterOpts.UseClangIncludeTree), importSymbolicCXXDecls( ctx.LangOpts.hasFeature(Feature::ImportSymbolicCXXDecls)), IsReadingBridgingPCH(false), diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h index c31d51f4279d4..094b06e7aa02e 100644 --- a/lib/ClangImporter/ImporterImpl.h +++ b/lib/ClangImporter/ImporterImpl.h @@ -467,6 +467,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation const bool BridgingHeaderExplicitlyRequested; const bool DisableOverlayModules; const bool EnableClangSPI; + const bool UseClangIncludeTree; bool importSymbolicCXXDecls; bool IsReadingBridgingPCH; diff --git a/lib/DependencyScan/ModuleDependencyScanner.cpp b/lib/DependencyScan/ModuleDependencyScanner.cpp index 9c953020f8481..402e6cf651142 100644 --- a/lib/DependencyScan/ModuleDependencyScanner.cpp +++ b/lib/DependencyScan/ModuleDependencyScanner.cpp @@ -185,7 +185,8 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker( ScanASTContext, *static_cast( ScanASTContext.getModuleInterfaceChecker()), - &DependencyTracker, ModuleLoadingMode::OnlyInterface); + &DependencyTracker, + ScanCompilerInvocation.getSearchPathOptions().ModuleLoadMode); } ModuleDependencyVector diff --git a/lib/DependencyScan/ScanDependencies.cpp b/lib/DependencyScan/ScanDependencies.cpp index 841c4d12b257e..f8f6c3c0f082e 100644 --- a/lib/DependencyScan/ScanDependencies.cpp +++ b/lib/DependencyScan/ScanDependencies.cpp @@ -192,7 +192,7 @@ updateModuleCacheKey(ModuleDependencyInfo &depInfo, } static llvm::Error resolveExplicitModuleInputs( - ModuleDependencyID moduleID, const ModuleDependencyInfo &resolvingDepInfo, + ModuleDependencyID moduleID, const std::set &dependencies, ModuleDependenciesCache &cache, CompilerInstance &instance, std::optional> bridgingHeaderDeps) { @@ -200,6 +200,7 @@ static llvm::Error resolveExplicitModuleInputs( if (moduleID.Kind == ModuleDependencyKind::SwiftPlaceholder) return llvm::Error::success(); + auto &resolvingDepInfo = cache.findKnownDependency(moduleID); // If the dependency is already finalized, nothing needs to be done. if (resolvingDepInfo.isFinalized()) return llvm::Error::success(); @@ -242,13 +243,10 @@ static llvm::Error resolveExplicitModuleInputs( std::vector commandLine = resolvingDepInfo.getCommandline(); for (const auto &depModuleID : dependencies) { - const auto optionalDepInfo = - cache.findDependency(depModuleID); - assert(optionalDepInfo.has_value()); - const auto depInfo = optionalDepInfo.value(); + const auto &depInfo = cache.findKnownDependency(depModuleID); switch (depModuleID.Kind) { case swift::ModuleDependencyKind::SwiftInterface: { - auto interfaceDepDetails = depInfo->getAsSwiftInterfaceModule(); + auto interfaceDepDetails = depInfo.getAsSwiftInterfaceModule(); assert(interfaceDepDetails && "Expected Swift Interface dependency."); auto &path = interfaceDepDetails->moduleCacheKey.empty() ? interfaceDepDetails->moduleOutputPath @@ -257,7 +255,7 @@ static llvm::Error resolveExplicitModuleInputs( path); } break; case swift::ModuleDependencyKind::SwiftBinary: { - auto binaryDepDetails = depInfo->getAsSwiftBinaryModule(); + auto binaryDepDetails = depInfo.getAsSwiftBinaryModule(); assert(binaryDepDetails && "Expected Swift Binary Module dependency."); auto &path = binaryDepDetails->moduleCacheKey.empty() ? binaryDepDetails->compiledModulePath @@ -269,24 +267,23 @@ static llvm::Error resolveExplicitModuleInputs( // order to resolve the header's own header include directives. for (const auto &bridgingHeaderDepName : binaryDepDetails->headerModuleDependencies) { - auto optionalBridgingHeaderDepModuleInfo = cache.findDependency( + auto optionalBridgingHeaderDepModuleInfo = cache.findKnownDependency( {bridgingHeaderDepName, ModuleDependencyKind::Clang}); - assert(optionalDepInfo.has_value()); const auto bridgingHeaderDepModuleDetails = - optionalBridgingHeaderDepModuleInfo.value()->getAsClangModule(); + optionalBridgingHeaderDepModuleInfo.getAsClangModule(); commandLine.push_back( "-fmodule-map-file=" + remapPath(bridgingHeaderDepModuleDetails->moduleMapFile)); } } break; case swift::ModuleDependencyKind::SwiftPlaceholder: { - auto placeholderDetails = depInfo->getAsPlaceholderDependencyModule(); + auto placeholderDetails = depInfo.getAsPlaceholderDependencyModule(); assert(placeholderDetails && "Expected Swift Placeholder dependency."); commandLine.push_back("-swift-module-file=" + depModuleID.ModuleName + "=" + placeholderDetails->compiledModulePath); } break; case swift::ModuleDependencyKind::Clang: { - auto clangDepDetails = depInfo->getAsClangModule(); + auto clangDepDetails = depInfo.getAsClangModule(); assert(clangDepDetails && "Expected Clang Module dependency."); if (!resolvingDepInfo.isClangModule()) { commandLine.push_back("-Xcc"); @@ -303,13 +300,13 @@ static llvm::Error resolveExplicitModuleInputs( } // Only need to merge the CASFS from clang importer. - if (auto ID = depInfo->getCASFSRootID()) + if (auto ID = depInfo.getCASFSRootID()) rootIDs.push_back(*ID); - if (auto ID = depInfo->getClangIncludeTree()) + if (auto ID = depInfo.getClangIncludeTree()) includeTrees.push_back(*ID); } break; case swift::ModuleDependencyKind::SwiftSource: { - if (auto E = addBridgingHeaderDeps(*depInfo)) + if (auto E = addBridgingHeaderDeps(depInfo)) return E; break; } @@ -390,9 +387,8 @@ static llvm::Error resolveExplicitModuleInputs( std::vector newCommandLine = dependencyInfoCopy.getBridgingHeaderCommandline(); for (auto bridgingDep : *bridgingHeaderDeps) { - auto dep = cache.findDependency(bridgingDep); - assert(dep && "unknown clang dependency"); - auto *clangDep = (*dep)->getAsClangModule(); + auto &dep = cache.findKnownDependency(bridgingDep); + auto *clangDep = dep.getAsClangModule(); assert(clangDep && "wrong module dependency kind"); if (!clangDep->moduleCacheKey.empty()) { newCommandLine.push_back("-Xcc"); @@ -406,19 +402,11 @@ static llvm::Error resolveExplicitModuleInputs( dependencyInfoCopy.updateBridgingHeaderCommandLine(newCommandLine); } - if (resolvingDepInfo.isClangModule() || - resolvingDepInfo.isSwiftInterfaceModule()) { - // Compute and update module cache key. - auto Key = updateModuleCacheKey(dependencyInfoCopy, cache, CAS); - if (!Key) - return Key.takeError(); - } - - // For binary module, we need to make sure the lookup key is setup here in - // action cache. We just use the CASID of the binary module itself as key. - if (auto *binaryDep = dependencyInfoCopy.getAsSwiftBinaryModule()) { - auto Ref = - CASFS.getObjectRefForFileContent(binaryDep->compiledModulePath); + // Compute and update module cache key. + auto setupBinaryCacheKey = [&](StringRef path) -> llvm::Error { + // For binary module, we need to make sure the lookup key is setup here in + // action cache. We just use the CASID of the binary module itself as key. + auto Ref = CASFS.getObjectRefForFileContent(path); if (!Ref) return llvm::errorCodeToError(Ref.getError()); assert(*Ref && "Binary module should be loaded into CASFS already"); @@ -432,18 +420,36 @@ static llvm::Error resolveExplicitModuleInputs( if (auto E = instance.getActionCache().put(CAS.getID(**Ref), CAS.getID(*Result))) return E; + return llvm::Error::success(); + }; + + if (resolvingDepInfo.isClangModule() || + resolvingDepInfo.isSwiftInterfaceModule()) { + auto Key = updateModuleCacheKey(dependencyInfoCopy, cache, CAS); + if (!Key) + return Key.takeError(); + } else if (auto *binaryDep = dependencyInfoCopy.getAsSwiftBinaryModule()) { + if (auto E = setupBinaryCacheKey(binaryDep->compiledModulePath)) + return E; } } + dependencyInfoCopy.setIsFinalized(true); cache.updateDependency(moduleID, dependencyInfoCopy); return llvm::Error::success(); } -static llvm::Error pruneUnusedVFSOverlays( - ModuleDependencyID moduleID, const ModuleDependencyInfo &resolvingDepInfo, - const std::set &dependencies, - ModuleDependenciesCache &cache, CompilerInstance &instance) { +static llvm::Error +pruneUnusedVFSOverlays(ModuleDependencyID moduleID, + const std::set &dependencies, + ModuleDependenciesCache &cache, + CompilerInstance &instance) { + // Pruning of unused VFS overlay options for Clang dependencies + // is performed by the Clang dependency scanner. + if (moduleID.Kind == ModuleDependencyKind::Clang) + return llvm::Error::success(); + auto isVFSOverlayFlag = [](StringRef arg) { return arg == "-ivfsoverlay" || arg == "-vfsoverlay"; }; @@ -451,11 +457,7 @@ static llvm::Error pruneUnusedVFSOverlays( return arg == "-Xcc"; }; - // Pruning of unused VFS overlay options for Clang dependencies - // is performed by the Clang dependency scanner. - if (!resolvingDepInfo.isSwiftModule()) - return llvm::Error::success(); - + auto &resolvingDepInfo = cache.findKnownDependency(moduleID); // If this Swift dependency contains any VFS overlay paths, // then attempt to prune the ones not used by any of the Clang dependencies. if (!llvm::any_of(resolvingDepInfo.getCommandline(), @@ -469,10 +471,8 @@ static llvm::Error pruneUnusedVFSOverlays( // pruned by the Clang dependency scanner. llvm::StringSet<> usedVFSOverlayPaths; for (const auto &depModuleID : dependencies) { - const auto optionalDepInfo = cache.findDependency(depModuleID); - assert(optionalDepInfo.has_value()); - const auto depInfo = optionalDepInfo.value(); - if (auto clangDepDetails = depInfo->getAsClangModule()) { + const auto &depInfo = cache.findKnownDependency(depModuleID); + if (auto clangDepDetails = depInfo.getAsClangModule()) { const auto &depCommandLine = clangDepDetails->buildCommandLine; // true if the previous argument was the dash-option of an option pair bool getNext = false; @@ -1158,24 +1158,17 @@ generateFullDependencyGraph(const CompilerInstance &instance, for (size_t i = 0; i < allModules.size(); ++i) { const auto &module = allModules[i]; - // Grab the completed module dependencies. - auto moduleDepsQuery = cache.findDependency(module); - if (!moduleDepsQuery) { - llvm::report_fatal_error(Twine("Module Dependency Cache missing module") + - module.ModuleName); - } - - auto moduleDeps = *moduleDepsQuery; + auto &moduleDeps = cache.findKnownDependency(module); // Collect all the required pieces to build a ModuleInfo - auto swiftPlaceholderDeps = moduleDeps->getAsPlaceholderDependencyModule(); - auto swiftTextualDeps = moduleDeps->getAsSwiftInterfaceModule(); - auto swiftSourceDeps = moduleDeps->getAsSwiftSourceModule(); - auto swiftBinaryDeps = moduleDeps->getAsSwiftBinaryModule(); - auto clangDeps = moduleDeps->getAsClangModule(); + auto swiftPlaceholderDeps = moduleDeps.getAsPlaceholderDependencyModule(); + auto swiftTextualDeps = moduleDeps.getAsSwiftInterfaceModule(); + auto swiftSourceDeps = moduleDeps.getAsSwiftSourceModule(); + auto swiftBinaryDeps = moduleDeps.getAsSwiftBinaryModule(); + auto clangDeps = moduleDeps.getAsClangModule(); // ModulePath const char *modulePathSuffix = - moduleDeps->isSwiftModule() ? ".swiftmodule" : ".pcm"; + moduleDeps.isSwiftModule() ? ".swiftmodule" : ".pcm"; std::string modulePath; if (swiftTextualDeps) modulePath = swiftTextualDeps->moduleOutputPath; @@ -1196,10 +1189,8 @@ generateFullDependencyGraph(const CompilerInstance &instance, sourceFiles = clangDeps->fileDependencies; } - auto optionalDepInfo = cache.findDependency(module); - assert(optionalDepInfo.has_value() && "Missing dependency info during graph generation diagnosis."); - auto depInfo = optionalDepInfo.value(); - auto directDependencies = depInfo->getDirectModuleDependencies(); + auto &depInfo = cache.findKnownDependency(module); + auto directDependencies = depInfo.getDirectModuleDependencies(); // Generate a swiftscan_clang_details_t object based on the dependency kind auto getModuleDetails = [&]() -> swiftscan_module_details_t { @@ -1208,9 +1199,12 @@ generateFullDependencyGraph(const CompilerInstance &instance, swiftscan_string_ref_t moduleInterfacePath = create_clone(swiftTextualDeps->swiftInterfaceFile.c_str()); swiftscan_string_ref_t bridgingHeaderPath = - swiftTextualDeps->textualModuleDetails.bridgingHeaderFile.has_value() + swiftTextualDeps->textualModuleDetails.bridgingHeaderFile + .has_value() ? create_clone( - swiftTextualDeps->textualModuleDetails.bridgingHeaderFile.value().c_str()) + swiftTextualDeps->textualModuleDetails.bridgingHeaderFile + .value() + .c_str()) : create_null(); details->kind = SWIFTSCAN_DEPENDENCY_INFO_SWIFT_TEXTUAL; // Create an overlay dependencies set according to the output format @@ -1414,12 +1408,12 @@ computeTransitiveClosureOfExplicitDependencies( } static std::set computeBridgingHeaderTransitiveDependencies( - const ModuleDependencyInfo *dep, + const ModuleDependencyInfo &dep, const std::unordered_map> &transitiveClosures, const ModuleDependenciesCache &cache) { std::set result; - auto *sourceDep = dep->getAsSwiftSourceModule(); + auto *sourceDep = dep.getAsSwiftSourceModule(); if (!sourceDep) return result; @@ -1871,22 +1865,19 @@ static void resolveDependencyCommandLineArguments( // For main module or binary modules, no command-line to resolve. // For Clang modules, their dependencies are resolved by the clang Scanner // itself for us. - auto optionalDeps = cache.findDependency(modID); - assert(optionalDeps.has_value()); - auto deps = optionalDeps.value(); + auto &deps = cache.findKnownDependency(modID); std::optional> bridgingHeaderDeps; if (modID.Kind == ModuleDependencyKind::SwiftSource) bridgingHeaderDeps = computeBridgingHeaderTransitiveDependencies( deps, moduleTransitiveClosures, cache); - if (auto E = - resolveExplicitModuleInputs(modID, *deps, dependencyClosure, cache, - instance, bridgingHeaderDeps)) + if (auto E = resolveExplicitModuleInputs(modID, dependencyClosure, cache, + instance, bridgingHeaderDeps)) instance.getDiags().diagnose(SourceLoc(), diag::error_cas, toString(std::move(E))); - if (auto E = pruneUnusedVFSOverlays(modID, *deps, dependencyClosure, - cache, instance)) + if (auto E = + pruneUnusedVFSOverlays(modID, dependencyClosure, cache, instance)) instance.getDiags().diagnose(SourceLoc(), diag::error_cas, toString(std::move(E))); } diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index b28976fb8dc17..3f990a386ee2c 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1884,8 +1884,7 @@ static bool validateSwiftModuleFileArgumentAndAdd(const std::string &swiftModule return false; } -static bool ParseSearchPathArgs(SearchPathOptions &Opts, - ArgList &Args, +static bool ParseSearchPathArgs(SearchPathOptions &Opts, ArgList &Args, DiagnosticEngine &Diags, StringRef workingDirectory) { using namespace options; @@ -2020,6 +2019,31 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts, for (StringRef Opt : Args.getAllArgValues(OPT_scanner_prefix_map)) { Opts.ScannerPrefixMapper.push_back(Opt.str()); } + + Opts.NoScannerModuleValidation |= + Args.hasArg(OPT_no_scanner_module_validation); + + std::optional forceModuleLoadingMode; + if (auto *A = Args.getLastArg(OPT_module_load_mode)) + forceModuleLoadingMode = A->getValue(); + else if (auto Env = llvm::sys::Process::GetEnv("SWIFT_FORCE_MODULE_LOADING")) + forceModuleLoadingMode = Env; + if (forceModuleLoadingMode) { + if (*forceModuleLoadingMode == "prefer-interface" || + *forceModuleLoadingMode == "prefer-parseable") + Opts.ModuleLoadMode = ModuleLoadingMode::PreferInterface; + else if (*forceModuleLoadingMode == "prefer-serialized") + Opts.ModuleLoadMode = ModuleLoadingMode::PreferSerialized; + else if (*forceModuleLoadingMode == "only-interface" || + *forceModuleLoadingMode == "only-parseable") + Opts.ModuleLoadMode = ModuleLoadingMode::OnlyInterface; + else if (*forceModuleLoadingMode == "only-serialized") + Opts.ModuleLoadMode = ModuleLoadingMode::OnlySerialized; + else + Diags.diagnose(SourceLoc(), diag::unknown_forced_module_loading_mode, + *forceModuleLoadingMode); + } + // Opts.RuntimeIncludePath is set by calls to // setRuntimeIncludePath() or setMainExecutablePath(). // Opts.RuntimeImportPath is set by calls to diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 099b4e161f98d..94d76433bd9f6 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -709,26 +709,7 @@ bool CompilerInstance::setUpModuleLoaders() { enableLibraryEvolution, getDependencyTracker())); } - auto MLM = ModuleLoadingMode::PreferSerialized; - if (auto forceModuleLoadingMode = - llvm::sys::Process::GetEnv("SWIFT_FORCE_MODULE_LOADING")) { - if (*forceModuleLoadingMode == "prefer-interface" || - *forceModuleLoadingMode == "prefer-parseable") - MLM = ModuleLoadingMode::PreferInterface; - else if (*forceModuleLoadingMode == "prefer-serialized") - MLM = ModuleLoadingMode::PreferSerialized; - else if (*forceModuleLoadingMode == "only-interface" || - *forceModuleLoadingMode == "only-parseable") - MLM = ModuleLoadingMode::OnlyInterface; - else if (*forceModuleLoadingMode == "only-serialized") - MLM = ModuleLoadingMode::OnlySerialized; - else { - Diagnostics.diagnose(SourceLoc(), - diag::unknown_forced_module_loading_mode, - *forceModuleLoadingMode); - return true; - } - } + auto MLM = Invocation.getSearchPathOptions().ModuleLoadMode; auto IgnoreSourceInfoFile = Invocation.getFrontendOptions().IgnoreSwiftSourceInfo; if (Invocation.getLangOptions().EnableMemoryBufferImporter) { diff --git a/lib/Frontend/ModuleInterfaceLoader.cpp b/lib/Frontend/ModuleInterfaceLoader.cpp index 04e93b05f1a13..d065f3837d1f6 100644 --- a/lib/Frontend/ModuleInterfaceLoader.cpp +++ b/lib/Frontend/ModuleInterfaceLoader.cpp @@ -1372,7 +1372,8 @@ std::error_code ModuleInterfaceLoader::findModuleFilesInDirectory( } std::vector -ModuleInterfaceCheckerImpl::getCompiledModuleCandidatesForInterface(StringRef moduleName, StringRef interfacePath) { +ModuleInterfaceCheckerImpl::getCompiledModuleCandidatesForInterface( + StringRef moduleName, StringRef interfacePath) { // Derive .swiftmodule path from the .swiftinterface path. auto interfaceExt = file_types::getExtension(file_types::TY_SwiftModuleInterfaceFile); auto newExt = file_types::getExtension(file_types::TY_SwiftModuleFile); @@ -1392,17 +1393,32 @@ ModuleInterfaceCheckerImpl::getCompiledModuleCandidatesForInterface(StringRef mo ModuleInterfaceLoaderImpl Impl(Ctx, modulePath, interfacePath, moduleName, CacheDir, PrebuiltCacheDir, BackupInterfaceDir, - SourceLoc(), Opts, - RequiresOSSAModules, - nullptr, - ModuleLoadingMode::PreferSerialized); + SourceLoc(), Opts, RequiresOSSAModules, + nullptr, Ctx.SearchPathOpts.ModuleLoadMode); std::vector results; - auto pair = Impl.getCompiledModuleCandidates(); - // Add compiled module candidates only when they are non-empty. - if (!pair.first.empty()) - results.push_back(pair.first); - if (!pair.second.empty()) - results.push_back(pair.second); + std::string adjacentMod, prebuiltMod; + std::tie(adjacentMod, prebuiltMod) = Impl.getCompiledModuleCandidates(); + + auto validateModule = [&](StringRef modulePath) { + // Legacy behavior do not validate module. + if (Ctx.SearchPathOpts.NoScannerModuleValidation) + return true; + + // If we picked the other module already, no need to validate this one since + // it should not be used anyway. + if (!results.empty()) + return false; + SmallVector deps; + std::unique_ptr moduleBuffer; + return Impl.upToDateChecker.swiftModuleIsUpToDate( + modulePath, Impl.rebuildInfo, deps, moduleBuffer); + }; + + // Add compiled module candidates only when they are non-empty and up-to-date. + if (!adjacentMod.empty() && validateModule(adjacentMod)) + results.push_back(adjacentMod); + if (!prebuiltMod.empty() && validateModule(prebuiltMod)) + results.push_back(prebuiltMod); return results; } @@ -1862,6 +1878,12 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl( genericSubInvocation.getSearchPathOptions().PluginSearchOpts = searchPathOpts.PluginSearchOpts; + // Get module loading behavior options. + genericSubInvocation.getSearchPathOptions().NoScannerModuleValidation = + searchPathOpts.NoScannerModuleValidation; + genericSubInvocation.getSearchPathOptions().ModuleLoadMode = + searchPathOpts.ModuleLoadMode; + auto &subClangImporterOpts = genericSubInvocation.getClangImporterOptions(); // Respect the detailed-record preprocessor setting of the parent context. // This, and the "raw" clang module format it implicitly enables, are diff --git a/lib/Sema/TypeCheckMacros.cpp b/lib/Sema/TypeCheckMacros.cpp index 84a0d273f150f..efdcc35414c02 100644 --- a/lib/Sema/TypeCheckMacros.cpp +++ b/lib/Sema/TypeCheckMacros.cpp @@ -290,7 +290,9 @@ initializeExecutablePlugin(ASTContext &ctx, if (!libraryPath.empty()) { #if SWIFT_BUILD_SWIFT_SYNTAX llvm::SmallString<128> resolvedLibraryPath; - auto fs = ctx.SourceMgr.getFileSystem(); + auto fs = ctx.ClangImporterOpts.HasClangIncludeTreeRoot + ? llvm::vfs::getRealFileSystem() + : ctx.SourceMgr.getFileSystem(); if (auto err = fs->getRealPath(libraryPath, resolvedLibraryPath)) { return llvm::createStringError(err, err.message()); } diff --git a/lib/Serialization/ScanningLoaders.cpp b/lib/Serialization/ScanningLoaders.cpp index a9dd8a9daba67..0bb53171a8c37 100644 --- a/lib/Serialization/ScanningLoaders.cpp +++ b/lib/Serialization/ScanningLoaders.cpp @@ -33,6 +33,7 @@ #include "llvm/Support/Threading.h" #include "llvm/Support/VirtualFileSystem.h" #include +#include using namespace swift; @@ -55,7 +56,8 @@ std::error_code SwiftModuleScanner::findModuleFilesInDirectory( if (LoadMode == ModuleLoadingMode::OnlySerialized || !InPath) { if (fs.exists(ModPath)) { // The module file will be loaded directly. - auto dependencies = scanModuleFile(ModPath, IsFramework); + auto dependencies = + scanModuleFile(ModPath, IsFramework, isTestableDependencyLookup); if (dependencies) { this->dependencies = std::move(dependencies.get()); return std::error_code(); @@ -66,7 +68,8 @@ std::error_code SwiftModuleScanner::findModuleFilesInDirectory( } assert(InPath); - auto dependencies = scanInterfaceFile(*InPath, IsFramework); + auto dependencies = + scanInterfaceFile(*InPath, IsFramework, isTestableDependencyLookup); if (dependencies) { this->dependencies = std::move(dependencies.get()); return std::error_code(); @@ -133,7 +136,7 @@ static std::vector getCompiledCandidates(ASTContext &ctx, llvm::ErrorOr SwiftModuleScanner::scanInterfaceFile(Twine moduleInterfacePath, - bool isFramework) { + bool isFramework, bool isTestableImport) { // Create a module filename. // FIXME: Query the module interface loader to determine an appropriate // name for the module, which includes an appropriate hash. @@ -152,8 +155,23 @@ SwiftModuleScanner::scanInterfaceFile(Twine moduleInterfacePath, std::string InPath = moduleInterfacePath.str(); auto compiledCandidates = getCompiledCandidates(Ctx, realModuleName.str(), InPath); - std::vector Args(BaseArgs.begin(), BaseArgs.end()); + if (!compiledCandidates.empty() && + !Ctx.SearchPathOpts.NoScannerModuleValidation) { + assert(compiledCandidates.size() == 1 && + "Should only have 1 candidate module"); + auto BinaryDep = scanModuleFile(compiledCandidates[0], isFramework, + isTestableImport); + if (BinaryDep) { + Result = *BinaryDep; + return std::error_code(); + } + // If return no such file, just fallback to use interface. + if (BinaryDep.getError() != std::errc::no_such_file_or_directory) + return BinaryDep.getError(); + } + + std::vector Args(BaseArgs.begin(), BaseArgs.end()); // Add explicit Swift dependency compilation flags Args.push_back("-explicit-interface-module-build"); Args.push_back("-disable-implicit-swift-modules"); diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index ce21cc0863e84..3e44ab7148a7d 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -1320,21 +1320,25 @@ void Serializer::writeInputBlock() { time_t importedHeaderModTime = 0; std::string contents; auto importedHeaderPath = Options.ImportedHeader; + std::string pchIncludeTree; // We do not want to serialize the explicitly-specified .pch path if one was // provided. Instead we write out the path to the original header source so // that clients can consume it. if (Options.ExplicitModuleBuild && llvm::sys::path::extension(importedHeaderPath) - .endswith(file_types::getExtension(file_types::TY_PCH))) - importedHeaderPath = clangImporter->getClangInstance() - .getASTReader() - ->getModuleManager() - .lookupByFileName(importedHeaderPath) - ->OriginalSourceFileName; + .ends_with(file_types::getExtension(file_types::TY_PCH))) { + auto *pch = clangImporter->getClangInstance() + .getASTReader() + ->getModuleManager() + .lookupByFileName(importedHeaderPath); + pchIncludeTree = pch->IncludeTreeID; + importedHeaderPath = pch->OriginalSourceFileName; + } if (!importedHeaderPath.empty()) { contents = clangImporter->getBridgingHeaderContents( - importedHeaderPath, importedHeaderSize, importedHeaderModTime); + importedHeaderPath, importedHeaderSize, importedHeaderModTime, + pchIncludeTree); } assert(publicImportSet.count(bridgingHeaderImport)); ImportedHeader.emit(ScratchRecord, diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index 3fca53c35caa7..6f888e8243cb9 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -25,6 +25,7 @@ #include "swift/Basic/Version.h" #include "swift/Frontend/ModuleInterfaceLoader.h" #include "swift/Option/Options.h" +#include "swift/Serialization/Validation.h" #include "llvm/Option/OptTable.h" #include "llvm/Option/ArgList.h" @@ -391,26 +392,14 @@ std::error_code SerializedModuleLoaderBase::openModuleFile( return std::error_code(); } -llvm::ErrorOr +SerializedModuleLoaderBase::BinaryModuleImports SerializedModuleLoaderBase::getImportsOfModule( - Twine modulePath, ModuleLoadingBehavior transitiveBehavior, - bool isFramework, bool isRequiredOSSAModules, StringRef SDKName, - StringRef packageName, llvm::vfs::FileSystem *fileSystem, - PathObfuscator &recoverer) { - auto moduleBuf = fileSystem->getBufferForFile(modulePath); - if (!moduleBuf) - return moduleBuf.getError(); - + const ModuleFileSharedCore &loadedModuleFile, + ModuleLoadingBehavior transitiveBehavior, StringRef packageName, + bool isTestableImport) { llvm::StringSet<> importedModuleNames; std::string importedHeader = ""; - // Load the module file without validation. - std::shared_ptr loadedModuleFile; - serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load( - "", "", std::move(moduleBuf.get()), nullptr, nullptr, isFramework, - isRequiredOSSAModules, - SDKName, recoverer, loadedModuleFile); - - for (const auto &dependency : loadedModuleFile->getDependencies()) { + for (const auto &dependency : loadedModuleFile.getDependencies()) { if (dependency.isHeader()) { assert(importedHeader.empty() && "Unexpected more than one header dependency"); @@ -419,11 +408,10 @@ SerializedModuleLoaderBase::getImportsOfModule( } ModuleLoadingBehavior dependencyTransitiveBehavior = - loadedModuleFile->getTransitiveLoadingBehavior( + loadedModuleFile.getTransitiveLoadingBehavior( dependency, /*debuggerMode*/ false, - /*isPartialModule*/ false, packageName, - loadedModuleFile->isTestable()); + /*isPartialModule*/ false, packageName, isTestableImport); if (dependencyTransitiveBehavior > transitiveBehavior) continue; @@ -437,41 +425,53 @@ SerializedModuleLoaderBase::getImportsOfModule( importedModuleNames.insert(moduleName); } - return SerializedModuleLoaderBase::BinaryModuleImports{importedModuleNames, importedHeader}; + return SerializedModuleLoaderBase::BinaryModuleImports{importedModuleNames, + importedHeader}; } llvm::ErrorOr -SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework) { +SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework, + bool isTestableImport) { const std::string moduleDocPath; const std::string sourceInfoPath; + + // Read and valid module. + auto moduleBuf = Ctx.SourceMgr.getFileSystem()->getBufferForFile(modulePath); + if (!moduleBuf) + return moduleBuf.getError(); + + std::shared_ptr loadedModuleFile; + serialization::ValidationInfo loadInfo = ModuleFileSharedCore::load( + "", "", std::move(moduleBuf.get()), nullptr, nullptr, isFramework, + isRequiredOSSAModules(), Ctx.LangOpts.SDKName, + Ctx.SearchPathOpts.DeserializedPathRecoverer, loadedModuleFile); + + if (!Ctx.SearchPathOpts.NoScannerModuleValidation) { + // If failed to load, just ignore and return do not found. + if (loadInfo.status != serialization::Status::Valid) { + if (Ctx.LangOpts.EnableModuleLoadingRemarks) + Ctx.Diags.diagnose(SourceLoc(), diag::skip_module_invalid, + modulePath.str()); + return std::make_error_code(std::errc::no_such_file_or_directory); + } + } + // Some transitive dependencies of binary modules are not required to be // imported during normal builds. // TODO: This is worth revisiting for debugger purposes where // loading the module is optional, and implementation-only imports // from modules with testing enabled where the dependency is // optional. - ModuleLoadingBehavior transitiveLoadingBehavior = - ModuleLoadingBehavior::Required; - auto binaryModuleImports = getImportsOfModule( - modulePath, transitiveLoadingBehavior, isFramework, - isRequiredOSSAModules(), - Ctx.LangOpts.SDKName, Ctx.LangOpts.PackageName, - Ctx.SourceMgr.getFileSystem().get(), - Ctx.SearchPathOpts.DeserializedPathRecoverer); - if (!binaryModuleImports) - return binaryModuleImports.getError(); + auto binaryModuleImports = + getImportsOfModule(*loadedModuleFile, ModuleLoadingBehavior::Required, + Ctx.LangOpts.PackageName, isTestableImport); // Lookup optional imports of this module also - auto binaryModuleOptionalImports = getImportsOfModule( - modulePath, ModuleLoadingBehavior::Optional, isFramework, - isRequiredOSSAModules(), - Ctx.LangOpts.SDKName, Ctx.LangOpts.PackageName, - Ctx.SourceMgr.getFileSystem().get(), - Ctx.SearchPathOpts.DeserializedPathRecoverer); - if (!binaryModuleOptionalImports) - return binaryModuleImports.getError(); + auto binaryModuleOptionalImports = + getImportsOfModule(*loadedModuleFile, ModuleLoadingBehavior::Optional, + Ctx.LangOpts.PackageName, isTestableImport); - auto importedModuleSet = binaryModuleImports.get().moduleImports; + auto importedModuleSet = binaryModuleImports.moduleImports; std::vector importedModuleNames; importedModuleNames.reserve(importedModuleSet.size()); llvm::transform(importedModuleSet.keys(), @@ -480,8 +480,8 @@ SerializedModuleLoaderBase::scanModuleFile(Twine modulePath, bool isFramework) { return N.str(); }); - auto importedHeader = binaryModuleImports.get().headerImport; - auto &importedOptionalModuleSet = binaryModuleOptionalImports.get().moduleImports; + auto importedHeader = binaryModuleImports.headerImport; + auto &importedOptionalModuleSet = binaryModuleOptionalImports.moduleImports; std::vector importedOptionalModuleNames; for (const auto optionalImportedModule : importedOptionalModuleSet.keys()) if (!importedModuleSet.contains(optionalImportedModule)) @@ -790,7 +790,8 @@ bool SerializedModuleLoaderBase::findModule( auto result = findModuleFilesInDirectory( moduleID, absoluteBaseName, moduleInterfacePath, moduleInterfaceSourcePath, moduleBuffer, moduleDocBuffer, - moduleSourceInfoBuffer, skipBuildingInterface, isFramework); + moduleSourceInfoBuffer, skipBuildingInterface, isFramework, + isTestableDependencyLookup); if (!result) return true; if (result == std::errc::not_supported) diff --git a/test/CAS/Xcc_args.swift b/test/CAS/Xcc_args.swift index 0ffbe0ace877d..498635f0a7fc5 100644 --- a/test/CAS/Xcc_args.swift +++ b/test/CAS/Xcc_args.swift @@ -5,14 +5,11 @@ // RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \ // RUN: %t/test.swift -o %t/deps.json -swift-version 5 -cache-compile-job -cas-path %t/cas -Xcc -D_VERSION=1 \ // RUN: -Xcc -fmodule-map-file=%t/include/module.modulemap -Xcc -ivfsoverlay -Xcc %t/empty.yaml \ -// RUN: -Xcc -I%t/empty.hmap +// RUN: -Xcc -I%t/empty.hmap -module-load-mode prefer-serialized // RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:SwiftShims > %t/shims.cmd // RUN: %swift_frontend_plain @%t/shims.cmd -// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json Swift > %t/swift.cmd -// RUN: %swift_frontend_plain @%t/swift.cmd - // RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:_Macro > %t/Macro.cmd // RUN: %swift_frontend_plain @%t/Macro.cmd diff --git a/test/CAS/bridging-header.swift b/test/CAS/bridging-header.swift index cae66faa194ae..bc0691e9af0f9 100644 --- a/test/CAS/bridging-header.swift +++ b/test/CAS/bridging-header.swift @@ -1,6 +1,12 @@ +// REQUIRES: objc_interop // RUN: %empty-directory(%t) // RUN: split-file %s %t +// RUN: %target-swift-frontend -emit-module -o %t/temp.swiftmodule -module-name Test -swift-version 5 \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \ +// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -import-objc-header %t/Bridging.h \ +// RUN: %t/test.swift + // RUN: %target-swift-frontend -scan-dependencies -module-name Test -module-cache-path %t/clang-module-cache -O \ // RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \ // RUN: %t/test.swift -o %t/deps.json -swift-version 5 -cache-compile-job -cas-path %t/cas \ @@ -27,21 +33,103 @@ // CHECK-NEXT: "-Xcc", // CHECK-NEXT: "llvmcas://{{.*}}" +/// Try build then import from a non-caching compilation. + +// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:SwiftShims > %t/shim.cmd +// RUN: %swift_frontend_plain @%t/shim.cmd +// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:B > %t/B.cmd +// RUN: %swift_frontend_plain @%t/B.cmd +// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:A > %t/A.cmd +// RUN: %swift_frontend_plain @%t/A.cmd + +// RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json +// RUN: llvm-cas --cas %t/cas --make-blob --data %t/map.json > %t/map.casid + +// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader | tail -n +2 > %t/header.cmd +// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules %t/Bridging.h -O -o %t/bridging.pch +// RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \ +// RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules %t/Bridging.h -O -o %t/bridging.pch > %t/keys.json +// RUN: %{python} %S/Inputs/ExtractOutputKey.py %t/keys.json %t/Bridging.h > %t/key + +// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json Test > %t/MyApp.cmd +// RUN: echo "\"-disable-implicit-string-processing-module-import\"" >> %t/MyApp.cmd +// RUN: echo "\"-disable-implicit-concurrency-module-import\"" >> %t/MyApp.cmd +// RUN: echo "\"-disable-implicit-swift-modules\"" >> %t/MyApp.cmd +// RUN: echo "\"-import-objc-header\"" >> %t/MyApp.cmd +// RUN: echo "\"%t/bridging.pch\"" >> %t/MyApp.cmd +// RUN: echo "\"-bridging-header-pch-key\"" >> %t/MyApp.cmd +// RUN: echo "\"@%t/key\"" >> %t/MyApp.cmd +// RUN: echo "\"-explicit-swift-module-map-file\"" >> %t/MyApp.cmd +// RUN: echo "\"@%t/map.casid\"" >> %t/MyApp.cmd + +// RUN: %target-swift-frontend -cache-compile-job -module-name Test -O -cas-path %t/cas @%t/MyApp.cmd %t/test.swift \ +// RUN: -emit-module -o %t/Test.swiftmodule + +/// Importing binary module with bridging header built from CAS from a regluar build. +/// This should succeed even it is also importing a bridging header that shares same header dependencies (with proper header guard). +// RUN: %target-swift-frontend -typecheck -module-name User -swift-version 5 \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \ +// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap \ +// RUN: -I %t %t/user.swift -import-objc-header %t/Bridging2.h + +/// Importing binary module with bridging header built from CAS from a cached build. This should work without additional bridging header deps. +// RUN: %target-swift-frontend -scan-dependencies -module-name User -module-cache-path %t/clang-module-cache -O \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \ +// RUN: %t/user.swift -o %t/deps2.json -swift-version 5 -cache-compile-job -cas-path %t/cas \ +// RUN: -Xcc -fmodule-map-file=%t/a.modulemap -Xcc -fmodule-map-file=%t/b.modulemap -I %t + +// RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps2.json > %t/map2.json +// RUN: llvm-cas --cas %t/cas --make-blob --data %t/map2.json > %t/map2.casid +// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps2.json User > %t/User.cmd +// RUN: %target-swift-frontend -cache-compile-job -module-name User -O -cas-path %t/cas \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -disable-implicit-swift-modules \ +// RUN: -explicit-swift-module-map-file @%t/map2.casid @%t/User.cmd %t/user.swift \ +// RUN: -emit-module -o %t/User.swiftmodule + //--- test.swift -import B -public func test() {} +public func test() { + b() +} +public class TestB: B {} + +//--- user.swift +import Test + +func user() { + var b: TestB + test() +} + +extension A { + public func testA() {} +} + //--- Bridging.h #include "Foo.h" +#include "Foo2.h" + +//--- Bridging2.h +#include "Foo.h" +#include "Foo2.h" //--- Foo.h #import "a.h" +//--- Foo2.h +#pragma once +int Foo = 0; + //--- a.h #include "b.h" +struct A { + int a; +}; //--- b.h void b(void); +@interface B +@end //--- a.modulemap module A { diff --git a/test/CAS/cached_diagnostics.swift b/test/CAS/cached_diagnostics.swift index 3bb71963b33b7..8ac6bd000da2e 100644 --- a/test/CAS/cached_diagnostics.swift +++ b/test/CAS/cached_diagnostics.swift @@ -5,12 +5,10 @@ // RUN: %target-swift-frontend -scan-dependencies -module-name Test -O -import-objc-header %S/Inputs/objc.h \ // RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \ -// RUN: %s -o %t/deps.json -cache-compile-job -cas-path %t/cas +// RUN: %s -o %t/deps.json -cache-compile-job -cas-path %t/cas -module-load-mode prefer-serialized // RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:SwiftShims > %t/shim.cmd // RUN: %swift_frontend_plain @%t/shim.cmd -// RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json Swift > %t/swift.cmd -// RUN: %swift_frontend_plain @%t/swift.cmd // RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json bridgingHeader | tail -n +2 > %t/header.cmd // RUN: %target-swift-frontend @%t/header.cmd -disable-implicit-swift-modules %S/Inputs/objc.h -O -o %t/objc.pch 2>&1 | %FileCheck %s -check-prefix CHECK-BRIDGE diff --git a/test/CAS/cross_import.swift b/test/CAS/cross_import.swift index 9e34140953536..9abba2673f00a 100644 --- a/test/CAS/cross_import.swift +++ b/test/CAS/cross_import.swift @@ -15,7 +15,7 @@ // RUN: %target-swift-frontend -scan-dependencies -module-name Test -module-cache-path %t/clang-module-cache %t/main.swift \ // RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \ -// RUN: -o %t/deps.json -I %t -cache-compile-job -cas-path %t/cas -swift-version 5 -enable-cross-import-overlays +// RUN: -o %t/deps.json -I %t -cache-compile-job -cas-path %t/cas -swift-version 5 -enable-cross-import-overlays -module-load-mode prefer-interface // RUN: %{python} %S/Inputs/BuildCommandExtractor.py %t/deps.json A > %t/A.cmd // RUN: %swift_frontend_plain @%t/A.cmd diff --git a/test/CAS/index-store.swift b/test/CAS/index-store.swift index 5e39880edef21..421fa3e105ad7 100644 --- a/test/CAS/index-store.swift +++ b/test/CAS/index-store.swift @@ -7,7 +7,7 @@ // RUN: -emit-module-interface-path %t/A.swiftinterface \ // RUN: -o %t/A.swiftmodule -// RUN: %target-swift-frontend -scan-dependencies -module-name Test -O -module-cache-path %t/clang-module-cache \ +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-name Test -O -module-cache-path %t/clang-module-cache \ // RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \ // RUN: %t/test.swift -I %t -o %t/deps.json -cache-compile-job -cas-path %t/cas diff --git a/test/CAS/macro_option_set.swift b/test/CAS/macro_option_set.swift new file mode 100644 index 0000000000000..f2e95a4dd749b --- /dev/null +++ b/test/CAS/macro_option_set.swift @@ -0,0 +1,53 @@ +// REQUIRES: swift_swift_parser + +// RUN: %empty-directory(%t) + +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-serialized -module-name MyApp -module-cache-path %t/clang-module-cache -O \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \ +// RUN: %s -o %t/deps.json -swift-version 5 -cache-compile-job -cas-path %t/cas -plugin-path %swift-plugin-dir + +// RUN: %S/Inputs/SwiftDepsExtractor.py %t/deps.json MyApp casFSRootID > %t/fs.casid +// RUN: llvm-cas -cas %t/cas -ls-tree-recursive @%t/fs.casid | %FileCheck %s --check-prefix=FS + +// FS: SwiftMacros + +// RUN: %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:SwiftShims > %t/SwiftShims.cmd +// RUN: %swift_frontend_plain @%t/SwiftShims.cmd + +// RUN: %S/Inputs/BuildCommandExtractor.py %t/deps.json MyApp > %t/MyApp.cmd +// RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json +// RUN: llvm-cas --cas %t/cas --make-blob --data %t/map.json > %t/map.casid + +// RUN: %target-swift-frontend \ +// RUN: -typecheck -verify -cache-compile-job -cas-path %t/cas \ +// RUN: -swift-version 5 -disable-implicit-swift-modules \ +// RUN: -plugin-path %swift-plugin-dir \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \ +// RUN: -module-name MyApp -explicit-swift-module-map-file @%t/map.casid \ +// RUN: %s @%t/MyApp.cmd + +import Swift + +@attached(member, names: named(RawValue), named(rawValue), named(`init`), arbitrary) +@attached(extension, conformances: OptionSet) +public macro OptionSet() = + #externalMacro(module: "SwiftMacros", type: "OptionSetMacro") + +@OptionSet +struct ShippingOptions { + private enum Options: Int { + case nextDay + case secondDay + case priority + case standard + } + + static let express: ShippingOptions = [.nextDay, .secondDay] + static let all: ShippingOptions = [.express, .priority, .standard] +} + +let options = ShippingOptions.express +assert(options.contains(.nextDay)) +assert(options.contains(.secondDay)) +assert(!options.contains(.standard)) + diff --git a/test/CAS/macro_plugin.swift b/test/CAS/macro_plugin.swift new file mode 100644 index 0000000000000..71c26e32b675e --- /dev/null +++ b/test/CAS/macro_plugin.swift @@ -0,0 +1,73 @@ +// REQUIRES: swift_swift_parser + +/// Test loading and external library through `-load-plugin-library` +/// TODO: switch this test case to use `-external-plugin-path`. + +// RUN: %empty-directory(%t) +// RUN: %empty-directory(%t/plugins) +// +//== Build the plugin library +// RUN: %host-build-swift \ +// RUN: -swift-version 5 \ +// RUN: -emit-library \ +// RUN: -o %t/plugins/%target-library-name(MacroDefinition) \ +// RUN: -module-name=MacroDefinition \ +// RUN: %S/../Macros/Inputs/syntax_macro_definitions.swift \ +// RUN: -g -no-toolchain-stdlib-rpath + +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-serialized -module-name MyApp -module-cache-path %t/clang-module-cache -O \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \ +// RUN: %s -o %t/deps.json -swift-version 5 -cache-compile-job -cas-path %t/cas -load-plugin-library %t/plugins/%target-library-name(MacroDefinition) + +// RUN: %S/Inputs/SwiftDepsExtractor.py %t/deps.json MyApp casFSRootID > %t/fs.casid +// RUN: llvm-cas -cas %t/cas -ls-tree-recursive @%t/fs.casid | %FileCheck %s --check-prefix=FS + +// FS: MacroDefinition + +// RUN: %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:SwiftShims > %t/SwiftShims.cmd +// RUN: %swift_frontend_plain @%t/SwiftShims.cmd + +// RUN: %S/Inputs/BuildCommandExtractor.py %t/deps.json MyApp > %t/MyApp.cmd +// RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json +// RUN: llvm-cas --cas %t/cas --make-blob --data %t/map.json > %t/map.casid + +// RUN: %target-swift-frontend \ +// RUN: -typecheck -verify -cache-compile-job -cas-path %t/cas \ +// RUN: -swift-version 5 -disable-implicit-swift-modules \ +// RUN: -load-plugin-library %t/plugins/%target-library-name(MacroDefinition) \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \ +// RUN: -module-name MyApp -explicit-swift-module-map-file @%t/map.casid \ +// RUN: %s @%t/MyApp.cmd + +@attached(extension, conformances: P, names: named(requirement)) +macro DelegatedConformance() = #externalMacro(module: "MacroDefinition", type: "DelegatedConformanceViaExtensionMacro") + +protocol P { + static func requirement() +} + +struct Wrapped: P { + static func requirement() { + print("Wrapped.requirement") + } +} + +@DelegatedConformance +struct Generic {} + +// CHECK: {"expandMacroResult":{"diagnostics":[],"expandedSource":"extension Generic: P where Element: P {\n static func requirement() {\n Element.requirement()\n }\n}"}} + +func requiresP(_ value: (some P).Type) { + value.requirement() +} + +requiresP(Generic.self) + +struct Outer { + @DelegatedConformance + struct Nested {} +} + +// CHECK: {"expandMacroResult":{"diagnostics":[],"expandedSource":"extension Outer.Nested: P where Element: P {\n static func requirement() {\n Element.requirement()\n }\n}"}} + +requiresP(Outer.Nested.self) diff --git a/test/CAS/macro_plugin_external.swift b/test/CAS/macro_plugin_external.swift new file mode 100644 index 0000000000000..7a904f4d3172a --- /dev/null +++ b/test/CAS/macro_plugin_external.swift @@ -0,0 +1,73 @@ +// REQUIRES: swift_swift_parser + +/// Test loading and external library through `-load-plugin-library` +/// TODO: switch this test case to use `-external-plugin-path`. + +// RUN: %empty-directory(%t) +// RUN: %empty-directory(%t/plugins) +// +//== Build the plugin library +// RUN: %host-build-swift \ +// RUN: -swift-version 5 \ +// RUN: -emit-library \ +// RUN: -o %t/plugins/%target-library-name(MacroDefinition) \ +// RUN: -module-name=MacroDefinition \ +// RUN: %S/../Macros/Inputs/syntax_macro_definitions.swift \ +// RUN: -g -no-toolchain-stdlib-rpath + +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-serialized -module-name MyApp -module-cache-path %t/clang-module-cache -O \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \ +// RUN: %s -o %t/deps.json -swift-version 5 -cache-compile-job -cas-path %t/cas -external-plugin-path %t/plugins#%swift-plugin-server + +// RUN: %S/Inputs/SwiftDepsExtractor.py %t/deps.json MyApp casFSRootID > %t/fs.casid +// RUN: llvm-cas -cas %t/cas -ls-tree-recursive @%t/fs.casid | %FileCheck %s --check-prefix=FS + +// FS: MacroDefinition + +// RUN: %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:SwiftShims > %t/SwiftShims.cmd +// RUN: %swift_frontend_plain @%t/SwiftShims.cmd + +// RUN: %S/Inputs/BuildCommandExtractor.py %t/deps.json MyApp > %t/MyApp.cmd +// RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json +// RUN: llvm-cas --cas %t/cas --make-blob --data %t/map.json > %t/map.casid + +// RUN: %target-swift-frontend \ +// RUN: -typecheck -verify -cache-compile-job -cas-path %t/cas \ +// RUN: -swift-version 5 -disable-implicit-swift-modules \ +// RUN: -external-plugin-path %t/plugins/#%swift-plugin-server \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \ +// RUN: -module-name MyApp -explicit-swift-module-map-file @%t/map.casid \ +// RUN: %s @%t/MyApp.cmd + +@attached(extension, conformances: P, names: named(requirement)) +macro DelegatedConformance() = #externalMacro(module: "MacroDefinition", type: "DelegatedConformanceViaExtensionMacro") + +protocol P { + static func requirement() +} + +struct Wrapped: P { + static func requirement() { + print("Wrapped.requirement") + } +} + +@DelegatedConformance +struct Generic {} + +// CHECK: {"expandMacroResult":{"diagnostics":[],"expandedSource":"extension Generic: P where Element: P {\n static func requirement() {\n Element.requirement()\n }\n}"}} + +func requiresP(_ value: (some P).Type) { + value.requirement() +} + +requiresP(Generic.self) + +struct Outer { + @DelegatedConformance + struct Nested {} +} + +// CHECK: {"expandMacroResult":{"diagnostics":[],"expandedSource":"extension Outer.Nested: P where Element: P {\n static func requirement() {\n Element.requirement()\n }\n}"}} + +requiresP(Outer.Nested.self) diff --git a/test/CAS/module_deps.swift b/test/CAS/module_deps.swift index be04d1236b09d..fd2957394c6df 100644 --- a/test/CAS/module_deps.swift +++ b/test/CAS/module_deps.swift @@ -4,7 +4,7 @@ // RUN: mkdir -p %t/clang-module-cache // RUN: mkdir -p %t/cas -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -cache-compile-job -cas-path %t/cas -no-clang-include-tree +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -cache-compile-job -cas-path %t/cas -no-clang-include-tree // Check the contents of the JSON output // RUN: %validate-json %t/deps.json &>/dev/null // RUN: %FileCheck -check-prefix CHECK -check-prefix CHECK_NO_CLANG_TARGET %s < %t/deps.json @@ -15,12 +15,12 @@ // Check the make-style dependencies file // RUN: %FileCheck %s -check-prefix CHECK-MAKE-DEPS < %t/deps.d -// RUN: %target-swift-frontend -scan-dependencies -test-dependency-scan-cache-serialization -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -cache-compile-job -cas-path %t/cas -no-clang-include-tree +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -test-dependency-scan-cache-serialization -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -cache-compile-job -cas-path %t/cas -no-clang-include-tree // RUN: %validate-json %t/deps.json &>/dev/null // RUN: %FileCheck -check-prefix CHECK -check-prefix CHECK_NO_CLANG_TARGET %s < %t/deps.json // Ensure that scanning with `-clang-target` makes sure that Swift modules' respective PCM-dependency-build-argument sets do not contain target triples. -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps_clang_target.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -clang-target %target-cpu-apple-macosx10.14 -cache-compile-job -cas-path %t/cas -no-clang-include-tree +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps_clang_target.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -clang-target %target-cpu-apple-macosx10.14 -cache-compile-job -cas-path %t/cas -no-clang-include-tree // Check the contents of the JSON output // RUN: %validate-json %t/deps_clang_target.json &>/dev/null // RUN: %FileCheck -check-prefix CHECK_CLANG_TARGET %s < %t/deps_clang_target.json diff --git a/test/CAS/module_deps_include_tree.swift b/test/CAS/module_deps_include_tree.swift index b20c3e3a1f580..9800c30080cf5 100644 --- a/test/CAS/module_deps_include_tree.swift +++ b/test/CAS/module_deps_include_tree.swift @@ -4,7 +4,7 @@ // RUN: mkdir -p %t/clang-module-cache // RUN: mkdir -p %t/cas -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -cache-compile-job -cas-path %t/cas +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -cache-compile-job -cas-path %t/cas // Check the contents of the JSON output // RUN: %validate-json %t/deps.json &>/dev/null // RUN: %FileCheck -check-prefix CHECK -check-prefix CHECK_NO_CLANG_TARGET %s < %t/deps.json @@ -15,12 +15,12 @@ // Check the make-style dependencies file // RUN: %FileCheck %s -check-prefix CHECK-MAKE-DEPS < %t/deps.d -// RUN: %target-swift-frontend -scan-dependencies -test-dependency-scan-cache-serialization -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -cache-compile-job -cas-path %t/cas +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -test-dependency-scan-cache-serialization -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -cache-compile-job -cas-path %t/cas // RUN: %validate-json %t/deps.json &>/dev/null // RUN: %FileCheck -check-prefix CHECK -check-prefix CHECK_NO_CLANG_TARGET %s < %t/deps.json // Ensure that scanning with `-clang-target` makes sure that Swift modules' respective PCM-dependency-build-argument sets do not contain target triples. -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps_clang_target.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -clang-target %target-cpu-apple-macosx10.14 -cache-compile-job -cas-path %t/cas +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps_clang_target.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h -swift-version 4 -clang-target %target-cpu-apple-macosx10.14 -cache-compile-job -cas-path %t/cas // Check the contents of the JSON output // RUN: %validate-json %t/deps_clang_target.json &>/dev/null // RUN: %FileCheck -check-prefix CHECK_CLANG_TARGET %s < %t/deps_clang_target.json diff --git a/test/CAS/module_hash.swift b/test/CAS/module_hash.swift index 2a8e0c250b9bd..4272bb24cb88f 100644 --- a/test/CAS/module_hash.swift +++ b/test/CAS/module_hash.swift @@ -1,9 +1,9 @@ // RUN: %empty-directory(%t) // RUN: mkdir -p %t/clang-module-cache -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -module-name Test +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps.json -module-name Test -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps_cache.json -module-name Test \ +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps_cache.json -module-name Test \ // RUN: -cache-compile-job -cas-path %t/cas // RUN: %{python} %S/Inputs/SwiftDepsExtractor.py %t/deps.json Swift modulePath > %t/path1 diff --git a/test/CAS/plugin_cas.swift b/test/CAS/plugin_cas.swift index 9a689b755e04b..a31f66b071f6f 100644 --- a/test/CAS/plugin_cas.swift +++ b/test/CAS/plugin_cas.swift @@ -4,7 +4,7 @@ // RUN: mkdir -p %t/clang-module-cache // RUN: mkdir -p %t/cas -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s \ +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s \ // RUN: -o %t/deps.json -I %S/../ScanDependencies/Inputs/CHeaders -I %S/../ScanDependencies/Inputs/Swift \ // RUN: -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h \ // RUN: -swift-version 4 -cache-compile-job \ @@ -23,7 +23,7 @@ // RUN: %FileCheck %s -check-prefix CHECK-MAKE-DEPS < %t/deps.d // Ensure that scanning with `-clang-target` makes sure that Swift modules' respective PCM-dependency-build-argument sets do not contain target triples. -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s \ +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s \ // RUN: -o %t/deps_clang_target.json -I %S/../ScanDependencies/Inputs/CHeaders \ // RUN: -I %S/../ScanDependencies/Inputs/Swift -import-objc-header %S/../ScanDependencies/Inputs/CHeaders/Bridging.h \ // RUN: -swift-version 4 -clang-target %target-cpu-apple-macosx10.14 -cache-compile-job \ diff --git a/test/Frontend/module-alias-scan-deps.swift b/test/Frontend/module-alias-scan-deps.swift index bf313ed52f280..a22c74411b0af 100644 --- a/test/Frontend/module-alias-scan-deps.swift +++ b/test/Frontend/module-alias-scan-deps.swift @@ -11,7 +11,7 @@ // RUN: test -f %t/AppleLogging.swiftmodule /// Scanned dependencies should contain real name AppleLogging -// RUN: %target-swift-frontend -scan-dependencies %t/FileLib.swift -module-alias XLogging=AppleLogging -I %t > %t/scandump.output +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface %t/FileLib.swift -module-alias XLogging=AppleLogging -I %t > %t/scandump.output // RUN: %validate-json %t/scandump.output | %FileCheck %s -check-prefix=CHECK-REAL-NAME // CHECK-REAL-NAME-NOT: "swiftPrebuiltExternal": "XLogging" // CHECK-REAL-NAME-NOT: "compiledModulePath":{{.*}}XLogging.swiftmodule", @@ -24,7 +24,7 @@ // RUN: test -f %t/AppleLoggingIF.swiftinterface /// Scanned dependencies should contain real name AppleLoggingIF -// RUN: %target-swift-frontend -scan-dependencies %t/FileLib.swift -module-alias XLogging=AppleLoggingIF -I %t > %t/scandumpIF.output +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface %t/FileLib.swift -module-alias XLogging=AppleLoggingIF -I %t > %t/scandumpIF.output // RUN: %validate-json %t/scandumpIF.output | %FileCheck %s -check-prefix=CHECK-REAL-NAME-IF // CHECK-REAL-NAME-IF-NOT: "swift": "XLogging" // CHECK-REAL-NAME-IF-NOT: "moduleInterfacePath":{{.*}}XLogging.swiftinterface diff --git a/test/ModuleInterface/clang-args-transitive-availability.swift b/test/ModuleInterface/clang-args-transitive-availability.swift index bdfb692fd3cee..dfc4df497cb38 100644 --- a/test/ModuleInterface/clang-args-transitive-availability.swift +++ b/test/ModuleInterface/clang-args-transitive-availability.swift @@ -5,7 +5,7 @@ // received the TANGERINE macro // RUN: %target-swift-frontend -typecheck -strict-implicit-module-context %s -I %S/Inputs/macro-only-module -Xcc -DTANGERINE=1 -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -// RUN: %target-swift-frontend -scan-dependencies -strict-implicit-module-context %s -o %t/deps.json -I %S/Inputs/macro-only-module -Xcc -DTANGERINE=1 -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -strict-implicit-module-context %s -o %t/deps.json -I %S/Inputs/macro-only-module -Xcc -DTANGERINE=1 -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import // RUN: %validate-json %t/deps.json &>/dev/null // RUN: %FileCheck %s < %t/deps.json diff --git a/test/ModuleInterface/clang-session-transitive.swift b/test/ModuleInterface/clang-session-transitive.swift index ae6ef6e6ef4df..8bf1cd8314245 100644 --- a/test/ModuleInterface/clang-session-transitive.swift +++ b/test/ModuleInterface/clang-session-transitive.swift @@ -4,7 +4,7 @@ // RUN: %target-build-swift -module-name TestModule -module-link-name TestModule %S/Inputs/TestModule.swift -enable-library-evolution -emit-module-interface -o %t/TestModule.swiftmodule -swift-version 5 -Xfrontend -disable-implicit-concurrency-module-import -Xfrontend -disable-implicit-string-processing-module-import -// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I%t -validate-clang-modules-once -clang-build-session-file %t/Build.session -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import +// RUN: %target-swift-frontend -scan-dependencies -no-scanner-module-validation %s -o %t/deps.json -I%t -validate-clang-modules-once -clang-build-session-file %t/Build.session -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import // RUN: %validate-json %t/deps.json &>/dev/null // RUN: %FileCheck %s < %t/deps.json diff --git a/test/ModuleInterface/extension-transitive-availability.swift b/test/ModuleInterface/extension-transitive-availability.swift index 318986238f24a..a677fc4d6292c 100644 --- a/test/ModuleInterface/extension-transitive-availability.swift +++ b/test/ModuleInterface/extension-transitive-availability.swift @@ -3,7 +3,7 @@ // RUN: %target-swift-emit-module-interface(%t/ExtensionAvailable.swiftinterface) %S/Inputs/extension-available.swift -module-name ExtensionAvailable -I%t -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I%t -application-extension -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import +// RUN: %target-swift-frontend -scan-dependencies -no-scanner-module-validation %s -o %t/deps.json -I%t -application-extension -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import // RUN: %validate-json %t/deps.json &>/dev/null // RUN: %FileCheck %s < %t/deps.json diff --git a/test/ModuleInterface/infer-arch-from-file.swift b/test/ModuleInterface/infer-arch-from-file.swift index ab1e409401a13..f75771843269c 100644 --- a/test/ModuleInterface/infer-arch-from-file.swift +++ b/test/ModuleInterface/infer-arch-from-file.swift @@ -5,7 +5,7 @@ import arm64 -// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -target arm64-apple-macos11.0 +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface %s -o %t/deps.json -I %t -target arm64-apple-macos11.0 // RUN: %validate-json %t/deps.json | %FileCheck %s // CHECK-NOT: arm64e-apple-macos11.0 diff --git a/test/ScanDependencies/FilterClangSearchPaths.swift b/test/ScanDependencies/FilterClangSearchPaths.swift index e8fdf399e224a..45563dd4c8506 100644 --- a/test/ScanDependencies/FilterClangSearchPaths.swift +++ b/test/ScanDependencies/FilterClangSearchPaths.swift @@ -1,7 +1,7 @@ // RUN: %empty-directory(%t) // RUN: %empty-directory(%t/clang-module-cache) -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -Xcc -fobjc-disable-direct-methods-for-testing -Xcc -I -Xcc /tmp/foo -Xcc -I/tmp/bar +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -Xcc -fobjc-disable-direct-methods-for-testing -Xcc -I -Xcc /tmp/foo -Xcc -I/tmp/bar // Check the contents of the JSON output // RUN: %validate-json %t/deps.json | %FileCheck %s diff --git a/test/ScanDependencies/ObjCStrict.swift b/test/ScanDependencies/ObjCStrict.swift index 5ba108d5fabed..c5764b7c7a1f1 100644 --- a/test/ScanDependencies/ObjCStrict.swift +++ b/test/ScanDependencies/ObjCStrict.swift @@ -1,7 +1,7 @@ // RUN: %empty-directory(%t) // RUN: %empty-directory(%t/clang-module-cache) -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -Xcc -fobjc-disable-direct-methods-for-testing +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -Xcc -fobjc-disable-direct-methods-for-testing // Check the contents of the JSON output // RUN: %validate-json %t/deps.json | %FileCheck %s diff --git a/test/ScanDependencies/batch_module_scan.swift b/test/ScanDependencies/batch_module_scan.swift index e276fda317883..6c4714e5612bc 100644 --- a/test/ScanDependencies/batch_module_scan.swift +++ b/test/ScanDependencies/batch_module_scan.swift @@ -14,7 +14,7 @@ // RUN: echo "\"output\": \"%/t/outputs/F.pcm.json\"" >> %/t/inputs/input.json // RUN: echo "}]" >> %/t/inputs/input.json -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -batch-scan-input-file %/t/inputs/input.json +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -batch-scan-input-file %/t/inputs/input.json // Check the contents of the JSON output // RUN: %validate-json %t/outputs/F.pcm.json | %FileCheck %s -check-prefix=CHECK-PCM diff --git a/test/ScanDependencies/bin_mod_import.swift b/test/ScanDependencies/bin_mod_import.swift index bf4ad63e4673f..79a04013891e8 100644 --- a/test/ScanDependencies/bin_mod_import.swift +++ b/test/ScanDependencies/bin_mod_import.swift @@ -7,11 +7,11 @@ import EWrapper // Step 1: Build a swift interface into a binary module // RUN: %target-swift-frontend -compile-module-from-interface %S/Inputs/Swift/EWrapper.swiftinterface -o %t/EWrapper.swiftmodule -I %t // Step 3: scan dependency should give us the binary module and a textual swift dependency from it -// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface %s -o %t/deps.json -I %t // RUN: %validate-json %t/deps.json | %FileCheck %s // Step 4: Ensure that round-trip serialization does not affect result -// RUN: %target-swift-frontend -scan-dependencies -test-dependency-scan-cache-serialization %s -o %t/deps.json -I %t +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -test-dependency-scan-cache-serialization %s -o %t/deps.json -I %t // RUN: %validate-json %t/deps.json | %FileCheck %s // CHECK: "modulePath": "{{.*}}EWrapper.swiftmodule" diff --git a/test/ScanDependencies/blocklist-path-pass-down.swift b/test/ScanDependencies/blocklist-path-pass-down.swift index 0136ddf9cefe7..bd7c40efb128c 100644 --- a/test/ScanDependencies/blocklist-path-pass-down.swift +++ b/test/ScanDependencies/blocklist-path-pass-down.swift @@ -14,7 +14,7 @@ // Run the scan -// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -F %t/Frameworks/ -sdk %t -blocklist-file %t/blocklist.yml +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface %s -o %t/deps.json -F %t/Frameworks/ -sdk %t -blocklist-file %t/blocklist.yml // RUN: %validate-json %t/deps.json | %FileCheck %s import E diff --git a/test/ScanDependencies/bridging_header_dep_module_map.swift b/test/ScanDependencies/bridging_header_dep_module_map.swift index ac17bfba27eb8..7c14b3e40afd9 100644 --- a/test/ScanDependencies/bridging_header_dep_module_map.swift +++ b/test/ScanDependencies/bridging_header_dep_module_map.swift @@ -20,7 +20,7 @@ // - Scan main module and ensure that the "FooClient" recipe includes the modulemap for Foo's briding header's module dependencies // but not other dependencies -// RUN: %target-swift-frontend -scan-dependencies %t/bridging_header_dep_module_map.swift -I %t/FooModuleDir -I %t/TestSwiftInterfaces -I %t/TestCHeaders -I %S/Inputs/CHeaders -o %t/deps.json +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface %t/bridging_header_dep_module_map.swift -I %t/FooModuleDir -I %t/TestSwiftInterfaces -I %t/TestCHeaders -I %S/Inputs/CHeaders -o %t/deps.json // RUN: %validate-json %t/deps.json | %FileCheck %s // Given the following dependency graph: diff --git a/test/ScanDependencies/can_import_placeholder.swift b/test/ScanDependencies/can_import_placeholder.swift index c7400bccc4611..9a42e2b9a04a2 100644 --- a/test/ScanDependencies/can_import_placeholder.swift +++ b/test/ScanDependencies/can_import_placeholder.swift @@ -10,11 +10,11 @@ // RUN: echo "\"isFramework\": false" >> %/t/inputs/map.json // RUN: echo "}]" >> %/t/inputs/map.json -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -placeholder-dependency-module-map-file %t/inputs/map.json -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -placeholder-dependency-module-map-file %t/inputs/map.json -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 // RUN: %validate-json %t/deps.json | %FileCheck %s // Ensure that round-trip serialization does not affect result -// RUN: %target-swift-frontend -scan-dependencies -test-dependency-scan-cache-serialization -module-cache-path %t/clang-module-cache %s -placeholder-dependency-module-map-file %t/inputs/map.json -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -test-dependency-scan-cache-serialization -module-cache-path %t/clang-module-cache %s -placeholder-dependency-module-map-file %t/inputs/map.json -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 // RUN: %validate-json %t/deps.json | %FileCheck %s // REQUIRES: executable_test diff --git a/test/ScanDependencies/clang-target.swift b/test/ScanDependencies/clang-target.swift index 5bfaf3601b8cd..3c0170b80a251 100644 --- a/test/ScanDependencies/clang-target.swift +++ b/test/ScanDependencies/clang-target.swift @@ -12,7 +12,7 @@ // With -clang-target, we build one X.pcm // RUN: find %t.module-cache -name "X-*.pcm" | count 1 -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t.module-cache %s -o %t.deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -target %target-cpu-apple-macosx10.14 -clang-target %target-cpu-apple-macosx10.14 +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t.module-cache %s -o %t.deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -target %target-cpu-apple-macosx10.14 -clang-target %target-cpu-apple-macosx10.14 // RUN: %validate-json %t.deps.json | %FileCheck %s diff --git a/test/ScanDependencies/clang_auxiliary_module_framework.swift b/test/ScanDependencies/clang_auxiliary_module_framework.swift index 0c3448ce00c71..5154fdd85e5cb 100644 --- a/test/ScanDependencies/clang_auxiliary_module_framework.swift +++ b/test/ScanDependencies/clang_auxiliary_module_framework.swift @@ -1,11 +1,11 @@ // REQUIRES: OS=macosx // RUN: %empty-directory(%t) -// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -emit-dependencies -emit-dependencies-path %t/deps.d -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -F %S/Inputs/Frameworks -verify +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface %s -o %t/deps.json -emit-dependencies -emit-dependencies-path %t/deps.d -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -F %S/Inputs/Frameworks -verify // Check the contents of the JSON output // RUN: %validate-json %t/deps.json | %FileCheck %s // Ensure that round-trip serialization does not affect result -// RUN: %target-swift-frontend -scan-dependencies -test-dependency-scan-cache-serialization %s -o %t/deps.json -emit-dependencies -emit-dependencies-path %t/deps.d -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -F %S/Inputs/Frameworks -verify +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -test-dependency-scan-cache-serialization %s -o %t/deps.json -emit-dependencies -emit-dependencies-path %t/deps.d -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -F %S/Inputs/Frameworks -verify // RUN: %validate-json %t/deps.json | %FileCheck %s import WithAuxClangModule diff --git a/test/ScanDependencies/compiled_swift_modules.swift b/test/ScanDependencies/compiled_swift_modules.swift index d4bb2864dd23f..4ccda3f788fc1 100644 --- a/test/ScanDependencies/compiled_swift_modules.swift +++ b/test/ScanDependencies/compiled_swift_modules.swift @@ -8,32 +8,46 @@ import Foo // HAS_COMPILED: "compiledModuleCandidates": [ // HAS_COMPILED-NEXT: "{{.*}}Foo.swiftmodule{{.*}}.swiftmodule" +// HAS_BINARY: "swiftPrebuiltExternal": "Foo" + // HAS_NO_COMPILED-NOT: "{{.*}}Foo.swiftmodule{{.*}}.swiftmodule" // Step 1: build swift interface and swift module side by side // 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 // Step 2: scan dependency should give us the binary module adjacent to the interface file. -// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d +// RUN: %target-swift-frontend -scan-dependencies -no-scanner-module-validation %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d // RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=HAS_COMPILED +/// Check scanner picked binary dependency if not requesting raw scan output. +// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d +// RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=HAS_BINARY + // Step 3: remove the adjacent module. // RUN: rm %t/Foo.swiftmodule/%target-swiftmodule-name // Step 4: scan dependency should give us the interface file. -// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d +// RUN: %target-swift-frontend -scan-dependencies -no-scanner-module-validation %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d // RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=HAS_NO_COMPILED // Step 4: build prebuilt module cache using the interface. // RUN: %target-swift-frontend -compile-module-from-interface -o %t/ResourceDir/%target-sdk-name/prebuilt-modules/Foo.swiftmodule/%target-swiftmodule-name -module-name Foo -disable-interface-lock %t/Foo.swiftmodule/%target-swiftinterface-name // Step 5: scan dependency now should give us the prebuilt module cache -// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d -sdk %t -prebuilt-module-cache-path %t/ResourceDir/%target-sdk-name/prebuilt-modules +// RUN: %target-swift-frontend -scan-dependencies -no-scanner-module-validation %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d -sdk %t -prebuilt-module-cache-path %t/ResourceDir/%target-sdk-name/prebuilt-modules // RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=HAS_COMPILED +/// Check scanner picked binary dependency if not requesting raw scan output. +// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d -sdk %t -prebuilt-module-cache-path %t/ResourceDir/%target-sdk-name/prebuilt-modules +// RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=HAS_BINARY + // Step 6: update the interface file from where the prebuilt module cache was built. // RUN: touch %t/Foo.swiftmodule/%target-swiftinterface-name // Step 7: scan dependency should give us the prebuilt module file even though it's out-of-date. -// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d -sdk %t -prebuilt-module-cache-path %t/ResourceDir/%target-sdk-name/prebuilt-modules +// RUN: %target-swift-frontend -scan-dependencies -no-scanner-module-validation %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d -sdk %t -prebuilt-module-cache-path %t/ResourceDir/%target-sdk-name/prebuilt-modules // RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=HAS_COMPILED + +// Step 8: The new scanner behavior should not give use prebuilt module file because it is out-of-date. +// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -I %t -emit-dependencies -emit-dependencies-path %t/deps.d -sdk %t -prebuilt-module-cache-path %t/ResourceDir/%target-sdk-name/prebuilt-modules +// RUN: %validate-json %t/deps.json | %FileCheck %s -check-prefix=HAS_NO_COMPILED diff --git a/test/ScanDependencies/direct_cc1_scan.swift b/test/ScanDependencies/direct_cc1_scan.swift index 996fdec35832b..5888db7a9bd2f 100644 --- a/test/ScanDependencies/direct_cc1_scan.swift +++ b/test/ScanDependencies/direct_cc1_scan.swift @@ -7,13 +7,13 @@ // RUN: -emit-module-interface-path %t/A.swiftinterface \ // RUN: -o %t/A.swiftmodule -// RUN: %target-swift-frontend -scan-dependencies -o %t/deps.json -I %t \ +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -o %t/deps.json -I %t \ // RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \ // RUN: %t/test.swift -module-name Test -swift-version 5 // RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json A | %FileCheck %s --check-prefix CHECK-NO-DIRECT-CC1 // RUN: %{python} %S/../CAS/Inputs/BuildCommandExtractor.py %t/deps.json Test | %FileCheck %s --allow-empty --check-prefix CHECK-NO-DIRECT-CC1 -// RUN: %target-swift-frontend -scan-dependencies -o %t/deps2.json -I %t \ +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -o %t/deps2.json -I %t \ // RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \ // RUN: -g -file-compilation-dir %t -Xcc -ferror-limit=1 \ // RUN: %t/test.swift -module-name Test -swift-version 5 -experimental-clang-importer-direct-cc1-scan diff --git a/test/ScanDependencies/eliminate_unused_vfs.swift b/test/ScanDependencies/eliminate_unused_vfs.swift index 7e5b88cff8ec2..dc2a9909595ec 100644 --- a/test/ScanDependencies/eliminate_unused_vfs.swift +++ b/test/ScanDependencies/eliminate_unused_vfs.swift @@ -6,7 +6,7 @@ // RUN: sed -e "s|OUT_DIR|%t/redirects|g" -e "s|IN_DIR|%S/Inputs/CHeaders|g" %t/overlay_template.yaml > %t/overlay.yaml -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/module-cache %t/test.swift -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -Xcc -ivfsoverlay -Xcc %t/overlay.yaml +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/module-cache %t/test.swift -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -Xcc -ivfsoverlay -Xcc %t/overlay.yaml // RUN: %validate-json %t/deps.json | %FileCheck %s //--- overlay_template.yaml diff --git a/test/ScanDependencies/explicit-swift-dependencies.swift b/test/ScanDependencies/explicit-swift-dependencies.swift index 746bf7f8416bf..e5a281caec5a0 100644 --- a/test/ScanDependencies/explicit-swift-dependencies.swift +++ b/test/ScanDependencies/explicit-swift-dependencies.swift @@ -1,7 +1,7 @@ // RUN: %empty-directory(%t) // RUN: mkdir -p %t/clang-module-cache -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 // Check the contents of the JSON output // RUN: %validate-json %t/deps.json | %FileCheck %s diff --git a/test/ScanDependencies/header_deps_of_binary.swift b/test/ScanDependencies/header_deps_of_binary.swift index 20b43c3343925..d1c6e2b830ca8 100644 --- a/test/ScanDependencies/header_deps_of_binary.swift +++ b/test/ScanDependencies/header_deps_of_binary.swift @@ -23,7 +23,7 @@ // RUN: %target-swift-frontend -emit-module -emit-module-path %t/SwiftModules/Foo.swiftmodule %t/foo.swift -module-name Foo -import-objc-header %t/PCH/foo.pch -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -disable-implicit-swift-modules -explicit-swift-module-map-file %t/map.json // - Scan main module and ensure that the header dependencies point to .h and not .pch file -// RUN: %target-swift-frontend -scan-dependencies %t/header_deps_of_binary.swift -I %t/SwiftModules -I %S/Inputs/Swift -I %S/Inputs/CHeaders -o %t/deps.json +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface %t/header_deps_of_binary.swift -I %t/SwiftModules -I %S/Inputs/Swift -I %S/Inputs/CHeaders -o %t/deps.json // RUN: %validate-json %t/deps.json | %FileCheck %s // CHECK: "swift": "FooClient" diff --git a/test/ScanDependencies/include-sdk-in-command.swift b/test/ScanDependencies/include-sdk-in-command.swift index 1f1d96e1ec7bf..84512632a0b25 100644 --- a/test/ScanDependencies/include-sdk-in-command.swift +++ b/test/ScanDependencies/include-sdk-in-command.swift @@ -1,6 +1,6 @@ // RUN: %empty-directory(%t) -// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -sdk %t/mysecretsdk.sdk +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface %s -o %t/deps.json -sdk %t/mysecretsdk.sdk // Check the contents of the JSON output // RUN: %validate-json %t/deps.json | %FileCheck %s diff --git a/test/ScanDependencies/module_deps_binary_dep_swift_overlay.swift b/test/ScanDependencies/module_deps_binary_dep_swift_overlay.swift index 75c70287c7cb1..8814a95ecfb3b 100644 --- a/test/ScanDependencies/module_deps_binary_dep_swift_overlay.swift +++ b/test/ScanDependencies/module_deps_binary_dep_swift_overlay.swift @@ -8,7 +8,7 @@ // RUN: %target-swift-frontend -emit-module -emit-module-path %t/DependencyModules/BinaryModuleDep.swiftmodule -module-cache-path %t/clang-module-cache %t/BinaryModuleDepSource.swift -module-name BinaryModuleDep -I %S/Inputs/CHeaders -I %S/Inputs/Swift // Scan the client and ensure both the Client and BinaryModuleDep modules have a Swift overlay dependency on 'F' as imported by 'ClangModuleWithOverlayedDep' -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -I %t/DependencyModules +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -I %t/DependencyModules // Check the contents of the JSON output // RUN: %validate-json %t/deps.json | %FileCheck %s diff --git a/test/ScanDependencies/module_deps_cache_reuse.swift b/test/ScanDependencies/module_deps_cache_reuse.swift index 4012e5d406597..51718ede38662 100644 --- a/test/ScanDependencies/module_deps_cache_reuse.swift +++ b/test/ScanDependencies/module_deps_cache_reuse.swift @@ -2,10 +2,10 @@ // RUN: mkdir -p %t/clang-module-cache // Run the scanner once, emitting the serialized scanner cache -// RUN: %target-swift-frontend -scan-dependencies -Rdependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/clang-module-cache %s -o %t/deps_initial.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-SAVE +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -Rdependency-scan-cache -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/clang-module-cache %s -o %t/deps_initial.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-SAVE // Run the scanner again, but now re-using previously-serialized cache -// RUN: %target-swift-frontend -scan-dependencies -Rdependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-LOAD +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -Rdependency-scan-cache -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 2>&1 | %FileCheck %s -check-prefix CHECK-REMARK-LOAD // Check the contents of the JSON output // RUN: %validate-json %t/deps.json &>/dev/null diff --git a/test/ScanDependencies/module_deps_cross_import_overlay.swift b/test/ScanDependencies/module_deps_cross_import_overlay.swift index b7a047a3b7461..c5a663ca9a551 100644 --- a/test/ScanDependencies/module_deps_cross_import_overlay.swift +++ b/test/ScanDependencies/module_deps_cross_import_overlay.swift @@ -1,11 +1,11 @@ // RUN: %empty-directory(%t) // RUN: mkdir -p %t/clang-module-cache -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -I %S/Inputs/CHeaders/ExtraCModules -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -module-name CrossImportTestModule +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -I %S/Inputs/CHeaders/ExtraCModules -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -module-name CrossImportTestModule // Check the contents of the JSON output // RUN: %validate-json %t/deps.json | %FileCheck %s // Ensure that round-trip serialization does not affect result -// RUN: %target-swift-frontend -scan-dependencies -test-dependency-scan-cache-serialization -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -I %S/Inputs/CHeaders/ExtraCModules -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -module-name CrossImportTestModule +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -test-dependency-scan-cache-serialization -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -I %S/Inputs/CHeaders/ExtraCModules -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -module-name CrossImportTestModule // RUN: %validate-json %t/deps.json | %FileCheck %s // REQUIRES: executable_test diff --git a/test/ScanDependencies/module_deps_different_paths_no_reuse.swift b/test/ScanDependencies/module_deps_different_paths_no_reuse.swift index 9844160fe9e61..0afa3bab97918 100644 --- a/test/ScanDependencies/module_deps_different_paths_no_reuse.swift +++ b/test/ScanDependencies/module_deps_different_paths_no_reuse.swift @@ -4,12 +4,12 @@ // This test ensures that subsequent invocations of the dependency scanner that re-use previous cache state do not re-use cache entries that contain modules found outside of the current scanner invocation's search paths. // Run the scanner once, emitting the serialized scanner cache, with one set of search paths -// RUN: %target-swift-frontend -scan-dependencies -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/clang-module-cache %s -o %t/deps_initial.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -serialize-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/clang-module-cache %s -o %t/deps_initial.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 // RUN: %validate-json %t/deps_initial.json &>/dev/null // RUN: %FileCheck -input-file %t/deps_initial.json %s -check-prefix CHECK-INITIAL-SCAN // Run the scanner again, but now re-using previously-serialized cache and using a different search path for Swift modules -// RUN: %target-swift-frontend -scan-dependencies -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/SwiftDifferent -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -load-dependency-scan-cache -dependency-scan-cache-path %t/cache.moddepcache -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/SwiftDifferent -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 // RUN: %validate-json %t/deps.json &>/dev/null // RUN: %FileCheck -input-file %t/deps.json %s -check-prefix CHECK-DIFFERENT diff --git a/test/ScanDependencies/module_deps_external.swift b/test/ScanDependencies/module_deps_external.swift index 515d7a33edcb7..37a61b6b349e4 100644 --- a/test/ScanDependencies/module_deps_external.swift +++ b/test/ScanDependencies/module_deps_external.swift @@ -10,7 +10,7 @@ // RUN: echo "\"isFramework\": false" >> %/t/inputs/map.json // RUN: echo "}]" >> %/t/inputs/map.json -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -placeholder-dependency-module-map-file %t/inputs/map.json -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -placeholder-dependency-module-map-file %t/inputs/map.json -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 // Check the contents of the JSON output // RUN: %validate-json %t/deps.json | %FileCheck %s @@ -28,7 +28,7 @@ // RUN: %target-run %t/main %t/deps.json // Ensure that round-trip serialization does not affect result -// RUN: %target-swift-frontend -scan-dependencies -test-dependency-scan-cache-serialization -module-cache-path %t/clang-module-cache %s -placeholder-dependency-module-map-file %t/inputs/map.json -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -test-dependency-scan-cache-serialization -module-cache-path %t/clang-module-cache %s -placeholder-dependency-module-map-file %t/inputs/map.json -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 // RUN: %validate-json %t/deps.json | %FileCheck %s // REQUIRES: executable_test diff --git a/test/ScanDependencies/module_framework.swift b/test/ScanDependencies/module_framework.swift index 296ac57759690..2789c058fe21d 100644 --- a/test/ScanDependencies/module_framework.swift +++ b/test/ScanDependencies/module_framework.swift @@ -1,11 +1,11 @@ // REQUIRES: OS=macosx // RUN: %empty-directory(%t) -// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -emit-dependencies -emit-dependencies-path %t/deps.d -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -F %S/Inputs/Frameworks +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface %s -o %t/deps.json -emit-dependencies -emit-dependencies-path %t/deps.d -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -F %S/Inputs/Frameworks // Check the contents of the JSON output // RUN: %validate-json %t/deps.json | %FileCheck %s // Ensure that round-trip serialization does not affect result -// RUN: %target-swift-frontend -scan-dependencies -test-dependency-scan-cache-serialization %s -o %t/deps.json -emit-dependencies -emit-dependencies-path %t/deps.d -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -F %S/Inputs/Frameworks +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -test-dependency-scan-cache-serialization %s -o %t/deps.json -emit-dependencies -emit-dependencies-path %t/deps.d -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -F %S/Inputs/Frameworks // RUN: %validate-json %t/deps.json | %FileCheck %s import ScannerTestKit diff --git a/test/ScanDependencies/module_load_mode.swift b/test/ScanDependencies/module_load_mode.swift new file mode 100644 index 0000000000000..29ab5996dc185 --- /dev/null +++ b/test/ScanDependencies/module_load_mode.swift @@ -0,0 +1,21 @@ +// RUN: %empty-directory(%t) +// RUN: split-file %s %t + +// 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 -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib + +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode only-serialized \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \ +// RUN: %t/main.swift -I %t -o - | %FileCheck %s --check-prefix=SERIALIZED + +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode only-interface \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \ +// RUN: %t/main.swift -I %t -o - | %FileCheck %s --check-prefix=INTERFACE + +// SERIALIZED: "swiftPrebuiltExternal": "Foo" +// INTERFACE: "swift": "Foo" + +//--- main.swift +import Foo + +//--- Foo.swift +public func foo() {} diff --git a/test/ScanDependencies/no_cross_import_module_for_self.swift b/test/ScanDependencies/no_cross_import_module_for_self.swift index 4d34d97e1692c..042baf7ace9f6 100644 --- a/test/ScanDependencies/no_cross_import_module_for_self.swift +++ b/test/ScanDependencies/no_cross_import_module_for_self.swift @@ -1,6 +1,6 @@ // RUN: %empty-directory(%t) // RUN: mkdir -p %t/clang-module-cache -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/CHeaders/ExtraCModules -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -swift-version 4 -module-name _cross_import_E +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/CHeaders/ExtraCModules -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -swift-version 4 -module-name _cross_import_E // Check the contents of the JSON output // RUN: %validate-json %t/deps.json | %FileCheck %s diff --git a/test/ScanDependencies/no_main_module_cross_import.swift b/test/ScanDependencies/no_main_module_cross_import.swift index a111f9737fe0c..4aa299a9d4ee5 100644 --- a/test/ScanDependencies/no_main_module_cross_import.swift +++ b/test/ScanDependencies/no_main_module_cross_import.swift @@ -1,6 +1,6 @@ // RUN: %empty-directory(%t) // RUN: mkdir -p %t/clang-module-cache -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/CHeaders/ExtraCModules -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -swift-version 4 -module-name SubE +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/CHeaders/ExtraCModules -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -swift-version 4 -module-name SubE // Check the contents of the JSON output // RUN: %validate-json %t/deps.json | %FileCheck %s diff --git a/test/ScanDependencies/package_interface.swift b/test/ScanDependencies/package_interface.swift index 4688fa3575698..0d0f0b079cb8c 100644 --- a/test/ScanDependencies/package_interface.swift +++ b/test/ScanDependencies/package_interface.swift @@ -9,21 +9,21 @@ // RUN: -emit-private-module-interface-path %t/Bar.private.swiftinterface \ // RUN: -emit-package-module-interface-path %t/Bar.package.swiftinterface -// RUN: %target-swift-frontend -scan-dependencies -o %t/deps.json -I %t -experimental-package-interface-load \ +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -o %t/deps.json -I %t -experimental-package-interface-load \ // RUN: %t/Client.swift -module-name Client -package-name barpkg -swift-version 5 // RUN: %FileCheck %s --input-file=%t/deps.json --check-prefix CHECK --check-prefix CHECK-PACKAGE /// When package name doesn't match or not used, it should find private interface. -// RUN: %target-swift-frontend -scan-dependencies -o %t/deps2.json -I %t -experimental-package-interface-load \ +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -o %t/deps2.json -I %t -experimental-package-interface-load \ // RUN: %t/Client.swift -module-name Client -package-name foopkg -swift-version 5 // RUN: %FileCheck %s --input-file=%t/deps2.json --check-prefix CHECK --check-prefix CHECK-PRIVATE -// RUN: %target-swift-frontend -scan-dependencies -o %t/deps3.json -I %t -experimental-package-interface-load \ +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -o %t/deps3.json -I %t -experimental-package-interface-load \ // RUN: %t/Client.swift -module-name Client -swift-version 5 // RUN: %FileCheck %s --input-file=%t/deps3.json --check-prefix CHECK --check-prefix CHECK-PRIVATE /// If -experimental-package-interface-load is not used but in the same package, it should find the binary module -// RUN: %target-swift-frontend -scan-dependencies -I %t \ +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -I %t \ // RUN: %t/Client.swift -module-name Client -package-name barpkg -swift-version 5 | \ // RUN: %FileCheck %s --check-prefix CHECK-BINARY diff --git a/test/ScanDependencies/preserve_used_vfs.swift b/test/ScanDependencies/preserve_used_vfs.swift index 6efbe236b2a9f..d7348931bf4ec 100644 --- a/test/ScanDependencies/preserve_used_vfs.swift +++ b/test/ScanDependencies/preserve_used_vfs.swift @@ -6,7 +6,7 @@ // RUN: sed -e "s|OUT_DIR|%t/redirects|g" -e "s|IN_DIR|%S/Inputs/CHeaders|g" %t/overlay_template.yaml > %t/overlay.yaml -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/module-cache %t/test.swift -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -Xcc -ivfsoverlay -Xcc %t/overlay.yaml +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/module-cache %t/test.swift -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import -Xcc -ivfsoverlay -Xcc %t/overlay.yaml // RUN: %validate-json %t/deps.json | %FileCheck %s //--- redirects/RedirectedF.h diff --git a/test/ScanDependencies/private_interface_candidate_module.swift b/test/ScanDependencies/private_interface_candidate_module.swift index bf6752ee14555..41d9dd9013718 100644 --- a/test/ScanDependencies/private_interface_candidate_module.swift +++ b/test/ScanDependencies/private_interface_candidate_module.swift @@ -15,7 +15,7 @@ // RUN: %target-swift-frontend -emit-module -emit-module-path %t/Frameworks/E.framework/Modules/E.swiftmodule/%module-target-triple.swiftmodule -module-cache-path %t.module-cache %t/foo.swift -module-name E // Run the scan -// RUN: %target-swift-frontend -scan-dependencies %s -o %t/deps.json -F %t/Frameworks/ -sdk %t +// RUN: %target-swift-frontend -scan-dependencies -no-scanner-module-validation %s -o %t/deps.json -F %t/Frameworks/ -sdk %t // RUN: %validate-json %t/deps.json | %FileCheck %s import E diff --git a/test/ScanDependencies/separate_bridging_header_deps.swift b/test/ScanDependencies/separate_bridging_header_deps.swift index 69e5de969112b..f9c9ed02bc758 100644 --- a/test/ScanDependencies/separate_bridging_header_deps.swift +++ b/test/ScanDependencies/separate_bridging_header_deps.swift @@ -1,7 +1,7 @@ // RUN: %empty-directory(%t) // RUN: mkdir -p %t/clang-module-cache -// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 5 // RUN: %validate-json %t/deps.json | %FileCheck %s import E diff --git a/test/ScanDependencies/testable-dependencies.swift b/test/ScanDependencies/testable-dependencies.swift new file mode 100644 index 0000000000000..87c5166ae0282 --- /dev/null +++ b/test/ScanDependencies/testable-dependencies.swift @@ -0,0 +1,80 @@ +// RUN: %empty-directory(%t) +// RUN: split-file %s %t + +// RUN: %target-swift-frontend -emit-module -module-name B -o %t/internal/B.swiftmodule -swift-version 5 \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \ +// RUN: -emit-module-interface-path %t/internal/B.swiftinterface -enable-library-evolution -I %t \ +// RUN: %t/B.swift + +// RUN: %target-swift-frontend -emit-module -module-name A -o %t/testable/A.swiftmodule -swift-version 5 \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \ +// RUN: -emit-module-interface-path %t/testable/A.swiftinterface -enable-library-evolution -I %t/internal -enable-testing \ +// RUN: %t/A.swift + +// RUN: %target-swift-frontend -emit-module -module-name A -o %t/regular/A.swiftmodule -swift-version 5 \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \ +// RUN: -emit-module-interface-path %t/regular/A.swiftinterface -enable-library-evolution -I %t/internal \ +// RUN: %t/A.swift + +/// Import testable build, should use binary but no extra dependencies. +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-serialized -module-name Test %t/main.swift \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \ +// RUN: -o %t/deps1.json -I %t/testable -swift-version 5 -Rmodule-loading +// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps1.json Test directDependencies | %FileCheck %s --check-prefix TEST1 +// TEST1: "swiftPrebuiltExternal": "A" +// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps1.json A directDependencies | %FileCheck %s --check-prefix EMPTY --allow-empty +// EMPTY-NOT: B + +/// Import regular build, should use binary. +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-serialized -module-name Test %t/main.swift \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \ +// RUN: -o %t/deps2.json -I %t/regular -swift-version 5 -Rmodule-loading +// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps2.json Test directDependencies | %FileCheck %s --check-prefix TEST2 +// TEST2: "swiftPrebuiltExternal": "A" +// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps2.json swiftPrebuiltExternal:A directDependencies | %FileCheck %s --check-prefix EMPTY --allow-empty + +/// Testable import testable build, should use binary, even interface is preferred. +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-name Test %t/testable.swift \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -enable-testing \ +// RUN: -o %t/deps3.json -I %t/testable -I %t/internal -swift-version 5 -Rmodule-loading +// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps3.json Test directDependencies | %FileCheck %s --check-prefix TEST3 +// TEST3: "swiftPrebuiltExternal": "A" +// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps3.json swiftPrebuiltExternal:A directDependencies | %FileCheck %s --check-prefix TEST3-A +// TEST3-A: "swift": "B" + +/// Testable import non-testable build without enable testing. +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-name Test %t/testable.swift \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib \ +// RUN: -o %t/deps4.json -I %t/regular -swift-version 5 +// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps4.json Test directDependencies | %FileCheck %s --check-prefix TEST4 +// TEST4: "swiftPrebuiltExternal": "A" +// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps4.json swiftPrebuiltExternal:A directDependencies | %FileCheck %s --check-prefix EMPTY --allow-empty + +/// Testable import non-testable build enable testing, still succeed since swift-frontend can provide a better diagnostics when the module is actually imported. +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-name Test %t/testable.swift \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -enable-testing \ +// RUN: -o %t/deps5.json -I %t/regular -swift-version 5 -Rmodule-loading + +/// Regular import a testable module with no interface, don't load optional dependencies. +// RUN: rm %t/testable/A.swiftinterface +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-name Test %t/main.swift \ +// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -enable-testing \ +// RUN: -o %t/deps6.json -I %t/testable -swift-version 5 -Rmodule-loading +// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps6.json Test directDependencies | %FileCheck %s --check-prefix TEST6 +// TEST6: "swiftPrebuiltExternal": "A" +// RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps6.json swiftPrebuiltExternal:A directDependencies | %FileCheck %s --check-prefix EMPTY --allow-empty + + +//--- main.swift +import A + +//--- testable.swift +@testable import A + +//--- A.swift +internal import B +@_spi(Testing) public func a() {} + +//--- B.swift +public func b() {} + diff --git a/test/ScanDependencies/testable-import.swift b/test/ScanDependencies/testable-import.swift index d2323cf9e3bf8..d6e57bd9c66c7 100644 --- a/test/ScanDependencies/testable-import.swift +++ b/test/ScanDependencies/testable-import.swift @@ -16,14 +16,14 @@ // RUN: -emit-module-interface-path %t/A.swiftinterface -enable-library-evolution -I %t -enable-testing \ // RUN: %t/A.swift -// RUN: %target-swift-frontend -scan-dependencies -module-name Test %t/test1.swift \ +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-name Test %t/test1.swift \ // RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -enable-testing \ // RUN: -o %t/deps1.json -I %t -swift-version 5 // RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps1.json Test directDependencies | %FileCheck %s --check-prefix TEST1 // TEST1-DAG: "swiftPrebuiltExternal": "B" // TEST1-DAG: "swift": "C" -// RUN: %target-swift-frontend -scan-dependencies -module-name Test %t/test2.swift \ +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-name Test %t/test2.swift \ // RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -enable-testing \ // RUN: -o %t/deps2.json -I %t -swift-version 5 // RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps2.json Test directDependencies | %FileCheck %s --check-prefix TEST2 @@ -36,7 +36,7 @@ // TEST2-A-DAG: "swift": "C" /// An indirect @testable import is still interface deps. -// RUN: %target-swift-frontend -scan-dependencies -module-name Test %t/test3.swift \ +// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-interface -module-name Test %t/test3.swift \ // RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import -parse-stdlib -enable-testing \ // RUN: -o %t/deps3.json -I %t -swift-version 5 // RUN: %{python} %S/../CAS/Inputs/SwiftDepsExtractor.py %t/deps3.json Test directDependencies | %FileCheck %s --check-prefix TEST3