Skip to content

[swift/release/6.2][clang][modules] Determine if the SDK supports builtin modules independent of the target #10445

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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
6 changes: 5 additions & 1 deletion clang/include/clang/Basic/DarwinSDKInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,16 +143,19 @@ class DarwinSDKInfo {

DarwinSDKInfo(
VersionTuple Version, VersionTuple MaximumDeploymentTarget,
llvm::Triple::OSType OS,
llvm::DenseMap<OSEnvPair::StorageType,
std::optional<RelatedTargetVersionMapping>>
VersionMappings =
llvm::DenseMap<OSEnvPair::StorageType,
std::optional<RelatedTargetVersionMapping>>())
: Version(Version), MaximumDeploymentTarget(MaximumDeploymentTarget),
VersionMappings(std::move(VersionMappings)) {}
OS(OS), VersionMappings(std::move(VersionMappings)) {}

const llvm::VersionTuple &getVersion() const { return Version; }

const llvm::Triple::OSType &getOS() const { return OS; }

// Returns the optional, target-specific version mapping that maps from one
// target to another target.
//
Expand All @@ -177,6 +180,7 @@ class DarwinSDKInfo {
private:
VersionTuple Version;
VersionTuple MaximumDeploymentTarget;
llvm::Triple::OSType OS;
// Need to wrap the value in an optional here as the value has to be default
// constructible, and std::unique_ptr doesn't like DarwinSDKInfo being
// Optional as Optional is trying to copy it in emplace.
Expand Down
26 changes: 25 additions & 1 deletion clang/lib/Basic/DarwinSDKInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "clang/Basic/DarwinSDKInfo.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/MemoryBuffer.h"
Expand Down Expand Up @@ -62,6 +63,28 @@ DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(
Min, Max, MinValue, MaximumDeploymentTarget, std::move(Mapping));
}

static llvm::Triple::OSType parseOS(const llvm::json::Object &Obj) {
// The CanonicalName is the Xcode platform followed by a version, e.g.
// macosx16.0.
auto CanonicalName = Obj.getString("CanonicalName");
if (!CanonicalName)
return llvm::Triple::UnknownOS;
size_t VersionStart = CanonicalName->find_first_of("0123456789");
StringRef XcodePlatform = CanonicalName->slice(0, VersionStart);
return llvm::StringSwitch<llvm::Triple::OSType>(XcodePlatform)
.Case("macosx", llvm::Triple::MacOSX)
.Case("iphoneos", llvm::Triple::IOS)
.Case("iphonesimulator", llvm::Triple::IOS)
.Case("appletvos", llvm::Triple::TvOS)
.Case("appletvsimulator", llvm::Triple::TvOS)
.Case("watchos", llvm::Triple::WatchOS)
.Case("watchsimulator", llvm::Triple::WatchOS)
.Case("xros", llvm::Triple::XROS)
.Case("xrsimulator", llvm::Triple::XROS)
.Case("driverkit", llvm::Triple::DriverKit)
.Default(llvm::Triple::UnknownOS);
}

static std::optional<VersionTuple> getVersionKey(const llvm::json::Object &Obj,
StringRef Key) {
auto Value = Obj.getString(Key);
Expand All @@ -82,6 +105,7 @@ DarwinSDKInfo::parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj) {
getVersionKey(*Obj, "MaximumDeploymentTarget");
if (!MaximumDeploymentVersion)
return std::nullopt;
llvm::Triple::OSType OS = parseOS(*Obj);
llvm::DenseMap<OSEnvPair::StorageType,
std::optional<RelatedTargetVersionMapping>>
VersionMappings;
Expand Down Expand Up @@ -124,7 +148,7 @@ DarwinSDKInfo::parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj) {
}

return DarwinSDKInfo(std::move(*Version),
std::move(*MaximumDeploymentVersion),
std::move(*MaximumDeploymentVersion), OS,
std::move(VersionMappings));
}

Expand Down
60 changes: 29 additions & 31 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1960,7 +1960,8 @@ struct DarwinPlatform {
assert(IsValid && "invalid SDK version");
return DarwinSDKInfo(
Version,
/*MaximumDeploymentTarget=*/VersionTuple(Version.getMajor(), 0, 99));
/*MaximumDeploymentTarget=*/VersionTuple(Version.getMajor(), 0, 99),
getOSFromPlatform(Platform));
}

