3838using namespace swift ;
3939
4040ExportContext::ExportContext (DeclContext *DC, FragileFunctionKind kind,
41- bool spi, bool exported, bool implicit,
42- bool deprecated )
41+ bool spi, bool exported, bool implicit, bool deprecated,
42+ Optional<PlatformKind> unavailablePlatformKind )
4343 : DC(DC), FragileKind(kind) {
4444 SPI = spi;
4545 Exported = exported;
4646 Implicit = implicit;
4747 Deprecated = deprecated;
48- Reason = ExportabilityReason::General;
48+ if (unavailablePlatformKind) {
49+ Unavailable = 1 ;
50+ Platform = unsigned (*unavailablePlatformKind);
51+ } else {
52+ Unavailable = 0 ;
53+ Platform = 0 ;
54+ }
55+
56+ Reason = unsigned (ExportabilityReason::General);
4957}
5058
5159bool swift::isExported (const ValueDecl *VD) {
@@ -141,28 +149,39 @@ static void forEachOuterDecl(DeclContext *DC, Fn fn) {
141149}
142150
143151static void computeExportContextBits (Decl *D,
144- bool *implicit, bool *deprecated) {
152+ bool *implicit, bool *deprecated,
153+ Optional<PlatformKind> *unavailablePlatformKind) {
145154 if (D->isImplicit ())
146155 *implicit = true ;
147156
148- if (D->getAttrs ().getDeprecated (D->getASTContext ()))
157+ auto &Ctx = D->getASTContext ();
158+
159+ if (D->getAttrs ().getDeprecated (Ctx))
149160 *deprecated = true ;
150161
162+ if (auto *A = D->getAttrs ().getUnavailable (Ctx)) {
163+ *unavailablePlatformKind = A->Platform ;
164+ }
165+
151166 if (auto *PBD = dyn_cast<PatternBindingDecl>(D)) {
152167 for (unsigned i = 0 , e = PBD->getNumPatternEntries (); i < e; ++i) {
153168 if (auto *VD = PBD->getAnchoringVarDecl (i))
154- computeExportContextBits (VD, implicit, deprecated);
169+ computeExportContextBits (VD, implicit, deprecated,
170+ unavailablePlatformKind);
155171 }
156172 }
157173}
158174
159175ExportContext ExportContext::forDeclSignature (Decl *D) {
160176 bool implicit = false ;
161177 bool deprecated = false ;
162- computeExportContextBits (D, &implicit, &deprecated);
178+ Optional<PlatformKind> unavailablePlatformKind;
179+ computeExportContextBits (D, &implicit, &deprecated,
180+ &unavailablePlatformKind);
163181 forEachOuterDecl (D->getDeclContext (),
164182 [&](Decl *D) {
165- computeExportContextBits (D, &implicit, &deprecated);
183+ computeExportContextBits (D, &implicit, &deprecated,
184+ &unavailablePlatformKind);
166185 });
167186
168187 auto *DC = D->getInnermostDeclContext ();
@@ -182,15 +201,18 @@ ExportContext ExportContext::forDeclSignature(Decl *D) {
182201
183202 bool exported = ::isExported (D);
184203
185- return ExportContext (DC, fragileKind, spi, exported, implicit, deprecated);
204+ return ExportContext (DC, fragileKind, spi, exported, implicit, deprecated,
205+ unavailablePlatformKind);
186206}
187207
188208ExportContext ExportContext::forFunctionBody (DeclContext *DC) {
189209 bool implicit = false ;
190210 bool deprecated = false ;
211+ Optional<PlatformKind> unavailablePlatformKind;
191212 forEachOuterDecl (DC,
192213 [&](Decl *D) {
193- computeExportContextBits (D, &implicit, &deprecated);
214+ computeExportContextBits (D, &implicit, &deprecated,
215+ &unavailablePlatformKind);
194216 });
195217
196218 auto fragileKind = DC->getFragileFunctionKind ();
@@ -204,12 +226,13 @@ ExportContext ExportContext::forFunctionBody(DeclContext *DC) {
204226 assert (fragileKind.kind == FragileFunctionKind::None);
205227 }
206228
207- return ExportContext (DC, fragileKind, spi, exported, implicit, deprecated);
229+ return ExportContext (DC, fragileKind, spi, exported, implicit, deprecated,
230+ unavailablePlatformKind);
208231}
209232
210233ExportContext ExportContext::withReason (ExportabilityReason reason) const {
211234 auto copy = *this ;
212- copy.Reason = reason;
235+ copy.Reason = unsigned ( reason) ;
213236 return copy;
214237}
215238
@@ -219,13 +242,19 @@ ExportContext ExportContext::withExported(bool exported) const {
219242 return copy;
220243}
221244
245+ Optional<PlatformKind> ExportContext::getUnavailablePlatformKind () const {
246+ if (Unavailable)
247+ return PlatformKind (Platform);
248+ return None;
249+ }
250+
222251bool ExportContext::mustOnlyReferenceExportedDecls () const {
223252 return Exported || FragileKind.kind != FragileFunctionKind::None;
224253}
225254
226255Optional<ExportabilityReason> ExportContext::getExportabilityReason () const {
227256 if (Exported)
228- return Reason;
257+ return ExportabilityReason ( Reason) ;
229258 return None;
230259}
231260
@@ -1644,62 +1673,15 @@ const AvailableAttr *TypeChecker::getDeprecated(const Decl *D) {
16441673 return nullptr ;
16451674}
16461675
1647- // / Returns true if some declaration lexically enclosing the reference
1648- // / matches the passed in predicate and false otherwise.
1649- static bool
1650- someEnclosingDeclMatches (SourceRange ReferenceRange,
1651- const DeclContext *ReferenceDC,
1652- llvm::function_ref<bool (const Decl *)> Pred) {
1653- // Climb the DeclContext hierarchy to see if any of the containing
1654- // declarations matches the predicate.
1655- const DeclContext *DC = ReferenceDC;
1656- while (true ) {
1657- auto *D = DC->getInnermostDeclarationDeclContext ();
1658- if (!D)
1659- break ;
1660-
1661- if (Pred (D)) {
1662- return true ;
1663- }
1664-
1665- // If we are in an accessor, check to see if the associated
1666- // property matches the predicate.
1667- if (auto accessor = dyn_cast<AccessorDecl>(D)) {
1668- if (Pred (accessor->getStorage ()))
1669- return true ;
1670- }
1671-
1672- DC = D->getDeclContext ();
1673- }
1674-
1675- // Search the AST starting from our innermost declaration context to see if
1676- // if the reference is inside a property declaration but not inside an
1677- // accessor (this can happen for the TypeRepr for the declared type of a
1678- // property, for example).
1679- // We can't rely on the DeclContext hierarchy climb above because properties
1680- // do not introduce a new DeclContext.
1681-
1682- // Don't search for a containing declaration if we don't have a source range.
1683- if (ReferenceRange.isInvalid ())
1684- return false ;
1685-
1686- ASTContext &Ctx = ReferenceDC->getASTContext ();
1687- const Decl *DeclToSearch =
1688- findContainingDeclaration (ReferenceRange, ReferenceDC, Ctx.SourceMgr );
1689-
1690- // We may not be able to find a declaration to search if the ReferenceRange
1691- // isn't useful (i.e., we are in synthesized code).
1692- if (!DeclToSearch)
1693- return false ;
1694-
1695- return Pred (abstractSyntaxDeclForAvailableAttribute (DeclToSearch));
1696- }
1697-
16981676// / Returns true if the reference or any of its parents is an
16991677// / unconditional unavailable declaration for the same platform.
17001678static bool isInsideCompatibleUnavailableDeclaration (
1701- const ValueDecl *referencedD, SourceRange ReferenceRange,
1702- const DeclContext *ReferenceDC, const AvailableAttr *attr) {
1679+ const ValueDecl *D, ExportContext where,
1680+ const AvailableAttr *attr) {
1681+ auto referencedPlatform = where.getUnavailablePlatformKind ();
1682+ if (!referencedPlatform)
1683+ return false ;
1684+
17031685 if (!attr->isUnconditionallyUnavailable ()) {
17041686 return false ;
17051687 }
@@ -1708,20 +1690,13 @@ static bool isInsideCompatibleUnavailableDeclaration(
17081690 // but allow the use of types.
17091691 PlatformKind platform = attr->Platform ;
17101692 if (platform == PlatformKind::none &&
1711- !isa<TypeDecl>(referencedD )) {
1693+ !isa<TypeDecl>(D )) {
17121694 return false ;
17131695 }
17141696
1715- auto IsUnavailable = [platform](const Decl *D) {
1716- auto EnclosingUnavailable =
1717- D->getAttrs ().getUnavailable (D->getASTContext ());
1718- return EnclosingUnavailable &&
1719- (EnclosingUnavailable->Platform == platform ||
1720- inheritsAvailabilityFromPlatform (platform,
1721- EnclosingUnavailable->Platform ));
1722- };
1723-
1724- return someEnclosingDeclMatches (ReferenceRange, ReferenceDC, IsUnavailable);
1697+ return (*referencedPlatform == platform ||
1698+ inheritsAvailabilityFromPlatform (platform,
1699+ *referencedPlatform));
17251700}
17261701
17271702static void fixItAvailableAttrRename (InFlightDiagnostic &diag,
@@ -2201,8 +2176,8 @@ void swift::diagnoseUnavailableOverride(ValueDecl *override,
22012176 return ;
22022177 }
22032178
2204- diagnoseExplicitUnavailability (base, override -> getLoc (),
2205- override ->getDeclContext () ,
2179+ ExportContext where = ExportContext::forDeclSignature ( override );
2180+ diagnoseExplicitUnavailability (base, override ->getLoc (), where ,
22062181 /* Flags*/ None,
22072182 [&](InFlightDiagnostic &diag) {
22082183 ParsedDeclName parsedName = parseDeclName (attr->Rename );
@@ -2235,10 +2210,10 @@ void swift::diagnoseUnavailableOverride(ValueDecl *override,
22352210// / marked as unavailable, either through "unavailable" or "obsoleted:".
22362211bool swift::diagnoseExplicitUnavailability (const ValueDecl *D,
22372212 SourceRange R,
2238- const DeclContext *DC ,
2213+ ExportContext Where ,
22392214 const ApplyExpr *call,
22402215 DeclAvailabilityFlags Flags) {
2241- return diagnoseExplicitUnavailability (D, R, DC , Flags,
2216+ return diagnoseExplicitUnavailability (D, R, Where , Flags,
22422217 [=](InFlightDiagnostic &diag) {
22432218 fixItAvailableAttrRename (diag, R, D, AvailableAttr::isUnavailable (D),
22442219 call);
@@ -2309,7 +2284,7 @@ bool isSubscriptReturningString(const ValueDecl *D, ASTContext &Context) {
23092284bool swift::diagnoseExplicitUnavailability (
23102285 const ValueDecl *D,
23112286 SourceRange R,
2312- const DeclContext *DC ,
2287+ ExportContext Where ,
23132288 DeclAvailabilityFlags Flags,
23142289 llvm::function_ref<void (InFlightDiagnostic &)> attachRenameFixIts) {
23152290 auto *Attr = AvailableAttr::isUnavailable (D);
@@ -2320,9 +2295,8 @@ bool swift::diagnoseExplicitUnavailability(
23202295 // unavailability is OK -- the eventual caller can't call the
23212296 // enclosing code in the same situations it wouldn't be able to
23222297 // call this code.
2323- if (isInsideCompatibleUnavailableDeclaration (D, R, DC, Attr)) {
2298+ if (isInsideCompatibleUnavailableDeclaration (D, Where, Attr))
23242299 return false ;
2325- }
23262300
23272301 SourceLoc Loc = R.Start ;
23282302 DeclName Name;
@@ -2776,9 +2750,7 @@ AvailabilityWalker::diagAvailability(ConcreteDeclRef declRef, SourceRange R,
27762750 }
27772751 }
27782752
2779- auto *DC = Where.getDeclContext ();
2780-
2781- if (diagnoseExplicitUnavailability (D, R, DC, call, Flags))
2753+ if (diagnoseExplicitUnavailability (D, R, Where, call, Flags))
27822754 return true ;
27832755
27842756 // Make sure not to diagnose an accessor's deprecation if we already
@@ -2794,6 +2766,8 @@ AvailabilityWalker::diagAvailability(ConcreteDeclRef declRef, SourceRange R,
27942766 && isa<ProtocolDecl>(D))
27952767 return false ;
27962768
2769+ auto *DC = Where.getDeclContext ();
2770+
27972771 // Diagnose (and possibly signal) for potential unavailability
27982772 auto maybeUnavail = TypeChecker::checkDeclarationAvailability (D, R.Start , DC);
27992773 if (maybeUnavail.hasValue ()) {
0 commit comments