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,12 @@ 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:
27892796 // / The original declaration that "names" the opaque type. Although a specific
27902797 // / opaque type cannot be explicitly named, oapque types can propagate
27912798 // / arbitrarily through expressions, so we need to know *which* opaque type is
@@ -2805,8 +2812,17 @@ class OpaqueTypeDecl final :
28052812 // / expressed as a SubstitutionMap for the opaque interface generic signature.
28062813 // / This maps types in the interface generic signature to the outer generic
28072814 // / signature of the original declaration.
2808- Optional<SubstitutionMap> UnderlyingTypeSubstitutions;
2809-
2815+ Optional<SubstitutionMap> UniqueUnderlyingType;
2816+
2817+ // / A set of substitutions which are used based on the availability
2818+ // / checks performed at runtime. This set of only populated if there
2819+ // / is no single unique underlying type for this opaque type declaration.
2820+ // /
2821+ // / It always contains one or more conditionally available substitutions
2822+ // / followed by a universally available type used as a fallback.
2823+ Optional<MutableArrayRef<ConditionallyAvailableSubstitutions *>>
2824+ ConditionallyAvailableTypes = None;
2825+
28102826 mutable Identifier OpaqueReturnTypeIdentifier;
28112827
28122828 OpaqueTypeDecl (ValueDecl *NamingDecl, GenericParamList *GenericParams,
@@ -2882,16 +2898,25 @@ class OpaqueTypeDecl final :
28822898 }
28832899
28842900 // / The substitutions that map the generic parameters of the opaque type to
2885- // / their underlying types, when that information is known.
2886- Optional<SubstitutionMap> getUnderlyingTypeSubstitutions () const {
2887- return UnderlyingTypeSubstitutions ;
2901+ // / the unique underlying types, when that information is known.
2902+ Optional<SubstitutionMap> getUniqueUnderlyingTypeSubstitutions () const {
2903+ return UniqueUnderlyingType ;
28882904 }
28892905
2890- void setUnderlyingTypeSubstitutions (SubstitutionMap subs) {
2891- assert (!UnderlyingTypeSubstitutions .hasValue () && " resetting underlying type?!" );
2892- UnderlyingTypeSubstitutions = subs;
2906+ void setUniqueUnderlyingTypeSubstitutions (SubstitutionMap subs) {
2907+ assert (!UniqueUnderlyingType .hasValue () && " resetting underlying type?!" );
2908+ UniqueUnderlyingType = subs;
28932909 }
2894-
2910+
2911+ ArrayRef<ConditionallyAvailableSubstitutions *>
2912+ getConditionallyAvailableSubstitutions () const {
2913+ assert (ConditionallyAvailableTypes);
2914+ return ConditionallyAvailableTypes.getValue ();
2915+ }
2916+
2917+ void setConditionallyAvailableSubstitutions (
2918+ ArrayRef<ConditionallyAvailableSubstitutions *> substitutions);
2919+
28952920 // Opaque type decls are currently always implicit
28962921 SourceRange getSourceRange () const { return SourceRange (); }
28972922
@@ -2910,6 +2935,40 @@ class OpaqueTypeDecl final :
29102935 return classof (D);
29112936 return false ;
29122937 }
2938+
2939+ class ConditionallyAvailableSubstitutions final
2940+ : private llvm::TrailingObjects<ConditionallyAvailableSubstitutions,
2941+ VersionRange> {
2942+ friend TrailingObjects;
2943+
2944+ unsigned NumAvailabilityConditions;
2945+
2946+ SubstitutionMap Substitutions;
2947+
2948+ // / A type with limited availability described by the provided set
2949+ // / of availability conditions (with `and` relationship).
2950+ ConditionallyAvailableSubstitutions (
2951+ ArrayRef<VersionRange> availabilityContext,
2952+ SubstitutionMap substitutions)
2953+ : NumAvailabilityConditions(availabilityContext.size()),
2954+ Substitutions (substitutions) {
2955+ assert (!availabilityContext.empty ());
2956+ std::uninitialized_copy (availabilityContext.begin (),
2957+ availabilityContext.end (),
2958+ getTrailingObjects<VersionRange>());
2959+ }
2960+
2961+ public:
2962+ ArrayRef<VersionRange> getAvailability () const {
2963+ return {getTrailingObjects<VersionRange>(), NumAvailabilityConditions};
2964+ }
2965+
2966+ SubstitutionMap getSubstitutions () const { return Substitutions; }
2967+
2968+ static ConditionallyAvailableSubstitutions *
2969+ get (ASTContext &ctx, ArrayRef<VersionRange> availabilityContext,
2970+ SubstitutionMap substitutions);
2971+ };
29132972};
29142973
29152974// / TypeAliasDecl - This is a declaration of a typealias, for example:
0 commit comments