From c2c4f87ccb23a9885037c894d359a183b3068c06 Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Fri, 2 Feb 2024 16:14:26 +0000 Subject: [PATCH 1/4] [AST] Improve availability support. Use `.def` files to generate code for feature availability and runtime version to OS version mappings. rdar://121522431 --- include/swift/AST/ASTContext.h | 202 +++++------ include/swift/AST/FeatureAvailability.def | 68 ++++ include/swift/AST/RuntimeVersions.def | 151 ++++++++ lib/AST/Availability.cpp | 398 +++------------------- 4 files changed, 351 insertions(+), 468 deletions(-) create mode 100644 include/swift/AST/FeatureAvailability.def create mode 100644 include/swift/AST/RuntimeVersions.def diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index f98f9b0a28ca3..bba5d16ea9795 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -18,6 +18,7 @@ #define SWIFT_AST_ASTCONTEXT_H #include "swift/AST/ASTAllocated.h" +#include "swift/AST/Availability.h" #include "swift/AST/Evaluator.h" #include "swift/AST/GenericSignature.h" #include "swift/AST/Identifier.h" @@ -876,159 +877,124 @@ class ASTContext final { addCleanup([&object]{ object.~T(); }); } - /// Get the runtime availability of the class metadata update callback - /// mechanism for the target platform. - AvailabilityContext getObjCMetadataUpdateCallbackAvailability(); - - /// Get the runtime availability of the objc_getClass() hook for the target - /// platform. - AvailabilityContext getObjCGetClassHookAvailability(); - - /// Get the runtime availability of features introduced in the Swift 5.0 - /// compiler for the target platform. - AvailabilityContext getSwift50Availability(); - - /// Get the runtime availability of the opaque types language feature for the - /// target platform. - AvailabilityContext getOpaqueTypeAvailability(); - - /// Get the runtime availability of the objc_loadClassref() entry point for - /// the target platform. - AvailabilityContext getObjCClassStubsAvailability(); - - /// Get the runtime availability of features introduced in the Swift 5.1 - /// compiler for the target platform. - AvailabilityContext getSwift51Availability(); - - /// Get the runtime availability of - /// swift_getTypeByMangledNameInContextInMetadataState. - AvailabilityContext getTypesInAbstractMetadataStateAvailability(); - - /// Get the runtime availability of support for prespecialized generic - /// metadata. - AvailabilityContext getPrespecializedGenericMetadataAvailability(); - - /// Get the runtime availability of the swift_compareTypeContextDescriptors - /// for the target platform. - AvailabilityContext getCompareTypeContextDescriptorsAvailability(); - - /// Get the runtime availability of the - /// swift_compareProtocolConformanceDescriptors entry point for the target - /// platform. - AvailabilityContext getCompareProtocolConformanceDescriptorsAvailability(); - - /// Get the runtime availability of support for inter-module prespecialized - /// generic metadata. - AvailabilityContext getIntermodulePrespecializedGenericMetadataAvailability(); - - /// Get the runtime availability of support for concurrency. - AvailabilityContext getConcurrencyAvailability(); - - /// Get the runtime availability of task executors. - AvailabilityContext getTaskExecutorAvailability(); - - /// Get the runtime availability of the `DiscardingTaskGroup`, - /// and supporting runtime functions function - AvailabilityContext getConcurrencyDiscardingTaskGroupAvailability(); - - /// Get the back-deployed availability for concurrency. - AvailabilityContext getBackDeployedConcurrencyAvailability(); - - /// The the availability since when distributed actors are able to have custom - /// executors. - AvailabilityContext - getConcurrencyDistributedActorWithCustomExecutorAvailability(); - - /// Get the runtime availability of support for differentiation. - AvailabilityContext getDifferentiationAvailability(); - - /// Get the runtime availability of support for typed throws. - AvailabilityContext getTypedThrowsAvailability(); - - /// Get the runtime availability of getters and setters of multi payload enum - /// tag single payloads. - AvailabilityContext getMultiPayloadEnumTagSinglePayload(); - - /// Get the runtime availability of the Objective-C enabled - /// swift_isUniquelyReferenced functions. - AvailabilityContext getObjCIsUniquelyReferencedAvailability(); + /// Get the availability of features introduced in the specified version + /// of the Swift compiler for the target platform. + AvailabilityContext getSwiftAvailability(unsigned major, unsigned minor) const; + + // For each feature defined in FeatureAvailability, define two functions; + // the latter, with the suffix RuntimeAvailabilty, is for use with + // AvailabilityContext::forRuntimeTarget(), and only looks at the Swift + // runtime version. +#define FEATURE(N, V) \ + inline AvailabilityContext get##N##Availability() const { \ + return getSwiftAvailability V; \ + } \ + inline AvailabilityContext get##N##RuntimeAvailability() const { \ + return AvailabilityContext(VersionRange::allGTE(llvm::VersionTuple V)); \ + } - /// Get the runtime availability of metadata manipulation runtime functions - /// for extended existential types. - AvailabilityContext getParameterizedExistentialRuntimeAvailability(); + #include "swift/AST/FeatureAvailability.def" - /// Get the runtime availability of array buffers placed in constant data - /// sections. - AvailabilityContext getStaticReadOnlyArraysAvailability(); + /// Get the runtime availability of features that have been introduced in the + /// Swift compiler for future versions of the target platform. + AvailabilityContext getSwiftFutureAvailability() const; - /// Get the runtime availability of runtime functions for - /// variadic generic types. - AvailabilityContext getVariadicGenericTypeAvailability(); + /// Returns `true` if versioned availability annotations are supported for the + /// target triple. + bool supportsVersionedAvailability() const; - /// Get the runtime availability of the conformsToProtocol runtime entrypoint - /// that takes a signed protocol descriptor pointer. - AvailabilityContext getSignedConformsToProtocolAvailability(); + //===--------------------------------------------------------------------===// + // Compatibility availability functions + //===--------------------------------------------------------------------===// - /// Get the runtime availability of runtime entrypoints that take signed type - /// descriptors. - AvailabilityContext getSignedDescriptorAvailability(); + // Note: Don't add more of these version-specific availability functions; + // just use getSwiftAvailability() instead. - /// Get the runtime availability of the swift_initRawStructMetadata entrypoint - /// that fixes up the value witness table of @_rawLayout dependent types. - AvailabilityContext getInitRawStructMetadataAvailability(); + /// Get the runtime availability of features introduced in the Swift 5.0 + /// compiler for the target platform. + inline AvailabilityContext getSwift50Availability() const { + return getSwiftAvailability(5, 0); + } - /// Get the runtime availability of being able to use symbolic references to - /// objective c protocols. - AvailabilityContext getObjCSymbolicReferencesAvailability(); + /// Get the runtime availability of features introduced in the Swift 5.1 + /// compiler for the target platform. + inline AvailabilityContext getSwift51Availability() const { + return getSwiftAvailability(5, 1); + } /// Get the runtime availability of features introduced in the Swift 5.2 /// compiler for the target platform. - AvailabilityContext getSwift52Availability(); + inline AvailabilityContext getSwift52Availability() const { + return getSwiftAvailability(5, 2); + } /// Get the runtime availability of features introduced in the Swift 5.3 /// compiler for the target platform. - AvailabilityContext getSwift53Availability(); + inline AvailabilityContext getSwift53Availability() const { + return getSwiftAvailability(5, 3); + } /// Get the runtime availability of features introduced in the Swift 5.4 /// compiler for the target platform. - AvailabilityContext getSwift54Availability(); + inline AvailabilityContext getSwift54Availability() const { + return getSwiftAvailability(5, 4); + } /// Get the runtime availability of features introduced in the Swift 5.5 /// compiler for the target platform. - AvailabilityContext getSwift55Availability(); + inline AvailabilityContext getSwift55Availability() const { + return getSwiftAvailability(5, 5); + } /// Get the runtime availability of features introduced in the Swift 5.6 /// compiler for the target platform. - AvailabilityContext getSwift56Availability(); + inline AvailabilityContext getSwift56Availability() const { + return getSwiftAvailability(5, 6); + } /// Get the runtime availability of features introduced in the Swift 5.7 /// compiler for the target platform. - AvailabilityContext getSwift57Availability(); + inline AvailabilityContext getSwift57Availability() const { + return getSwiftAvailability(5, 7); + } /// Get the runtime availability of features introduced in the Swift 5.8 /// compiler for the target platform. - AvailabilityContext getSwift58Availability(); + inline AvailabilityContext getSwift58Availability() const { + return getSwiftAvailability(5, 8); + } /// Get the runtime availability of features introduced in the Swift 5.9 /// compiler for the target platform. - AvailabilityContext getSwift59Availability(); + inline AvailabilityContext getSwift59Availability() const { + return getSwiftAvailability(5, 9); + } - /// Get the runtime availability of features introduced in the Swift 5.9 + /// Get the runtime availability of features introduced in the Swift 5.10 /// compiler for the target platform. - AvailabilityContext getSwift511Availability(); - - // Note: Update this function if you add a new getSwiftXYAvailability above. - /// Get the runtime availability for a particular version of Swift (5.0+). - AvailabilityContext - getSwift5PlusAvailability(llvm::VersionTuple swiftVersion); + inline AvailabilityContext getSwift510Availability() const { + return getSwiftAvailability(5, 10); + } - /// Get the runtime availability of features that have been introduced in the - /// Swift compiler for future versions of the target platform. - AvailabilityContext getSwiftFutureAvailability(); + /// Get the runtime availability of features introduced in the Swift 5.11 + /// compiler for the target platform. + inline AvailabilityContext getSwift511Availability() const { + return getSwiftAvailability(5, 11); + } - /// Returns `true` if versioned availability annotations are supported for the - /// target triple. - bool supportsVersionedAvailability() const; + /// Get the runtime availability for a particular version of Swift (5.0+). + inline AvailabilityContext + getSwift5PlusAvailability(llvm::VersionTuple swiftVersion) const { + return getSwiftAvailability(swiftVersion.getMajor(), + *swiftVersion.getMinor()); + } + + /// Get the runtime availability of getters and setters of multi payload enum + /// tag single payloads. + inline AvailabilityContext getMultiPayloadEnumTagSinglePayload() const { + // This didn't fit the pattern, so needed renaming + return getMultiPayloadEnumTagSinglePayloadAvailability(); + } //===--------------------------------------------------------------------===// // Diagnostics Helper functions diff --git a/include/swift/AST/FeatureAvailability.def b/include/swift/AST/FeatureAvailability.def new file mode 100644 index 0000000000000..9e818395db0f4 --- /dev/null +++ b/include/swift/AST/FeatureAvailability.def @@ -0,0 +1,68 @@ +//===--- FeatureAvailability.def - Availability Metaprogramming -*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file defines macros used for macro-metaprogramming with feature +// availability. +// +//===----------------------------------------------------------------------===// + +/// FEATURE(N, V) +/// N - The name of the feature (in UpperCamelCase). +/// V - The Swift version number, as a tuple, or FUTURE. +#ifndef FEATURE +#define FEATURE(N, V) +#endif + +/// FUTURE +/// +/// The version to use for future support. +#ifndef FUTURE +#define FUTURE (99, 99) +#endif + +FEATURE(ObjCMetadataUpdateCallback, (5, 0)) +FEATURE(ObjCGetClassHook, (5, 0)) + +FEATURE(OpaqueType, (5, 1)) +FEATURE(ObjCClassStubs, (5, 1)) +FEATURE(BackDeployedConcurrency, (5, 1)) + +FEATURE(TypesInAbstractMetadataState, (5, 2)) + +FEATURE(PrespecializedGenericMetadata, (5, 4)) +FEATURE(CompareTypeContextDescriptors, (5, 4)) +FEATURE(CompareProtocolConformanceDescriptors, (5, 4)) +FEATURE(IntermodulePrespecializedGenericMetadata, (5, 4)) + +FEATURE(Concurrency, (5, 5)) + +FEATURE(MultiPayloadEnumTagSinglePayload, (5, 6)) +FEATURE(ObjCIsUniquelyReferenced, (5, 6)) + +FEATURE(ParameterizedExistentialRuntime, (5, 7)) + +FEATURE(VariadicGenericType, (5, 9)) +FEATURE(SignedConformsToProtocol, (5, 9)) +FEATURE(ConcurrencyDiscardingTaskGroup, (5, 9)) +FEATURE(ConcurrencyDistributedActorWithCustomExecutor, (5, 9)) +FEATURE(SignedDescriptor, (5, 9)) + +FEATURE(ObjCSymbolicReferences, (5, 11)) +FEATURE(TypedThrows, (5, 11)) +FEATURE(StaticReadOnlyArrays, (5, 11)) + +FEATURE(TaskExecutor, FUTURE) +FEATURE(Differentiation, FUTURE) +FEATURE(InitRawStructMetadata, FUTURE) + +#undef FEATURE +#undef FUTURE diff --git a/include/swift/AST/RuntimeVersions.def b/include/swift/AST/RuntimeVersions.def new file mode 100644 index 0000000000000..1c9828b97eb33 --- /dev/null +++ b/include/swift/AST/RuntimeVersions.def @@ -0,0 +1,151 @@ +//===--- RuntimeVersions.def - Runtime Version Metaprogramming --*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file defines macros used for macro-metaprogramming with runtime +// versions. +// +//===----------------------------------------------------------------------===// + +/// MAJOR_VERSION(V) +/// V - The major version number. +/// +/// This should be used to bracket RUNTIME_VERSIONs for a given major version. +#ifndef MAJOR_VERSION +#define MAJOR_VERSION(V) +#endif + +/// END_MAJOR_VERSION(V) +/// V - The major version number. +/// +/// This should be used to bracket RUNTIME_VERSIONs for a given major version. +#ifndef END_MAJOR_VERSION +#define END_MAJOR_VERSION(V) +#endif + +/// RUNTIME_VERSION(V, Ps) +/// V - A tuple of (major, minor) version numbers. +/// Ps - A list of corresponding platform versions. +/// +/// Describes a runtime version. Ps should be a list of PLATFORM() or FUTURE +/// labels describing the mapping between runtime versions and platform. Do +/// not include any separators in the list (i.e. no ','s or ';'s). +#ifndef RUNTIME_VERSION +#define RUNTIME_VERSION(V, Ps) +#endif + +/// PLATFORM(P, V) +/// P - The name of the platform (e.g. macOS, iOS, or watchOS) +/// V - A tuple containing the platform version. +#ifndef PLATFORM +#define PLATFORM(P, V) +#endif + +/// FUTURE +/// +/// Label a runtime version as a future version. +#ifndef FUTURE +#define FUTURE +#endif + +// .. Swift 5 ............................................................... // + +MAJOR_VERSION(5) + +RUNTIME_VERSION( + (5, 0), + PLATFORM(macOS, (10, 14, 4)) + PLATFORM(iOS, (12, 2)) + PLATFORM(watchOS, (5, 2)) +) + +RUNTIME_VERSION( + (5, 1), + PLATFORM(macOS, (10, 15, 0)) + PLATFORM(iOS, (13, 0, 0)) + PLATFORM(watchOS, (6, 0, 0)) +) + +RUNTIME_VERSION( + (5, 2), + PLATFORM(macOS, (10, 15, 4)) + PLATFORM(iOS, (13, 4, 0)) + PLATFORM(watchOS, (6, 2, 0)) +) + +RUNTIME_VERSION( + (5, 3), + PLATFORM(macOS, (10, 16, 0)) + PLATFORM(iOS, (14, 0, 0)) + PLATFORM(watchOS, (7, 0, 0)) +) + +RUNTIME_VERSION( + (5, 4), + PLATFORM(macOS, (11, 3, 0)) + PLATFORM(iOS, (14, 5, 0)) + PLATFORM(watchOS, (7, 4, 0)) +) + +RUNTIME_VERSION( + (5, 5), + PLATFORM(macOS, (12, 0, 0)) + PLATFORM(iOS, (15, 0, 0)) + PLATFORM(watchOS, (8, 0, 0)) +) + +RUNTIME_VERSION( + (5, 6), + PLATFORM(macOS, (12, 3, 0)) + PLATFORM(iOS, (15, 4, 0)) + PLATFORM(watchOS, (8, 5, 0)) +) + +RUNTIME_VERSION( + (5, 7), + PLATFORM(macOS, (13, 0, 0)) + PLATFORM(iOS, (16, 0, 0)) + PLATFORM(watchOS, (9, 0, 0)) +) + +RUNTIME_VERSION( + (5, 8), + PLATFORM(macOS, (13, 3, 0)) + PLATFORM(iOS, (16, 4, 0)) + PLATFORM(watchOS, (9, 4, 0)) +) + +RUNTIME_VERSION( + (5, 9), + PLATFORM(macOS, (14, 0, 0)) + PLATFORM(iOS, (17, 0, 0)) + PLATFORM(watchOS, (10, 0, 0)) +) + +RUNTIME_VERSION( + (5, 10), + FUTURE +) + +RUNTIME_VERSION( + (5, 11), + FUTURE +) + +END_MAJOR_VERSION(5) + +// .......................................................................... // + +#undef MAJOR_VERSION +#undef END_MAJOR_VERSION +#undef RUNTIME_VERSION +#undef PLATFORM +#undef FUTURE diff --git a/lib/AST/Availability.cpp b/lib/AST/Availability.cpp index e28605e540e5c..c13cc9d70f840 100644 --- a/lib/AST/Availability.cpp +++ b/lib/AST/Availability.cpp @@ -452,380 +452,78 @@ AvailabilityContext AvailabilityInference::inferForType(Type t) { return walker.AvailabilityInfo; } -AvailabilityContext ASTContext::getObjCMetadataUpdateCallbackAvailability() { - return getSwift50Availability(); -} - -AvailabilityContext ASTContext::getObjCGetClassHookAvailability() { - return getSwift50Availability(); -} - -AvailabilityContext ASTContext::getSwift50Availability() { - auto target = LangOpts.Target; - - if (target.getArchName() == "arm64e") - return AvailabilityContext::alwaysAvailable(); - - if (target.isMacOSX()) { - if (target.isAArch64()) - return AvailabilityContext::alwaysAvailable(); - - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(10,14,4))); - } else if (target.isiOS()) { - if (target.isAArch64() && - (target.isSimulatorEnvironment() || target.isMacCatalystEnvironment())) - return AvailabilityContext::alwaysAvailable(); - - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(12,2))); - } else if (target.isWatchOS()) { - if (target.isArch64Bit()) - return AvailabilityContext::alwaysAvailable(); - - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(5,2))); - } else { - return AvailabilityContext::alwaysAvailable(); - } -} - -AvailabilityContext ASTContext::getOpaqueTypeAvailability() { - return getSwift51Availability(); -} - -AvailabilityContext ASTContext::getObjCClassStubsAvailability() { - return getSwift51Availability(); -} - -AvailabilityContext ASTContext::getSwift51Availability() { +AvailabilityContext ASTContext::getSwiftFutureAvailability() const { auto target = LangOpts.Target; - - if (target.getArchName() == "arm64e") - return AvailabilityContext::alwaysAvailable(); - - if (target.isMacOSX()) { - if (target.isAArch64()) - return AvailabilityContext::alwaysAvailable(); + if (target.isMacOSX() ) { return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(10,15,0))); + VersionRange::allGTE(llvm::VersionTuple(99, 99, 0))); } else if (target.isiOS()) { - if (target.isAArch64() && - (target.isSimulatorEnvironment() || target.isMacCatalystEnvironment())) - return AvailabilityContext::alwaysAvailable(); - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(13,0,0))); + VersionRange::allGTE(llvm::VersionTuple(99, 99, 0))); } else if (target.isWatchOS()) { - if (target.isArch64Bit()) - return AvailabilityContext::alwaysAvailable(); - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(6,0,0))); + VersionRange::allGTE(llvm::VersionTuple(99, 99, 0))); } else { return AvailabilityContext::alwaysAvailable(); } } -AvailabilityContext ASTContext::getTypesInAbstractMetadataStateAvailability() { - return getSwift52Availability(); -} - -AvailabilityContext ASTContext::getPrespecializedGenericMetadataAvailability() { - return getSwift54Availability(); -} - -AvailabilityContext ASTContext::getCompareTypeContextDescriptorsAvailability() { - return getSwift54Availability(); -} - -AvailabilityContext -ASTContext::getCompareProtocolConformanceDescriptorsAvailability() { - return getSwift54Availability(); -} - AvailabilityContext -ASTContext::getIntermodulePrespecializedGenericMetadataAvailability() { - return getSwift54Availability(); -} - -AvailabilityContext ASTContext::getConcurrencyAvailability() { - return getSwift55Availability(); -} - -AvailabilityContext ASTContext::getTaskExecutorAvailability() { - return getSwiftFutureAvailability(); -} - -AvailabilityContext ASTContext::getConcurrencyDiscardingTaskGroupAvailability() { - return getSwift59Availability(); -} - -AvailabilityContext ASTContext::getBackDeployedConcurrencyAvailability() { - return getSwift51Availability(); -} - -AvailabilityContext ASTContext::getConcurrencyDistributedActorWithCustomExecutorAvailability() { - return getSwift59Availability(); -} - -AvailabilityContext ASTContext::getDifferentiationAvailability() { - return getSwiftFutureAvailability(); -} - -AvailabilityContext ASTContext::getTypedThrowsAvailability() { - return getSwift511Availability(); -} - -AvailabilityContext ASTContext::getMultiPayloadEnumTagSinglePayload() { - return getSwift56Availability(); -} - -AvailabilityContext ASTContext::getObjCIsUniquelyReferencedAvailability() { - return getSwift56Availability(); -} - -AvailabilityContext -ASTContext::getParameterizedExistentialRuntimeAvailability() { - return getSwift57Availability(); -} - -AvailabilityContext -ASTContext::getStaticReadOnlyArraysAvailability() { - return getSwift511Availability(); -} - -AvailabilityContext -ASTContext::getVariadicGenericTypeAvailability() { - return getSwift59Availability(); -} - -AvailabilityContext -ASTContext::getSignedConformsToProtocolAvailability() { - return getSwift59Availability(); -} - -AvailabilityContext -ASTContext::getSignedDescriptorAvailability() { - return getSwift59Availability(); -} - -AvailabilityContext -ASTContext::getInitRawStructMetadataAvailability() { - return getSwiftFutureAvailability(); -} - -AvailabilityContext ASTContext::getObjCSymbolicReferencesAvailability() { - return getSwift511Availability(); -} - -AvailabilityContext ASTContext::getSwift52Availability() { +ASTContext::getSwiftAvailability(unsigned major, unsigned minor) const { auto target = LangOpts.Target; - if (target.getArchName() == "arm64e") - return AvailabilityContext::alwaysAvailable(); - - if (target.isMacOSX()) { - if (target.isAArch64()) + // Deal with special cases for Swift 5.3 and lower + if (major == 5 && minor <= 3) { + if (target.getArchName() == "arm64e") return AvailabilityContext::alwaysAvailable(); - - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(10, 15, 4))); - } else if (target.isiOS()) { - if (target.isAArch64() && - (target.isSimulatorEnvironment() || target.isMacCatalystEnvironment())) + if (target.isMacOSX() && target.isAArch64()) return AvailabilityContext::alwaysAvailable(); - - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(13, 4, 0))); - } else if (target.isWatchOS()) { - if (target.isArch64Bit()) + if (target.isiOS() && target.isAArch64() + && (target.isSimulatorEnvironment() + || target.isMacCatalystEnvironment())) return AvailabilityContext::alwaysAvailable(); - - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(6, 2, 0))); - } - return AvailabilityContext::alwaysAvailable(); -} - -AvailabilityContext ASTContext::getSwift53Availability() { - auto target = LangOpts.Target; - - if (target.getArchName() == "arm64e") - return AvailabilityContext::alwaysAvailable(); - - if (target.isMacOSX() ) { - if (target.isAArch64()) + if (target.isWatchOS() && target.isArch64Bit()) return AvailabilityContext::alwaysAvailable(); - - llvm::VersionTuple macOVersion53(10, 16, 0); - macOVersion53 = canonicalizePlatformVersion(PlatformKind::macOS, macOVersion53); - return AvailabilityContext( - VersionRange::allGTE(macOVersion53)); - } else if (target.isiOS()) { - if (target.isAArch64() && - (target.isSimulatorEnvironment() || target.isMacCatalystEnvironment())) - return AvailabilityContext::alwaysAvailable(); - - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(14, 0, 0))); - } else if (target.isWatchOS()) { - if (target.isArch64Bit()) - return AvailabilityContext::alwaysAvailable(); - - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(7, 0, 0))); - } else { - return AvailabilityContext::alwaysAvailable(); - } -} - -AvailabilityContext ASTContext::getSwift54Availability() { - auto target = LangOpts.Target; - - if (target.isMacOSX()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(11, 3, 0))); - } else if (target.isiOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(14, 5, 0))); - } else if (target.isWatchOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(7, 4, 0))); - } else { - return AvailabilityContext::alwaysAvailable(); - } -} - -AvailabilityContext ASTContext::getSwift55Availability() { - auto target = LangOpts.Target; - - if (target.isMacOSX() ) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(12, 0, 0))); - } else if (target.isiOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(15, 0, 0))); - } else if (target.isWatchOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(8, 0, 0))); - } else { - return AvailabilityContext::alwaysAvailable(); - } -} - -AvailabilityContext ASTContext::getSwift56Availability() { - auto target = LangOpts.Target; - - if (target.isMacOSX() ) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(12, 3, 0))); - } else if (target.isiOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(15, 4, 0))); - } else if (target.isWatchOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(8, 5, 0))); - } else { - return AvailabilityContext::alwaysAvailable(); - } -} - -AvailabilityContext ASTContext::getSwift57Availability() { - auto target = LangOpts.Target; - - if (target.isMacOSX()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(13, 0, 0))); - } else if (target.isiOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(16, 0, 0))); - } else if (target.isWatchOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(9, 0, 0))); - } else { - return AvailabilityContext::alwaysAvailable(); } -} -AvailabilityContext ASTContext::getSwift58Availability() { - auto target = LangOpts.Target; - - if (target.isMacOSX()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(13, 3, 0))); - } else if (target.isiOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(16, 4, 0))); - } else if (target.isWatchOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(9, 4, 0))); - } else { - return AvailabilityContext::alwaysAvailable(); + switch (major) { +#define MAJOR_VERSION(V) case V: switch (minor) { +#define END_MAJOR_VERSION(V) } break; +#define PLATFORM(P, V) \ + if (IS_PLATFORM(P)) \ + return AvailabilityContext(VersionRange::allGTE(llvm::VersionTuple V)); +#define IS_PLATFORM(P) PLATFORM_TEST_##P +#define FUTURE return getSwiftFutureAvailability(); +#define PLATFORM_TEST_macOS target.isMacOSX() +#define PLATFORM_TEST_iOS target.isiOS() +#define PLATFORM_TEST_watchOS target.isWatchOS() + +#define _SECOND(A, B) B +#define SECOND(T) _SECOND T + +#define RUNTIME_VERSION(V, PLATFORMS) \ + case SECOND(V): \ + PLATFORMS \ + return AvailabilityContext::alwaysAvailable(); + + #include "swift/AST/RuntimeVersions.def" + +#undef PLATFORM_TEST_macOS +#undef PLATFORM_TEST_iOS +#undef PLATFORM_TEST_watchOS +#undef _SECOND +#undef SECOND + + case 99: + if (minor == 99) + return getSwiftFutureAvailability(); + break; } -} -AvailabilityContext ASTContext::getSwift59Availability() { - auto target = LangOpts.Target; - - if (target.isMacOSX()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(14, 0, 0))); - } else if (target.isiOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(17, 0, 0))); - } else if (target.isWatchOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(10, 0, 0))); - } else { - return AvailabilityContext::alwaysAvailable(); - } -} - -AvailabilityContext ASTContext::getSwift511Availability() { - // Placeholder - return getSwiftFutureAvailability(); -} - -AvailabilityContext ASTContext::getSwiftFutureAvailability() { - auto target = LangOpts.Target; - - if (target.isMacOSX() ) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(99, 99, 0))); - } else if (target.isiOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(99, 99, 0))); - } else if (target.isWatchOS()) { - return AvailabilityContext( - VersionRange::allGTE(llvm::VersionTuple(99, 99, 0))); - } else { - return AvailabilityContext::alwaysAvailable(); - } -} - -AvailabilityContext -ASTContext::getSwift5PlusAvailability(llvm::VersionTuple swiftVersion) { - if (swiftVersion.getMajor() == 5) { - switch (*swiftVersion.getMinor()) { - case 0: return getSwift50Availability(); - case 1: return getSwift51Availability(); - case 2: return getSwift52Availability(); - case 3: return getSwift53Availability(); - case 4: return getSwift54Availability(); - case 5: return getSwift55Availability(); - case 6: return getSwift56Availability(); - case 7: return getSwift57Availability(); - case 8: return getSwift58Availability(); - case 9: return getSwift59Availability(); - case 11: return getSwift511Availability(); - default: break; - } - } llvm::report_fatal_error( - Twine("Missing call to getSwiftXYAvailability for Swift ") + - swiftVersion.getAsString()); + Twine("Missing runtime version data for Swift ") + + Twine(major) + Twine('.') + Twine(minor)); } bool ASTContext::supportsVersionedAvailability() const { From c226bf3c3cfa4bbcc764be55339ee553faeb3294 Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Fri, 2 Feb 2024 16:17:08 +0000 Subject: [PATCH 2/4] [AST][IRGen] Add -min-runtime-version option and IRGen support code. Add a `-min-runtime-version` option that can be used to avoid problems when building on Linux and Windows where because the runtime isn't part of the OS, availability doesn't solve the problem of trying to build the compiler against an older runtime. Also add functions to IRGen to make it easy to test feature availability using both the runtime version and the existing Darwin availability support. rdar://121522431 --- include/swift/AST/Availability.h | 8 ++++++-- include/swift/Basic/LangOptions.h | 3 +++ include/swift/Basic/Version.h | 3 +++ include/swift/Option/Options.td | 5 +++++ lib/AST/Availability.cpp | 9 +++++++-- lib/Basic/Version.cpp | 17 +++++++++++++++++ lib/Frontend/CompilerInvocation.cpp | 3 +++ lib/IRGen/IRGenModule.cpp | 24 ++++++++++++++++++------ lib/IRGen/IRGenModule.h | 7 +++++++ 9 files changed, 69 insertions(+), 10 deletions(-) diff --git a/include/swift/AST/Availability.h b/include/swift/AST/Availability.h index 6cdb09b250bff..d865cf7e341fc 100644 --- a/include/swift/AST/Availability.h +++ b/include/swift/AST/Availability.h @@ -238,11 +238,15 @@ class AvailabilityContext { /// Creates a context that imposes the constraints of the ASTContext's /// deployment target. - static AvailabilityContext forDeploymentTarget(ASTContext &Ctx); + static AvailabilityContext forDeploymentTarget(const ASTContext &Ctx); /// Creates a context that imposes the constraints of the ASTContext's /// inlining target (i.e. minimum inlining version). - static AvailabilityContext forInliningTarget(ASTContext &Ctx); + static AvailabilityContext forInliningTarget(const ASTContext &Ctx); + + /// Creates a context that imposes the constraints of the ASTContext's + /// minimum runtime version. + static AvailabilityContext forRuntimeTarget(const ASTContext &Ctx); /// Creates a context that imposes no constraints. /// diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index 3460776536127..7528dd86bbfd2 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -174,6 +174,9 @@ namespace swift { /// User-overridable language version to compile for. version::Version EffectiveLanguageVersion = version::Version::getCurrentLanguageVersion(); + /// Swift runtime version to compile for. + version::Version RuntimeVersion = version::Version::getCurrentLanguageVersion(); + /// PackageDescription version to compile for. version::Version PackageDescriptionVersion; diff --git a/include/swift/Basic/Version.h b/include/swift/Basic/Version.h index 20e40ab395302..5aea52bd3837a 100644 --- a/include/swift/Basic/Version.h +++ b/include/swift/Basic/Version.h @@ -64,6 +64,9 @@ class Version { /// Create a literal version from a list of components. Version(std::initializer_list Values) : Components(Values) {} + /// Create a version from an llvm::VersionTuple. + Version(const llvm::VersionTuple &version); + /// Return a string to be used as an internal preprocessor define. /// /// The components of the version are multiplied element-wise by diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index f3d28384598bc..926c4b13f5f32 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -1349,6 +1349,11 @@ def min_inlining_target_version : Separate<["-"], "target-min-inlining-version"> HelpText<"Require inlinable code with no '@available' attribute to back-deploy " "to this version of the '-target' OS">; +def min_runtime_version : Separate<["-"], "min-runtime-version">, + Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>, + HelpText<"Specify the minimum runtime version to build force on non-Darwin " + "systems">; + def profile_generate : Flag<["-"], "profile-generate">, Flags<[FrontendOption, NoInteractiveOption]>, HelpText<"Generate instrumented code to collect execution counts">; diff --git a/lib/AST/Availability.cpp b/lib/AST/Availability.cpp index c13cc9d70f840..afe238f1794cc 100644 --- a/lib/AST/Availability.cpp +++ b/lib/AST/Availability.cpp @@ -28,16 +28,21 @@ using namespace swift; -AvailabilityContext AvailabilityContext::forDeploymentTarget(ASTContext &Ctx) { +AvailabilityContext AvailabilityContext::forDeploymentTarget(const ASTContext &Ctx) { return AvailabilityContext( VersionRange::allGTE(Ctx.LangOpts.getMinPlatformVersion())); } -AvailabilityContext AvailabilityContext::forInliningTarget(ASTContext &Ctx) { +AvailabilityContext AvailabilityContext::forInliningTarget(const ASTContext &Ctx) { return AvailabilityContext( VersionRange::allGTE(Ctx.LangOpts.MinimumInliningTargetVersion)); } +AvailabilityContext AvailabilityContext::forRuntimeTarget(const ASTContext &Ctx) { + return AvailabilityContext( + VersionRange::allGTE(Ctx.LangOpts.RuntimeVersion)); +} + namespace { /// The inferred availability required to access a group of declarations diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp index 5cc0e694f3879..e7769e47290f2 100644 --- a/lib/Basic/Version.cpp +++ b/lib/Basic/Version.cpp @@ -100,6 +100,23 @@ Version::preprocessorDefinition(StringRef macroName, return define; } +Version::Version(const llvm::VersionTuple &version) { + if (version.empty()) + return; + + Components.emplace_back(version.getMajor()); + + if (auto minor = version.getMinor()) { + Components.emplace_back(*minor); + if (auto subminor = version.getSubminor()) { + Components.emplace_back(*subminor); + if (auto build = version.getBuild()) { + Components.emplace_back(*build); + } + } + } +} + Version::operator llvm::VersionTuple() const { switch (Components.size()) { diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index d1c481035ed4b..d8823660d2d14 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1213,6 +1213,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, // FIXME: Should we diagnose if it's below the default? Opts.MinimumInliningTargetVersion = *vers; + if (auto vers = parseVersionArg(OPT_min_runtime_version)) + Opts.RuntimeVersion = version::Version(*vers); + if (auto vers = parseVersionArg(OPT_target_sdk_version)) Opts.SDKVersion = *vers; diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index 9035c2f369ea3..750fd1e58fede 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -1998,6 +1998,20 @@ void IRGenModule::error(SourceLoc loc, const Twine &message) { bool IRGenModule::useDllStorage() { return ::useDllStorage(Triple); } +#define FEATURE(N, V) \ +bool IRGenModule::is##N##FeatureAvailable(const ASTContext &context) { \ + auto deploymentAvailability \ + = AvailabilityContext::forDeploymentTarget(context); \ + auto runtimeAvailability \ + = AvailabilityContext::forRuntimeTarget(context); \ + return deploymentAvailability.isContainedIn( \ + context.get##N##Availability()) \ + && runtimeAvailability.isContainedIn( \ + context.get##N##RuntimeAvailability()); \ +} + +#include "swift/AST/FeatureAvailability.def" + bool IRGenModule::shouldPrespecializeGenericMetadata() { auto canPrespecializeTarget = (Triple.isOSDarwin() || Triple.isOSWindows() || @@ -2017,11 +2031,9 @@ bool IRGenModule::shouldPrespecializeGenericMetadata() { bool IRGenModule::canUseObjCSymbolicReferences() { if (!IRGen.Opts.EnableObjectiveCProtocolSymbolicReferences) return false; - auto &context = getSwiftModule()->getASTContext(); - auto deploymentAvailability = - AvailabilityContext::forDeploymentTarget(context); - return deploymentAvailability.isContainedIn( - context.getObjCSymbolicReferencesAvailability()); + return isObjCSymbolicReferencesFeatureAvailable( + getSwiftModule()->getASTContext() + ); } bool IRGenModule::canMakeStaticObjectReadOnly(SILType objectType) { @@ -2043,7 +2055,7 @@ bool IRGenModule::canMakeStaticObjectReadOnly(SILType objectType) { if (clDecl->getNameStr() != "_ContiguousArrayStorage") return false; - if (!getAvailabilityContext().isContainedIn(Context.getStaticReadOnlyArraysAvailability())) + if (!isStaticReadOnlyArraysFeatureAvailable()) return false; if (!getStaticArrayStorageDecl()) diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h index 708c6585ab33a..6b8d4985a60c6 100644 --- a/lib/IRGen/IRGenModule.h +++ b/lib/IRGen/IRGenModule.h @@ -934,6 +934,13 @@ class IRGenModule { ClassDecl *getStaticArrayStorageDecl(); +#define FEATURE(N, V) \ + bool is##N##FeatureAvailable(const ASTContext &context); \ + inline bool is##N##FeatureAvailable() { \ + return is##N##FeatureAvailable(Context); \ + } + #include "swift/AST/FeatureAvailability.def" + bool canUseObjCSymbolicReferences(); Size getAtomicBoolSize() const { return AtomicBoolSize; } From e48b05f12c7c159a976cedd94c061f0e1f28ca52 Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Fri, 2 Feb 2024 16:19:06 +0000 Subject: [PATCH 3/4] [SwiftCompilerSources] Enable use of the `-min-runtime-version` option. Turn on the use of `-min-runtime-version` when building the compiler. rdar://121522431 --- CMakeLists.txt | 6 ++++++ SwiftCompilerSources/CMakeLists.txt | 6 ++++++ utils/build-script-impl | 9 +++++++++ 3 files changed, 21 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c92fa28ea8459..c49298d1c51cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,9 +101,11 @@ include(FetchContent) check_language(Swift) if(CMAKE_Swift_COMPILER) enable_language(Swift) + set(DEFAULT_SWIFT_MIN_RUNTIME_VERSION "${CMAKE_Swift_COMPILER_VERSION}") else() message(STATUS "WARNING! Did not find a host compiler swift?! Can not build any compiler host sources written in Swift") + set(DEFAULT_SWIFT_MIN_RUNTIME_VERSION) endif() # A convenience pattern to match Darwin platforms. Example: @@ -464,6 +466,10 @@ set(SWIFT_DARWIN_MODULE_ARCHS "" CACHE STRING targets on Darwin platforms. These targets are in addition to the full \ library targets.") +set(SWIFT_MIN_RUNTIME_VERSION "${DEFAULT_SWIFT_MIN_RUNTIME_VERSION}" CACHE STRING + "Specify the minimum version of the runtime that we target when building \ +the compiler itself. This is used on non-Darwin platforms to ensure \ +that it's possible to build the compiler using host tools.") # # User-configurable Android specific options. diff --git a/SwiftCompilerSources/CMakeLists.txt b/SwiftCompilerSources/CMakeLists.txt index fbff4baf6fd3a..9b88db45aa2ed 100644 --- a/SwiftCompilerSources/CMakeLists.txt +++ b/SwiftCompilerSources/CMakeLists.txt @@ -106,7 +106,13 @@ function(add_swift_compiler_modules_library name) "-Xcc" "-std=c++17" "-Xcc" "-DCOMPILED_WITH_SWIFT" "-Xcc" "-DSWIFT_TARGET" "-Xcc" "-UIBOutlet" "-Xcc" "-UIBAction" "-Xcc" "-UIBInspectable") + if (NOT BOOTSTRAPPING_MODE STREQUAL "HOSTTOOLS") + if(SWIFT_MIN_RUNTIME_VERSION) + list(APPEND swift_compile_options + "-Xfrontend" "-min-runtime-version" + "-Xfrontend" "${SWIFT_MIN_RUNTIME_VERSION}") + endif() list(APPEND swift_compile_options "-Xfrontend" "-disable-implicit-string-processing-module-import") endif() diff --git a/utils/build-script-impl b/utils/build-script-impl index ce7e3e6d4f11f..73a51585e5838 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -116,6 +116,9 @@ KNOWN_SETTINGS=( darwin-toolchain-require-use-os-runtime "0" "When setting up a plist for a toolchain, require the users of the toolchain to link against the OS instead of the packaged toolchain runtime. 0 for false, 1 for true" darwin-xcrun-toolchain "default" "the name of the toolchain to use on Darwin" + ## Runtime options + min-runtime-version "" "Used to specify the minimum host runtime version when building the compiler on non-Darwin platforms" + ## WebAssembly/WASI Options wasi-sysroot "" "An absolute path to the wasi-sysroot that will be used as a libc implementation for Wasm builds" @@ -750,6 +753,12 @@ function set_build_options_for_host() { ) fi + if [[ ! -z "${MIN_RUNTIME_VERSION}" ]]; then + swift_cmake_options+=( + -DSWIFT_MIN_RUNTIME_VERSION="${MIN_RUNTIME_VERSION}" + ) + fi + swift_cmake_options+=( -DSWIFT_DARWIN_DEPLOYMENT_VERSION_OSX="${DARWIN_DEPLOYMENT_VERSION_OSX}" -DSWIFT_DARWIN_DEPLOYMENT_VERSION_IOS="${DARWIN_DEPLOYMENT_VERSION_IOS}" From b8284baf40b013d5160e6427fa25a585f1829228 Mon Sep 17 00:00:00 2001 From: Alastair Houghton Date: Fri, 2 Feb 2024 18:07:06 +0000 Subject: [PATCH 4/4] [AST] Update RuntimeVersions.def for 5.10. This was just updated in #71297. rdar://121522431 --- include/swift/AST/RuntimeVersions.def | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/swift/AST/RuntimeVersions.def b/include/swift/AST/RuntimeVersions.def index 1c9828b97eb33..3223756a6dcb5 100644 --- a/include/swift/AST/RuntimeVersions.def +++ b/include/swift/AST/RuntimeVersions.def @@ -132,7 +132,9 @@ RUNTIME_VERSION( RUNTIME_VERSION( (5, 10), - FUTURE + PLATFORM(macOS, (14, 4, 0)) + PLATFORM(iOS, (17, 4, 0)) + PLATFORM(watchOS, (10, 4, 0)) ) RUNTIME_VERSION(