diff --git a/include/swift/AST/PluginLoader.h b/include/swift/AST/PluginLoader.h index 5ef31029af38f..229161515f867 100644 --- a/include/swift/AST/PluginLoader.h +++ b/include/swift/AST/PluginLoader.h @@ -28,6 +28,13 @@ class ASTContext; /// * Load plugins resolving VFS paths /// * Track plugin dependencies class PluginLoader { +public: + struct PluginEntry { + StringRef libraryPath; + StringRef executablePath; + }; + +private: /// Plugin registry. Lazily populated by get/setRegistry(). /// NOTE: Do not reference this directly. Use getRegistry(). PluginRegistry *Registry = nullptr; @@ -38,16 +45,15 @@ class PluginLoader { ASTContext &Ctx; DependencyTracker *DepTracker; - /// Map a module name to an executable plugin path that provides the module. - llvm::DenseMap ExecutablePluginPaths; + /// Map a module name to an plugin entry that provides the module. + llvm::Optional> PluginMap; - void createModuleToExecutablePluginMap(); + /// Get or lazily create and populate 'PluginMap'. + llvm::DenseMap &getPluginMap(); public: PluginLoader(ASTContext &Ctx, DependencyTracker *DepTracker) - : Ctx(Ctx), DepTracker(DepTracker) { - createModuleToExecutablePluginMap(); - } + : Ctx(Ctx), DepTracker(DepTracker) {} void setRegistry(PluginRegistry *newValue); PluginRegistry *getRegistry(); @@ -63,8 +69,7 @@ class PluginLoader { /// '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); + const PluginEntry &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 be355091b29d6..12a96849ed722 100644 --- a/include/swift/AST/SearchPathOptions.h +++ b/include/swift/AST/SearchPathOptions.h @@ -14,8 +14,8 @@ #define SWIFT_AST_SEARCHPATHOPTIONS_H #include "swift/Basic/ArrayRefView.h" +#include "swift/Basic/ExternalUnion.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" @@ -187,25 +187,81 @@ 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; -}; +class PluginSearchOption { +public: + 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; + }; + + enum class Kind : uint8_t { + LoadPluginLibrary, + LoadPluginExecutable, + PluginPath, + ExternalPluginPath, + }; -using Value = TaggedUnion; -} // namespace PluginSearchOption +private: + using Members = ExternalUnionMembers; + static Members::Index getIndexForKind(Kind kind) { + switch (kind) { + case Kind::LoadPluginLibrary: + return Members::indexOf(); + case Kind::LoadPluginExecutable: + return Members::indexOf(); + case Kind::PluginPath: + return Members::indexOf(); + case Kind::ExternalPluginPath: + return Members::indexOf(); + } + }; + using Storage = ExternalUnion; + + Kind kind; + Storage storage; + +public: + PluginSearchOption(const LoadPluginLibrary &v) + : kind(Kind::LoadPluginLibrary) { + storage.emplace(kind, v); + } + PluginSearchOption(const LoadPluginExecutable &v) + : kind(Kind::LoadPluginExecutable) { + storage.emplace(kind, v); + } + PluginSearchOption(const PluginPath &v) : kind(Kind::PluginPath) { + storage.emplace(kind, v); + } + PluginSearchOption(const ExternalPluginPath &v) + : kind(Kind::ExternalPluginPath) { + storage.emplace(kind, v); + } + + Kind getKind() const { return kind; } + + template + const T *dyn_cast() const { + if (Members::indexOf() != getIndexForKind(kind)) + return nullptr; + return &storage.get(kind); + } + + template + const T &get() const { + return storage.get(kind); + } +}; /// Options for controlling search path behavior. class SearchPathOptions { @@ -383,7 +439,7 @@ class SearchPathOptions { std::vector RuntimeLibraryPaths; /// Plugin search path options. - std::vector PluginSearchOpts; + std::vector PluginSearchOpts; /// Don't look in for compiler-provided modules. bool SkipRuntimeLibraryImportPaths = false; diff --git a/include/swift/Serialization/SerializationOptions.h b/include/swift/Serialization/SerializationOptions.h index d3e4f49f2441d..d38467eca23d8 100644 --- a/include/swift/Serialization/SerializationOptions.h +++ b/include/swift/Serialization/SerializationOptions.h @@ -13,6 +13,7 @@ #ifndef SWIFT_SERIALIZATION_SERIALIZATIONOPTIONS_H #define SWIFT_SERIALIZATION_SERIALIZATIONOPTIONS_H +#include "swift/AST/SearchPathOptions.h" #include "swift/Basic/LLVM.h" #include "swift/Basic/PathRemapper.h" #include "llvm/Support/VersionTuple.h" @@ -43,10 +44,7 @@ namespace swift { StringRef ModuleLinkName; StringRef ModuleInterface; std::vector ExtraClangOptions; - std::vector PluginSearchPaths; - std::vector ExternalPluginSearchPaths; - std::vector CompilerPluginLibraryPaths; - std::vector CompilerPluginExecutablePaths; + std::vector PluginSearchOptions; /// Path prefixes that should be rewritten in debug info. PathRemapper DebuggingOptionsPrefixMap; diff --git a/include/swift/Serialization/Validation.h b/include/swift/Serialization/Validation.h index a82380e74963a..9ba02485ae973 100644 --- a/include/swift/Serialization/Validation.h +++ b/include/swift/Serialization/Validation.h @@ -111,10 +111,8 @@ struct ValidationInfo { class ExtendedValidationInfo { SmallVector ExtraClangImporterOpts; - SmallVector PluginSearchPaths; - SmallVector ExternalPluginSearchPaths; - SmallVector CompilerPluginLibraryPaths; - SmallVector CompilerPluginExecutablePaths; + SmallVector, 2> + PluginSearchOptions; std::string SDKPath; StringRef ModuleABIName; @@ -149,32 +147,13 @@ class ExtendedValidationInfo { ExtraClangImporterOpts.push_back(option); } - ArrayRef getPluginSearchPaths() const { - return PluginSearchPaths; + ArrayRef> + getPluginSearchOptions() const { + return PluginSearchOptions; } - void addPluginSearchPath(StringRef path) { - PluginSearchPaths.push_back(path); - } - - ArrayRef getExternalPluginSearchPaths() const { - return ExternalPluginSearchPaths; - } - void addExternalPluginSearchPath(StringRef path) { - ExternalPluginSearchPaths.push_back(path); - } - - ArrayRef getCompilerPluginLibraryPaths() const { - return CompilerPluginLibraryPaths; - } - void addCompilerPluginLibraryPath(StringRef path) { - CompilerPluginLibraryPaths.push_back(path); - } - - ArrayRef getCompilerPluginExecutablePaths() const { - return CompilerPluginExecutablePaths; - } - void addCompilerPluginExecutablePath(StringRef path) { - CompilerPluginExecutablePaths.push_back(path); + void addPluginSearchOption( + const std::pair &opt) { + PluginSearchOptions.push_back(opt); } bool isSIB() const { return Bits.IsSIB; } diff --git a/lib/AST/PluginLoader.cpp b/lib/AST/PluginLoader.cpp index 1bdfc95b1e7ef..2f89336577107 100644 --- a/lib/AST/PluginLoader.cpp +++ b/lib/AST/PluginLoader.cpp @@ -15,23 +15,11 @@ #include "swift/AST/DiagnosticEngine.h" #include "swift/AST/DiagnosticsFrontend.h" #include "swift/Basic/SourceManager.h" +#include "swift/Parse/Lexer.h" #include "llvm/Config/config.h" using namespace swift; -void PluginLoader::createModuleToExecutablePluginMap() { - 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; - } - } - } -} - void PluginLoader::setRegistry(PluginRegistry *newValue) { assert(Registry == nullptr && "Too late to set a new plugin registry"); Registry = newValue; @@ -48,59 +36,121 @@ PluginRegistry *PluginLoader::getRegistry() { return Registry; } -std::pair -PluginLoader::lookupPluginByModuleName(Identifier moduleName) { - auto fs = Ctx.SourceMgr.getFileSystem(); - - // Look for 'lib${module name}(.dylib|.so)'. +/// Get plugin module name from \p path if the path looks like a shared library +/// path. Otherwise, returns an empty string. +static StringRef pluginModuleNameStringFromPath(StringRef path) { + // Plugin library must be named 'lib${module name}(.dylib|.so|.dll)'. // FIXME: Shared library prefix might be different between platforms. - SmallString<64> pluginLibBasename; - pluginLibBasename.append("lib"); - pluginLibBasename.append(moduleName.str()); - pluginLibBasename.append(LTDL_SHLIB_EXT); + constexpr StringRef libPrefix = "lib"; + constexpr StringRef libSuffix = LTDL_SHLIB_EXT; + + StringRef filename = llvm::sys::path::filename(path); + if (filename.starts_with(libPrefix) && filename.ends_with(libSuffix)) { + // We don't check if the result it a valid identifier. Even if we put + // invalid name in the lookup table, clients wound not be able to lookup + // that name, thus harmless. + return filename.drop_front(libPrefix.size()).drop_back(libSuffix.size()); + } + return ""; +} + +llvm::DenseMap & +PluginLoader::getPluginMap() { + if (PluginMap.has_value()) { + return PluginMap.value(); + } + + // Create and populate the map. + PluginMap.emplace(); + auto &map = PluginMap.value(); + + // Helper function to try inserting an entry if there's no existing entry + // associated with the module name. + auto try_emplace = [&](StringRef moduleName, StringRef libPath, + StringRef execPath) { + auto moduleNameIdentifier = Ctx.getIdentifier(moduleName); + if (map.find(moduleNameIdentifier) != map.end()) { + // Specified module name is already in the map. + return; + } + + libPath = libPath.empty() ? "" : Ctx.AllocateCopy(libPath); + execPath = execPath.empty() ? "" : Ctx.AllocateCopy(execPath); + auto result = map.insert({moduleNameIdentifier, {libPath, execPath}}); + assert(result.second); + (void)result; + }; + + auto fs = Ctx.SourceMgr.getFileSystem(); + std::error_code ec; - // 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, ""}; + switch (entry.getKind()) { + + // '-load-plugin-library '. + case PluginSearchOption::Kind::LoadPluginLibrary: { + auto &val = entry.get(); + auto moduleName = pluginModuleNameStringFromPath(val.LibraryPath); + if (!moduleName.empty()) { + try_emplace(moduleName, val.LibraryPath, /*executablePath=*/""); } continue; } - // Try '-load-plugin-executable'. - if (auto *v = entry.dyn_cast()) { - auto found = ExecutablePluginPaths.find(moduleName); - if (found != ExecutablePluginPaths.end()) { - return {"", std::string(found->second)}; + // '-load-plugin-executable #, ...'. + case PluginSearchOption::Kind::LoadPluginExecutable: { + auto &val = entry.get(); + assert(!val.ExecutablePath.empty() && "empty plugin path"); + for (auto &moduleName : val.ModuleNames) { + try_emplace(moduleName, /*libraryPath=*/"", val.ExecutablePath); } continue; } - // 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), ""}; + // '-plugin-path '. + case PluginSearchOption::Kind::PluginPath: { + auto &val = entry.get(); + for (auto i = fs->dir_begin(val.SearchPath, ec); + i != llvm::vfs::directory_iterator(); i = i.increment(ec)) { + auto libPath = i->path(); + auto moduleName = pluginModuleNameStringFromPath(libPath); + if (!moduleName.empty()) { + try_emplace(moduleName, libPath, /*executablePath=*/""); + } } continue; } - // 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}; + // '-external-plugin-path #'. + case PluginSearchOption::Kind::ExternalPluginPath: { + auto &val = entry.get(); + for (auto i = fs->dir_begin(val.SearchPath, ec); + i != llvm::vfs::directory_iterator(); i = i.increment(ec)) { + auto libPath = i->path(); + auto moduleName = pluginModuleNameStringFromPath(libPath); + if (!moduleName.empty()) { + try_emplace(moduleName, libPath, val.ServerPath); + } } continue; } + } + llvm_unreachable("unhandled PluginSearchOption::Kind"); } - return {}; + return map; +} + +const PluginLoader::PluginEntry & +PluginLoader::lookupPluginByModuleName(Identifier moduleName) { + auto &map = getPluginMap(); + auto found = map.find(moduleName); + if (found != map.end()) { + return found->second; + } else { + static PluginEntry notFound{"", ""}; + return notFound; + } } LoadedLibraryPlugin *PluginLoader::loadLibraryPlugin(StringRef path) { diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index dcb454b27b76b..e80755aba18be 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -202,36 +202,8 @@ SerializationOptions CompilerInvocation::computeSerializationOptions( serializationOpts.ExtraClangOptions = getClangImporterOptions().ExtraArgs; } - // 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.PluginSearchOptions = + getSearchPathOptions().PluginSearchOpts; serializationOpts.DisableCrossModuleIncrementalInfo = opts.DisableCrossModuleIncrementalBuild; diff --git a/lib/Sema/TypeCheckMacros.cpp b/lib/Sema/TypeCheckMacros.cpp index 14d3dfa315f36..73558d21495f9 100644 --- a/lib/Sema/TypeCheckMacros.cpp +++ b/lib/Sema/TypeCheckMacros.cpp @@ -342,21 +342,17 @@ LoadedCompilerPlugin CompilerPluginLoadRequest::evaluate(Evaluator &evaluator, ASTContext *ctx, Identifier moduleName) const { PluginLoader &loader = ctx->getPluginLoader(); + const auto &entry = loader.lookupPluginByModuleName(moduleName); - std::string libraryPath; - std::string executablePath; - std::tie(libraryPath, executablePath) = - loader.lookupPluginByModuleName(moduleName); - - if (!executablePath.empty()) { + if (!entry.executablePath.empty()) { if (LoadedExecutablePlugin *executablePlugin = - loader.loadExecutablePlugin(executablePath)) { - return initializeExecutablePlugin(*ctx, executablePlugin, libraryPath, - moduleName); + loader.loadExecutablePlugin(entry.executablePath)) { + return initializeExecutablePlugin(*ctx, executablePlugin, + entry.libraryPath, moduleName); } - } else if (!libraryPath.empty()) { + } else if (!entry.libraryPath.empty()) { if (LoadedLibraryPlugin *libraryPlugin = - loader.loadLibraryPlugin(libraryPath)) { + loader.loadLibraryPlugin(entry.libraryPath)) { return libraryPlugin; } } diff --git a/lib/Serialization/ModuleFileSharedCore.cpp b/lib/Serialization/ModuleFileSharedCore.cpp index edf2c566edcc0..d0ed501ebf4bb 100644 --- a/lib/Serialization/ModuleFileSharedCore.cpp +++ b/lib/Serialization/ModuleFileSharedCore.cpp @@ -126,18 +126,27 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor, case options_block::XCC: extendedInfo.addExtraClangImporterOption(blobData); break; - case options_block::PLUGIN_SEARCH_PATH: - extendedInfo.addPluginSearchPath(blobData); - break; - case options_block::EXTERNAL_SEARCH_PLUGIN_PATH: - extendedInfo.addExternalPluginSearchPath(blobData); - break; - case options_block::COMPILER_PLUGIN_LIBRARY_PATH: - extendedInfo.addCompilerPluginLibraryPath(blobData); - break; - case options_block::COMPILER_PLUGIN_EXECUTABLE_PATH: - extendedInfo.addCompilerPluginExecutablePath(blobData); + case options_block::PLUGIN_SEARCH_OPTION: { + unsigned kind; + options_block::ResilienceStrategyLayout::readRecord(scratch, kind); + PluginSearchOption::Kind optKind; + switch (PluginSearchOptionKind(kind)) { + case PluginSearchOptionKind::PluginPath: + optKind = PluginSearchOption::Kind::PluginPath; + break; + case PluginSearchOptionKind::ExternalPluginPath: + optKind = PluginSearchOption::Kind::ExternalPluginPath; + break; + case PluginSearchOptionKind::LoadPluginLibrary: + optKind = PluginSearchOption::Kind::LoadPluginLibrary; + break; + case PluginSearchOptionKind::LoadPluginExecutable: + optKind = PluginSearchOption::Kind::LoadPluginExecutable; + break; + } + extendedInfo.addPluginSearchOption({optKind, blobData}); break; + } case options_block::IS_SIB: bool IsSIB; options_block::IsSIBLayout::readRecord(scratch, IsSIB); diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index 06f660f266d4e..5bfff95ac4b17 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 787; // HasCxxInteroperability +const uint16_t SWIFTMODULE_VERSION_MINOR = 788; // PluginSearchOption /// A standard hash seed used for all string hashes in a serialized module. /// @@ -651,6 +651,16 @@ enum class MacroIntroducedDeclNameKind : uint8_t { }; using MacroIntroducedDeclNameKindField = BCFixed<4>; +// These IDs must \em not be renumbered or reordered without incrementing +// the module version. +enum class PluginSearchOptionKind : uint8_t { + PluginPath, + ExternalPluginPath, + LoadPluginLibrary, + LoadPluginExecutable, +}; +using PluginSearchOptionKindField = BCFixed<3>; + // Encodes a VersionTuple: // // Major @@ -884,10 +894,7 @@ namespace options_block { IS_CONCURRENCY_CHECKED, MODULE_PACKAGE_NAME, MODULE_EXPORT_AS_NAME, - PLUGIN_SEARCH_PATH, - EXTERNAL_SEARCH_PLUGIN_PATH, - COMPILER_PLUGIN_LIBRARY_PATH, - COMPILER_PLUGIN_EXECUTABLE_PATH, + PLUGIN_SEARCH_OPTION, HAS_CXX_INTEROPERABILITY_ENABLED, }; @@ -901,24 +908,10 @@ namespace options_block { BCBlob // -Xcc flag, as string >; - using PluginSearchPathLayout = BCRecordLayout< - PLUGIN_SEARCH_PATH, - BCBlob // -plugin-path value - >; - - using ExternalPluginSearchPathLayout = BCRecordLayout< - EXTERNAL_SEARCH_PLUGIN_PATH, - BCBlob // -external-plugin-path value - >; - - using CompilerPluginLibraryPathLayout = BCRecordLayout< - COMPILER_PLUGIN_LIBRARY_PATH, - BCBlob // -load-plugin-library value - >; - - using CompilerPluginExecutablePathLayout = BCRecordLayout< - COMPILER_PLUGIN_EXECUTABLE_PATH, - BCBlob // -load-plugin-executable value + using PluginSearchOptionLayout = BCRecordLayout< + PLUGIN_SEARCH_OPTION, + PluginSearchOptionKindField, // kind + BCBlob // option value string >; using IsSIBLayout = BCRecordLayout< diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 58c8daded1d2f..1003d84a26c2c 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -846,10 +846,7 @@ void Serializer::writeBlockInfoBlock() { BLOCK_RECORD(options_block, HAS_CXX_INTEROPERABILITY_ENABLED); BLOCK_RECORD(options_block, MODULE_PACKAGE_NAME); BLOCK_RECORD(options_block, MODULE_EXPORT_AS_NAME); - BLOCK_RECORD(options_block, PLUGIN_SEARCH_PATH); - BLOCK_RECORD(options_block, EXTERNAL_SEARCH_PLUGIN_PATH); - BLOCK_RECORD(options_block, COMPILER_PLUGIN_LIBRARY_PATH); - BLOCK_RECORD(options_block, COMPILER_PLUGIN_EXECUTABLE_PATH); + BLOCK_RECORD(options_block, PLUGIN_SEARCH_OPTION); BLOCK(INPUT_BLOCK); BLOCK_RECORD(input_block, IMPORTED_MODULE); @@ -1138,27 +1135,44 @@ void Serializer::writeHeader(const SerializationOptions &options) { } // Macro plugins - options_block::PluginSearchPathLayout PluginSearchPath(Out); - for (auto Arg : options.PluginSearchPaths) { - PluginSearchPath.emit(ScratchRecord, Arg); - } - - options_block::ExternalPluginSearchPathLayout - ExternalPluginSearchPath(Out); - for (auto Arg : options.ExternalPluginSearchPaths) { - ExternalPluginSearchPath.emit(ScratchRecord, Arg); - } - - options_block::CompilerPluginLibraryPathLayout - CompilerPluginLibraryPath(Out); - for (auto Arg : options.CompilerPluginLibraryPaths) { - CompilerPluginLibraryPath.emit(ScratchRecord, Arg); - } - - options_block::CompilerPluginExecutablePathLayout - CompilerPluginExecutablePath(Out); - for (auto Arg : options.CompilerPluginExecutablePaths) { - CompilerPluginExecutablePath.emit(ScratchRecord, Arg); + options_block::PluginSearchOptionLayout PluginSearchOpt(Out); + for (auto &elem : options.PluginSearchOptions) { + switch (elem.getKind()) { + case PluginSearchOption::Kind::PluginPath: { + auto &opt = elem.get(); + PluginSearchOpt.emit(ScratchRecord, + uint8_t(PluginSearchOptionKind::PluginPath), + opt.SearchPath); + continue; + } + case PluginSearchOption::Kind::ExternalPluginPath: { + auto &opt = elem.get(); + PluginSearchOpt.emit( + ScratchRecord, + uint8_t(PluginSearchOptionKind::ExternalPluginPath), + opt.SearchPath + "#" + opt.ServerPath); + continue; + } + case PluginSearchOption::Kind::LoadPluginLibrary: { + auto &opt = elem.get(); + PluginSearchOpt.emit( + ScratchRecord, + uint8_t(PluginSearchOptionKind::LoadPluginLibrary), + opt.LibraryPath); + continue; + } + case PluginSearchOption::Kind::LoadPluginExecutable: { + auto &opt = elem.get(); + std::string optStr = opt.ExecutablePath + "#"; + llvm::interleave( + opt.ModuleNames, [&](auto &name) { optStr += name; }, + [&]() { optStr += ","; }); + PluginSearchOpt.emit( + ScratchRecord, + uint8_t(PluginSearchOptionKind::LoadPluginExecutable), optStr); + continue; + } + } } } } diff --git a/test/Macros/serialize_plugin_search_paths.swift b/test/Macros/serialize_plugin_search_paths.swift index ef9c5c8d7ee88..cd4b53fc4725f 100644 --- a/test/Macros/serialize_plugin_search_paths.swift +++ b/test/Macros/serialize_plugin_search_paths.swift @@ -11,10 +11,10 @@ // RUN: -load-plugin-executable %t/mock-plugin#TestPlugin // RUN: %lldb-moduleimport-test -verbose -dump-module %t/a.out | %FileCheck %s -// CHECK: - Macro Search Paths: -// 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 +// CHECK: - Plugin Search Options: +// 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 +// CHECK: -plugin-path {{.*}}plugins +// CHECK: -plugin-path {{.*}}plugins diff --git a/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp b/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp index 6d9314b3ecd3a..4f0c4a44acd42 100644 --- a/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp +++ b/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp @@ -89,15 +89,25 @@ static bool validateModule( llvm::outs() << ", system=" << (searchPath.IsSystem ? "true" : "false") << "\n"; } - llvm::outs() << "- Macro Search Paths:\n"; - for (auto path : extendedInfo.getPluginSearchPaths()) - llvm::outs() << " -plugin-path: " << path << "\n"; - for (auto path : extendedInfo.getExternalPluginSearchPaths()) - llvm::outs() << " -external-plugin-path: " << path << "\n"; - for (auto path : extendedInfo.getCompilerPluginLibraryPaths()) - llvm::outs() << " -load-plugin-library: " << path << "\n"; - for (auto path : extendedInfo.getCompilerPluginExecutablePaths()) - llvm::outs() << " -load-plugin-executable: " << path << "\n"; + llvm::outs() << "- Plugin Search Options:\n"; + for (auto opt : extendedInfo.getPluginSearchOptions()) { + StringRef optStr; + switch (opt.first) { + case swift::PluginSearchOption::Kind::PluginPath: + optStr = "-plugin-path"; + break; + case swift::PluginSearchOption::Kind::ExternalPluginPath: + optStr = "-external-plugin-path"; + break; + case swift::PluginSearchOption::Kind::LoadPluginLibrary: + optStr = "-load-plugin-library"; + break; + case swift::PluginSearchOption::Kind::LoadPluginExecutable: + optStr = "-load-plugin-executable"; + break; + } + llvm::outs() << " " << optStr << " " << opt.second << "\n"; + } } return true;