1919
2020#include " swift/AST/AccessScope.h"
2121#include " swift/AST/Attr.h"
22+ #include " swift/AST/Availability.h"
2223#include " swift/AST/CaptureInfo.h"
2324#include " swift/AST/ClangNode.h"
2425#include " swift/AST/ConcreteDeclRef.h"
@@ -2786,6 +2787,40 @@ class OpaqueTypeDecl final :
27862787 private llvm::TrailingObjects<OpaqueTypeDecl, OpaqueReturnTypeRepr *> {
27872788 friend TrailingObjects;
27882789
2790+ public:
2791+ // / A set of substitutions that represents a possible underlying type iff
2792+ // / associated set of availability conditions is met.
2793+ class ConditionallyAvailableSubstitutions ;
2794+
2795+ private:
2796+ // / A container to keep a set of conditional available underlying type
2797+ // / substitutions with their availability conditions.
2798+ class ConditionalAlternatives final
2799+ : private llvm::TrailingObjects<ConditionalAlternatives,
2800+ ConditionallyAvailableSubstitutions *> {
2801+ friend TrailingObjects;
2802+
2803+ unsigned NumAlternatives;
2804+
2805+ ConditionalAlternatives (
2806+ ArrayRef<ConditionallyAvailableSubstitutions *> underlyingTypes)
2807+ : NumAlternatives(underlyingTypes.size()) {
2808+ std::uninitialized_copy (
2809+ underlyingTypes.begin (), underlyingTypes.end (),
2810+ getTrailingObjects<ConditionallyAvailableSubstitutions *>());
2811+ }
2812+
2813+ public:
2814+ ArrayRef<ConditionallyAvailableSubstitutions *> getAlternatives () const {
2815+ return {getTrailingObjects<ConditionallyAvailableSubstitutions *>(),
2816+ NumAlternatives};
2817+ }
2818+
2819+ static ConditionalAlternatives *
2820+ get (ASTContext &ctx,
2821+ ArrayRef<ConditionallyAvailableSubstitutions *> underlyingTypes);
2822+ };
2823+
27892824 // / The original declaration that "names" the opaque type. Although a specific
27902825 // / opaque type cannot be explicitly named, oapque types can propagate
27912826 // / arbitrarily through expressions, so we need to know *which* opaque type is
@@ -2806,7 +2841,12 @@ class OpaqueTypeDecl final :
28062841 // / This maps types in the interface generic signature to the outer generic
28072842 // / signature of the original declaration.
28082843 Optional<SubstitutionMap> UnderlyingTypeSubstitutions;
2809-
2844+
2845+ // / A set of substitutions which are used based on the availability
2846+ // / checks performed at runtime. This set of only populated if there
2847+ // / is no single unique underlying type for this opaque type declaration.
2848+ ConditionalAlternatives *ConditionallyAvailableTypes = nullptr ;
2849+
28102850 mutable Identifier OpaqueReturnTypeIdentifier;
28112851
28122852 OpaqueTypeDecl (ValueDecl *NamingDecl, GenericParamList *GenericParams,
@@ -2891,7 +2931,15 @@ class OpaqueTypeDecl final :
28912931 assert (!UnderlyingTypeSubstitutions.hasValue () && " resetting underlying type?!" );
28922932 UnderlyingTypeSubstitutions = subs;
28932933 }
2894-
2934+ t
2935+ void setConditionallyAvailableSubstitutions (
2936+ ArrayRef<ConditionallyAvailableSubstitutions *> substitutions) {
2937+ assert (!ConditionallyAvailableTypes &&
2938+ " resetting conditional substitutions?!" );
2939+ ConditionallyAvailableTypes =
2940+ ConditionalAlternatives::get (getASTContext (), substitutions);
2941+ }
2942+
28952943 // Opaque type decls are currently always implicit
28962944 SourceRange getSourceRange () const { return SourceRange (); }
28972945
@@ -2910,6 +2958,40 @@ class OpaqueTypeDecl final :
29102958 return classof (D);
29112959 return false ;
29122960 }
2961+
2962+ class ConditionallyAvailableSubstitutions final
2963+ : private llvm::TrailingObjects<ConditionallyAvailableSubstitutions,
2964+ VersionRange> {
2965+ friend TrailingObjects;
2966+
2967+ unsigned NumAvailabilityConditions;
2968+
2969+ SubstitutionMap Substitutions;
2970+
2971+ // / A type with limited availability described by the provided set
2972+ // / of availability conditions (with `and` relationship).
2973+ ConditionallyAvailableSubstitutions (
2974+ ArrayRef<VersionRange> availabilityContext,
2975+ SubstitutionMap substitutions)
2976+ : NumAvailabilityConditions(availabilityContext.size()),
2977+ Substitutions (substitutions) {
2978+ assert (!availabilityContext.empty ());
2979+ std::uninitialized_copy (availabilityContext.begin (),
2980+ availabilityContext.end (),
2981+ getTrailingObjects<VersionRange>());
2982+ }
2983+
2984+ public:
2985+ ArrayRef<VersionRange> getAvailability () const {
2986+ return {getTrailingObjects<VersionRange>(), NumAvailabilityConditions};
2987+ }
2988+
2989+ SubstitutionMap getSubstitutions () const { return Substitutions; }
2990+
2991+ static ConditionallyAvailableSubstitutions *
2992+ get (ASTContext &ctx, ArrayRef<VersionRange> availabilityContext,
2993+ SubstitutionMap substitutions);
2994+ };
29132995};
29142996
29152997// / TypeAliasDecl - This is a declaration of a typealias, for example:
0 commit comments