diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-05-01 20:07:12 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-05-01 20:07:12 +0000 |
commit | b33f3ad379f497c5fc6d0ada618745dd46d0e717 (patch) | |
tree | 4f50079861066f9933e7fc58afc0db444b391287 /lib/Sema/SemaDeclObjC.cpp | |
parent | e9146f2e9f1c4e281544e8c080934c72d41012ca (diff) |
Check for method type conflict between declaration in
class/protocol and implementation which could be
an imm. implementation or down in the inheritance
hierarchy.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70568 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclObjC.cpp')
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 122 |
1 files changed, 85 insertions, 37 deletions
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 0c98a5f44b..80b30bdb74 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -885,6 +885,79 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc, CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, IDecl); } +/// MatchAllMethodDeclarations - Check methods declaraed in interface or +/// or protocol against those declared in their implementations. +/// +void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap, + const llvm::DenseSet<Selector> &ClsMap, + llvm::DenseSet<Selector> &InsMapSeen, + llvm::DenseSet<Selector> &ClsMapSeen, + ObjCImplDecl* IMPDecl, + ObjCContainerDecl* CDecl, + bool &IncompleteImpl, + bool ImmediateClass) +{ + // Check and see if instance methods in class interface have been + // implemented in the implementation class. If so, their types match. + for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(Context), + E = CDecl->instmeth_end(Context); I != E; ++I) { + if (InsMapSeen.count((*I)->getSelector())) + continue; + InsMapSeen.insert((*I)->getSelector()); + if (!(*I)->isSynthesized() && + !InsMap.count((*I)->getSelector())) { + if (ImmediateClass) + WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl); + continue; + } + else { + ObjCMethodDecl *ImpMethodDecl = + IMPDecl->getInstanceMethod(Context, (*I)->getSelector()); + ObjCMethodDecl *IntfMethodDecl = + CDecl->getInstanceMethod(Context, (*I)->getSelector()); + assert(IntfMethodDecl && + "IntfMethodDecl is null in ImplMethodsVsClassMethods"); + // ImpMethodDecl may be null as in a @dynamic property. + if (ImpMethodDecl) + WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl); + } + } + + // Check and see if class methods in class interface have been + // implemented in the implementation class. If so, their types match. + for (ObjCInterfaceDecl::classmeth_iterator + I = CDecl->classmeth_begin(Context), + E = CDecl->classmeth_end(Context); + I != E; ++I) { + if (ClsMapSeen.count((*I)->getSelector())) + continue; + ClsMapSeen.insert((*I)->getSelector()); + if (!ClsMap.count((*I)->getSelector())) { + if (ImmediateClass) + WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl); + } + else { + ObjCMethodDecl *ImpMethodDecl = + IMPDecl->getClassMethod(Context, (*I)->getSelector()); + ObjCMethodDecl *IntfMethodDecl = + CDecl->getClassMethod(Context, (*I)->getSelector()); + WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl); + } + } + if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) { + // Check for any implementation of a methods declared in protocol. + for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(), + E = I->protocol_end(); PI != E; ++PI) + MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, + IMPDecl, + (*PI), IncompleteImpl, false); + if (I->getSuperClass()) + MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, + IMPDecl, + I->getSuperClass(), IncompleteImpl, false); + } +} + void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl, ObjCContainerDecl* CDecl, bool IncompleteImpl) { @@ -933,51 +1006,26 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl, } } - for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(Context), - E = CDecl->instmeth_end(Context); I != E; ++I) { - if (!(*I)->isSynthesized() && !InsMap.count((*I)->getSelector())) { - WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl); - continue; - } - - ObjCMethodDecl *ImpMethodDecl = - IMPDecl->getInstanceMethod(Context, (*I)->getSelector()); - ObjCMethodDecl *IntfMethodDecl = - CDecl->getInstanceMethod(Context, (*I)->getSelector()); - assert(IntfMethodDecl && - "IntfMethodDecl is null in ImplMethodsVsClassMethods"); - // ImpMethodDecl may be null as in a @dynamic property. - if (ImpMethodDecl) - WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl); - } - llvm::DenseSet<Selector> ClsMap; - // Check and see if class methods in class interface have been - // implemented in the implementation class. for (ObjCImplementationDecl::classmeth_iterator - I = IMPDecl->classmeth_begin(Context), - E = IMPDecl->classmeth_end(Context); I != E; ++I) + I = IMPDecl->classmeth_begin(Context), + E = IMPDecl->classmeth_end(Context); I != E; ++I) ClsMap.insert((*I)->getSelector()); - for (ObjCInterfaceDecl::classmeth_iterator - I = CDecl->classmeth_begin(Context), - E = CDecl->classmeth_end(Context); - I != E; ++I) - if (!ClsMap.count((*I)->getSelector())) - WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl); - else { - ObjCMethodDecl *ImpMethodDecl = - IMPDecl->getClassMethod(Context, (*I)->getSelector()); - ObjCMethodDecl *IntfMethodDecl = - CDecl->getClassMethod(Context, (*I)->getSelector()); - WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl); - } - + // Check for type conflict of methods declared in a class/protocol and + // its implementation; if any. + llvm::DenseSet<Selector> InsMapSeen, ClsMapSeen; + MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, + IMPDecl, CDecl, + IncompleteImpl, true); // Check the protocol list for unimplemented methods in the @implementation // class. + // Check and see if class methods in class interface have been + // implemented in the implementation class. + if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) { - for (ObjCCategoryDecl::protocol_iterator PI = I->protocol_begin(), + for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(), E = I->protocol_end(); PI != E; ++PI) CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl, InsMap, ClsMap, I); |