Skip to content

[pull] swiftwasm-release/5.3 from swift/release/5.3 #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lldb/include/lldb/Core/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,11 @@ class Module : public std::enable_shared_from_this<Module>,

std::vector<lldb::DataBufferSP> GetASTData(lldb::LanguageType language);

/// Return the Xcode SDK this module was compiled against. This
/// is computed by merging the SDKs from each compilation unit in
/// the module.
XcodeSDK GetXcodeSDK() const { return m_xcode_sdk; }

/// Update the ArchSpec to a more specific variant.
bool MergeArchitecture(const ArchSpec &arch_spec);

Expand Down
22 changes: 18 additions & 4 deletions lldb/include/lldb/Utility/XcodeSDK.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class XcodeSDK {

public:
XcodeSDK() = default;
/// Initialize an XcodeSDK object with an SDK name. The SDK name is the last
/// directory component of a path one would pass to clang's -isysroot
/// parameter. For example, "MacOSX.10.14.sdk".
XcodeSDK(std::string &&name) : m_name(std::move(name)) {}
static XcodeSDK GetAnyMacOS() { return XcodeSDK("MacOSX.sdk"); }

Expand All @@ -37,7 +40,6 @@ class XcodeSDK {
numSDKTypes,
unknown = -1
};
static llvm::StringRef GetNameForType(Type type);

/// The merge function follows a strict order to maintain monotonicity:
/// 1. SDK with the higher SDKType wins.
Expand All @@ -47,15 +49,27 @@ class XcodeSDK {
XcodeSDK &operator=(XcodeSDK other);
bool operator==(XcodeSDK other);

/// Return parsed SDK number, and SDK version number.
std::tuple<Type, llvm::VersionTuple> Parse() const;
/// A parsed SDK directory name.
struct Info {
Type type = unknown;
llvm::VersionTuple version;
bool internal = false;

Info() = default;
bool operator<(const Info &other) const;
};

/// Return parsed SDK type and version number.
Info Parse() const;
bool IsAppleInternalSDK() const;
llvm::VersionTuple GetVersion() const;
Type GetType() const;
llvm::StringRef GetString() const;

static bool SDKSupportsModules(Type type, llvm::VersionTuple version);
static bool SDKSupportsModules(Type desired_type, const FileSpec &sdk_path);
static llvm::StringRef GetSDKNameForType(Type type);
/// Return the canonical SDK name, such as "macosx" for the macOS SDK.
static std::string GetCanonicalName(Info info);
};

} // namespace lldb_private
Expand Down
87 changes: 58 additions & 29 deletions lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
Original file line number Diff line number Diff line change
Expand Up @@ -298,37 +298,66 @@ static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
}

