@@ -1921,21 +1921,8 @@ void TypeChecker::diagnosePotentialAccessorUnavailability(
1921
1921
Reason.getRequiredOSVersionRange (), *this );
1922
1922
}
1923
1923
1924
- bool TypeChecker::isInsideImplicitFunction (const DeclContext *DC) {
1925
- do {
1926
- auto *AFD = dyn_cast<AbstractFunctionDecl>(DC);
1927
- if (AFD && AFD->isImplicit ()) {
1928
- return true ;
1929
- }
1930
-
1931
- DC = DC->getParent ();
1932
- } while (DC);
1933
-
1934
- return false ;
1935
- }
1936
-
1937
1924
const AvailabilityAttr *TypeChecker::getDeprecated (const Decl *D) {
1938
- if (auto *Attr = D->getAttrs ().getDeprecated (Context ))
1925
+ if (auto *Attr = D->getAttrs ().getDeprecated (D-> getASTContext () ))
1939
1926
return Attr;
1940
1927
1941
1928
// Treat extensions methods as deprecated if their extension
@@ -1948,37 +1935,36 @@ const AvailabilityAttr *TypeChecker::getDeprecated(const Decl *D) {
1948
1935
return nullptr ;
1949
1936
}
1950
1937
1951
- // / Returns true if the reference is lexically contained in a declaration
1952
- // / that is deprecated on all deployment targets.
1953
- static bool isInsideDeprecatedDeclaration (SourceRange ReferenceRange,
1954
- const DeclContext *ReferenceDC,
1955
- TypeChecker &TC) {
1938
+ // / Returns true if some declaration lexically enclosing the reference
1939
+ // / matches the passed in predicate and false otherwise.
1940
+ static bool someEnclosingDeclMatches (SourceRange ReferenceRange,
1941
+ const DeclContext *ReferenceDC,
1942
+ TypeChecker &TC,
1943
+ std::function<bool (const Decl *)> Pred) {
1956
1944
ASTContext &Ctx = TC.Context ;
1957
1945
1958
1946
// Climb the DeclContext hierarchy to see if any of the containing
1959
- // declarations are deprecated on on all deployment targets .
1947
+ // declarations matches the predicate .
1960
1948
const DeclContext *DC = ReferenceDC;
1961
1949
do {
1962
1950
auto *D = DC->getInnermostDeclarationDeclContext ();
1963
1951
if (!D)
1964
1952
break ;
1965
1953
1966
- if (D-> getAttrs (). getDeprecated (Ctx )) {
1954
+ if (Pred (D )) {
1967
1955
return true ;
1968
1956
}
1969
1957
1970
1958
// If we are in an accessor, check to see if the associated
1971
- // property is deprecated .
1959
+ // property is matches the predicate .
1972
1960
auto *FD = dyn_cast<FuncDecl>(D);
1973
- if (FD && FD->isAccessor () &&
1974
- TC.getDeprecated (FD->getAccessorStorageDecl ())) {
1961
+ if (FD && FD->isAccessor () && Pred (FD->getAccessorStorageDecl ())) {
1975
1962
return true ;
1976
1963
}
1977
1964
1978
1965
DC = DC->getParent ();
1979
1966
} while (DC);
1980
1967
1981
-
1982
1968
// Search the AST starting from our innermost declaration context to see if
1983
1969
// if the reference is inside a property declaration but not inside an
1984
1970
// accessor (this can happen for the TypeRepr for the declared type of a
@@ -1991,8 +1977,12 @@ static bool isInsideDeprecatedDeclaration(SourceRange ReferenceRange,
1991
1977
if (!ReferenceDC->isTypeContext () && !ReferenceDC->isModuleScopeContext ())
1992
1978
return false ;
1993
1979
1980
+ // Don't search for a containing declaration if we don't have a source range.
1981
+ if (ReferenceRange.isInvalid ())
1982
+ return false ;
1983
+
1994
1984
const Decl *DeclToSearch =
1995
- findContainingDeclaration (ReferenceRange, ReferenceDC, Ctx.SourceMgr );
1985
+ findContainingDeclaration (ReferenceRange, ReferenceDC, Ctx.SourceMgr );
1996
1986
1997
1987
// We may not be able to find a declaration to search if the ReferenceRange
1998
1988
// is invalid (i.e., we are in synthesized code).
@@ -2011,14 +2001,38 @@ static bool isInsideDeprecatedDeclaration(SourceRange ReferenceRange,
2011
2001
if (FoundDeclarationNode.hasValue ()) {
2012
2002
const Decl *D = FoundDeclarationNode.getValue ().get <Decl *>();
2013
2003
D = abstractSyntaxDeclForAvailabilityAttribute (D);
2014
- if (TC. getDeprecated (D)) {
2004
+ if (Pred (D)) {
2015
2005
return true ;
2016
2006
}
2017
2007
}
2018
2008
2019
2009
return false ;
2020
2010
}
2021
2011
2012
+ bool TypeChecker::isInsideImplicitFunction (SourceRange ReferenceRange,
2013
+ const DeclContext *DC) {
2014
+ std::function<bool (const Decl *)> IsInsideImplicitFunc = [](const Decl *D) {
2015
+ auto *AFD = dyn_cast<AbstractFunctionDecl>(D);
2016
+ return AFD && AFD->isImplicit ();
2017
+ };
2018
+
2019
+ return someEnclosingDeclMatches (ReferenceRange, DC, *this ,
2020
+ IsInsideImplicitFunc);
2021
+ }
2022
+
2023
+ // / Returns true if the reference is lexically contained in a declaration
2024
+ // / that is deprecated on all deployment targets.
2025
+ static bool isInsideDeprecatedDeclaration (SourceRange ReferenceRange,
2026
+ const DeclContext *ReferenceDC,
2027
+ TypeChecker &TC) {
2028
+ std::function<bool (const Decl *)> IsDeprecated = [](const Decl *D) {
2029
+ return D->getAttrs ().getDeprecated (D->getASTContext ());
2030
+ };
2031
+
2032
+ return someEnclosingDeclMatches (ReferenceRange, ReferenceDC, TC,
2033
+ IsDeprecated);
2034
+ }
2035
+
2022
2036
void TypeChecker::diagnoseDeprecated (SourceRange ReferenceRange,
2023
2037
const DeclContext *ReferenceDC,
2024
2038
const AvailabilityAttr *Attr,
@@ -2035,7 +2049,7 @@ void TypeChecker::diagnoseDeprecated(SourceRange ReferenceRange,
2035
2049
// a deprecated API element. rdar://problem/20024980 tracks these
2036
2050
// special-case diagnostics.
2037
2051
if (!getLangOpts ().EnableAvailabilityCheckingInImplicitFunctions &&
2038
- isInsideImplicitFunction (ReferenceDC)) {
2052
+ isInsideImplicitFunction (ReferenceRange, ReferenceDC)) {
2039
2053
return ;
2040
2054
}
2041
2055
0 commit comments