Skip to content

Commit 186af78

Browse files
committed
Deserialize Swift macro implementation paths from Swift modules
This patch parses the Swift compiler plugin paths from all Swift modules and rewrites them to use swift-plugin-server where approprate and adds them to the Swift compiler invocation. rdar://107030837
1 parent 59b1687 commit 186af78

File tree

1 file changed

+141
-33
lines changed

1 file changed

+141
-33
lines changed

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp

Lines changed: 141 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,34 @@ void SwiftASTContext::DiagnoseWarnings(Process &process, Module &module) const {
10551055
process.PrintWarningCantLoadSwiftModule(module, message);
10561056
}
10571057

1058+
/// Locate the swift-plugin-server for a plugin library,
1059+
/// by converting ${toolchain}/usr/(local)?/lib/swift/host/plugins
1060+
/// into ${toolchain}/usr/bin/swift-plugin-server
1061+
/// FIXME: move this to Host, it may be platform-specific.
1062+
static std::string GetPluginServer(llvm::StringRef plugin_library_path) {
1063+
llvm::StringRef path = llvm::sys::path::parent_path(plugin_library_path);
1064+
if (llvm::sys::path::filename(path) != "plugins")
1065+
return {};
1066+
path = llvm::sys::path::parent_path(path);
1067+
if (llvm::sys::path::filename(path) != "host")
1068+
return {};
1069+
path = llvm::sys::path::parent_path(path);
1070+
if (llvm::sys::path::filename(path) != "swift")
1071+
return {};
1072+
path = llvm::sys::path::parent_path(path);
1073+
if (llvm::sys::path::filename(path) != "lib")
1074+
return {};
1075+
path = llvm::sys::path::parent_path(path);
1076+
if (llvm::sys::path::filename(path) == "local")
1077+
path = llvm::sys::path::parent_path(path);
1078+
llvm::SmallString<256> server(path);
1079+
llvm::sys::path::append(server, "bin", "swift-plugin-server");
1080+
std::string result(server);
1081+
if (FileSystem::Instance().Exists(result))
1082+
return result;
1083+
return {};
1084+
}
1085+
10581086
/// Retrieve the serialized AST data blobs and initialize the compiler
10591087
/// invocation with the concatenated search paths from the blobs.
10601088
/// \returns true if an error was encountered.
@@ -1076,21 +1104,31 @@ static bool DeserializeAllCompilerFlags(swift::CompilerInvocation &invocation,
10761104
return false;
10771105

10781106
auto &search_path_options = invocation.getSearchPathOptions();
1079-
std::vector<std::string> import_search_paths;
1080-
llvm::StringSet<> known_import_search_paths;
1081-
for (auto &path : search_path_options.getImportSearchPaths()) {
1082-
import_search_paths.push_back(path);
1083-
known_import_search_paths.insert(path);
1084-
}
10851107

1086-
std::vector<swift::SearchPathOptions::FrameworkSearchPath>
1087-
framework_search_paths;
1088-
llvm::StringSet<> known_framework_search_paths;
1089-
for (auto &path : search_path_options.getFrameworkSearchPaths()) {
1090-
framework_search_paths.push_back(path);
1091-
known_framework_search_paths.insert(path.Path);
1092-
}
1093-
1108+
#define INIT_SEARCH_PATH_SET(TYPE, ACCESSOR, NAME, KEY) \
1109+
std::vector<TYPE> NAME; \
1110+
llvm::StringSet<> known_##NAME; \
1111+
for (auto &path : search_path_options.ACCESSOR) { \
1112+
NAME.push_back(path); \
1113+
known_##NAME.insert(path KEY); \
1114+
}
1115+
1116+
INIT_SEARCH_PATH_SET(std::string, getImportSearchPaths(),
1117+
import_search_paths, );
1118+
INIT_SEARCH_PATH_SET(swift::SearchPathOptions::FrameworkSearchPath,
1119+
getFrameworkSearchPaths(), framework_search_paths,
1120+
.Path);
1121+
INIT_SEARCH_PATH_SET(std::string, PluginSearchPaths, plugin_search_paths, );
1122+
INIT_SEARCH_PATH_SET(swift::ExternalPluginSearchPathAndServerPath,
1123+
ExternalPluginSearchPaths, external_plugin_search_paths,
1124+
.SearchPath);
1125+
INIT_SEARCH_PATH_SET(std::string, getCompilerPluginLibraryPaths(),
1126+
compiler_plugin_library_paths, );
1127+
INIT_SEARCH_PATH_SET(swift::PluginExecutablePathAndModuleNames,
1128+
getCompilerPluginExecutablePaths(),
1129+
compiler_plugin_executable_paths, .ExecutablePath);
1130+
1131+
10941132
// An AST section consists of one or more AST modules, optionally
10951133
// with headers. Iterate over all AST modules.
10961134
for (auto ast_file_data_sp : ast_file_datas) {
@@ -1133,27 +1171,89 @@ static bool DeserializeAllCompilerFlags(swift::CompilerInvocation &invocation,
11331171
/// serialized AST.
11341172
auto deserializeCompilerFlags = [&]() -> bool {
11351173
auto result = invocation.loadFromSerializedAST(moduleData);
1136-
if (result == swift::serialization::Status::Valid) {
1137-
if (discover_implicit_search_paths) {
1138-
for (auto &searchPath : searchPaths) {
1139-
std::string path = remap(searchPath.Path);
1140-
if (!searchPath.IsFramework) {
1141-
if (known_import_search_paths.insert(path).second)
1142-
import_search_paths.push_back(path);
1143-
} else {
1144-
swift::SearchPathOptions::FrameworkSearchPath
1145-
framework_search_path(path, searchPath.IsSystem);
1146-
if (known_framework_search_paths.insert(path).second)
1147-
framework_search_paths.push_back(framework_search_path);
1148-
}
1174+
if (result != swift::serialization::Status::Valid) {
1175+
error << "Could not deserialize " << info.name << ":\n"
1176+
<< getImportFailureString(result) << "\n";
1177+
return false;
1178+
}
1179+
if (discover_implicit_search_paths) {
1180+
for (auto &searchPath : searchPaths) {
1181+
std::string path = remap(searchPath.Path);
1182+
if (!searchPath.IsFramework) {
1183+
if (known_import_search_paths.insert(path).second)
1184+
import_search_paths.push_back(path);
1185+
} else {
1186+
swift::SearchPathOptions::FrameworkSearchPath
1187+
framework_search_path(path, searchPath.IsSystem);
1188+
if (known_framework_search_paths.insert(path).second)
1189+
framework_search_paths.push_back(framework_search_path);
11491190
}
11501191
}
1151-
return true;
11521192
}
1193+
auto exists = [&](llvm::StringRef path) {
1194+
if (FileSystem::Instance().Exists(path))
1195+
return true;
1196+
HEALTH_LOG_PRINTF("Ignoring missing Swift plugin at path: %s",
1197+
path.str().c_str());
1198+
return false;
1199+
};
1200+
1201+
// Discover, rewrite, and unique compiler plugin paths.
1202+
for (auto path : extended_validation_info.getPluginSearchPaths()) {
1203+
// System plugins shipping with the compiler.
1204+
// Rewrite them to go through an ABI-compatible swift-plugin-server.
1205+
if (known_plugin_search_paths.insert(path).second) {
1206+
if (known_external_plugin_search_paths.insert(path).second) {
1207+
std::string server = GetPluginServer(path);
1208+
if (server.empty()) {
1209+
HEALTH_LOG_PRINTF("Could not find swift-plugin-server for %s",
1210+
path.str().c_str());
1211+
continue;
1212+
}
1213+
if (exists(path))
1214+
external_plugin_search_paths.push_back({path.str(), server});
1215+
}
1216+
}
1217+
for (auto path :
1218+
extended_validation_info.getExternalPluginSearchPaths()) {
1219+
// Sandboxed system plugins shipping with some compiler.
1220+
// Keep the original plugin server path, it needs to be ABI
1221+
// compatible with the version of SwiftSyntax used by the plugin.
1222+
auto plugin_server = path.split('#');
1223+
llvm::StringRef plugin = plugin_server.first;
1224+
llvm::StringRef server = plugin_server.second;
1225+
if (known_external_plugin_search_paths.insert(plugin).second)
1226+
if (exists(plugin) && exists(server))
1227+
external_plugin_search_paths.push_back(
1228+
{plugin.str(), server.str()});
1229+
}
11531230

1154-
error << "Could not deserialize " << info.name << ":\n"
1155-
<< getImportFailureString(result) << "\n";
1156-
return false;
1231+
for (auto path :
1232+
extended_validation_info.getCompilerPluginLibraryPaths()) {
1233+
// Compiler plugin libraries.
1234+
if (known_compiler_plugin_library_paths.insert(path).second)
1235+
if (exists(path))
1236+
compiler_plugin_library_paths.push_back(path.str());
1237+
}
1238+
1239+
for (auto path :
1240+
extended_validation_info.getCompilerPluginExecutablePaths()) {
1241+
// Compiler plugin executables.
1242+
auto plugin_modules = path.split('#');
1243+
llvm::StringRef plugin = plugin_modules.first;
1244+
llvm::StringRef modules_list = plugin_modules.second;
1245+
llvm::SmallVector<llvm::StringRef, 0> modules;
1246+
modules_list.split(modules, ",");
1247+
std::vector<std::string> modules_vec;
1248+
for (auto m : modules)
1249+
modules_vec.push_back(m.str());
1250+
if (known_compiler_plugin_executable_paths.insert(path).second)
1251+
if (exists(plugin))
1252+
compiler_plugin_executable_paths.push_back(
1253+
{plugin.str(), modules_vec});
1254+
}
1255+
}
1256+
return true;
11571257
};
11581258

11591259
got_serialized_options |= deserializeCompilerFlags();
@@ -1166,8 +1266,16 @@ static bool DeserializeAllCompilerFlags(swift::CompilerInvocation &invocation,
11661266
}
11671267
}
11681268

1169-
search_path_options.setImportSearchPaths(import_search_paths);
1170-
search_path_options.setFrameworkSearchPaths(framework_search_paths);
1269+
search_path_options.setImportSearchPaths(std::move(import_search_paths));
1270+
search_path_options.setFrameworkSearchPaths(
1271+
std::move(framework_search_paths));
1272+
// (All PluginSearchPaths were rewritten to be external.)
1273+
search_path_options.ExternalPluginSearchPaths =
1274+
std::move(external_plugin_search_paths);
1275+
search_path_options.setCompilerPluginLibraryPaths(
1276+
std::move(compiler_plugin_library_paths));
1277+
search_path_options.setCompilerPluginExecutablePaths(
1278+
std::move(compiler_plugin_executable_paths));
11711279
return found_validation_errors;
11721280
}
11731281

0 commit comments

Comments
 (0)