@@ -1573,6 +1573,60 @@ extension Triple {
15731573// MARK: - Darwin Versions
15741574
15751575extension Triple {
1576+ // Version 26 alignment helpers, ported from LLVM's `isValidVersionForOS` /
1577+ // `getCanonicalVersionForOS`. Each Apple OS jumped to the version 26, leaving
1578+ // an unshipped version gap below 26. Only `_iOSVersion` consumes these.
1579+
1580+ /// False if `version` is in the unshipped gap.
1581+ static func _isValidVersion( _ version: Version , for os: OS ) -> Bool {
1582+ let commonMajor = 26
1583+ func valid( after starting: Int ) -> Bool {
1584+ !( version. major > starting && version. major < commonMajor)
1585+ }
1586+ switch os {
1587+ case . watchos: return valid ( after: 12 )
1588+ case . ios, . tvos: return valid ( after: 19 )
1589+ case . macosx: return valid ( after: 16 )
1590+ case . visionos: return valid ( after: 3 )
1591+ default : return true
1592+ }
1593+ }
1594+
1595+ /// Canonicalize a pre-26 or gap version into the year-aligned (26+) space.
1596+ static func _canonicalVersion( _ version: Version , for os: OS ,
1597+ isInValidRange: Bool ) -> Version {
1598+ func bumped( by delta: Int ) -> Version {
1599+ Version ( version. major + delta, version. minor, version. micro)
1600+ }
1601+ func isExactly( _ major: Int ) -> Bool {
1602+ version. major == major && version. minor == 0 && version. micro == 0
1603+ }
1604+ switch os {
1605+ case . macosx:
1606+ if version. major == 10 && version. minor == 16 { return Version ( 11 , 0 , 0 ) }
1607+ if isExactly ( 16 ) { return Version ( 26 , 0 , 0 ) }
1608+ if !isInValidRange { return bumped ( by: 10 ) }
1609+ case . ios, . tvos:
1610+ if isExactly ( 19 ) { return Version ( 26 , 0 , 0 ) }
1611+ if !isInValidRange { return bumped ( by: 7 ) }
1612+ case . visionos:
1613+ if isExactly ( 3 ) { return Version ( 26 , 0 , 0 ) }
1614+ if !isInValidRange { return bumped ( by: 23 ) }
1615+ case . watchos:
1616+ if isExactly ( 12 ) { return Version ( 26 , 0 , 0 ) }
1617+ if !isInValidRange { return bumped ( by: 14 ) }
1618+ default :
1619+ break
1620+ }
1621+ return version
1622+ }
1623+
1624+ /// Canonicalize using the platform's own validity check.
1625+ static func _canonicalVersion( _ version: Version , for os: OS ) -> Version {
1626+ _canonicalVersion ( version, for: os,
1627+ isInValidRange: _isValidVersion ( version, for: os) )
1628+ }
1629+
15761630 /// Parse the version number as with getOSVersion and then
15771631 /// translate generic "darwin" versions to the corresponding OS X versions.
15781632 /// This may also be called with IOS triples but the OS X version number is
@@ -1649,19 +1703,29 @@ extension Triple {
16491703 // toolchain that wants to know the iOS version number even when targeting
16501704 // OS X.
16511705 return Version ( 5 , 0 , 0 )
1652- case . ios:
1706+ case . ios, . tvos :
16531707 var version = self . osVersion
16541708 // Default to 5.0 (or 7.0 for arm64).
16551709 if version. major == 0 {
16561710 version. major = arch == . aarch64 ? 7 : 5
16571711 }
1658- return version
1659- case . tvos:
1660- return osVersion
1712+ // iOS & tvOS 19 correspond to iOS 26.
1713+ if version. major == 19 {
1714+ return Version ( 26 , 0 , 0 )
1715+ }
1716+ return Triple . _canonicalVersion ( version, for: . ios)
16611717 case . visionos:
1662- return Version ( 15 , 0 , 0 )
1718+ let version = self . osVersion
1719+ // xrOS 1/2 are aligned with iOS 17/18.
1720+ if version. major < 3 {
1721+ return Version ( version. major + 16 , version. minor, version. micro)
1722+ }
1723+ // visionOS 3 corresponds to iOS 26.
1724+ return Triple . _canonicalVersion ( version, for: . visionos)
16631725 case . watchos:
1664- fatalError ( " conflicting triple info " )
1726+ let version = self . osVersion
1727+ // watchOS 12 corresponds to iOS 26.
1728+ return Triple . _canonicalVersion ( version, for: . watchos)
16651729 default :
16661730 fatalError ( " unexpected OS for Darwin triple " )
16671731 }
0 commit comments