@@ -431,147 +431,139 @@ llvm::Triple swift::getUnversionedTriple(const llvm::Triple &triple) {
431
431
unversionedOSName);
432
432
}
433
433
434
+ namespace {
435
+
436
+ enum class Platform {
437
+ macOS,
438
+ iOS,
439
+ watchOS,
440
+ visionOS
441
+ };
442
+
443
+ // / A specific platform release.
444
+ struct PlatformRelease {
445
+ Platform platform;
446
+ llvm::VersionTuple version;
447
+ };
448
+
449
+ struct SwiftRelease {
450
+ // / The release version of the Swift runtime.
451
+ llvm::VersionTuple version;
452
+
453
+ // / Platform releases that provide this release of the Swift runtime.
454
+ std::initializer_list<PlatformRelease> providers;
455
+ };
456
+
457
+ } // end anonymous namespace
458
+
459
+ // TODO: do some constexpr trickery to split these out by platform
460
+ static constexpr SwiftRelease swiftReleases[] = {
461
+ #define PLATFORM (NAME, VERSION ) \
462
+ { \
463
+ Platform::NAME, \
464
+ llvm::VersionTuple VERSION \
465
+ },
466
+ #define FUTURE
467
+ #define RUNTIME_VERSION (SWIFT_TUPLE, PROVIDERS ) \
468
+ { \
469
+ llvm::VersionTuple SWIFT_TUPLE, \
470
+ { \
471
+ PROVIDERS \
472
+ } \
473
+ },
474
+ #include " swift/AST/RuntimeVersions.def"
475
+ };
476
+
477
+ // / Return the highest Swift release that matches the given platform and
478
+ // / has a version no greater than the target version. Don't return a version
479
+ // / older that the minimum. Returns null if the target version matches the
480
+ // / notional future release version.
481
+ static std::optional<llvm::VersionTuple>
482
+ findSwiftRuntimeVersion (Platform targetPlatform,
483
+ llvm::VersionTuple targetVersion,
484
+ llvm::VersionTuple minimumRelease) {
485
+ #define MAX (a, b ) ((a) > (b) ? (a) : (b))
486
+
487
+ // Just do a simple reverse scan for now.
488
+ for (auto &swiftRelease : llvm::reverse (llvm::ArrayRef (swiftReleases))) {
489
+ for (auto &provider : swiftRelease.providers ) {
490
+ // If the provider version is <= the deployment target, then
491
+ // the deployment target includes support for the given Swift
492
+ // release. Since we're scanning in reverse order of Swift
493
+ // releases (because of the order of entries in RuntimeVersions.def),
494
+ // this must be the highest supported Swift release.
495
+ if (provider.platform == targetPlatform &&
496
+ provider.version <= targetVersion) {
497
+ return MAX (swiftRelease.version , minimumRelease);
498
+ }
499
+ }
500
+ }
501
+
502
+ // If we didn't find anything, but the target release is at least the
503
+ // notional future-release version, return that we aren't
504
+ // deployment-limited.
505
+ if (targetVersion >= llvm::VersionTuple (99 , 99 ))
506
+ return std::nullopt;
507
+
508
+ // Otherwise, return the minimum release.
509
+ return minimumRelease;
510
+ }
511
+
434
512
std::optional<llvm::VersionTuple>
435
513
swift::getSwiftRuntimeCompatibilityVersionForTarget (
436
514
const llvm::Triple &Triple) {
437
- #define MAX (a, b ) ((a) > (b) ? (a) : (b))
438
515
439
516
if (Triple.isMacOSX ()) {
440
517
llvm::VersionTuple OSVersion;
441
518
Triple.getMacOSXVersion (OSVersion);
442
- unsigned Major = OSVersion.getMajor ();
443
- unsigned Minor = OSVersion.getMinor ().value_or (0 );
444
-
445
- auto floorFor64 = [&Triple](llvm::VersionTuple v) {
446
- if (!Triple.isAArch64 ()) return v;
447
- // macOS got first arm64(e) support in 11.0, i.e. VersionTuple(5, 3)
448
- return MAX (v, llvm::VersionTuple (5 , 3 ));
449
- };
450
-
451
- if (Major == 10 ) {
452
- if (Triple.isAArch64 () && Minor <= 16 )
453
- return floorFor64 (llvm::VersionTuple (5 , 3 ));
454
-
455
- if (Minor <= 14 ) {
456
- return floorFor64 (llvm::VersionTuple (5 , 0 ));
457
- } else if (Minor <= 15 ) {
458
- if (OSVersion.getSubminor ().value_or (0 ) <= 3 ) {
459
- return floorFor64 (llvm::VersionTuple (5 , 1 ));
460
- } else {
461
- return floorFor64 (llvm::VersionTuple (5 , 2 ));
462
- }
463
- }
464
- } else if (Major == 11 ) {
465
- if (Minor <= 2 )
466
- return floorFor64 (llvm::VersionTuple (5 , 3 ));
467
- return floorFor64 (llvm::VersionTuple (5 , 4 ));
468
- } else if (Major == 12 ) {
469
- if (Minor <= 2 )
470
- return floorFor64 (llvm::VersionTuple (5 , 5 ));
471
- return floorFor64 (llvm::VersionTuple (5 , 6 ));
472
- } else if (Major == 13 ) {
473
- if (Minor <= 2 )
474
- return floorFor64 (llvm::VersionTuple (5 , 7 ));
475
- return floorFor64 (llvm::VersionTuple (5 , 8 ));
476
- } else if (Major == 14 ) {
477
- if (Minor <= 3 )
478
- return floorFor64 (llvm::VersionTuple (5 , 9 ));
479
- return floorFor64 (llvm::VersionTuple (5 , 10 ));
480
- }
519
+
520
+ // macOS releases predate the stable ABI, so use Swift 5.0 as our base.
521
+ auto baseRelease = llvm::VersionTuple (5 , 0 );
522
+
523
+ // macOS got its first arm64(e) support in 11.0, which included Swift 5.3.
524
+ if (Triple.isAArch64 ())
525
+ baseRelease = llvm::VersionTuple (5 , 3 );
526
+
527
+ return findSwiftRuntimeVersion (Platform::macOS, OSVersion, baseRelease);
528
+
481
529
} else if (Triple.isiOS ()) { // includes tvOS
482
530
llvm::VersionTuple OSVersion = Triple.getiOSVersion ();
483
- unsigned Major = OSVersion.getMajor ();
484
- unsigned Minor = OSVersion.getMinor ().value_or (0 );
485
-
486
- auto floorForArchitecture = [&Triple, Major](llvm::VersionTuple v) {
487
- // arm64 simulators and macCatalyst are introduced in iOS 14.0/tvOS 14.0
488
- // with Swift 5.3
489
- if (Triple.isAArch64 () && Major <= 14 &&
490
- (Triple.isSimulatorEnvironment () ||
491
- Triple.isMacCatalystEnvironment ()))
492
- return MAX (v, llvm::VersionTuple (5 , 3 ));
493
-
494
- if (Triple.getArchName () != " arm64e" ) return v;
495
-
496
- // iOS got first arm64e support in 12.0, which has a Swift runtime version
497
- // older than 5.0, so let's floor at VersionTuple(5, 0) instead.
498
- return MAX (v, llvm::VersionTuple (5 , 0 ));
499
- };
500
-
501
- if (Major <= 12 ) {
502
- return floorForArchitecture (llvm::VersionTuple (5 , 0 ));
503
- } else if (Major <= 13 ) {
504
- if (Minor <= 3 ) {
505
- return floorForArchitecture (llvm::VersionTuple (5 , 1 ));
506
- } else {
507
- return floorForArchitecture (llvm::VersionTuple (5 , 2 ));
508
- }
509
- } else if (Major <= 14 ) {
510
- if (Minor <= 4 )
511
- return floorForArchitecture (llvm::VersionTuple (5 , 3 ));
512
-
513
- return floorForArchitecture (llvm::VersionTuple (5 , 4 ));
514
- } else if (Major <= 15 ) {
515
- if (Minor <= 3 )
516
- return floorForArchitecture (llvm::VersionTuple (5 , 5 ));
517
- return floorForArchitecture (llvm::VersionTuple (5 , 6 ));
518
- } else if (Major <= 16 ) {
519
- if (Minor <= 3 )
520
- return floorForArchitecture (llvm::VersionTuple (5 , 7 ));
521
- return floorForArchitecture (llvm::VersionTuple (5 , 8 ));
522
- } else if (Major <= 17 ) {
523
- if (Minor <= 3 )
524
- return floorForArchitecture (llvm::VersionTuple (5 , 9 ));
525
- return floorForArchitecture (llvm::VersionTuple (5 , 10 ));
526
- }
531
+
532
+ // iOS releases predate the stable ABI, so use Swift 5.0 as our base.
533
+ auto baseRelease = llvm::VersionTuple (5 , 0 );
534
+
535
+ // arm64 simulators and macCatalyst were introduced in iOS 14.0/tvOS 14.0,
536
+ // which included Swift 5.3.
537
+ if (Triple.isAArch64 () &&
538
+ (Triple.isSimulatorEnvironment () ||
539
+ Triple.isMacCatalystEnvironment ()))
540
+ baseRelease = llvm::VersionTuple (5 , 3 );
541
+
542
+ // iOS first got arm64e support in 12.0, which did not yet support the
543
+ // Swift stable ABI, so it does not provide a useful version bump.
544
+
545
+ return findSwiftRuntimeVersion (Platform::iOS, OSVersion, baseRelease);
546
+
527
547
} else if (Triple.isWatchOS ()) {
528
548
llvm::VersionTuple OSVersion = Triple.getWatchOSVersion ();
529
- unsigned Major = OSVersion.getMajor ();
530
- unsigned Minor = OSVersion.getMinor ().value_or (0 );
531
-
532
- auto floorFor64bits = [&Triple](llvm::VersionTuple v) {
533
- if (!Triple.isArch64Bit ()) return v;
534
- // 64-bit watchOS was introduced with Swift 5.3
535
- return MAX (v, llvm::VersionTuple (5 , 3 ));
536
- };
537
-
538
- if (Major <= 5 ) {
539
- return floorFor64bits (llvm::VersionTuple (5 , 0 ));
540
- } else if (Major <= 6 ) {
541
- if (Minor <= 1 ) {
542
- return floorFor64bits (llvm::VersionTuple (5 , 1 ));
543
- } else {
544
- return floorFor64bits (llvm::VersionTuple (5 , 2 ));
545
- }
546
- } else if (Major <= 7 ) {
547
- if (Minor <= 3 )
548
- return floorFor64bits (llvm::VersionTuple (5 , 3 ));
549
-
550
- return floorFor64bits (llvm::VersionTuple (5 , 4 ));
551
- } else if (Major <= 8 ) {
552
- if (Minor <= 4 )
553
- return floorFor64bits (llvm::VersionTuple (5 , 5 ));
554
- return floorFor64bits (llvm::VersionTuple (5 , 6 ));
555
- } else if (Major <= 9 ) {
556
- if (Minor <= 3 )
557
- return floorFor64bits (llvm::VersionTuple (5 , 7 ));
558
- return floorFor64bits (llvm::VersionTuple (5 , 8 ));
559
- } else if (Major <= 10 ) {
560
- if (Minor <= 3 )
561
- return floorFor64bits (llvm::VersionTuple (5 , 9 ));
562
- return floorFor64bits (llvm::VersionTuple (5 , 10 ));
563
- }
564
- }
565
- else if (Triple.isXROS ()) {
549
+
550
+ // tvOS releases predate the stable ABI, so use Swift 5.0 as our base.
551
+ auto baseRelease = llvm::VersionTuple (5 , 0 );
552
+
553
+ // 64-bit watchOS was first supported by watchOS 7, which provided
554
+ // Swift 5.3.
555
+ if (Triple.isArch64Bit ())
556
+ baseRelease = llvm::VersionTuple (5 , 3 );
557
+
558
+ return findSwiftRuntimeVersion (Platform::watchOS, OSVersion, baseRelease);
559
+
560
+ } else if (Triple.isXROS ()) {
566
561
llvm::VersionTuple OSVersion = Triple.getOSVersion ();
567
- unsigned Major = OSVersion.getMajor ();
568
- unsigned Minor = OSVersion.getMinor ().value_or (0 );
569
562
570
- if (Major <= 1 ) {
571
- if (Minor <= 0 )
572
- return llvm::VersionTuple (5 , 9 );
573
- return llvm::VersionTuple (5 , 10 );
574
- }
563
+ // visionOS 1.0 provided Swift 5.9.
564
+ auto baseRelease = llvm::VersionTuple (5 , 9 );
565
+
566
+ return findSwiftRuntimeVersion (Platform::visionOS, OSVersion, baseRelease);
575
567
}
576
568
577
569
return std::nullopt;
0 commit comments