aprantl created this revision.
aprantl added reviewers: JDevlieghere, vsk.

Unfortunately I discovered that I do need to be able to go full round-trip in 
swift-lldb.

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


https://reviews.llvm.org/D79603

Files:
  lldb/include/lldb/Utility/XcodeSDK.h
  lldb/source/Utility/XcodeSDK.cpp
  lldb/unittests/Utility/XcodeSDKTest.cpp

Index: lldb/unittests/Utility/XcodeSDKTest.cpp
===================================================================
--- lldb/unittests/Utility/XcodeSDKTest.cpp
+++ 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) {
Index: lldb/source/Utility/XcodeSDK.cpp
===================================================================
--- lldb/source/Utility/XcodeSDK.cpp
+++ lldb/source/Utility/XcodeSDK.cpp
@@ -18,6 +18,43 @@
 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 {};
+  }
+  static_assert(XcodeSDK::Linux == XcodeSDK::numSDKTypes - 1,
+                "New SDK type was added, update this list!");
+}
+
+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 +106,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 +142,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 +193,6 @@
   case Linux:
     name = "linux";
     break;
-  case numSDKTypes:
   case unknown:
     return {};
   }
Index: lldb/include/lldb/Utility/XcodeSDK.h
===================================================================
--- lldb/include/lldb/Utility/XcodeSDK.h
+++ 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;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to