Skip to content

Commit 7af2982

Browse files
Merge pull request #6960 from adrian-prantl/109854291-next
Support Swift macros in the expression evaluator.
2 parents 41617bc + 03ea0b0 commit 7af2982

File tree

5 files changed

+216
-63
lines changed

5 files changed

+216
-63
lines changed

lldb/include/lldb/Target/Target.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ class TargetProperties : public Properties {
184184

185185
EnableSwiftCxxInterop GetEnableSwiftCxxInterop() const;
186186

187+
Args GetSwiftPluginServerForPath() const;
188+
187189
bool GetSwiftAutoImportFrameworks() const;
188190

189191
bool GetEnableAutoImportClangModules() const;

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

Lines changed: 178 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,14 @@ static std::string GetPluginServer(llvm::StringRef plugin_library_path) {
11441144
return {};
11451145
}
11461146

1147+
static std::string GetPluginServerForSDK(llvm::StringRef sdk_path) {
1148+
XcodeSDK sdk(std::string(llvm::sys::path::filename(sdk_path)));
1149+
auto server_or_err = HostInfo::FindSDKTool(sdk, "swift-plugin-server");
1150+
if (!server_or_err)
1151+
return "";
1152+
return server_or_err->str();
1153+
}
1154+
11471155
/// Retrieve the serialized AST data blobs and initialize the compiler
11481156
/// invocation with the concatenated search paths from the blobs.
11491157
/// \returns true if an error was encountered.
@@ -1165,6 +1173,37 @@ static bool DeserializeAllCompilerFlags(swift::CompilerInvocation &invocation,
11651173
return false;
11661174

11671175
auto &search_path_options = invocation.getSearchPathOptions();
1176+
auto get_override_server = [&](llvm::StringRef plugin_path) -> std::string {
1177+
// If the user manually specified an override plugin server for a
1178+
// specific path prefix, return it.
1179+
Args plugin_servers =
1180+
Target::GetGlobalProperties().GetSwiftPluginServerForPath();
1181+
for (auto &arg: plugin_servers) {
1182+
auto key_value = arg.ref().split('=');
1183+
llvm::SmallString<0> ignore(plugin_path);
1184+
if (llvm::sys::path::replace_path_prefix(ignore, key_value.first, {}))
1185+
return key_value.second.str();
1186+
}
1187+
return {};
1188+
};
1189+
auto get_plugin_server = [&](llvm::StringRef plugin,
1190+
std::function<std::string(void)> fallback) {
1191+
// Search for a manual override first, then try fallback.
1192+
std::string server = get_override_server(plugin);
1193+
if (server.empty())
1194+
server = fallback();
1195+
if (server.empty()) {
1196+
HEALTH_LOG_PRINTF("Could not find swift-plugin-server for %s",
1197+
plugin.str().c_str());
1198+
return std::string();
1199+
}
1200+
if (!FileSystem::Instance().Exists(server)) {
1201+
HEALTH_LOG_PRINTF("Swift plugin server does not exist: %s",
1202+
server.c_str());
1203+
server.clear();
1204+
}
1205+
return server;
1206+
};
11681207

11691208
#define INIT_SEARCH_PATH_SET(TYPE, ACCESSOR, NAME, KEY) \
11701209
std::vector<TYPE> NAME; \
@@ -1265,54 +1304,73 @@ static bool DeserializeAllCompilerFlags(swift::CompilerInvocation &invocation,
12651304
// Rewrite them to go through an ABI-compatible swift-plugin-server.
12661305
if (known_plugin_search_paths.insert(path).second) {
12671306
if (known_external_plugin_search_paths.insert(path).second) {
1268-
std::string server = GetPluginServer(path);
1269-
if (server.empty()) {
1270-
HEALTH_LOG_PRINTF("Could not find swift-plugin-server for %s",
1271-
path.str().c_str());
1307+
std::string server = get_plugin_server(
1308+
path, [&]() { return GetPluginServer(path); });
1309+
if (server.empty())
12721310
continue;
1273-
}
12741311
if (exists(path))
12751312
external_plugin_search_paths.push_back({path.str(), server});
12761313
}
12771314
}
1278-
for (auto path :
1279-
extended_validation_info.getExternalPluginSearchPaths()) {
1280-
// Sandboxed system plugins shipping with some compiler.
1281-
// Keep the original plugin server path, it needs to be ABI
1282-
// compatible with the version of SwiftSyntax used by the plugin.
1283-
auto plugin_server = path.split('#');
1284-
llvm::StringRef plugin = plugin_server.first;
1285-
llvm::StringRef server = plugin_server.second;
1286-
if (known_external_plugin_search_paths.insert(plugin).second)
1287-
if (exists(plugin) && exists(server))
1288-
external_plugin_search_paths.push_back(
1289-
{plugin.str(), server.str()});
1290-
}
1315+
}
1316+
for (auto path :
1317+
extended_validation_info.getExternalPluginSearchPaths()) {
1318+
// Sandboxed system plugins shipping with some compiler.
1319+
// Keep the original plugin server path, it needs to be ABI
1320+
// compatible with the version of SwiftSyntax used by the plugin.
1321+
auto plugin_server = path.split('#');
1322+
llvm::StringRef plugin = plugin_server.first;
1323+
std::string server = get_plugin_server(
1324+
plugin, [&]() { return plugin_server.second.str(); });
1325+
if (server.empty())
1326+
continue;
1327+
if (known_external_plugin_search_paths.insert(plugin).second)
1328+
if (exists(plugin))
1329+
external_plugin_search_paths.push_back({plugin.str(), server});
1330+
}
12911331

1292-
for (auto path :
1293-
extended_validation_info.getCompilerPluginLibraryPaths()) {
1294-
// Compiler plugin libraries.
1295-
if (known_compiler_plugin_library_paths.insert(path).second)
1296-
if (exists(path))
1297-
compiler_plugin_library_paths.push_back(path.str());
1298-
}
1332+
for (auto dylib :
1333+
extended_validation_info.getCompilerPluginLibraryPaths()) {
1334+
// Compiler plugin libraries.
1335+
if (known_compiler_plugin_library_paths.insert(dylib).second)
1336+
if (exists(dylib)) {
1337+
// We never want to directly load any plugins, since a crash in
1338+
// the plugin would bring down LLDB. Here, we assume that the
1339+
// correct plugin server for a direct compiler plugin is the one
1340+
// from the SDK the compiler was building for. This is just a
1341+
// heuristic.
1342+
llvm::SmallString<0> dir(dylib);
1343+
llvm::sys::path::remove_filename(dir);
1344+
std::string server = get_plugin_server(dir, [&]() {
1345+
return GetPluginServerForSDK(invocation.getSDKPath());
1346+
});
1347+
if (server.empty())
1348+
continue;
12991349

1300-
for (auto path :
1301-
extended_validation_info.getCompilerPluginExecutablePaths()) {
1302-
// Compiler plugin executables.
1303-
auto plugin_modules = path.split('#');
1304-
llvm::StringRef plugin = plugin_modules.first;
1305-
llvm::StringRef modules_list = plugin_modules.second;
1306-
llvm::SmallVector<llvm::StringRef, 0> modules;
1307-
modules_list.split(modules, ",");
1308-
std::vector<std::string> modules_vec;
1309-
for (auto m : modules)
1310-
modules_vec.push_back(m.str());
1311-
if (known_compiler_plugin_executable_paths.insert(path).second)
1312-
if (exists(plugin))
1313-
compiler_plugin_executable_paths.push_back(
1314-
{plugin.str(), modules_vec});
1315-
}
1350+
// FIXME: The Swift compiler expects external plugins
1351+
// to be named libModuleName.[dylib|so|dll]. This
1352+
// means this our translation attempts only work for
1353+
// macro libraries following this convention. cf.
1354+
// PluginLoader::lookupExternalLibraryPluginByModuleName().
1355+
external_plugin_search_paths.push_back({dir.str().str(), server});
1356+
}
1357+
}
1358+
1359+
for (auto path :
1360+
extended_validation_info.getCompilerPluginExecutablePaths()) {
1361+
// Compiler plugin executables.
1362+
auto plugin_modules = path.split('#');
1363+
llvm::StringRef plugin = plugin_modules.first;
1364+
llvm::StringRef modules_list = plugin_modules.second;
1365+
llvm::SmallVector<llvm::StringRef, 0> modules;
1366+
modules_list.split(modules, ",");
1367+
std::vector<std::string> modules_vec;
1368+
for (auto m : modules)
1369+
modules_vec.push_back(m.str());
1370+
if (known_compiler_plugin_executable_paths.insert(path).second)
1371+
if (exists(plugin))
1372+
compiler_plugin_executable_paths.push_back(
1373+
{plugin.str(), modules_vec});
13161374
}
13171375
return true;
13181376
};
@@ -1945,6 +2003,10 @@ static void
19452003
ProcessModule(ModuleSP module_sp, std::string m_description,
19462004
bool discover_implicit_search_paths, bool use_all_compiler_flags,
19472005
Target &target, llvm::Triple triple,
2006+
std::vector<swift::ExternalPluginSearchPathAndServerPath>
2007+
&external_plugin_search_paths,
2008+
std::vector<swift::PluginExecutablePathAndModuleNames>
2009+
&compiler_plugin_executable_paths,
19482010
std::vector<std::string> &module_search_paths,
19492011
std::vector<std::pair<std::string, bool>> &framework_search_paths,
19502012
std::vector<std::string> &extra_clang_args) {
@@ -2063,7 +2125,15 @@ ProcessModule(ModuleSP module_sp, std::string m_description,
20632125
// collected here and surfaced.
20642126
}
20652127

2128+
// Copy the interesting deserialized flags to the out parameters.
20662129
const auto &opts = invocation.getSearchPathOptions();
2130+
external_plugin_search_paths.insert(external_plugin_search_paths.end(),
2131+
opts.ExternalPluginSearchPaths.begin(),
2132+
opts.ExternalPluginSearchPaths.end());
2133+
compiler_plugin_executable_paths.insert(
2134+
compiler_plugin_executable_paths.end(),
2135+
opts.getCompilerPluginExecutablePaths().begin(),
2136+
opts.getCompilerPluginExecutablePaths().end());
20672137
module_search_paths.insert(module_search_paths.end(),
20682138
opts.getImportSearchPaths().begin(),
20692139
opts.getImportSearchPaths().end());
@@ -2086,6 +2156,10 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
20862156

20872157
LLDB_SCOPED_TIMER();
20882158
std::string m_description = "SwiftASTContextForExpressions";
2159+
std::vector<swift::ExternalPluginSearchPathAndServerPath>
2160+
external_plugin_search_paths;
2161+
std::vector<swift::PluginExecutablePathAndModuleNames>
2162+
compiler_plugin_executable_paths;
20892163
std::vector<std::string> module_search_paths;
20902164
std::vector<std::pair<std::string, bool>> framework_search_paths;
20912165
TargetSP target_sp = typeref_typesystem.GetTargetWP().lock();
@@ -2259,8 +2333,9 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
22592333
std::vector<std::string> extra_clang_args;
22602334
ProcessModule(target.GetImages().GetModuleAtIndex(mi), m_description,
22612335
discover_implicit_search_paths, use_all_compiler_flags,
2262-
target, triple, module_search_paths, framework_search_paths,
2263-
extra_clang_args);
2336+
target, triple, external_plugin_search_paths,
2337+
compiler_plugin_executable_paths, module_search_paths,
2338+
framework_search_paths, extra_clang_args);
22642339
swift_ast_sp->AddExtraClangArgs(extra_clang_args);
22652340
}
22662341

