Skip to content
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
70 changes: 34 additions & 36 deletions clang/include/clang/Basic/DarwinSDKInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,32 @@ class DarwinSDKInfo {
/// definitions, in the SDK.
struct SDKPlatformInfo {
public:
using TripleStorageType = SmallVector<llvm::Triple, 5>;

SDKPlatformInfo(TripleStorageType Triples, StringRef PlatformPrefix)
: Triples(std::move(Triples)), PlatformPrefix(PlatformPrefix) {}

const TripleStorageType &getTriples() const { return Triples; }
SDKPlatformInfo(llvm::Triple::VendorType Vendor, llvm::Triple::OSType OS,
llvm::Triple::EnvironmentType Environment,
llvm::Triple::ObjectFormatType ObjectFormat,
StringRef PlatformPrefix)
: Vendor(Vendor), OS(OS), Environment(Environment),
ObjectFormat(ObjectFormat), PlatformPrefix(PlatformPrefix) {}

llvm::Triple::VendorType getVendor() const { return Vendor; }
llvm::Triple::OSType getOS() const { return OS; }
llvm::Triple::EnvironmentType getEnvironment() const { return Environment; }
llvm::Triple::ObjectFormatType getObjectFormat() const {
return ObjectFormat;
}
StringRef getPlatformPrefix() const { return PlatformPrefix; }

bool operator==(const llvm::Triple &RHS) const {
return (Vendor == RHS.getVendor()) && (OS == RHS.getOS()) &&
(Environment == RHS.getEnvironment()) &&
(ObjectFormat == RHS.getObjectFormat());
}

private:
TripleStorageType Triples;
llvm::Triple::VendorType Vendor;
llvm::Triple::OSType OS;
llvm::Triple::EnvironmentType Environment;
llvm::Triple::ObjectFormatType ObjectFormat;
std::string PlatformPrefix;
};

Expand Down Expand Up @@ -174,22 +190,12 @@ class DarwinSDKInfo {
VersionMappings =
llvm::DenseMap<OSEnvPair::StorageType,
std::optional<RelatedTargetVersionMapping>>())
: FilePath(std::move(FilePath)), OS(OS), Environment(Environment),
Version(Version), DisplayName(DisplayName),
: FilePath(FilePath), OS(OS), Environment(Environment), Version(Version),
DisplayName(DisplayName),
MaximumDeploymentTarget(MaximumDeploymentTarget),
PlatformInfos(std::move(PlatformInfos)),
VersionMappings(std::move(VersionMappings)) {}

/// Construct SDK Info inferred from the parameters rather than read from
/// SDKSettings.json.
///
/// This will infer \c PlatformInfos from an SDK for the OS/Environment that
/// predates the introduction of SDKSettings.json, and will not infer version
/// mappings.
DarwinSDKInfo(llvm::Triple::OSType OS,
llvm::Triple::EnvironmentType Environment, VersionTuple Version,
StringRef DisplayName, VersionTuple MaximumDeploymentTarget);

StringRef getFilePath() const { return FilePath; }

llvm::Triple::OSType getOS() const { return OS; }
Expand All @@ -200,18 +206,19 @@ class DarwinSDKInfo {

const StringRef getDisplayName() const { return DisplayName; }

const llvm::Triple &getCanonicalPlatformTriple() const {
return PlatformInfos[0].getTriples()[0];
const SDKPlatformInfo &getCanonicalPlatformInfo() const {
return PlatformInfos[0];
}

bool supportsTriple(const llvm::Triple &Triple) const {
return getPlatformInfo(Triple) != nullptr;
bool supportsTriple(llvm::Triple Triple) const {
return llvm::find(PlatformInfos, Triple) != PlatformInfos.end();
}

StringRef getPlatformPrefix(const llvm::Triple &Triple) const {
if (const SDKPlatformInfo *PlatformInfo = getPlatformInfo(Triple))
return PlatformInfo->getPlatformPrefix();
return StringRef();
const StringRef getPlatformPrefix(llvm::Triple Triple) const {
auto PlatformInfoIt = llvm::find(PlatformInfos, Triple);
if (PlatformInfoIt == PlatformInfos.end())
return StringRef();
return PlatformInfoIt->getPlatformPrefix();
}

// Returns the optional, target-specific version mapping that maps from one
Expand All @@ -237,15 +244,6 @@ class DarwinSDKInfo {
const llvm::json::Object *Obj);

private:
const SDKPlatformInfo *getPlatformInfo(const llvm::Triple &Triple) const {
for (const SDKPlatformInfo &PlatformInfo : PlatformInfos) {
const auto &Triples = PlatformInfo.getTriples();
if (llvm::find(Triples, Triple) != Triples.end())
return &PlatformInfo;
}
return nullptr;
}

std::string FilePath;
llvm::Triple::OSType OS;
llvm::Triple::EnvironmentType Environment;
Expand Down
134 changes: 25 additions & 109 deletions clang/lib/Basic/DarwinSDKInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,117 +100,39 @@ parseOSAndEnvironment(std::optional<StringRef> XcodePlatform) {
return {OS, Environment};
}

static DarwinSDKInfo::PlatformInfoStorageType
legacyPlatformInfos(llvm::Triple::OSType SDKOS,
llvm::Triple::EnvironmentType SDKEnvironment) {
DarwinSDKInfo::PlatformInfoStorageType PlatformInfos;
// Synthesize platform infos for older SDKs from the first SDKs with
// SupportedTargets: macOS 10.15 (DriverKit 19.0), iOS 13.0, tvOS 13.0,
// watchOS 6.0. Older SDKs (especially iOS) most likely supported armv6 and
// armv7 architectures that aren't listed here and are difficult to identify
// from the SDK.
switch (SDKOS) {
case llvm::Triple::MacOSX:
PlatformInfos.push_back({{llvm::Triple("x86_64-apple-macosx")}, ""});
// macOS 10.15 also has a Mac Catalyst supported target, but Mac Catalyst
// was new in that version so omit it for older versions.
break;
case llvm::Triple::DriverKit:
// DriverKit 19.0 only had SDKSettings.plist, which isn't used. So this code
// path is used in 19.x as well, not just earlier versions.
PlatformInfos.push_back(
{{llvm::Triple("x86_64-apple-driverkit")}, "/System/DriverKit"});
break;
case llvm::Triple::IOS:
switch (SDKEnvironment) {
case llvm::Triple::UnknownEnvironment:
PlatformInfos.push_back(
{{llvm::Triple("armv7-apple-ios"), llvm::Triple("armv7s-apple-ios"),
llvm::Triple("arm64-apple-ios")},
""});
break;
case llvm::Triple::Simulator:
PlatformInfos.push_back(
{{llvm::Triple("x86_64-apple-ios-simulator")}, ""});
break;
default:
break;
}
break;
case llvm::Triple::TvOS:
switch (SDKEnvironment) {
case llvm::Triple::UnknownEnvironment:
PlatformInfos.push_back({{llvm::Triple("arm64-apple-tvos")}, ""});
break;
case llvm::Triple::Simulator:
PlatformInfos.push_back(
{{llvm::Triple("x86_64-apple-tvos-simulator")}, ""});
break;
default:
break;
}
break;
case llvm::Triple::WatchOS:
switch (SDKEnvironment) {
case llvm::Triple::UnknownEnvironment:
PlatformInfos.push_back({{llvm::Triple("armv7k-apple-watchos"),
llvm::Triple("arm64_32-apple-watchos")},
""});
break;
case llvm::Triple::Simulator:
PlatformInfos.push_back(
{{llvm::Triple("x86_64-apple-watchos-simulator")}, ""});
break;
default:
break;
}
break;
case llvm::Triple::BridgeOS:
PlatformInfos.push_back({{llvm::Triple("armv7-apple-bridgeos"),
llvm::Triple("armv7s-apple-bridgeos"),
llvm::Triple("arm64-apple-bridgeos")},
""});
break;
default:
break;
}
return PlatformInfos;
}

static DarwinSDKInfo::PlatformInfoStorageType parsePlatformInfos(
const llvm::json::Object &Obj, std::optional<StringRef> XcodePlatform,
llvm::Triple::OSType SDKOS, llvm::Triple::EnvironmentType SDKEnvironment,
VersionTuple Version) {
DarwinSDKInfo::PlatformInfoStorageType PlatformInfos;
auto SupportedTargets = Obj.getObject("SupportedTargets");
if (!SupportedTargets)
return legacyPlatformInfos(SDKOS, SDKEnvironment);
if (!SupportedTargets) {
// For older SDKs that don't have SupportedTargets, infer one from the SDK's
// OS/Environment.
StringRef PlatformPrefix;
if (SDKOS == llvm::Triple::DriverKit)
PlatformPrefix = "/System/DriverKit";
PlatformInfos.push_back({llvm::Triple::Apple, SDKOS, SDKEnvironment,
llvm::Triple::MachO, PlatformPrefix});
return PlatformInfos;
}

for (const auto &SupportedTargetPair : *SupportedTargets) {
const llvm::json::Object *SupportedTarget =
for (auto SupportedTargetPair : *SupportedTargets) {
llvm::json::Object *SupportedTarget =
SupportedTargetPair.getSecond().getAsObject();
if (!SupportedTarget)
continue;

auto Archs = SupportedTarget->getArray("Archs");
auto Vendor = SupportedTarget->getString("LLVMTargetTripleVendor");
auto OS = SupportedTarget->getString("LLVMTargetTripleSys");
if (!Archs || !Vendor || !OS)
if (!Vendor || !OS)
continue;

DarwinSDKInfo::SDKPlatformInfo::TripleStorageType Triples;
StringRef Arch = llvm::Triple::getArchName(llvm::Triple::UnknownArch);
auto Environment =
SupportedTarget->getString("LLVMTargetTripleEnvironment");
for (const auto &ArchValue : *Archs) {
if (auto Arch = ArchValue.getAsString()) {
if (Environment)
Triples.emplace_back(*Arch, *Vendor, *OS, *Environment);
else
Triples.emplace_back(*Arch, *Vendor, *OS);
}
}
if (Triples.empty())
continue;
llvm::Triple Triple;
if (Environment)
Triple = llvm::Triple(Arch, *Vendor, *OS, *Environment);
else
Triple = llvm::Triple(Arch, *Vendor, *OS);

// The key is either the Xcode platform, or a variant. The platform must be
// the first entry in the returned PlatformInfoStorageType.
Expand All @@ -225,17 +147,19 @@ static DarwinSDKInfo::PlatformInfoStorageType parsePlatformInfos(
} else {
// Older SDKs don't have SystemPrefix in SupportedTargets, manually add
// their prefixes.
if ((Triples[0].getOS() == llvm::Triple::DriverKit) &&
if ((Triple.getOS() == llvm::Triple::DriverKit) &&
(Version < VersionTuple(22, 1)))
EffectivePlatformPrefix = "/System/DriverKit";
}
}

DarwinSDKInfo::SDKPlatformInfo PlatformInfo(
Triple.getVendor(), Triple.getOS(), Triple.getEnvironment(),
Triple.getObjectFormat(), EffectivePlatformPrefix);
if (PlatformOrVariant == XcodePlatform)
PlatformInfos.insert(PlatformInfos.begin(),
{std::move(Triples), EffectivePlatformPrefix});
PlatformInfos.insert(PlatformInfos.begin(), PlatformInfo);
else
PlatformInfos.emplace_back(std::move(Triples), EffectivePlatformPrefix);
PlatformInfos.push_back(PlatformInfo);
}
return PlatformInfos;
}
Expand Down Expand Up @@ -341,11 +265,3 @@ clang::parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath) {
return llvm::make_error<llvm::StringError>("invalid SDKSettings.json",
llvm::inconvertibleErrorCode());
}

DarwinSDKInfo::DarwinSDKInfo(llvm::Triple::OSType OS,
llvm::Triple::EnvironmentType Environment,
VersionTuple Version, StringRef DisplayName,
VersionTuple MaximumDeploymentTarget)
: DarwinSDKInfo("", OS, Environment, Version, DisplayName,
MaximumDeploymentTarget,
legacyPlatformInfos(OS, Environment)) {}
18 changes: 12 additions & 6 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1220,7 +1220,7 @@ AppleMachO::~AppleMachO() {}
MachO::~MachO() {}

void Darwin::VerifyTripleForSDK(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple) const {
const llvm::Triple Triple) const {
if (SDKInfo) {
if (!SDKInfo->supportsTriple(Triple))
getDriver().Diag(diag::warn_incompatible_sysroot)
Expand Down Expand Up @@ -2041,14 +2041,15 @@ struct DarwinPlatform {
}
static DarwinPlatform createFromSDKInfo(StringRef SDKRoot,
const DarwinSDKInfo &SDKInfo) {
const llvm::Triple &PlatformTriple = SDKInfo.getCanonicalPlatformTriple();
const llvm::Triple::OSType OS = PlatformTriple.getOS();
const DarwinSDKInfo::SDKPlatformInfo PlatformInfo =
SDKInfo.getCanonicalPlatformInfo();
const llvm::Triple::OSType OS = PlatformInfo.getOS();
VersionTuple Version = SDKInfo.getVersion();
if (OS == llvm::Triple::MacOSX)
Version = getVersionFromString(
getSystemOrSDKMacOSVersion(Version.getAsString()));
DarwinPlatform Result(InferredFromSDK, getPlatformFromOS(OS), Version);
Result.Environment = getEnvKindFromEnvType(PlatformTriple.getEnvironment());
Result.Environment = getEnvKindFromEnvType(PlatformInfo.getEnvironment());
Result.InferSimulatorFromArch = false;
Result.InferredSource = SDKRoot;
return Result;
Expand Down Expand Up @@ -2081,10 +2082,15 @@ struct DarwinPlatform {
llvm::Triple::OSType OS = getOSFromPlatform(Platform);
llvm::Triple::EnvironmentType EnvironmentType =
getEnvTypeFromEnvKind(Environment);
return DarwinSDKInfo(OS, EnvironmentType, getOSVersion(),
StringRef PlatformPrefix =
(Platform == DarwinPlatformKind::DriverKit) ? "/System/DriverKit" : "";
return DarwinSDKInfo("", OS, EnvironmentType, getOSVersion(),
getDisplayName(Platform, Environment, getOSVersion()),
/*MaximumDeploymentTarget=*/
VersionTuple(getOSVersion().getMajor(), 0, 99));
VersionTuple(getOSVersion().getMajor(), 0, 99),
{DarwinSDKInfo::SDKPlatformInfo(
llvm::Triple::Apple, OS, EnvironmentType,
llvm::Triple::MachO, PlatformPrefix)});
}

private:
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Darwin.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public AppleMachO {
void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const;

void VerifyTripleForSDK(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple) const;
const llvm::Triple Triple) const;

protected:
/// Lazily initialize the target platform from the triple when
Expand Down
4 changes: 2 additions & 2 deletions clang/unittests/Basic/DarwinSDKInfoTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ TEST(DarwinSDKInfo, PlatformPrefix) {
ASSERT_TRUE(SDKInfo);
EXPECT_EQ(SDKInfo->getPlatformPrefix(Triple("arm64-apple-macos26.0")),
"/System/macOSSupport");
// The triple's architecture matters.
EXPECT_NE(SDKInfo->getPlatformPrefix(Triple("ppc-apple-macos26.0")),
// The triple's architecture doesn't matter.
EXPECT_EQ(SDKInfo->getPlatformPrefix(Triple("ppc-apple-macos26.0")),
"/System/macOSSupport");
// OSes that aren't specified in the SDK never get a system prefix.
EXPECT_EQ(SDKInfo->getPlatformPrefix(Triple("arm64-apple-ios26.0")), "");
Expand Down