std::string HostInfoMacOSX::GetXcodeSDK(XcodeSDK sdk) {
std::string xcrun_cmd = "xcrun --show-sdk-path --sdk " +
XcodeSDK::GetSDKNameForType(sdk.GetType()).str();
llvm::VersionTuple version = sdk.GetVersion();
if (!version.empty())
xcrun_cmd += version.getAsString();

int status = 0;
int signo = 0;
std::string output_str;
lldb_private::Status error =
Host::RunShellCommand(xcrun_cmd.c_str(), FileSpec(), &status, &signo,
&output_str, std::chrono::seconds(15));

// Check that xcrun return something useful.
if (status != 0 || output_str.empty())
return {};

// Convert to a StringRef so we can manipulate the string without modifying
// the underlying data.
llvm::StringRef output(output_str);

// Remove any trailing newline characters.
output = output.rtrim();
XcodeSDK::Info info = sdk.Parse();
std::string sdk_name = XcodeSDK::GetCanonicalName(info);
auto find_sdk = [](std::string sdk_name) -> std::string {
std::string xcrun_cmd = "xcrun --show-sdk-path --sdk " + sdk_name;
int status = 0;
int signo = 0;
std::string output_str;
lldb_private::Status error =
Host::RunShellCommand(xcrun_cmd.c_str(), FileSpec(), &status, &signo,
&output_str, std::chrono::seconds(15));

// Check that xcrun return something useful.
if (status != 0 || output_str.empty())
return {};

// Convert to a StringRef so we can manipulate the string without modifying
// the underlying data.
llvm::StringRef output(output_str);

// Remove any trailing newline characters.
output = output.rtrim();

// Strip any leading newline characters and everything before them.
const size_t last_newline = output.rfind('\n');
if (last_newline != llvm::StringRef::npos)
output = output.substr(last_newline + 1);

return output.str();
};

std::string path = find_sdk(sdk_name);
while (path.empty()) {
// Try an alternate spelling of the name ("macosx10.9internal").
if (info.type == XcodeSDK::Type::MacOSX && !info.version.empty() &&
info.internal) {
llvm::StringRef fixed(sdk_name);
if (fixed.consume_back(".internal"))
sdk_name = fixed.str() + "internal";
path = find_sdk(sdk_name);
if (!path.empty())
break;
}
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
LLDB_LOGF(log, "Couldn't find SDK %s on host", sdk_name.c_str());

// Try without the version.
if (!info.version.empty()) {
info.version = {};
sdk_name = XcodeSDK::GetCanonicalName(info);
path = find_sdk(sdk_name);
if (!path.empty())
break;
}

// Strip any leading newline characters and everything before them.
const size_t last_newline = output.rfind('\n');
if (last_newline != llvm::StringRef::npos)
output = output.substr(last_newline + 1);
LLDB_LOGF(log, "Couldn't find any matching SDK on host");
return {};
}

// Whatever is left in output should be a valid path.
if (!FileSystem::Instance().Exists(output))
if (!FileSystem::Instance().Exists(path))
return {};
return output.str();
return path;
}
42 changes: 23 additions & 19 deletions lldb/source/Symbol/SwiftASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,9 @@ static SDKTypeMinVersion GetSDKType(const llvm::Triple &target,
StringRef SwiftASTContext::GetSwiftStdlibOSDir(const llvm::Triple &target,
const llvm::Triple &host) {
auto sdk = GetSDKType(target, host);
llvm::StringRef sdk_name = XcodeSDK::GetSDKNameForType(sdk.sdk_type);
XcodeSDK::Info sdk_info;
sdk_info.type = sdk.sdk_type;
llvm::StringRef sdk_name = XcodeSDK::GetCanonicalName(sdk_info);
if (!sdk_name.empty())
return sdk_name;
return target.getOSName();
Expand Down Expand Up @@ -1668,17 +1670,21 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(lldb::LanguageType language,
set_triple = true;
}

// SDK path setup.
llvm::StringRef serialized_sdk_path =
swift_ast_sp->GetCompilerInvocation().getSDKPath();
if (serialized_sdk_path.empty()) {
if (serialized_sdk_path.empty())
LOG_PRINTF(LIBLLDB_LOG_TYPES, "No serialized SDK path.");
} else {
LOG_PRINTF(LIBLLDB_LOG_TYPES, "Got serialized SDK path %s.",
else
LOG_PRINTF(LIBLLDB_LOG_TYPES, "Serialized SDK path is %s.",
serialized_sdk_path.str().c_str());
FileSpec sdk_spec(serialized_sdk_path.str().c_str());
if (FileSystem::Instance().Exists(sdk_spec)) {
swift_ast_sp->SetPlatformSDKPath(serialized_sdk_path);
}
XcodeSDK sdk = module.GetXcodeSDK();
PlatformSP platform =
Platform::GetPlatformForArchitecture(module.GetArchitecture(), nullptr);
std::string sdk_path = platform->GetSDKPath(sdk);
LOG_PRINTF(LIBLLDB_LOG_TYPES, "Host SDK path is %s.", sdk_path.c_str());
if (FileSystem::Instance().Exists(sdk_path)) {
swift_ast_sp->SetPlatformSDKPath(sdk_path);
}
}

Expand Down Expand Up @@ -2668,14 +2674,6 @@ void SwiftASTContext::InitializeSearchPathOptions(
// someone is passing this to us on the command line (e.g., for the
// REPL), they probably know what they're doing.

set_sdk = true;
}
} else if (!m_platform_sdk_path.empty()) {
FileSpec platform_sdk(m_platform_sdk_path.c_str());

if (FileSystem::Instance().Exists(platform_sdk) &&
SDKSupportsSwift(platform_sdk, XcodeSDK::Type::unknown)) {
invocation.setSDKPath(m_platform_sdk_path.c_str());
set_sdk = true;
}
}
Expand All @@ -2694,13 +2692,19 @@ void SwiftASTContext::InitializeSearchPathOptions(
auto sdk = GetSDKType(triple, HostInfo::GetArchitecture().GetTriple());
// Explicitly leave the SDKPath blank on other platforms.
if (sdk.sdk_type != XcodeSDK::Type::unknown) {
auto dir = GetSDKDirectory(sdk.sdk_type, sdk.min_version_major,
sdk.min_version_minor);
std::string sdk_path = m_platform_sdk_path;
if (sdk_path.empty() || !FileSystem::Instance().Exists(sdk_path) ||
!SDKSupportsSwift(FileSpec(sdk_path), sdk.sdk_type)) {
sdk_path = GetSDKDirectory(sdk.sdk_type, sdk.min_version_major,
sdk.min_version_minor)
.GetStringRef()
.str();
}
// Note that calling setSDKPath() also recomputes all paths that
// depend on the SDK path including the
// RuntimeLibraryImportPaths, which are *only* initialized
// through this mechanism.
invocation.setSDKPath(dir.AsCString(""));
invocation.setSDKPath(sdk_path);
}

std::vector<std::string> &lpaths =
Expand Down
81 changes: 61 additions & 20 deletions lldb/source/Utility/XcodeSDK.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,24 @@ static llvm::VersionTuple ParseSDKVersion(llvm::StringRef &name) {
return version;
}

static bool ParseAppleInternalSDK(llvm::StringRef &name) {
return name.consume_front("Internal.");
}

XcodeSDK::Info XcodeSDK::Parse() const {
XcodeSDK::Info info;
llvm::StringRef input(m_name);
info.type = ParseSDKName(input);
info.version = ParseSDKVersion(input);
info.internal = ParseAppleInternalSDK(input);
return info;
}

std::tuple<XcodeSDK::Type, llvm::VersionTuple> XcodeSDK::Parse() const {
bool XcodeSDK::IsAppleInternalSDK() const {
llvm::StringRef input(m_name);
XcodeSDK::Type sdk = ParseSDKName(input);
llvm::VersionTuple version = ParseSDKVersion(input);
return std::make_tuple<XcodeSDK::Type, llvm::VersionTuple>(
std::move(sdk), std::move(version));
ParseSDKName(input);
ParseSDKVersion(input);
return ParseAppleInternalSDK(input);
}

llvm::VersionTuple XcodeSDK::GetVersion() const {
Expand All @@ -86,37 +97,64 @@ XcodeSDK::Type XcodeSDK::GetType() const {

llvm::StringRef XcodeSDK::GetString() const { return m_name; }

bool XcodeSDK::Info::operator<(const Info &other) const {
return std::tie(type, version, internal) <
std::tie(other.type, other.version, other.internal);
}
void XcodeSDK::Merge(XcodeSDK other) {
// The "bigger" SDK always wins.
if (Parse() < other.Parse())
auto l = Parse();
auto r = other.Parse();
if (l < r)
*this = other;
else {
// The Internal flag always wins.
if (llvm::StringRef(m_name).endswith(".sdk"))
if (!l.internal && r.internal)
m_name =
m_name.substr(0, m_name.size() - 3) + std::string("Internal.sdk");
}
}

llvm::StringRef XcodeSDK::GetSDKNameForType(XcodeSDK::Type type) {
switch (type) {
std::string XcodeSDK::GetCanonicalName(XcodeSDK::Info info) {
std::string name;
switch (info.type) {
case MacOSX:
return "macosx";
name = "macosx";
break;
case iPhoneSimulator:
return "iphonesimulator";
name = "iphonesimulator";
break;
case iPhoneOS:
return "iphoneos";
name = "iphoneos";
break;
case AppleTVSimulator:
return "appletvsimulator";
name = "appletvsimulator";
break;
case AppleTVOS:
return "appletvos";
name = "appletvos";
break;
case WatchSimulator:
return "watchsimulator";
name = "watchsimulator";
break;
case watchOS:
return "watchos";
name = "watchos";
break;
case bridgeOS:
return "bridgeos";
name = "bridgeos";
break;
case Linux:
return "linux";
name = "linux";
break;
case numSDKTypes:
case unknown:
return "";
return {};
}
llvm_unreachable("unhandled switch case");
if (!info.version.empty())
name += info.version.getAsString();
if (info.internal)
name += ".internal";
return name;
}

bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type sdk_type,
Expand Down Expand Up @@ -147,12 +185,15 @@ bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type desired_type,
const llvm::StringRef sdk_name = last_path_component.GetStringRef();

const std::string sdk_name_lower = sdk_name.lower();
const llvm::StringRef sdk_string = GetSDKNameForType(desired_type);
Info info;
info.type = desired_type;
const llvm::StringRef sdk_string = GetCanonicalName(info);
if (!llvm::StringRef(sdk_name_lower).startswith(sdk_string))
return false;

auto version_part = sdk_name.drop_front(sdk_string.size());
version_part.consume_back(".sdk");
version_part.consume_back(".Internal");

llvm::VersionTuple version;
if (version.tryParse(version_part))
Expand Down
4 changes: 4 additions & 0 deletions lldb/test/API/lang/swift/xcode_sdk/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SWIFT_SOURCES := main.swift
SWIFTFLAGS_EXTRAS := -Xfrontend -no-serialize-debugging-options

include Makefile.rules
Loading