diff options
Diffstat (limited to 'lib/Sema/SemaDeclObjC.cpp')
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 58 |
1 files changed, 37 insertions, 21 deletions
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 778b8062f68c..967573011d0d 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -248,19 +248,41 @@ bool Sema::CheckARCMethodDecl(ObjCMethodDecl *method) { return false; } -static void DiagnoseObjCImplementedDeprecations(Sema &S, - NamedDecl *ND, - SourceLocation ImplLoc, - int select) { - if (ND && ND->isDeprecated()) { - S.Diag(ImplLoc, diag::warn_deprecated_def) << select; - if (select == 0) +static void DiagnoseObjCImplementedDeprecations(Sema &S, const NamedDecl *ND, + SourceLocation ImplLoc) { + if (!ND) + return; + bool IsCategory = false; + AvailabilityResult Availability = ND->getAvailability(); + if (Availability != AR_Deprecated) { + if (isa<ObjCMethodDecl>(ND)) { + if (Availability != AR_Unavailable) + return; + // Warn about implementing unavailable methods. + S.Diag(ImplLoc, diag::warn_unavailable_def); S.Diag(ND->getLocation(), diag::note_method_declared_at) - << ND->getDeclName(); - else - S.Diag(ND->getLocation(), diag::note_previous_decl) - << (isa<ObjCCategoryDecl>(ND) ? "category" : "class"); + << ND->getDeclName(); + return; + } + if (const auto *CD = dyn_cast<ObjCCategoryDecl>(ND)) { + if (!CD->getClassInterface()->isDeprecated()) + return; + ND = CD->getClassInterface(); + IsCategory = true; + } else + return; } + S.Diag(ImplLoc, diag::warn_deprecated_def) + << (isa<ObjCMethodDecl>(ND) + ? /*Method*/ 0 + : isa<ObjCCategoryDecl>(ND) || IsCategory ? /*Category*/ 2 + : /*Class*/ 1); + if (isa<ObjCMethodDecl>(ND)) + S.Diag(ND->getLocation(), diag::note_method_declared_at) + << ND->getDeclName(); + else + S.Diag(ND->getLocation(), diag::note_previous_decl) + << (isa<ObjCCategoryDecl>(ND) ? "category" : "class"); } /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global @@ -385,9 +407,7 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { // No need to issue deprecated warning if deprecated mehod in class/category // is being implemented in its own implementation (no overriding is involved). if (!ImplDeclOfMethodDecl || ImplDeclOfMethodDecl != ImplDeclOfMethodDef) - DiagnoseObjCImplementedDeprecations(*this, - dyn_cast<NamedDecl>(IMD), - MDecl->getLocation(), 0); + DiagnoseObjCImplementedDeprecations(*this, IMD, MDecl->getLocation()); } if (MDecl->getMethodFamily() == OMF_init) { @@ -1873,10 +1893,8 @@ Decl *Sema::ActOnStartCategoryImplementation( CatIDecl->setImplementation(CDecl); // Warn on implementating category of deprecated class under // -Wdeprecated-implementations flag. - DiagnoseObjCImplementedDeprecations( - *this, - CatIDecl->isDeprecated() ? CatIDecl : dyn_cast<NamedDecl>(IDecl), - CDecl->getLocation(), 2); + DiagnoseObjCImplementedDeprecations(*this, CatIDecl, + CDecl->getLocation()); } } @@ -1996,9 +2014,7 @@ Decl *Sema::ActOnStartClassImplementation( PushOnScopeChains(IMPDecl, TUScope); // Warn on implementating deprecated class under // -Wdeprecated-implementations flag. - DiagnoseObjCImplementedDeprecations(*this, - dyn_cast<NamedDecl>(IDecl), - IMPDecl->getLocation(), 1); + DiagnoseObjCImplementedDeprecations(*this, IDecl, IMPDecl->getLocation()); } // If the superclass has the objc_runtime_visible attribute, we |