private:
Expand Down Expand Up @@ -1990,6 +1991,23 @@ struct DarwinPlatform {
}
}

static llvm::Triple::OSType getOSFromPlatform(DarwinPlatformKind Platform) {
switch (Platform) {
case DarwinPlatformKind::MacOS:
return llvm::Triple::MacOSX;
case DarwinPlatformKind::IPhoneOS:
return llvm::Triple::IOS;
case DarwinPlatformKind::TvOS:
return llvm::Triple::TvOS;
case DarwinPlatformKind::WatchOS:
return llvm::Triple::WatchOS;
case DarwinPlatformKind::DriverKit:
return llvm::Triple::DriverKit;
case DarwinPlatformKind::XROS:
return llvm::Triple::XROS;
}
}

SourceKind Kind;
DarwinPlatformKind Platform;
DarwinEnvironmentKind Environment = DarwinEnvironmentKind::NativeEnvironment;
Expand Down Expand Up @@ -3063,20 +3081,8 @@ bool Darwin::isAlignedAllocationUnavailable() const {
return TargetVersion < alignedAllocMinVersion(OS);
}

static bool sdkSupportsBuiltinModules(
const Darwin::DarwinPlatformKind &TargetPlatform,
const Darwin::DarwinEnvironmentKind &TargetEnvironment,
const std::optional<DarwinSDKInfo> &SDKInfo) {
if (TargetEnvironment == Darwin::NativeEnvironment ||
TargetEnvironment == Darwin::Simulator ||
TargetEnvironment == Darwin::MacCatalyst) {
// Standard xnu/Mach/Darwin based environments
// depend on the SDK version.
} else {
// All other environments support builtin modules from the start.
return true;
}

static bool
sdkSupportsBuiltinModules(const std::optional<DarwinSDKInfo> &SDKInfo) {
if (!SDKInfo)
// If there is no SDK info, assume this is building against a
// pre-SDK version of macOS (i.e. before Mac OS X 10.4). Those
Expand All @@ -3087,26 +3093,18 @@ static bool sdkSupportsBuiltinModules(
return false;

VersionTuple SDKVersion = SDKInfo->getVersion();
switch (TargetPlatform) {
switch (SDKInfo->getOS()) {
// Existing SDKs added support for builtin modules in the fall
// 2024 major releases.
case Darwin::MacOS:
case llvm::Triple::MacOSX:
return SDKVersion >= VersionTuple(15U);
case Darwin::IPhoneOS:
switch (TargetEnvironment) {
case Darwin::MacCatalyst:
// Mac Catalyst uses `-target arm64-apple-ios18.0-macabi` so the platform
// is iOS, but it builds with the macOS SDK, so it's the macOS SDK version
// that's relevant.
return SDKVersion >= VersionTuple(15U);
default:
return SDKVersion >= VersionTuple(18U);
}
case Darwin::TvOS:
case llvm::Triple::IOS:
return SDKVersion >= VersionTuple(18U);
case Darwin::WatchOS:
case llvm::Triple::TvOS:
return SDKVersion >= VersionTuple(18U);
case llvm::Triple::WatchOS:
return SDKVersion >= VersionTuple(11U);
case Darwin::XROS:
case llvm::Triple::XROS:
return SDKVersion >= VersionTuple(2U);

// New SDKs support builtin modules from the start.
Expand Down Expand Up @@ -3267,7 +3265,7 @@ void Darwin::addClangTargetOptions(
// i.e. when the builtin stdint.h is in the Darwin module too, the cycle
// goes away. Note that -fbuiltin-headers-in-system-modules does nothing
// to fix the same problem with C++ headers, and is generally fragile.
if (!sdkSupportsBuiltinModules(TargetPlatform, TargetEnvironment, SDKInfo))
if (!sdkSupportsBuiltinModules(SDKInfo))
CC1Args.push_back("-fbuiltin-headers-in-system-modules");
}

Expand Down
1 change: 1 addition & 0 deletions clang/test/CAS/Inputs/MacOSX11.0.sdk/SDKSettings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"DefaultVariant": "macos", "DisplayName": "macOS 11",
"Version": "11.0",
"CanonicalName": "macosx11.0",
"MaximumDeploymentTarget": "11.0.99",
"PropertyConditionFallbackNames": [], "VersionMap": {
"iOSMac_macOS": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"Version":"23.0", "MaximumDeploymentTarget": "23.0.99"}
{"Version":"23.0", "CanonicalName": "driverkit23.0", "MaximumDeploymentTarget": "23.0.99"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"Version":"10.14", "MaximumDeploymentTarget": "10.14.99"}
{"Version":"10.14", "CanonicalName": "macosx10.14", "MaximumDeploymentTarget": "10.14.99"}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"Version":"10.14",
"CanonicalName": "macosx10.14",
"VersionMap" : {
"macOS_iOSMac" : {
"10.14.4" : "12.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"Version":"10.15",
"CanonicalName": "macosx10.15",
"MaximumDeploymentTarget": "10.15.99",
"VersionMap" : {
"macOS_iOSMac" : {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Driver/Inputs/MacOSX15.0.sdk/SDKSettings.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"Version":"15.0", "MaximumDeploymentTarget": "15.0.99"}
{"Version":"15.0", "CanonicalName": "macosx15.0", "MaximumDeploymentTarget": "15.0.99"}
2 changes: 1 addition & 1 deletion clang/test/Driver/Inputs/MacOSX15.1.sdk/SDKSettings.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"Version":"15.1", "MaximumDeploymentTarget": "15.1.99"}
{"Version":"15.1", "CanonicalName": "macosx15.1", "MaximumDeploymentTarget": "15.1.99"}
2 changes: 1 addition & 1 deletion clang/test/Driver/Inputs/WatchOS6.0.sdk/SDKSettings.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"Version":"6.0.0", "MaximumDeploymentTarget": "6.0.99"}
{"Version":"6.0", "CanonicalName": "watchos6.0", "MaximumDeploymentTarget": "6.0.99"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"Version":"13.0", "MaximumDeploymentTarget": "13.0.99"}
{"Version":"13.0", "CanonicalName": "iphoneos13.0", "MaximumDeploymentTarget": "13.0.99"}
4 changes: 2 additions & 2 deletions clang/test/Driver/darwin-ld-platform-version-watchos.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
// RUN: | FileCheck --check-prefix=SIMUL %s

// LINKER-OLD: "-watchos_version_min" "5.2.0"
// LINKER-NEW: "-platform_version" "watchos" "5.2.0" "6.0.0"
// SIMUL: "-platform_version" "watchos-simulator" "6.0.0" "6.0.0"
// LINKER-NEW: "-platform_version" "watchos" "5.2.0" "6.0"
// SIMUL: "-platform_version" "watchos-simulator" "6.0.0" "6.0"
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"DefaultVariant": "macos", "DisplayName": "macOS 13",
"Version": "13.0",
"CanonicalName": "macosx13.0",
"MaximumDeploymentTarget": "13.0.99",
"PropertyConditionFallbackNames": [], "VersionMap": {
"iOSMac_macOS": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"DisplayName": "tvOS 15.0",
"Version": "15.0",
"CanonicalName": "appletvos15.0",
"MaximumDeploymentTarget": "15.0.99",
"PropertyConditionFallbackNames": [],
"VersionMap": {
Expand Down
1 change: 1 addition & 0 deletions clang/test/Sema/Inputs/MacOSX11.0.sdk/SDKSettings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"DefaultVariant": "macos", "DisplayName": "macOS 11",
"Version": "11.0",
"CanonicalName": "macosx11.0",
"MaximumDeploymentTarget": "11.0.99",
"PropertyConditionFallbackNames": [], "VersionMap": {
"iOSMac_macOS": {
Expand Down
1 change: 1 addition & 0 deletions clang/test/Sema/Inputs/WatchOS7.0.sdk/SDKSettings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"DisplayName": "watchOS 7.0",
"Version": "7.0",
"CanonicalName": "watchos7.0",
"MaximumDeploymentTarget": "7.0.99",
"PropertyConditionFallbackNames": [],
"VersionMap": {
Expand Down