Skip to content

Commit 464b04e

Browse files
Merge pull request #6943 from adrian-prantl/109854291
Support Swift macros in the expression evaluator.
2 parents d085290 + 394f6cf commit 464b04e

File tree

9 files changed

+362
-156
lines changed

9 files changed

+362
-156
lines changed

lldb/include/lldb/Host/HostInfoBase.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "lldb/Utility/XcodeSDK.h"
1717
#include "lldb/lldb-enumerations.h"
1818
#include "llvm/ADT/StringRef.h"
19+
#include "llvm/Support/Errc.h"
1920

2021
#include <cstdint>
2122

@@ -133,6 +134,12 @@ class HostInfoBase {
133134
return llvm::make_error<HostInfoError>("cannot determine SDK root");
134135
}
135136

137+
/// Return the path to a specific tool in the specified Xcode SDK.
138+
static llvm::Expected<llvm::StringRef> FindSDKTool(XcodeSDK sdk,
139+
llvm::StringRef tool) {
140+
return llvm::errorCodeToError(llvm::errc::no_such_file_or_directory);
141+
}
142+
136143
/// Return information about module \p image_name if it is loaded in
137144
/// the current process's address space.
138145
static SharedCacheImageInfo

lldb/include/lldb/Host/macosx/HostInfoMacOSX.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "lldb/Host/posix/HostInfoPosix.h"
1313
#include "lldb/Utility/FileSpec.h"
1414
#include "lldb/Utility/XcodeSDK.h"
15+
#include "llvm/ADT/StringRef.h"
1516
#include "llvm/Support/VersionTuple.h"
1617

1718
namespace lldb_private {
@@ -51,8 +52,9 @@ class HostInfoMacOSX : public HostInfoPosix {
5152
FileSpec &file_spec, bool verify);
5253
#endif
5354

54-
/// Query xcrun to find an Xcode SDK directory.
5555
static llvm::Expected<llvm::StringRef> GetSDKRoot(SDKOptions options);
56+
static llvm::Expected<llvm::StringRef> FindSDKTool(XcodeSDK sdk,
57+
llvm::StringRef tool);
5658

5759
/// Shared cache utilities
5860
static SharedCacheImageInfo

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/Host/macosx/objcxx/HostInfoMacOSX.mm

Lines changed: 118 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -373,84 +373,86 @@ static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
373373
return g_developer_directory;
374374
}
375375

