3838using namespace swift ;
3939
4040ExportContext::ExportContext (DeclContext *DC, FragileFunctionKind kind,
41- bool spi, bool exported)
41+ bool spi, bool exported, bool deprecated )
4242 : DC(DC), FragileKind(kind) {
4343 SPI = spi;
4444 Exported = exported;
45+ Deprecated = deprecated;
4546 Reason = ExportabilityReason::General;
4647}
4748
@@ -95,7 +96,73 @@ bool swift::isExported(const Decl *D) {
9596 return true ;
9697}
9798
99+ template <typename Fn>
100+ static void forEachOuterDecl (DeclContext *DC, Fn fn) {
101+ for (; !DC->isModuleScopeContext (); DC = DC->getParent ()) {
102+ switch (DC->getContextKind ()) {
103+ case DeclContextKind::AbstractClosureExpr:
104+ case DeclContextKind::TopLevelCodeDecl:
105+ case DeclContextKind::SerializedLocal:
106+ case DeclContextKind::Module:
107+ case DeclContextKind::FileUnit:
108+ break ;
109+
110+ case DeclContextKind::Initializer:
111+ if (auto *PBI = dyn_cast<PatternBindingInitializer>(DC))
112+ fn (PBI->getBinding ());
113+ break ;
114+
115+ case DeclContextKind::SubscriptDecl:
116+ fn (cast<SubscriptDecl>(DC));
117+ break ;
118+
119+ case DeclContextKind::EnumElementDecl:
120+ fn (cast<EnumElementDecl>(DC));
121+ break ;
122+
123+ case DeclContextKind::AbstractFunctionDecl:
124+ fn (cast<AbstractFunctionDecl>(DC));
125+
126+ if (auto *AD = dyn_cast<AccessorDecl>(DC))
127+ fn (AD->getStorage ());
128+ break ;
129+
130+ case DeclContextKind::GenericTypeDecl:
131+ fn (cast<GenericTypeDecl>(DC));
132+ break ;
133+
134+ case DeclContextKind::ExtensionDecl:
135+ fn (cast<ExtensionDecl>(DC));
136+ break ;
137+ }
138+ }
139+ }
140+
141+ static void computeExportContextBits (Decl *D,
142+ bool *implicit, bool *deprecated) {
143+ if (D->isImplicit ())
144+ *implicit = true ;
145+
146+ if (D->getAttrs ().getDeprecated (D->getASTContext ()))
147+ *deprecated = true ;
148+
149+ if (auto *PBD = dyn_cast<PatternBindingDecl>(D)) {
150+ for (unsigned i = 0 , e = PBD->getNumPatternEntries (); i < e; ++i) {
151+ if (auto *VD = PBD->getAnchoringVarDecl (i))
152+ computeExportContextBits (VD, implicit, deprecated);
153+ }
154+ }
155+ }
156+
98157ExportContext ExportContext::forDeclSignature (Decl *D) {
158+ bool implicit = false ;
159+ bool deprecated = false ;
160+ computeExportContextBits (D, &implicit, &deprecated);
161+ forEachOuterDecl (D->getDeclContext (),
162+ [&](Decl *D) {
163+ computeExportContextBits (D, &implicit, &deprecated);
164+ });
165+
99166 auto *DC = D->getInnermostDeclContext ();
100167 auto fragileKind = DC->getFragileFunctionKind ();
101168
@@ -113,11 +180,19 @@ ExportContext ExportContext::forDeclSignature(Decl *D) {
113180
114181 bool exported = ::isExported (D);
115182
116- return ExportContext (DC, fragileKind, spi, exported);
183+ return ExportContext (DC, fragileKind, spi, exported, deprecated );
117184}
118185
119186ExportContext ExportContext::forFunctionBody (DeclContext *DC) {
120- ;
187+ assert (DC && " Use ExportContext::forImplicit() for implicit decls" );
188+
189+ bool implicit = false ;
190+ bool deprecated = false ;
191+ forEachOuterDecl (DC,
192+ [&](Decl *D) {
193+ computeExportContextBits (D, &implicit, &deprecated);
194+ });
195+
121196 auto fragileKind = DC->getFragileFunctionKind ();
122197
123198 bool spi = false ;
@@ -129,16 +204,21 @@ ExportContext ExportContext::forFunctionBody(DeclContext *DC) {
129204 assert (fragileKind.kind == FragileFunctionKind::None);
130205 }
131206
132- return ExportContext (DC, fragileKind, spi, exported);
207+ return ExportContext (DC, fragileKind, spi, exported, deprecated);
208+ }
209+
210+ ExportContext ExportContext::forImplicit () {
211+ return ExportContext (nullptr , FragileFunctionKind (),
212+ false , false , false );
133213}
134214
135- ExportContext ExportContext::forReason (ExportabilityReason reason) const {
215+ ExportContext ExportContext::withReason (ExportabilityReason reason) const {
136216 auto copy = *this ;
137217 copy.Reason = reason;
138218 return copy;
139219}
140220
141- ExportContext ExportContext::forExported (bool exported) const {
221+ ExportContext ExportContext::withExported (bool exported) const {
142222 auto copy = *this ;
143223 copy.Exported = isExported () && exported;
144224 return copy;
@@ -1672,17 +1752,6 @@ static bool isInsideCompatibleUnavailableDeclaration(
16721752 return someEnclosingDeclMatches (ReferenceRange, ReferenceDC, IsUnavailable);
16731753}
16741754
1675- // / Returns true if the reference is lexically contained in a declaration
1676- // / that is deprecated on all deployment targets.
1677- static bool isInsideDeprecatedDeclaration (SourceRange ReferenceRange,
1678- const DeclContext *ReferenceDC){
1679- auto IsDeprecated = [](const Decl *D) {
1680- return D->getAttrs ().getDeprecated (D->getASTContext ());
1681- };
1682-
1683- return someEnclosingDeclMatches (ReferenceRange, ReferenceDC, IsDeprecated);
1684- }
1685-
16861755static void fixItAvailableAttrRename (InFlightDiagnostic &diag,
16871756 SourceRange referenceRange,
16881757 const ValueDecl *renamedDecl,
@@ -2059,13 +2128,15 @@ getAccessorKindAndNameForDiagnostics(const ValueDecl *D) {
20592128}
20602129
20612130void TypeChecker::diagnoseIfDeprecated (SourceRange ReferenceRange,
2062- const DeclContext *ReferenceDC ,
2131+ ExportContext Where ,
20632132 const ValueDecl *DeprecatedDecl,
20642133 const ApplyExpr *Call) {
20652134 const AvailableAttr *Attr = TypeChecker::getDeprecated (DeprecatedDecl);
20662135 if (!Attr)
20672136 return ;
20682137
2138+ auto *ReferenceDC = Where.getDeclContext ();
2139+
20692140 // We don't want deprecated declarations to trigger warnings
20702141 // in synthesized code.
20712142 if (ReferenceRange.isInvalid () &&
@@ -2075,7 +2146,7 @@ void TypeChecker::diagnoseIfDeprecated(SourceRange ReferenceRange,
20752146 // We match the behavior of clang to not report deprecation warnings
20762147 // inside declarations that are themselves deprecated on all deployment
20772148 // targets.
2078- if (isInsideDeprecatedDeclaration (ReferenceRange, ReferenceDC )) {
2149+ if (Where. isDeprecated ( )) {
20792150 return ;
20802151 }
20812152
@@ -2788,7 +2859,7 @@ AvailabilityWalker::diagAvailability(ConcreteDeclRef declRef, SourceRange R,
27882859
27892860 // Diagnose for deprecation
27902861 if (!isAccessorWithDeprecatedStorage)
2791- TypeChecker::diagnoseIfDeprecated (R, DC , D, call);
2862+ TypeChecker::diagnoseIfDeprecated (R, Where , D, call);
27922863
27932864 if (Flags.contains (DeclAvailabilityFlag::AllowPotentiallyUnavailable))
27942865 return false ;
0 commit comments