From 2fb325091a8e9d790e17bdab8db240262b3ebfd9 Mon Sep 17 00:00:00 2001 From: Manman Ren Date: Wed, 18 May 2016 18:12:34 +0000 Subject: ObjectiveC Class Properties: warn if a class property accessor is mistakenly an instance method. When diagnosing unimplemented class property, make sure we emit a warning when we only see an instance method with the right selector. Also warn when we only see a class method for an instance property. rdar://26141719 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@269968 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaObjCProperty.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'lib/Sema/SemaObjCProperty.cpp') diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index 1bf88f4e93..f9c495d641 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -1763,19 +1763,23 @@ void Sema::DefaultSynthesizeProperties(Scope *S, Decl *D) { DefaultSynthesizeProperties(S, IC, IDecl); } -static void DiagnoseUnimplementedAccessor(Sema &S, - ObjCInterfaceDecl *PrimaryClass, - Selector Method, - ObjCImplDecl* IMPDecl, - ObjCContainerDecl *CDecl, - ObjCCategoryDecl *C, - ObjCPropertyDecl *Prop, - Sema::SelectorSet &SMap) { +static void DiagnoseUnimplementedAccessor( + Sema &S, ObjCInterfaceDecl *PrimaryClass, Selector Method, + ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, ObjCCategoryDecl *C, + ObjCPropertyDecl *Prop, + llvm::SmallPtrSet &SMap) { + // Check to see if we have a corresponding selector in SMap and with the + // right method type. + auto I = std::find_if(SMap.begin(), SMap.end(), + [&](const ObjCMethodDecl *x) { + return x->getSelector() == Method && + x->isClassMethod() == Prop->isClassProperty(); + }); // When reporting on missing property setter/getter implementation in // categories, do not report when they are declared in primary class, // class's protocol, or one of it super classes. This is because, // the class is going to implement them. - if (!SMap.count(Method) && + if (I == SMap.end() && (PrimaryClass == nullptr || !PrimaryClass->lookupPropertyAccessor(Method, C, Prop->isClassProperty()))) { @@ -1867,10 +1871,10 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, for (const auto *I : IMPDecl->property_impls()) PropImplMap.insert(I->getPropertyDecl()); - SelectorSet InsMap; + llvm::SmallPtrSet InsMap; // Collect property accessors implemented in current implementation. for (const auto *I : IMPDecl->methods()) - InsMap.insert(I->getSelector()); + InsMap.insert(I); ObjCCategoryDecl *C = dyn_cast(CDecl); ObjCInterfaceDecl *PrimaryClass = nullptr; @@ -1882,7 +1886,7 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, // setter/getter is implemented in category's primary class // implementation. for (const auto *I : IMP->methods()) - InsMap.insert(I->getSelector()); + InsMap.insert(I); } for (ObjCContainerDecl::PropertyMap::iterator -- cgit v1.2.1