@@ -2305,6 +2380,15 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
23052380
return {};
23062381
}
23072382

2383+
// Initialize the compiler plugin search paths.
2384+
auto &opts = swift_ast_sp->GetSearchPathOptions();
2385+
opts.ExternalPluginSearchPaths.insert(opts.ExternalPluginSearchPaths.end(),
2386+
external_plugin_search_paths.begin(),
2387+
external_plugin_search_paths.end());
2388+
assert(opts.getCompilerPluginExecutablePaths().empty());
2389+
opts.setCompilerPluginExecutablePaths(
2390+
std::move(compiler_plugin_executable_paths));
2391+
23082392
for (size_t mi = 0; mi != num_images; ++mi) {
23092393
std::vector<std::string> module_names;
23102394
auto module_sp = target.GetImages().GetModuleAtIndex(mi);
@@ -4539,16 +4623,23 @@ void SwiftASTContextForExpressions::ModulesDidLoad(ModuleList &module_list) {
45394623
bool use_all_compiler_flags = target_sp->GetUseAllCompilerFlags();
45404624
unsigned num_images = module_list.GetSize();
45414625
for (size_t mi = 0; mi != num_images; ++mi) {
4626+
std::vector<swift::ExternalPluginSearchPathAndServerPath>
4627+
external_plugin_search_paths;
4628+
std::vector<swift::PluginExecutablePathAndModuleNames>
4629+
compiler_plugin_executable_paths;
45424630
std::vector<std::string> module_search_paths;
45434631
std::vector<std::pair<std::string, bool>> framework_search_paths;
45444632
std::vector<std::string> extra_clang_args;
45454633
lldb::ModuleSP module_sp = module_list.GetModuleAtIndex(mi);
45464634
ProcessModule(module_sp, m_description, discover_implicit_search_paths,
45474635
use_all_compiler_flags, *target_sp, GetTriple(),
4548-
module_search_paths, framework_search_paths,
4549-
extra_clang_args);
4550-
// If the use-all-compiler-flags setting is enabled, the expression
4551-
// context is supposed to merge all search paths from all dylibs.
4636+
external_plugin_search_paths,
4637+
compiler_plugin_executable_paths, module_search_paths,
4638+
framework_search_paths, extra_clang_args);
4639+
// If the use-all-compiler-flags setting is enabled, the
4640+
// expression context is supposed to merge all search paths
4641+
// from all dylibs.
4642+
// TODO: Maybe we should also do this for compiler plugins?
45524643
if (use_all_compiler_flags && !extra_clang_args.empty()) {
45534644
// We cannot reconfigure ClangImporter after its creation.
45544645
// Instead poison the SwiftASTContext so it gets recreated.
@@ -4579,16 +4670,20 @@ void SwiftASTContext::LogConfiguration() {
45794670
HEALTH_LOG_PRINTF(" (no AST context)");
45804671
return;
45814672
}
4673+
HEALTH_LOG_PRINTF(" Swift/C++ interop : %s",
4674+
m_ast_context_ap->LangOpts.EnableCXXInterop ? "on" : "off");
4675+
HEALTH_LOG_PRINTF(" Swift/Objective-C interop : %s",
4676+
m_ast_context_ap->LangOpts.EnableObjCInterop ? "on" : "off");
45824677

4583-
HEALTH_LOG_PRINTF(" Architecture : %s",
4678+
HEALTH_LOG_PRINTF(" Architecture : %s",
45844679
m_ast_context_ap->LangOpts.Target.getTriple().c_str());
45854680
HEALTH_LOG_PRINTF(
4586-
" SDK path : %s",
4681+
" SDK path : %s",
45874682
m_ast_context_ap->SearchPathOpts.getSDKPath().str().c_str());
45884683
HEALTH_LOG_PRINTF(
4589-
" Runtime resource path : %s",
4684+
" Runtime resource path : %s",
45904685
m_ast_context_ap->SearchPathOpts.RuntimeResourcePath.c_str());
4591-
HEALTH_LOG_PRINTF(" Runtime library paths : (%llu items)",
4686+
HEALTH_LOG_PRINTF(" Runtime library paths : (%llu items)",
45924687
(unsigned long long)m_ast_context_ap->SearchPathOpts
45934688
.RuntimeLibraryPaths.size());
45944689

@@ -4597,7 +4692,7 @@ void SwiftASTContext::LogConfiguration() {
45974692
HEALTH_LOG_PRINTF(" %s", runtime_library_path.c_str());
45984693
}
45994694

4600-
HEALTH_LOG_PRINTF(" Runtime library import paths : (%llu items)",
4695+
HEALTH_LOG_PRINTF(" Runtime library import paths : (%llu items)",
46014696
(unsigned long long)m_ast_context_ap->SearchPathOpts
46024697
.getRuntimeLibraryImportPaths()
46034698
.size());
@@ -4607,7 +4702,7 @@ void SwiftASTContext::LogConfiguration() {
46074702
HEALTH_LOG_PRINTF(" %s", runtime_import_path.c_str());
46084703
}
46094704

4610-
HEALTH_LOG_PRINTF(" Framework search paths : (%llu items)",
4705+
HEALTH_LOG_PRINTF(" Framework search paths : (%llu items)",
46114706
(unsigned long long)m_ast_context_ap->SearchPathOpts
46124707
.getFrameworkSearchPaths()
46134708
.size());
@@ -4616,7 +4711,7 @@ void SwiftASTContext::LogConfiguration() {
46164711
HEALTH_LOG_PRINTF(" %s", framework_search_path.Path.c_str());
46174712
}
46184713

4619-
HEALTH_LOG_PRINTF(" Import search paths : (%llu items)",
4714+
HEALTH_LOG_PRINTF(" Import search paths : (%llu items)",
46204715
(unsigned long long)m_ast_context_ap->SearchPathOpts
46214716
.getImportSearchPaths()
46224717
.size());
@@ -4629,13 +4724,39 @@ void SwiftASTContext::LogConfiguration() {
46294724
GetClangImporterOptions();
46304725

46314726
HEALTH_LOG_PRINTF(
4632-
" Extra clang arguments : (%llu items)",
4727+
" Extra clang arguments : (%llu items)",
46334728
(unsigned long long)clang_importer_options.ExtraArgs.size());
46344729
for (std::string &extra_arg : clang_importer_options.ExtraArgs) {
46354730
HEALTH_LOG_PRINTF(" %s", extra_arg.c_str());
46364731
}
4637-
HEALTH_LOG_PRINTF(" Swift/C++ interop mode: %s",
4638-
m_ast_context_ap->LangOpts.EnableCXXInterop ? "on" : "off");
4732+
4733+
#define PRINT_PLUGIN_PATHS(ACCESSOR, NAME, TEMPLATE, ...) \
4734+
{ \
4735+
auto paths = m_ast_context_ap->SearchPathOpts.ACCESSOR; \
4736+
HEALTH_LOG_PRINTF(" %s: (%llu items)", NAME, \
4737+
(unsigned long long)paths.size()); \
4738+
for (auto &path : paths) { \
4739+
HEALTH_LOG_PRINTF(" " TEMPLATE, ##__VA_ARGS__); \
4740+
} \
4741+
}
4742+
PRINT_PLUGIN_PATHS(getCompilerPluginLibraryPaths(),
4743+
"Compiler Plugin Library Paths ",
4744+
"%s", path.c_str());
4745+
PRINT_PLUGIN_PATHS(getCompilerPluginExecutablePaths(),
4746+
"Compiler Plugin Executable Paths ", "%s: [%s]",
4747+
path.ExecutablePath.c_str(),
4748+
[](auto path_names) -> std::string {
4749+
std::string s;
4750+
llvm::raw_string_ostream os(s);
4751+
llvm::interleaveComma(path_names, os);
4752+
return os.str();
4753+
}(path.ModuleNames)
4754+
.c_str());
4755+
PRINT_PLUGIN_PATHS(PluginSearchPaths, "Plugin search paths ",
4756+
"%s", path.c_str());
4757+
PRINT_PLUGIN_PATHS(ExternalPluginSearchPaths,
4758+
"External plugin search paths ", "%s (server: %s)",
4759+
path.SearchPath.c_str(), path.ServerPath.c_str());
46394760
}
46404761

46414762
bool SwiftASTContext::HasTarget() {

lldb/source/Target/Target.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4673,6 +4673,16 @@ EnableSwiftCxxInterop TargetProperties::GetEnableSwiftCxxInterop() const {
46734673
return enable_interop;
46744674
}
46754675

4676+
Args TargetProperties::GetSwiftPluginServerForPath() const {
4677+
const uint32_t idx = ePropertySwiftPluginServerForPath;
4678+
4679+
llvm::StringMap<std::string> result;
4680+
Args property_plugin_server_path;
4681+
m_experimental_properties_up->GetValueProperties()->GetPropertyAtIndexAsArgs(
4682+
nullptr, idx, property_plugin_server_path);
4683+
return property_plugin_server_path;
4684+
}
4685+
46764686
bool TargetProperties::GetSwiftAutoImportFrameworks() const {
46774687
const uint32_t idx = ePropertySwiftAutoImportFrameworks;
46784688
return GetPropertyAtIndexAs<bool>(

lldb/source/Target/TargetProperties.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ let Definition = "target_experimental" in {
2323
DefaultEnumValue<"eAutoDetectSwiftCxxInterop">,
2424
EnumValues<"OptionEnumValues(g_enable_swift_cxx_interop_values)">,
2525
Desc<"Passes the -enable-cxx-interop flag to the swift compiler.">;
26+
def SwiftPluginServerForPath: Property<"swift-plugin-server-for-path",
27+
"Dictionary">,
28+
ElementType<"String">,
29+
Desc<"A dictionary of plugin paths as keys and swift-plugin-server binaries as values">;
2630
}
2731

2832
let Definition = "target" in {

0 commit comments

Comments
 (0)