Skip to content

Commit 953b322

Browse files
authored
Merge pull request #2153 from nkcsgexi/177999453-2
2 parents 45e04b4 + cb587aa commit 953b322

2 files changed

Lines changed: 112 additions & 8 deletions

File tree

Sources/SwiftDriver/Utilities/Triple.swift

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,6 +1573,32 @@ extension Triple {
15731573
// MARK: - Darwin Versions
15741574

15751575
extension Triple {
1576+
// Version 26 alignment helper. Each Apple OS jumped to version 26, so the
1577+
// last pre-jump release canonicalizes to 26; versions in the unshipped gap
1578+
// below 26 are left unchanged. Only `_iOSVersion` consumes this.
1579+
1580+
/// Canonicalize the last pre-26 release to the year-aligned version 26.
1581+
/// Gap versions (between the pre-jump release and 26) pass through unchanged.
1582+
static func _canonicalVersion(_ version: Version, for os: OS) -> Version {
1583+
func isExactly(_ major: Int) -> Bool {
1584+
version.major == major && version.minor == 0 && version.micro == 0
1585+
}
1586+
switch os {
1587+
case .macosx:
1588+
if version.major == 10 && version.minor == 16 { return Version(11, 0, 0) }
1589+
if isExactly(16) { return Version(26, 0, 0) }
1590+
case .ios, .tvos:
1591+
if isExactly(19) { return Version(26, 0, 0) }
1592+
case .visionos:
1593+
if isExactly(3) { return Version(26, 0, 0) }
1594+
case .watchos:
1595+
if isExactly(12) { return Version(26, 0, 0) }
1596+
default:
1597+
break
1598+
}
1599+
return version
1600+
}
1601+
15761602
/// Parse the version number as with getOSVersion and then
15771603
/// translate generic "darwin" versions to the corresponding OS X versions.
15781604
/// This may also be called with IOS triples but the OS X version number is
@@ -1601,11 +1627,16 @@ extension Triple {
16011627
version.micro = 0
16021628
version.minor = version.major - 4
16031629
version.major = 10
1604-
} else {
1630+
} else if version.major < 25 {
16051631
version.micro = 0
16061632
version.minor = 0
1607-
// darwin20+ corresponds to macOS 11+.
1633+
// darwin20-24 corresponds to macOS 11-15.
16081634
version.major = version.major - 9
1635+
} else if version.major == 25 || version.major == 26 {
1636+
version.micro = 0
1637+
version.minor = 0
1638+
// darwin25-26 corresponds to macOS 26-27.
1639+
version.major = version.major + 1
16091640
}
16101641

16111642
case .macosx:
@@ -1644,19 +1675,29 @@ extension Triple {
16441675
// toolchain that wants to know the iOS version number even when targeting
16451676
// OS X.
16461677
return Version(5, 0, 0)
1647-
case .ios:
1678+
case .ios, .tvos:
16481679
var version = self.osVersion
16491680
// Default to 5.0 (or 7.0 for arm64).
16501681
if version.major == 0 {
16511682
version.major = arch == .aarch64 ? 7 : 5
16521683
}
1653-
return version
1654-
case .tvos:
1655-
return osVersion
1684+
// iOS & tvOS 19 correspond to iOS 26.
1685+
if version.major == 19 {
1686+
return Version(26, 0, 0)
1687+
}
1688+
return Triple._canonicalVersion(version, for: .ios)
16561689
case .visionos:
1657-
return Version(15, 0, 0)
1690+
let version = self.osVersion
1691+
// xrOS 1/2 are aligned with iOS 17/18.
1692+
if version.major < 3 {
1693+
return Version(version.major + 16, version.minor, version.micro)
1694+
}
1695+
// visionOS 3 corresponds to iOS 26.
1696+
return Triple._canonicalVersion(version, for: .visionos)
16581697
case .watchos:
1659-
fatalError("conflicting triple info")
1698+
let version = self.osVersion
1699+
// watchOS 12 corresponds to iOS 26.
1700+
return Triple._canonicalVersion(version, for: .watchos)
16601701
default:
16611702
fatalError("unexpected OS for Darwin triple")
16621703
}

Tests/SwiftDriverTests/TripleTests.swift

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,46 @@ import class TSCBasic.DiagnosticsEngine
994994
#expect(V?.minor == 0)
995995
#expect(V?.micro == 0)
996996

997+
T = Triple("x86_64-apple-darwin24")
998+
#expect(T.os?.isMacOSX == true)
999+
#expect(T.os?.isiOS == false)
1000+
V = T._macOSVersion
1001+
#expect(V?.major == 15)
1002+
#expect(V?.minor == 0)
1003+
#expect(V?.micro == 0)
1004+
1005+
T = Triple("x86_64-apple-darwin25")
1006+
#expect(T.os?.isMacOSX == true)
1007+
#expect(T.os?.isiOS == false)
1008+
V = T._macOSVersion
1009+
#expect(V?.major == 26)
1010+
#expect(V?.minor == 0)
1011+
#expect(V?.micro == 0)
1012+
1013+
T = Triple("x86_64-apple-darwin26")
1014+
#expect(T.os?.isMacOSX == true)
1015+
#expect(T.os?.isiOS == false)
1016+
V = T._macOSVersion
1017+
#expect(V?.major == 27)
1018+
#expect(V?.minor == 0)
1019+
#expect(V?.micro == 0)
1020+
1021+
T = Triple("x86_64-apple-darwin27")
1022+
#expect(T.os?.isMacOSX == true)
1023+
#expect(T.os?.isiOS == false)
1024+
V = T._macOSVersion
1025+
#expect(V?.major == 27)
1026+
#expect(V?.minor == 0)
1027+
#expect(V?.micro == 0)
1028+
1029+
T = Triple("x86_64-apple-darwin28")
1030+
#expect(T.os?.isMacOSX == true)
1031+
#expect(T.os?.isiOS == false)
1032+
V = T._macOSVersion
1033+
#expect(V?.major == 28)
1034+
#expect(V?.minor == 0)
1035+
#expect(V?.micro == 0)
1036+
9971037
T = Triple("x86_64-apple-macosx")
9981038
#expect(T.os?.isMacOSX == true)
9991039
#expect(T.os?.isiOS == false)
@@ -1140,6 +1180,29 @@ import class TSCBasic.DiagnosticsEngine
11401180
#expect(!T.isMacCatalyst)
11411181
}
11421182

1183+
/// Mirrors LLVM `getiOSVersion` / `getCanonicalVersionForOS` version-26 alignment.
1184+
@Test func iOSVersionAlignment() {
1185+
func iOSVersion(_ triple: String) -> Triple.Version { Triple(triple)._iOSVersion }
1186+
1187+
// iOS / tvOS 19 -> iOS 26; already-aligned and pre-jump values pass through;
1188+
// a gap version (20-25) passes through unchanged.
1189+
#expect(iOSVersion("arm64-apple-ios19.0") == Triple.Version(26, 0, 0))
1190+
#expect(iOSVersion("arm64-apple-ios26.0") == Triple.Version(26, 0, 0))
1191+
#expect(iOSVersion("arm64-apple-ios18.0") == Triple.Version(18, 0, 0))
1192+
#expect(iOSVersion("arm64-apple-ios21.0") == Triple.Version(21, 0, 0))
1193+
#expect(iOSVersion("arm64-apple-tvos19.0") == Triple.Version(26, 0, 0))
1194+
1195+
// visionOS (xrOS): 1/2 align with iOS 17/18, 3 -> iOS 26.
1196+
#expect(iOSVersion("arm64-apple-xros1.0") == Triple.Version(17, 0, 0))
1197+
#expect(iOSVersion("arm64-apple-xros2.0") == Triple.Version(18, 0, 0))
1198+
#expect(iOSVersion("arm64-apple-xros3.0") == Triple.Version(26, 0, 0))
1199+
#expect(iOSVersion("arm64-apple-xros26.0") == Triple.Version(26, 0, 0))
1200+
1201+
// watchOS 12 -> iOS 26.
1202+
#expect(iOSVersion("arm64-apple-watchos12.0") == Triple.Version(26, 0, 0))
1203+
#expect(iOSVersion("arm64-apple-watchos11.0") == Triple.Version(11, 0, 0))
1204+
}
1205+
11431206
@Test func fileFormat() {
11441207
#expect(.elf == Triple("i686-unknown-linux-gnu").objectFormat)
11451208
#expect(.elf == Triple("x86_64-unknown-linux-gnu").objectFormat)

0 commit comments

Comments
 (0)