Add an API to construct an XcodeSDK from an SDK type.

Also, this moves numSDKs out of the actual enum, as to not mess with
the switch-cases-covered warning.

Differential Revision: https://reviews.llvm.org/D79603
This commit is contained in:
Adrian Prantl 2020-05-07 16:02:23 -07:00
parent df5c9fdaac
commit ae920a81ff
3 changed files with 84 additions and 23 deletions

View File

@ -25,13 +25,7 @@ class XcodeSDK {
std::string m_name;
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"); }
/// Different types of Xcode SDKs.
enum Type : int {
MacOSX = 0,
iPhoneSimulator,
@ -42,18 +36,9 @@ public:
watchOS,
bridgeOS,
Linux,
numSDKTypes,
unknown = -1
};
/// The merge function follows a strict order to maintain monotonicity:
/// 1. SDK with the higher SDKType wins.
/// 2. The newer SDK wins.
void Merge(XcodeSDK other);
XcodeSDK &operator=(XcodeSDK other);
XcodeSDK(const XcodeSDK&) = default;
bool operator==(XcodeSDK other);
static constexpr int numSDKTypes = Linux + 1;
/// A parsed SDK directory name.
struct Info {
@ -63,8 +48,29 @@ public:
Info() = default;
bool operator<(const Info &other) const;
bool operator==(const Info &other) const;
};
/// Default constructor, constructs an empty string.
XcodeSDK() = default;
/// Construct an XcodeSDK object from a specification.
XcodeSDK(Info info);
/// 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"); }
/// The merge function follows a strict order to maintain monotonicity:
/// 1. SDK with the higher SDKType wins.
/// 2. The newer SDK wins.
void Merge(XcodeSDK other);
XcodeSDK &operator=(XcodeSDK other);
XcodeSDK(const XcodeSDK&) = default;
bool operator==(XcodeSDK other);
/// Return parsed SDK type and version number.
Info Parse() const;
bool IsAppleInternalSDK() const;

View File

@ -18,6 +18,41 @@
using namespace lldb;
using namespace lldb_private;
static llvm::StringRef GetName(XcodeSDK::Type type) {
switch (type) {
case XcodeSDK::MacOSX:
return "MacOSX";
case XcodeSDK::iPhoneSimulator:
return "iPhoneSimulator";
case XcodeSDK::iPhoneOS:
return "iPhoneOS";
case XcodeSDK::AppleTVSimulator:
return "AppleTVSimulator";
case XcodeSDK::AppleTVOS:
return "AppleTVOS";
case XcodeSDK::WatchSimulator:
return "WatchSimulator";
case XcodeSDK::watchOS:
return "WatchOS";
case XcodeSDK::bridgeOS:
return "bridgeOS";
case XcodeSDK::Linux:
return "Linux";
case XcodeSDK::unknown:
return {};
}
}
XcodeSDK::XcodeSDK(XcodeSDK::Info info) : m_name(GetName(info.type).str()) {
if (!m_name.empty()) {
if (!info.version.empty())
m_name += info.version.getAsString();
if (info.internal)
m_name += ".Internal";
m_name += ".sdk";
}
}
XcodeSDK &XcodeSDK::operator=(XcodeSDK other) {
m_name = other.m_name;
return *this;
@ -69,7 +104,7 @@ static llvm::VersionTuple ParseSDKVersion(llvm::StringRef &name) {
}
static bool ParseAppleInternalSDK(llvm::StringRef &name) {
return name.consume_front("Internal.");
return name.consume_front("Internal.") || name.consume_front(".Internal.");
}
XcodeSDK::Info XcodeSDK::Parse() const {
@ -105,6 +140,12 @@ bool XcodeSDK::Info::operator<(const Info &other) const {
return std::tie(type, version, internal) <
std::tie(other.type, other.version, other.internal);
}
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.
auto l = Parse();
@ -150,7 +191,6 @@ std::string XcodeSDK::GetCanonicalName(XcodeSDK::Info info) {
case Linux:
name = "linux";
break;
case numSDKTypes:
case unknown:
return {};
}

View File

@ -97,67 +97,82 @@ TEST(XcodeSDKTest, SDKSupportsSwift) {
EXPECT_FALSE(XcodeSDK("EverythingElse.sdk").SupportsSwift());
}
TEST(XcodeSDKTest, GetCanonicalName) {
TEST(XcodeSDKTest, GetCanonicalNameAndConstruct) {
XcodeSDK::Info info;
info.type = XcodeSDK::Type::MacOSX;
EXPECT_EQ("macosx", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::iPhoneSimulator;
EXPECT_EQ("iphonesimulator", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::iPhoneOS;
EXPECT_EQ("iphoneos", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::AppleTVSimulator;
EXPECT_EQ("appletvsimulator", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::AppleTVOS;
EXPECT_EQ("appletvos", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::WatchSimulator;
EXPECT_EQ("watchsimulator", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::watchOS;
EXPECT_EQ("watchos", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::Linux;
EXPECT_EQ("linux", XcodeSDK::GetCanonicalName(info));
info.type = XcodeSDK::Type::numSDKTypes;
EXPECT_EQ("", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::unknown;
EXPECT_EQ("", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.internal = true;
info.type = XcodeSDK::Type::MacOSX;
EXPECT_EQ("macosx.internal", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::iPhoneSimulator;
EXPECT_EQ("iphonesimulator.internal", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::iPhoneOS;
EXPECT_EQ("iphoneos.internal", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::AppleTVSimulator;
EXPECT_EQ("appletvsimulator.internal", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::AppleTVOS;
EXPECT_EQ("appletvos.internal", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::WatchSimulator;
EXPECT_EQ("watchsimulator.internal", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::watchOS;
EXPECT_EQ("watchos.internal", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::MacOSX;
info.version = llvm::VersionTuple(10, 9);
EXPECT_EQ("macosx10.9.internal", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
info.type = XcodeSDK::Type::iPhoneOS;
info.version = llvm::VersionTuple(7, 0);
EXPECT_EQ("iphoneos7.0.internal", XcodeSDK::GetCanonicalName(info));
EXPECT_EQ(XcodeSDK(info).Parse(), info);
}
TEST(XcodeSDKTest, GetSDKTypeForTriple) {