376-
llvm::Expected<std::string> GetXcodeSDK(XcodeSDK sdk) {
377-
XcodeSDK::Info info = sdk.Parse();
378-
std::string sdk_name = XcodeSDK::GetCanonicalName(info);
379-
if (sdk_name.empty())
380-
return llvm::createStringError(llvm::inconvertibleErrorCode(),
381-
"Unrecognized SDK type: " + sdk.GetString());
376+
static llvm::Expected<std::string>
377+
xcrun(const std::string &sdk, llvm::ArrayRef<llvm::StringRef> arguments,
378+
llvm::StringRef developer_dir = "") {
379+
Args args;
380+
if (!developer_dir.empty()) {
381+
args.AppendArgument("/usr/bin/env");
382+
args.AppendArgument("DEVELOPER_DIR=" + developer_dir.str());
383+
}
384+
args.AppendArgument("/usr/bin/xcrun");
385+
args.AppendArgument("--sdk");
386+
args.AppendArgument(sdk);
387+
for (auto arg: arguments)
388+
args.AppendArgument(arg);
382389

383390
Log *log = GetLog(LLDBLog::Host);
391+
if (log) {
392+
std::string cmdstr;
393+
args.GetCommandString(cmdstr);
394+
log->Printf("GetXcodeSDK() running shell cmd '%s'", cmdstr.c_str());
395+
}
384396

385-
auto xcrun = [](const std::string &sdk,
386-
llvm::StringRef developer_dir =
387-
"") -> llvm::Expected<std::string> {
388-
Args args;
389-
if (!developer_dir.empty()) {
390-
args.AppendArgument("/usr/bin/env");
391-
args.AppendArgument("DEVELOPER_DIR=" + developer_dir.str());
392-
}
393-
args.AppendArgument("/usr/bin/xcrun");
394-
args.AppendArgument("--show-sdk-path");
395-
args.AppendArgument("--sdk");
396-
args.AppendArgument(sdk);
397-
398-
Log *log = GetLog(LLDBLog::Host);
399-
if (log) {
400-
std::string cmdstr;
401-
args.GetCommandString(cmdstr);
402-
log->Printf("GetXcodeSDK() running shell cmd '%s'", cmdstr.c_str());
403-
}
397+
int status = 0;
398+
int signo = 0;
399+
std::string output_str;
400+
// The first time after Xcode was updated or freshly installed,
401+
// xcrun can take surprisingly long to build up its database.
402+
auto timeout = std::chrono::seconds(60);
403+
bool run_in_shell = false;
404+
lldb_private::Status error = Host::RunShellCommand(
405+
args, FileSpec(), &status, &signo, &output_str, timeout, run_in_shell);
406+
407+
// Check that xcrun returned something useful.
408+
if (error.Fail()) {
409+
// Catastrophic error.
410+
LLDB_LOG(log, "xcrun failed to execute: %s", error.AsCString());
411+
return error.ToError();
412+
}
413+
if (status != 0) {
414+
// xcrun didn't find a matching SDK. Not an error, we'll try
415+
// different spellings.
416+
LLDB_LOG(log, "xcrun returned exit code %d", status);
417+
return "";
418+
}
419+
if (output_str.empty()) {
420+
LLDB_LOG(log, "xcrun returned no results");
421+
return "";
422+
}
404423

405-
int status = 0;
406-
int signo = 0;
407-
std::string output_str;
408-
// The first time after Xcode was updated or freshly installed,
409-
// xcrun can take surprisingly long to build up its database.
410-
auto timeout = std::chrono::seconds(60);
411-
bool run_in_shell = false;
412-
lldb_private::Status error = Host::RunShellCommand(
413-
args, FileSpec(), &status, &signo, &output_str, timeout, run_in_shell);
414-
415-
// Check that xcrun returned something useful.
416-
if (error.Fail()) {
417-
// Catastrophic error.
418-
LLDB_LOG(log, "xcrun failed to execute: %s", error.AsCString());
419-
return error.ToError();
420-
}
421-
if (status != 0) {
422-
// xcrun didn't find a matching SDK. Not an error, we'll try
423-
// different spellings.
424-
LLDB_LOG(log, "xcrun returned exit code %d", status);
425-
return "";
426-
}
427-
if (output_str.empty()) {
428-
LLDB_LOG(log, "xcrun returned no results");
429-
return "";
430-
}
424+
// Convert to a StringRef so we can manipulate the string without modifying
425+
// the underlying data.
426+
llvm::StringRef output(output_str);
431427

432-
// Convert to a StringRef so we can manipulate the string without modifying
433-
// the underlying data.
434-
llvm::StringRef output(output_str);
428+
// Remove any trailing newline characters.
429+
output = output.rtrim();
435430

436-
// Remove any trailing newline characters.
437-
output = output.rtrim();
431+
// Strip any leading newline characters and everything before them.
432+
const size_t last_newline = output.rfind('\n');
433+
if (last_newline != llvm::StringRef::npos)
434+
output = output.substr(last_newline + 1);
438435

439-
// Strip any leading newline characters and everything before them.
440-
const size_t last_newline = output.rfind('\n');
441-
if (last_newline != llvm::StringRef::npos)
442-
output = output.substr(last_newline + 1);
436+
return output.str();
437+
}
443438

444-
return output.str();
445-
};
439+
static llvm::Expected<std::string> GetXcodeSDK(XcodeSDK sdk) {
440+
XcodeSDK::Info info = sdk.Parse();
441+
std::string sdk_name = XcodeSDK::GetCanonicalName(info);
442+
if (sdk_name.empty())
443+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
444+
"Unrecognized SDK type: " + sdk.GetString());
445+
446+
Log *log = GetLog(LLDBLog::Host);
446447

447448
auto find_sdk =
448-
[&xcrun](const std::string &sdk_name) -> llvm::Expected<std::string> {
449+
[](const std::string &sdk_name) -> llvm::Expected<std::string> {
450+
llvm::SmallVector<llvm::StringRef, 1> show_sdk_path = {"--show-sdk-path"};
449451
// Invoke xcrun with the developer dir specified in the environment.
450452
std::string developer_dir = GetEnvDeveloperDir();
451453
if (!developer_dir.empty()) {
452454
// Don't fallback if DEVELOPER_DIR was set.
453-
return xcrun(sdk_name, developer_dir);
455+
return xcrun(sdk_name, show_sdk_path, developer_dir);
454456
}
455457

456458
// Invoke xcrun with the shlib dir.
@@ -461,7 +463,8 @@ static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
461463
llvm::StringRef shlib_developer_dir =
462464
llvm::sys::path::parent_path(contents_dir);
463465
if (!shlib_developer_dir.empty()) {
464-
auto sdk = xcrun(sdk_name, std::move(shlib_developer_dir));
466+
auto sdk =
467+
xcrun(sdk_name, show_sdk_path, std::move(shlib_developer_dir));
465468
if (!sdk)
466469
return sdk.takeError();
467470
if (!sdk->empty())
@@ -471,7 +474,7 @@ static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
471474
}
472475

473476
// Invoke xcrun without a developer dir as a last resort.
474-
return xcrun(sdk_name);
477+
return xcrun(sdk_name, show_sdk_path);
475478
};
476479

477480
auto path_or_err = find_sdk(sdk_name);
@@ -519,41 +522,69 @@ static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
519522
return path;
520523
}
521524

522-
llvm::Expected<llvm::StringRef> HostInfoMacOSX::GetSDKRoot(SDKOptions options) {
523-
struct ErrorOrPath {
524-
std::string str;
525-
bool is_error;
526-
};
527-
static llvm::StringMap<ErrorOrPath> g_sdk_path;
528-
static std::mutex g_sdk_path_mutex;
525+
namespace {
526+
struct ErrorOrPath {
527+
std::string str;
528+
bool is_error;
529+
};
530+
} // namespace
529531

530-
std::lock_guard<std::mutex> guard(g_sdk_path_mutex);
532+
static llvm::Expected<llvm::StringRef>
533+
find_cached_path(llvm::StringMap<ErrorOrPath> &cache, std::mutex &mutex,
534+
llvm::StringRef key,
535+
std::function<llvm::Expected<std::string>(void)> compute) {
536+
std::lock_guard<std::mutex> guard(mutex);
531537
LLDB_SCOPED_TIMER();
532538

533-
if (!options.XcodeSDK)
534-
return llvm::createStringError(llvm::inconvertibleErrorCode(),
535-
"XCodeSDK not specified");
536-
XcodeSDK sdk = *options.XcodeSDK;
537-
538-
auto key = sdk.GetString();
539-
auto it = g_sdk_path.find(key);
540-
if (it != g_sdk_path.end()) {
539+
auto it = cache.find(key);
540+
if (it != cache.end()) {
541541
if (it->second.is_error)
542542
return llvm::createStringError(llvm::inconvertibleErrorCode(),
543543
it->second.str);
544-
else
545-
return it->second.str;
544+
return it->second.str;
546545
}
547-
auto path_or_err = GetXcodeSDK(sdk);
546+
auto path_or_err = compute();
548547
if (!path_or_err) {
549548
std::string error = toString(path_or_err.takeError());
550-
g_sdk_path.insert({key, {error, true}});
549+
cache.insert({key, {error, true}});
551550
return llvm::createStringError(llvm::inconvertibleErrorCode(), error);
552551
}
553-
auto it_new = g_sdk_path.insert({key, {*path_or_err, false}});
552+
auto it_new = cache.insert({key, {*path_or_err, false}});
554553
return it_new.first->second.str;
555554
}
556555

556+
llvm::Expected<llvm::StringRef> HostInfoMacOSX::GetSDKRoot(SDKOptions options) {
557+
static llvm::StringMap<ErrorOrPath> g_sdk_path;
558+
static std::mutex g_sdk_path_mutex;
559+
if (!options.XcodeSDK)
560+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
561+
"XCodeSDK not specified");
562+
XcodeSDK sdk = *options.XcodeSDK;
563+
auto key = sdk.GetString();
564+
return find_cached_path(g_sdk_path, g_sdk_path_mutex, key, [&](){
565+
return GetXcodeSDK(sdk);
566+
});
567+
}
568+
569+
llvm::Expected<llvm::StringRef>
570+
HostInfoMacOSX::FindSDKTool(XcodeSDK sdk, llvm::StringRef tool) {
571+
static llvm::StringMap<ErrorOrPath> g_tool_path;
572+
static std::mutex g_tool_path_mutex;
573+
std::string key;
574+
llvm::raw_string_ostream(key) << sdk.GetString() << ":" << tool;
575+
return find_cached_path(
576+
g_tool_path, g_tool_path_mutex, key,
577+
[&]() -> llvm::Expected<std::string> {
578+
std::string sdk_name = XcodeSDK::GetCanonicalName(sdk.Parse());
579+
if (sdk_name.empty())
580+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
581+
"Unrecognized SDK type: " +
582+
sdk.GetString());
583+
llvm::SmallVector<llvm::StringRef, 2> find = {"-find", tool};
584+
return xcrun(sdk_name, find);
585+
});
586+
}
587+
557588
namespace {
558589
struct dyld_shared_cache_dylib_text_info {
559590
uint64_t version; // current version 1

0 commit comments

Comments
 (0)