1818
1919using namespace swift ;
2020
21+ // Defined as a macro because you can't take the reference of a bitfield.
22+ #define CONSTRAIN_BOOL (_old, _new ) \
23+ [&]() { \
24+ if (_old || !_new) \
25+ return false ; \
26+ _old = true ; \
27+ return true ; \
28+ }()
29+
30+ static bool constrainRange (AvailabilityRange &existing,
31+ const AvailabilityRange &other) {
32+ if (!other.isContainedIn (existing))
33+ return false ;
34+
35+ existing = other;
36+ return true ;
37+ }
38+
2139bool AvailabilityContext::PlatformInfo::constrainWith (
2240 const PlatformInfo &other) {
2341 bool isConstrained = false ;
24- isConstrained |= constrainRange (other.Range );
42+ isConstrained |= constrainRange (Range, other.Range );
2543 if (other.IsUnavailable ) {
2644 isConstrained |= constrainUnavailability (other.UnavailablePlatform );
45+ isConstrained |=
46+ CONSTRAIN_BOOL (IsUnavailableInEmbedded, other.IsUnavailableInEmbedded );
2747 }
28- isConstrained |= constrainDeprecated ( other.IsDeprecated );
48+ isConstrained |= CONSTRAIN_BOOL (IsDeprecated, other.IsDeprecated );
2949
3050 return isConstrained;
3151}
@@ -35,13 +55,16 @@ bool AvailabilityContext::PlatformInfo::constrainWith(const Decl *decl) {
3555 auto &ctx = decl->getASTContext ();
3656
3757 if (auto range = AvailabilityInference::annotatedAvailableRange (decl))
38- isConstrained |= constrainRange (*range);
58+ isConstrained |= constrainRange (Range, *range);
3959
40- if (auto *attr = decl->getAttrs ().getUnavailable (ctx))
60+ if (auto *attr = decl->getAttrs ().getUnavailable (ctx)) {
4161 isConstrained |= constrainUnavailability (attr->Platform );
62+ isConstrained |=
63+ CONSTRAIN_BOOL (IsUnavailableInEmbedded, attr->isForEmbedded ());
64+ }
4265
43- if (!IsDeprecated)
44- isConstrained |= constrainDeprecated ( decl->getAttrs ().isDeprecated (ctx));
66+ isConstrained |=
67+ CONSTRAIN_BOOL (IsDeprecated, decl->getAttrs ().isDeprecated (ctx));
4568
4669 return isConstrained;
4770}
@@ -72,14 +95,6 @@ bool AvailabilityContext::PlatformInfo::constrainUnavailability(
7295 return true ;
7396}
7497
75- bool AvailabilityContext::PlatformInfo::constrainDeprecated (bool deprecated) {
76- if (IsDeprecated || !deprecated)
77- return false ;
78-
79- IsDeprecated = true ;
80- return true ;
81- }
82-
8398bool AvailabilityContext::PlatformInfo::isContainedIn (
8499 const PlatformInfo &other) const {
85100 if (!Range.isContainedIn (other.Range ))
@@ -94,6 +109,9 @@ bool AvailabilityContext::PlatformInfo::isContainedIn(
94109 inheritsAvailabilityFromPlatform (UnavailablePlatform,
95110 other.UnavailablePlatform ))
96111 return false ;
112+
113+ if (IsUnavailableInEmbedded && !other.IsUnavailableInEmbedded )
114+ return false ;
97115 }
98116
99117 if (!IsDeprecated && other.IsDeprecated )
@@ -110,6 +128,7 @@ AvailabilityContext AvailabilityContext::getDefault(ASTContext &ctx) {
110128 PlatformInfo platformInfo{AvailabilityRange::forInliningTarget (ctx),
111129 PlatformKind::none,
112130 /* IsUnavailable*/ false ,
131+ /* IsUnavailableInEmbedded*/ false ,
113132 /* IsDeprecated*/ false };
114133 return AvailabilityContext (Storage::get (platformInfo, ctx));
115134}
@@ -122,7 +141,8 @@ AvailabilityContext::get(const AvailabilityRange &platformAvailability,
122141 unavailablePlatform.has_value ()
123142 ? *unavailablePlatform
124143 : PlatformKind::none,
125- unavailablePlatform.has_value (), deprecated};
144+ unavailablePlatform.has_value (),
145+ /* IsUnavailableInEmbedded*/ false , deprecated};
126146 return AvailabilityContext (Storage::get (platformInfo, ctx));
127147}
128148
@@ -137,6 +157,10 @@ AvailabilityContext::getUnavailablePlatformKind() const {
137157 return std::nullopt ;
138158}
139159
160+ bool AvailabilityContext::isUnavailableInEmbedded () const {
161+ return Info->Platform .IsUnavailableInEmbedded ;
162+ }
163+
140164bool AvailabilityContext::isDeprecated () const {
141165 return Info->Platform .IsDeprecated ;
142166}
@@ -156,7 +180,7 @@ void AvailabilityContext::constrainWithDecl(const Decl *decl) {
156180void AvailabilityContext::constrainWithPlatformRange (
157181 const AvailabilityRange &platformRange, ASTContext &ctx) {
158182 PlatformInfo platformAvailability{Info->Platform };
159- if (!platformAvailability. constrainRange (platformRange))
183+ if (!constrainRange (platformAvailability. Range , platformRange))
160184 return ;
161185
162186 Info = Storage::get (platformAvailability, ctx);
@@ -167,7 +191,7 @@ void AvailabilityContext::constrainWithDeclAndPlatformRange(
167191 PlatformInfo platformAvailability{Info->Platform };
168192 bool isConstrained = false ;
169193 isConstrained |= platformAvailability.constrainWith (decl);
170- isConstrained |= platformAvailability. constrainRange (platformRange);
194+ isConstrained |= constrainRange (platformAvailability. Range , platformRange);
171195
172196 if (!isConstrained)
173197 return ;
0 commit comments