diff --git a/lldb/include/lldb/Utility/XcodeSDK.h b/lldb/include/lldb/Utility/XcodeSDK.h --- a/lldb/include/lldb/Utility/XcodeSDK.h +++ b/lldb/include/lldb/Utility/XcodeSDK.h @@ -25,13 +25,7 @@ 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 @@ 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 @@ 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; diff --git a/lldb/source/Utility/XcodeSDK.cpp b/lldb/source/Utility/XcodeSDK.cpp --- a/lldb/source/Utility/XcodeSDK.cpp +++ b/lldb/source/Utility/XcodeSDK.cpp @@ -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 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 @@ 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 @@ case Linux: name = "linux"; break; - case numSDKTypes: case unknown: return {}; } diff --git a/lldb/unittests/Utility/XcodeSDKTest.cpp b/lldb/unittests/Utility/XcodeSDKTest.cpp --- a/lldb/unittests/Utility/XcodeSDKTest.cpp +++ b/lldb/unittests/Utility/XcodeSDKTest.cpp @@ -97,67 +97,82 @@ 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) {