llvm-project/lldb/source/Utility/XcodeSDK.cpp

165 lines
4.6 KiB
C++

//===-- XcodeSDK.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/XcodeSDK.h"
#include "lldb/lldb-types.h"
using namespace lldb;
using namespace lldb_private;
XcodeSDK &XcodeSDK::operator=(XcodeSDK other) {
m_name = other.m_name;
return *this;
}
bool XcodeSDK::operator==(XcodeSDK other) {
return m_name == other.m_name;
}
static XcodeSDK::Type ParseSDKName(llvm::StringRef &name) {
if (name.consume_front("MacOSX"))
return XcodeSDK::MacOSX;
if (name.consume_front("iPhoneSimulator"))
return XcodeSDK::iPhoneSimulator;
if (name.consume_front("iPhoneOS"))
return XcodeSDK::iPhoneOS;
if (name.consume_front("AppleTVSimulator"))
return XcodeSDK::AppleTVSimulator;
if (name.consume_front("AppleTVOS"))
return XcodeSDK::AppleTVOS;
if (name.consume_front("WatchSimulator"))
return XcodeSDK::WatchSimulator;
if (name.consume_front("WatchOS"))
return XcodeSDK::watchOS;
if (name.consume_front("bridgeOS"))
return XcodeSDK::bridgeOS;
if (name.consume_front("Linux"))
return XcodeSDK::Linux;
static_assert(XcodeSDK::Linux == XcodeSDK::numSDKTypes - 1,
"New SDK type was added, update this list!");
return XcodeSDK::unknown;
}
static llvm::VersionTuple ParseSDKVersion(llvm::StringRef &name) {
unsigned i = 0;
while (i < name.size() && name[i] >= '0' && name[i] <= '9')
++i;
if (i == name.size() || name[i++] != '.')
return {};
while (i < name.size() && name[i] >= '0' && name[i] <= '9')
++i;
if (i == name.size() || name[i++] != '.')
return {};
llvm::VersionTuple version;
version.tryParse(name.slice(0, i - 1));
name = name.drop_front(i);
return version;
}
std::tuple<XcodeSDK::Type, llvm::VersionTuple> XcodeSDK::Parse() 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));
}
llvm::VersionTuple XcodeSDK::GetVersion() const {
llvm::StringRef input(m_name);
ParseSDKName(input);
return ParseSDKVersion(input);
}
XcodeSDK::Type XcodeSDK::GetType() const {
llvm::StringRef input(m_name);
return ParseSDKName(input);
}
llvm::StringRef XcodeSDK::GetString() const { return m_name; }
void XcodeSDK::Merge(XcodeSDK other) {
// The "bigger" SDK always wins.
if (Parse() < other.Parse())
*this = other;
}
llvm::StringRef XcodeSDK::GetSDKNameForType(XcodeSDK::Type type) {
switch (type) {
case MacOSX:
return "macosx";
case iPhoneSimulator:
return "iphonesimulator";
case iPhoneOS:
return "iphoneos";
case AppleTVSimulator:
return "appletvsimulator";
case AppleTVOS:
return "appletvos";
case WatchSimulator:
return "watchsimulator";
case watchOS:
return "watchos";
case bridgeOS:
return "bridgeos";
case Linux:
return "linux";
case numSDKTypes:
case unknown:
return "";
}
llvm_unreachable("unhandled switch case");
}
bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type sdk_type,
llvm::VersionTuple version) {
switch (sdk_type) {
case Type::MacOSX:
return version >= llvm::VersionTuple(10, 10);
case Type::iPhoneOS:
case Type::iPhoneSimulator:
case Type::AppleTVOS:
case Type::AppleTVSimulator:
return version >= llvm::VersionTuple(8);
case Type::watchOS:
case Type::WatchSimulator:
return version >= llvm::VersionTuple(6);
default:
return false;
}
return false;
}
bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type desired_type,
const FileSpec &sdk_path) {
ConstString last_path_component = sdk_path.GetLastPathComponent();
if (last_path_component) {
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);
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");
llvm::VersionTuple version;
if (version.tryParse(version_part))
return false;
return SDKSupportsModules(desired_type, version);
}
return false;
}