diff --git a/include/swift/AST/PluginLoader.h b/include/swift/AST/PluginLoader.h index d2ad612116882..5ef31029af38f 100644 --- a/include/swift/AST/PluginLoader.h +++ b/include/swift/AST/PluginLoader.h @@ -52,30 +52,19 @@ class PluginLoader { void setRegistry(PluginRegistry *newValue); PluginRegistry *getRegistry(); - /// Lookup a library plugin that can handle \p moduleName and return the path - /// to it from `-load-plugin-library`. - /// The path returned can be loaded by 'loadLibraryPlugin' method. - llvm::Optional - lookupExplicitLibraryPluginByModuleName(Identifier moduleName); - - /// Lookup a library plugin that can handle \p moduleName and return the path - /// to it from `-plugin-path`. - /// The path returned can be loaded by 'loadLibraryPlugin' method. - llvm::Optional - lookupLibraryPluginInSearchPathByModuleName(Identifier moduleName); - - /// Lookup an executable plugin that is declared to handle \p moduleName - /// module by '-load-plugin-executable'. - /// The path returned can be loaded by 'loadExecutablePlugin' method. - llvm::Optional - lookupExecutablePluginByModuleName(Identifier moduleName); - - /// Look for dynamic libraries in paths from `-external-plugin-path` and - /// return a pair of `(library path, plugin server executable)` if found. - /// These paths are valid within the VFS, use `FS.getRealPath()` for their - /// underlying path. - llvm::Optional> - lookupExternalLibraryPluginByModuleName(Identifier moduleName); + /// Lookup a plugin that can handle \p moduleName and return the path(s) to + /// it. The path returned can be loaded by 'load(Library|Executable)Plugin()'. + /// The return value is a pair of a "library path" and a "executable path". + /// + /// * (libPath: empty, execPath: empty) - plugin not found. + /// * (libPath: some, execPath: empty) - load the library path by + /// 'loadLibraryPlugin()'. + /// * (libPath: empty, execPath: some) - load the executable path by + /// 'loadExecutablePlugin()'. + /// * (libPath: some, execPath: some) - load the executable path by + /// 'loadExecutablePlugin()' and let the plugin load the libPath via IPC. + std::pair + lookupPluginByModuleName(Identifier moduleName); /// Load the specified dylib plugin path resolving the path with the /// current VFS. If it fails to load the plugin, a diagnostic is emitted, and diff --git a/include/swift/AST/SearchPathOptions.h b/include/swift/AST/SearchPathOptions.h index 74bc7d175af11..be355091b29d6 100644 --- a/include/swift/AST/SearchPathOptions.h +++ b/include/swift/AST/SearchPathOptions.h @@ -15,6 +15,7 @@ #include "swift/Basic/ArrayRefView.h" #include "swift/Basic/PathRemapper.h" +#include "swift/Basic/TaggedUnion.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringMap.h" @@ -34,7 +35,6 @@ enum class ModuleSearchPathKind { Framework, DarwinImplicitFramework, RuntimeLibrary, - CompilerPlugin, }; /// A single module search path that can come from different sources, e.g. @@ -187,6 +187,26 @@ struct ExternalPluginSearchPathAndServerPath { std::string ServerPath; }; +namespace PluginSearchOption { +struct LoadPluginLibrary { + std::string LibraryPath; +}; +struct LoadPluginExecutable { + std::string ExecutablePath; + std::vector ModuleNames; +}; +struct PluginPath { + std::string SearchPath; +}; +struct ExternalPluginPath { + std::string SearchPath; + std::string ServerPath; +}; + +using Value = TaggedUnion; +} // namespace PluginSearchOption + /// Options for controlling search path behavior. class SearchPathOptions { /// To call \c addImportSearchPath and \c addFrameworkSearchPath from @@ -259,14 +279,6 @@ class SearchPathOptions { ImportSearchPaths.size() - 1); } - void addCompilerPluginLibraryPath(StringRef Path, llvm::vfs::FileSystem *FS) { - CompilerPluginLibraryPaths.push_back(Path.str()); - Lookup.searchPathAdded(FS, CompilerPluginLibraryPaths.back(), - ModuleSearchPathKind::CompilerPlugin, - /*isSystem=*/false, - CompilerPluginLibraryPaths.size() - 1); - } - /// Add a single framework search path. Must only be called from /// \c ASTContext::addSearchPath. void addFrameworkSearchPath(FrameworkSearchPath NewPath, @@ -355,27 +367,6 @@ class SearchPathOptions { Lookup.searchPathsDidChange(); } - void setCompilerPluginLibraryPaths( - std::vector NewCompilerPluginLibraryPaths) { - CompilerPluginLibraryPaths = NewCompilerPluginLibraryPaths; - Lookup.searchPathsDidChange(); - } - - ArrayRef getCompilerPluginLibraryPaths() const { - return CompilerPluginLibraryPaths; - } - - void setCompilerPluginExecutablePaths( - std::vector &&newValue) { - CompilerPluginExecutablePaths = std::move(newValue); - Lookup.searchPathsDidChange(); - } - - ArrayRef - getCompilerPluginExecutablePaths() const { - return CompilerPluginExecutablePaths; - } - /// Path(s) to virtual filesystem overlay YAML files. std::vector VFSOverlayFiles; @@ -391,15 +382,8 @@ class SearchPathOptions { /// preference. std::vector RuntimeLibraryPaths; - /// Paths that contain compiler plugins loaded on demand for, e.g., - /// macro implementations. - std::vector PluginSearchPaths; - - /// Pairs of external compiler plugin search paths and the corresponding - /// plugin server executables. - /// e.g. {"/path/to/usr/lib/swift/host/plugins", - /// "/path/to/usr/bin/plugin-server"} - std::vector ExternalPluginSearchPaths; + /// Plugin search path options. + std::vector PluginSearchOpts; /// Don't look in for compiler-provided modules. bool SkipRuntimeLibraryImportPaths = false; diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h index 56636c17bc8b7..e85733aa66ddc 100644 --- a/include/swift/Frontend/Frontend.h +++ b/include/swift/Frontend/Frontend.h @@ -198,14 +198,6 @@ class CompilerInvocation { SearchPathOpts.VFSOverlayFiles = Overlays; } - void setCompilerPluginLibraryPaths(const std::vector &Paths) { - SearchPathOpts.setCompilerPluginLibraryPaths(Paths); - } - - ArrayRef getCompilerPluginLibraryPaths() { - return SearchPathOpts.getCompilerPluginLibraryPaths(); - } - void setExtraClangArgs(const std::vector &Args) { ClangImporterOpts.ExtraArgs = Args; } diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 1069d3ea2b10f..dba97b91132e0 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -304,15 +304,6 @@ def I : JoinedOrSeparate<["-"], "I">, def I_EQ : Joined<["-"], "I=">, Flags<[FrontendOption, ArgumentIsPath]>, Alias; -def plugin_path : Separate<["-"], "plugin-path">, - Flags<[FrontendOption, ArgumentIsPath, SwiftAPIExtractOption, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, - HelpText<"Add directory to the plugin search path">; - -def external_plugin_path : Separate<["-"], "external-plugin-path">, - Flags<[FrontendOption, ArgumentIsPath, SwiftAPIExtractOption, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, - HelpText<"Add directory to the plugin search path with a plugin server executable">, - MetaVarName<"#">; - def import_underlying_module : Flag<["-"], "import-underlying-module">, Flags<[FrontendOption, NoInteractiveOption]>, HelpText<"Implicitly imports the Objective-C half of a module">; @@ -1852,15 +1843,27 @@ def clang_include_tree_root: Separate<["-"], "clang-include-tree-root">, Flags<[FrontendOption, NoDriverOption]>, HelpText<"Clang Include Tree CASID">, MetaVarName<"">; + +def plugin_search_Group : OptionGroup<"">; + +def plugin_path : Separate<["-"], "plugin-path">, Group, + Flags<[FrontendOption, ArgumentIsPath, SwiftAPIExtractOption, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, + HelpText<"Add directory to the plugin search path">; + +def external_plugin_path : Separate<["-"], "external-plugin-path">, Group, + Flags<[FrontendOption, ArgumentIsPath, SwiftAPIExtractOption, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>, + HelpText<"Add directory to the plugin search path with a plugin server executable">, + MetaVarName<"#">; + def load_plugin_library: - Separate<["-"], "load-plugin-library">, + Separate<["-"], "load-plugin-library">, Group, Flags<[FrontendOption, DoesNotAffectIncrementalBuild, ArgumentIsPath]>, HelpText<"Path to a dynamic library containing compiler plugins such as " "macros">, MetaVarName<"">; def load_plugin_executable: - Separate<["-"], "load-plugin-executable">, + Separate<["-"], "load-plugin-executable">, Group, Flags<[FrontendOption, DoesNotAffectIncrementalBuild, ArgumentIsPath]>, HelpText<"Path to an executable compiler plugins and providing module names " "such as macros">, diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 93c8f0f0959e4..1fd84972038b3 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -103,11 +103,10 @@ llvm::StringRef swift::getProtocolName(KnownProtocolKind kind) { } namespace { - enum class SearchPathKind : uint8_t { - Import = 1 << 0, - Framework = 1 << 1, - CompilerPlugin = 1 << 2 - }; +enum class SearchPathKind : uint8_t { + Import = 1 << 0, + Framework = 1 << 1, +}; } // end anonymous namespace using AssociativityCacheType = @@ -694,8 +693,6 @@ ASTContext::ASTContext( getImpl().SearchPathsSet[path] |= SearchPathKind::Import; for (const auto &framepath : SearchPathOpts.getFrameworkSearchPaths()) getImpl().SearchPathsSet[framepath.Path] |= SearchPathKind::Framework; - for (StringRef path : SearchPathOpts.getCompilerPluginLibraryPaths()) - getImpl().SearchPathsSet[path] |= SearchPathKind::CompilerPlugin; // Register any request-evaluator functions available at the AST layer. registerAccessRequestFunctions(evaluator); diff --git a/lib/AST/PluginLoader.cpp b/lib/AST/PluginLoader.cpp index efae0a6ca2a2c..1bdfc95b1e7ef 100644 --- a/lib/AST/PluginLoader.cpp +++ b/lib/AST/PluginLoader.cpp @@ -20,12 +20,14 @@ using namespace swift; void PluginLoader::createModuleToExecutablePluginMap() { - for (auto &arg : Ctx.SearchPathOpts.getCompilerPluginExecutablePaths()) { - // Create a moduleName -> pluginPath mapping. - assert(!arg.ExecutablePath.empty() && "empty plugin path"); - StringRef pathStr = Ctx.AllocateCopy(arg.ExecutablePath); - for (auto moduleName : arg.ModuleNames) { - ExecutablePluginPaths[Ctx.getIdentifier(moduleName)] = pathStr; + for (auto &elem : Ctx.SearchPathOpts.PluginSearchOpts) { + if (auto *arg = elem.dyn_cast()) { + // Create a moduleName -> pluginPath mapping. + assert(!arg->ExecutablePath.empty() && "empty plugin path"); + StringRef pathStr = Ctx.AllocateCopy(arg->ExecutablePath); + for (auto moduleName : arg->ModuleNames) { + ExecutablePluginPaths[Ctx.getIdentifier(moduleName)] = pathStr; + } } } } @@ -46,69 +48,59 @@ PluginRegistry *PluginLoader::getRegistry() { return Registry; } -llvm::Optional -PluginLoader::lookupExplicitLibraryPluginByModuleName(Identifier moduleName) { - // Look for 'lib${module name}(.dylib|.so)'. - SmallString<64> expectedBasename; - expectedBasename.append("lib"); - expectedBasename.append(moduleName.str()); - expectedBasename.append(LTDL_SHLIB_EXT); - - // Try '-load-plugin-library'. - for (const auto &libPath : - Ctx.SearchPathOpts.getCompilerPluginLibraryPaths()) { - if (llvm::sys::path::filename(libPath) == expectedBasename) { - return libPath; - } - } - return None; -} +std::pair +PluginLoader::lookupPluginByModuleName(Identifier moduleName) { + auto fs = Ctx.SourceMgr.getFileSystem(); -llvm::Optional -PluginLoader::lookupLibraryPluginInSearchPathByModuleName( - Identifier moduleName) { // Look for 'lib${module name}(.dylib|.so)'. - SmallString<64> expectedBasename; - expectedBasename.append("lib"); - expectedBasename.append(moduleName.str()); - expectedBasename.append(LTDL_SHLIB_EXT); - - // Try '-plugin-path'. - auto fs = Ctx.SourceMgr.getFileSystem(); - for (const auto &searchPath : Ctx.SearchPathOpts.PluginSearchPaths) { - SmallString<128> fullPath(searchPath); - llvm::sys::path::append(fullPath, expectedBasename); - if (fs->exists(fullPath)) { - return std::string(fullPath); + // FIXME: Shared library prefix might be different between platforms. + SmallString<64> pluginLibBasename; + pluginLibBasename.append("lib"); + pluginLibBasename.append(moduleName.str()); + pluginLibBasename.append(LTDL_SHLIB_EXT); + + // FIXME: Should we create a lookup table keyed by module name? + for (auto &entry : Ctx.SearchPathOpts.PluginSearchOpts) { + using namespace PluginSearchOption; + // Try '-load-plugin-library'. + if (auto *val = entry.dyn_cast()) { + if (llvm::sys::path::filename(val->LibraryPath) == pluginLibBasename) { + return {val->LibraryPath, ""}; + } + continue; } - } - - return None; -} -Optional> -PluginLoader::lookupExternalLibraryPluginByModuleName(Identifier moduleName) { - auto fs = Ctx.SourceMgr.getFileSystem(); + // Try '-load-plugin-executable'. + if (auto *v = entry.dyn_cast()) { + auto found = ExecutablePluginPaths.find(moduleName); + if (found != ExecutablePluginPaths.end()) { + return {"", std::string(found->second)}; + } + continue; + } - for (auto &pair : Ctx.SearchPathOpts.ExternalPluginSearchPaths) { - SmallString<128> fullPath(pair.SearchPath); - llvm::sys::path::append(fullPath, - "lib" + moduleName.str() + LTDL_SHLIB_EXT); + // Try '-plugin-path'. + if (auto *v = entry.dyn_cast()) { + SmallString<128> fullPath(v->SearchPath); + llvm::sys::path::append(fullPath, pluginLibBasename); + if (fs->exists(fullPath)) { + return {std::string(fullPath), ""}; + } + continue; + } - if (fs->exists(fullPath)) { - return {{std::string(fullPath), pair.ServerPath}}; + // Try '-external-plugin-path'. + if (auto *v = entry.dyn_cast()) { + SmallString<128> fullPath(v->SearchPath); + llvm::sys::path::append(fullPath, pluginLibBasename); + if (fs->exists(fullPath)) { + return {std::string(fullPath), v->ServerPath}; + } + continue; } } - return None; -} -Optional -PluginLoader::lookupExecutablePluginByModuleName(Identifier moduleName) { - auto &execPluginPaths = ExecutablePluginPaths; - auto found = execPluginPaths.find(moduleName); - if (found == execPluginPaths.end()) - return None; - return found->second; + return {}; } LoadedLibraryPlugin *PluginLoader::loadLibraryPlugin(StringRef path) { diff --git a/lib/AST/SearchPathOptions.cpp b/lib/AST/SearchPathOptions.cpp index 4e110ccacd70d..88a1cb56e0548 100644 --- a/lib/AST/SearchPathOptions.cpp +++ b/lib/AST/SearchPathOptions.cpp @@ -73,12 +73,6 @@ void ModuleSearchPathLookup::rebuildLookupTable(const SearchPathOptions *Opts, /*isSystem=*/true, Entry.index()); } - for (auto Entry : llvm::enumerate(Opts->getCompilerPluginLibraryPaths())) { - addFilesInPathToLookupTable(FS, Entry.value(), - ModuleSearchPathKind::CompilerPlugin, - /*isSystem=*/false, Entry.index()); - } - State.FileSystem = FS; State.IsOSDarwin = IsOSDarwin; State.Opts = Opts; diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index c2dee09d575ba..9f4d5ba396ad5 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -236,8 +236,6 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI, inputArgs.AddAllArgs(arguments, options::OPT_I); inputArgs.AddAllArgs(arguments, options::OPT_F, options::OPT_Fsystem); inputArgs.AddAllArgs(arguments, options::OPT_vfsoverlay); - inputArgs.AddAllArgs(arguments, options::OPT_plugin_path); - inputArgs.AddAllArgs(arguments, options::OPT_external_plugin_path); inputArgs.AddLastArg(arguments, options::OPT_AssertConfig); inputArgs.AddLastArg(arguments, options::OPT_autolink_force_load); @@ -325,8 +323,6 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI, inputArgs.AddLastArg(arguments, options::OPT_enable_bare_slash_regex); inputArgs.AddLastArg(arguments, options::OPT_enable_experimental_cxx_interop); inputArgs.AddLastArg(arguments, options::OPT_cxx_interoperability_mode); - inputArgs.AddLastArg(arguments, options::OPT_load_plugin_library); - inputArgs.AddLastArg(arguments, options::OPT_load_plugin_executable); inputArgs.AddLastArg(arguments, options::OPT_enable_builtin_module); // Pass on any build config options @@ -376,9 +372,9 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI, inputArgs.AddAllArgs(arguments, options::OPT_file_compilation_dir); } - // Add plugin path options. - inputArgs.AddAllArgs(arguments, options::OPT_plugin_path); - + // Specify default plugin search path options after explicitly specified + // options. + inputArgs.AddAllArgs(arguments, options::OPT_plugin_search_Group); { SmallString<64> pluginPath; auto programPath = getDriver().getSwiftProgramPath(); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index d6c547c76d293..7e4aa57a3c54b 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1601,18 +1601,56 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts, } Opts.setFrameworkSearchPaths(FrameworkSearchPaths); - for (const Arg *A : Args.filtered(OPT_plugin_path)) { - Opts.PluginSearchPaths.push_back(resolveSearchPath(A->getValue())); - } - - for (const Arg *A : Args.filtered(OPT_external_plugin_path)) { - // '#'. - // FIXME: '#' can be used in the paths. - StringRef dylibPath; - StringRef serverPath; - std::tie(dylibPath, serverPath) = StringRef(A->getValue()).split('#'); - Opts.ExternalPluginSearchPaths.push_back( - {resolveSearchPath(dylibPath), resolveSearchPath(serverPath)}); + // All plugin search options, i.e. '-load-plugin-library', + // '-load-plugin-executable', '-plugin-path', and '-external-plugin-path' + // are grouped, and plugins are searched by the order of these options. + // e.g. For '-plugin-path A -load-plugin-library B/libModule.dylib', if + // 'A/libModule.dylib' exists, it's used. + for (const Arg *A : Args.filtered(OPT_plugin_search_Group)) { + switch (A->getOption().getID()) { + case OPT_load_plugin_library: { + Opts.PluginSearchOpts.emplace_back(PluginSearchOption::LoadPluginLibrary{ + resolveSearchPath(A->getValue())}); + break; + } + case OPT_load_plugin_executable: { + // '#' where the module names are + // comma separated. + StringRef path; + StringRef modulesStr; + std::tie(path, modulesStr) = StringRef(A->getValue()).rsplit('#'); + std::vector moduleNames; + for (auto name : llvm::split(modulesStr, ',')) { + moduleNames.emplace_back(name); + } + if (path.empty() || moduleNames.empty()) { + Diags.diagnose(SourceLoc(), diag::error_load_plugin_executable, + A->getValue()); + } else { + Opts.PluginSearchOpts.emplace_back( + PluginSearchOption::LoadPluginExecutable{resolveSearchPath(path), + std::move(moduleNames)}); + } + break; + } + case OPT_plugin_path: { + Opts.PluginSearchOpts.emplace_back( + PluginSearchOption::PluginPath{resolveSearchPath(A->getValue())}); + break; + } + case OPT_external_plugin_path: { + // '#'. + // FIXME: '#' can be used in the paths. + StringRef dylibPath; + StringRef serverPath; + std::tie(dylibPath, serverPath) = StringRef(A->getValue()).split('#'); + Opts.PluginSearchOpts.emplace_back(PluginSearchOption::ExternalPluginPath{ + resolveSearchPath(dylibPath), resolveSearchPath(serverPath)}); + break; + } + default: + llvm_unreachable("unhandled plugin search option"); + } } for (const Arg *A : Args.filtered(OPT_L)) { @@ -1674,36 +1712,6 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts, // is called before setTargetTriple() and parseArgs(). // TODO: improve the handling of RuntimeIncludePath. - std::vector CompilerPluginLibraryPaths( - Opts.getCompilerPluginLibraryPaths()); - for (const Arg *A : Args.filtered(OPT_load_plugin_library)) { - CompilerPluginLibraryPaths.push_back(resolveSearchPath(A->getValue())); - } - Opts.setCompilerPluginLibraryPaths(CompilerPluginLibraryPaths); - - std::vector CompilerPluginExecutablePaths( - Opts.getCompilerPluginExecutablePaths()); - for (const Arg *A : Args.filtered(OPT_load_plugin_executable)) { - // 'A' is '#' where the module names are - // comma separated. - StringRef path; - StringRef modulesStr; - std::tie(path, modulesStr) = StringRef(A->getValue()).rsplit('#'); - std::vector moduleNames; - for (auto name : llvm::split(modulesStr, ',')) { - moduleNames.emplace_back(name); - } - if (path.empty() || moduleNames.empty()) { - Diags.diagnose(SourceLoc(), diag::error_load_plugin_executable, - A->getValue()); - } else { - CompilerPluginExecutablePaths.push_back( - {resolveSearchPath(path), std::move(moduleNames)}); - } - } - Opts.setCompilerPluginExecutablePaths( - std::move(CompilerPluginExecutablePaths)); - return false; } diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index b65e628b31953..f96f80fc9647e 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -209,30 +209,35 @@ SerializationOptions CompilerInvocation::computeSerializationOptions( serializationOpts.ExtraClangOptions = getClangImporterOptions().ExtraArgs; } - // '-plugin-path' options. - for (const auto &path : getSearchPathOptions().PluginSearchPaths) { - serializationOpts.PluginSearchPaths.push_back(path); - } - // '-external-plugin-path' options. - for (const ExternalPluginSearchPathAndServerPath &pair : - getSearchPathOptions().ExternalPluginSearchPaths) { - serializationOpts.ExternalPluginSearchPaths.push_back( - pair.SearchPath + "#" + - pair.ServerPath); - } - // '-load-plugin-library' options. - for (const auto &path : - getSearchPathOptions().getCompilerPluginLibraryPaths()) { - serializationOpts.CompilerPluginLibraryPaths.push_back(path); - } - // '-load-plugin-executable' options. - for (const PluginExecutablePathAndModuleNames &pair : - getSearchPathOptions().getCompilerPluginExecutablePaths()) { - std::string optStr = pair.ExecutablePath + "#"; - llvm::interleave( - pair.ModuleNames, [&](auto &name) { optStr += name; }, - [&]() { optStr += ","; }); - serializationOpts.CompilerPluginExecutablePaths.push_back(optStr); + // FIXME: Preserve the order of these options. + for (auto &elem : getSearchPathOptions().PluginSearchOpts) { + // '-plugin-path' options. + if (auto *arg = elem.dyn_cast()) { + serializationOpts.PluginSearchPaths.push_back(arg->SearchPath); + continue; + } + + // '-external-plugin-path' options. + if (auto *arg = elem.dyn_cast()) { + serializationOpts.ExternalPluginSearchPaths.push_back( + arg->SearchPath + "#" + arg->ServerPath); + continue; + } + + // '-load-plugin-library' options. + if (auto *arg = elem.dyn_cast()) { + serializationOpts.CompilerPluginLibraryPaths.push_back(arg->LibraryPath); + continue; + } + + // '-load-plugin-executable' options. + if (auto *arg = elem.dyn_cast()) { + std::string optStr = arg->ExecutablePath + "#"; + llvm::interleave( + arg->ModuleNames, [&](auto &name) { optStr += name; }, + [&]() { optStr += ","; }); + serializationOpts.CompilerPluginExecutablePaths.push_back(optStr); + } } serializationOpts.DisableCrossModuleIncrementalInfo = diff --git a/lib/Sema/TypeCheckMacros.cpp b/lib/Sema/TypeCheckMacros.cpp index c7b0f454aca02..f939aeec229ef 100644 --- a/lib/Sema/TypeCheckMacros.cpp +++ b/lib/Sema/TypeCheckMacros.cpp @@ -345,25 +345,8 @@ CompilerPluginLoadRequest::evaluate(Evaluator &evaluator, ASTContext *ctx, std::string libraryPath; std::string executablePath; - - // '-load-plugin-libarary'. - if (auto found = loader.lookupExplicitLibraryPluginByModuleName(moduleName)) { - libraryPath = found.value(); - } - // '-load-plugin-executable'. - else if (auto found = loader.lookupExecutablePluginByModuleName(moduleName)) { - executablePath = found->str(); - } - // '-plugin-path'. - else if (auto found = - loader.lookupLibraryPluginInSearchPathByModuleName(moduleName)) { - libraryPath = found.value(); - } - // '-external-plugin-path'. - else if (auto found = - loader.lookupExternalLibraryPluginByModuleName(moduleName)) { - std::tie(libraryPath, executablePath) = found.value(); - } + std::tie(libraryPath, executablePath) = + loader.lookupPluginByModuleName(moduleName); if (!executablePath.empty()) { if (LoadedExecutablePlugin *executablePlugin = diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index 56327b501b71a..1107e1d48f1b4 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -205,8 +205,7 @@ void SerializedModuleLoaderBase::collectVisibleTopLevelModuleNamesImpl( }); return None; } - case ModuleSearchPathKind::RuntimeLibrary: - case ModuleSearchPathKind::CompilerPlugin: { + case ModuleSearchPathKind::RuntimeLibrary: { // Look for: // (Darwin OS) $PATH/{name}.swiftmodule/{arch}.{extension} // (Other OS) $PATH/{name}.{extension} @@ -678,8 +677,7 @@ bool SerializedModuleLoaderBase::findModule( switch (searchPath->getKind()) { case ModuleSearchPathKind::Import: - case ModuleSearchPathKind::RuntimeLibrary: - case ModuleSearchPathKind::CompilerPlugin: { + case ModuleSearchPathKind::RuntimeLibrary: { isFramework = false; // On Apple platforms, we can assume that the runtime libraries use diff --git a/test/Macros/macro_mixedpluginpath.swift b/test/Macros/macro_mixedpluginpath.swift index 2ca1e9406c571..ea559a4db9732 100644 --- a/test/Macros/macro_mixedpluginpath.swift +++ b/test/Macros/macro_mixedpluginpath.swift @@ -25,14 +25,14 @@ //#-- Check '-load-plugin-library' takes precedence over '-plugin-path'. // RUN: %target-swift-frontend -typecheck -verify -swift-version 5 \ -// RUN: -plugin-path %t/plugins \ // RUN: -load-plugin-library %t/plugins_local/%target-library-name(MacroDefinition) \ +// RUN: -plugin-path %t/plugins \ // RUN: %t/src/test.swift -//#-- Same, but with different argument order. -// RUN: %target-swift-frontend -typecheck -verify -swift-version 5 \ -// RUN: -load-plugin-library %t/plugins_local/%target-library-name(MacroDefinition) \ +//#-- Different argument order changes the search order, hence fail. +// RUN: not %target-swift-frontend -typecheck -verify -swift-version 5 \ // RUN: -plugin-path %t/plugins \ +// RUN: -load-plugin-library %t/plugins_local/%target-library-name(MacroDefinition) \ // RUN: %t/src/test.swift //--- test.swift @@ -40,7 +40,7 @@ func foo() { let _: Int = #constInt - // If 'MacroDefinition.float.swift' is loaded, type checking this fails because it expands to '4.2' which is a float literal. + // If 'MacroDefinition.float.swift' (in '-pluing-path') is loaded, type checking this fails because it expands to '4.2' which is a float literal. } //--- MacroDefinition.float.swift diff --git a/test/Macros/macro_plugin_searchorder.swift b/test/Macros/macro_plugin_searchorder.swift index 786630a832eed..562144fa86b48 100644 --- a/test/Macros/macro_plugin_searchorder.swift +++ b/test/Macros/macro_plugin_searchorder.swift @@ -50,39 +50,42 @@ //#-- Expect -load-plugin-library // RUN: %target-build-swift %t/src/test.swift \ -// RUN: -o %t/main1 \ // RUN: -module-name test \ +// RUN: -load-plugin-library %t/lib/tmp/%target-library-name(MacroDefinition) \ // RUN: -plugin-path %t/lib/plugins \ // RUN: -external-plugin-path %t/external#%swift-plugin-server \ -// RUN: -load-plugin-library %t/lib/tmp/%target-library-name(MacroDefinition) \ -// RUN: -load-plugin-executable %t/libexec/MacroDefinitionPlugin#MacroDefinition +// RUN: -load-plugin-executable %t/libexec/MacroDefinitionPlugin#MacroDefinition \ +// RUN: -o %t/main1 // RUN: %target-codesign %t/main1 // RUN: %target-run %t/main1 | %FileCheck --check-prefix=CHECK_LOAD_PLUGIN_LIBRARY %s //#-- Expect -load-plugin-executable // RUN: %target-build-swift %t/src/test.swift \ -// RUN: -o %t/main2 \ // RUN: -module-name test \ +// RUN: -load-plugin-executable %t/libexec/MacroDefinitionPlugin#MacroDefinition \ // RUN: -plugin-path %t/lib/plugins \ // RUN: -external-plugin-path %t/external#%swift-plugin-server \ -// RUN: -load-plugin-executable %t/libexec/MacroDefinitionPlugin#MacroDefinition +// RUN: -o %t/main2 // RUN: %target-codesign %t/main2 // RUN: %target-run %t/main2 | %FileCheck --check-prefix=CHECK_LOAD_PLUGIN_EXECUTABLE %s //#-- Expect -plugin-path // RUN: %target-build-swift %t/src/test.swift \ -// RUN: -o %t/main3 \ // RUN: -module-name test \ // RUN: -plugin-path %t/lib/plugins \ -// RUN: -external-plugin-path %t/external#%swift-plugin-server +// RUN: -load-plugin-library %t/lib/tmp/%target-library-name(MacroDefinition) \ +// RUN: -external-plugin-path %t/external#%swift-plugin-server \ +// RUN: -o %t/main3 // RUN: %target-codesign %t/main3 // RUN: %target-run %t/main3 | %FileCheck --check-prefix=CHECK_PLUGIN_PATH %s //#-- Expect -external-plugin-path // RUN: %target-build-swift %t/src/test.swift \ -// RUN: -o %t/main4 \ // RUN: -module-name test \ -// RUN: -external-plugin-path %t/external#%swift-plugin-server +// RUN: -external-plugin-path %t/external#%swift-plugin-server \ +// RUN: -plugin-path %t/lib/plugins \ +// RUN: -load-plugin-executable %t/libexec/MacroDefinitionPlugin#MacroDefinition \ +// RUN: -o %t/main4 // RUN: %target-codesign %t/main4 // RUN: %target-run %t/main4 | %FileCheck --check-prefix=CHECK_EXTERNAL_PLUGIN_PATH %s diff --git a/test/Macros/serialize_plugin_search_paths.swift b/test/Macros/serialize_plugin_search_paths.swift index 95e901895e42d..ef9c5c8d7ee88 100644 --- a/test/Macros/serialize_plugin_search_paths.swift +++ b/test/Macros/serialize_plugin_search_paths.swift @@ -15,7 +15,6 @@ // CHECK: -plugin-path: {{.*}}plugins // CHECK: -plugin-path: {{.*}}plugins // CHECK: -plugin-path: {{.*}}plugins -// CHECK: -plugin-path: {{.*}}plugins // CHECK: -external-plugin-path: {{.*}}plugins#{{.*}}swift-plugin-server // CHECK: -load-plugin-library: {{.*}}MacroDefinition.{{dylib|so|dll}} // CHECK: -load-plugin-executable: {{.*}}mock-plugin#TestPlugin diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp index 463f801d3949d..9d4908cc9be47 100644 --- a/tools/swift-ide-test/swift-ide-test.cpp +++ b/tools/swift-ide-test/swift-ide-test.cpp @@ -4513,15 +4513,12 @@ int main(int argc, char *argv[]) { } } - for (auto path : options::PluginPath) { - InitInvok.getSearchPathOptions().PluginSearchPaths.push_back(path); - } if (!options::LoadPluginLibrary.empty()) { std::vector paths; for (auto path: options::LoadPluginLibrary) { - paths.push_back(path); + InitInvok.getSearchPathOptions().PluginSearchOpts.emplace_back( + PluginSearchOption::LoadPluginLibrary{path}); } - InitInvok.getSearchPathOptions().setCompilerPluginLibraryPaths(paths); } if (!options::LoadPluginExecutable.empty()) { std::vector pairs; @@ -4533,10 +4530,14 @@ int main(int argc, char *argv[]) { for (auto name : llvm::split(modulesStr, ',')) { moduleNames.emplace_back(name); } - pairs.push_back({std::string(path), std::move(moduleNames)}); + InitInvok.getSearchPathOptions().PluginSearchOpts.emplace_back( + PluginSearchOption::LoadPluginExecutable{std::string(path), + std::move(moduleNames)}); } - - InitInvok.getSearchPathOptions().setCompilerPluginExecutablePaths(std::move(pairs)); + } + for (auto path : options::PluginPath) { + InitInvok.getSearchPathOptions().PluginSearchOpts.emplace_back( + PluginSearchOption::PluginPath{path}); } // Process the clang arguments last and allow them to override previously