diff options
-rw-r--r-- | clang/include/clang/AST/DeclObjC.h | 23 | ||||
-rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 23 |
3 files changed, 42 insertions, 20 deletions
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index 2e760d658e4..eebed07aa9a 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -1141,15 +1141,18 @@ public: // Lookup a method. First, we search locally. If a method isn't // found, we search referenced protocols and class categories. ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance, - bool shallowCategoryLookup= false, - const ObjCCategoryDecl *C= 0) const; - ObjCMethodDecl *lookupInstanceMethod(Selector Sel, - bool shallowCategoryLookup = false) const { - return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup); + bool shallowCategoryLookup = false, + bool followSuper = true, + const ObjCCategoryDecl *C = 0) const; + + /// Lookup an instance method for a given selector. + ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const { + return lookupMethod(Sel, true/*isInstance*/); } - ObjCMethodDecl *lookupClassMethod(Selector Sel, - bool shallowCategoryLookup = false) const { - return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup); + + /// Lookup a class method for a given selector. + ObjCMethodDecl *lookupClassMethod(Selector Sel) const { + return lookupMethod(Sel, false/*isInstance*/); } ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName); @@ -1167,7 +1170,9 @@ public: ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel, const ObjCCategoryDecl *Cat) const { return lookupMethod(Sel, true/*isInstance*/, - false/*shallowCategoryLookup*/, Cat); + false/*shallowCategoryLookup*/, + true /* followsSuper */, + Cat); } SourceLocation getEndOfDefinitionLoc() const { diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 28a651429c9..ca87bb8197f 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -457,9 +457,11 @@ ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) { /// When argument category "C" is specified, any implicit method found /// in this category is ignored. ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, - bool isInstance, - bool shallowCategoryLookup, - const ObjCCategoryDecl *C) const { + bool isInstance, + bool shallowCategoryLookup, + bool followSuper, + const ObjCCategoryDecl *C) const +{ // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) return 0; @@ -470,7 +472,7 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, if (data().ExternallyCompleted) LoadExternalDefinition(); - while (ClassDecl != NULL) { + while (ClassDecl) { if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance))) return MethodDecl; @@ -501,7 +503,11 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, return MethodDecl; } } - + + if (!followSuper) + return NULL; + + // Get the super class (if any). ClassDecl = ClassDecl->getSuperClass(); } return NULL; diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 08556961109..95e3b4f4669 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1664,7 +1664,10 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc, if (method->getImplementationControl() != ObjCMethodDecl::Optional && !method->isPropertyAccessor() && !InsMap.count(method->getSelector()) && - (!Super || !Super->lookupInstanceMethod(method->getSelector()))) { + (!Super || !Super->lookupMethod(method->getSelector(), + true /* instance */, + false /* shallowCategory */, + true /* followsSuper */))) { // If a method is not implemented in the category implementation but // has been declared in its primary class, superclass, // or in one of their protocols, no need to issue the warning. @@ -1675,8 +1678,10 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc, // have been synthesized due to a property declared in the class which // uses the protocol. if (ObjCMethodDecl *MethodInClass = - IDecl->lookupInstanceMethod(method->getSelector(), - true /*shallowCategoryLookup*/)) + IDecl->lookupMethod(method->getSelector(), + true /* instance */, + true /* shallowCategoryLookup */, + false /* followSuper */)) if (C || MethodInClass->isPropertyAccessor()) continue; unsigned DIAG = diag::warn_unimplemented_protocol_method; @@ -1695,11 +1700,17 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc, ObjCMethodDecl *method = *I; if (method->getImplementationControl() != ObjCMethodDecl::Optional && !ClsMap.count(method->getSelector()) && - (!Super || !Super->lookupClassMethod(method->getSelector()))) { + (!Super || !Super->lookupMethod(method->getSelector(), + false /* class method */, + false /* shallowCategoryLookup */, + true /* followSuper */))) { // See above comment for instance method lookups. - if (C && IDecl->lookupClassMethod(method->getSelector(), - true /*shallowCategoryLookup*/)) + if (C && IDecl->lookupMethod(method->getSelector(), + false /* class */, + true /* shallowCategoryLookup */, + false /* followSuper */)) continue; + unsigned DIAG = diag::warn_unimplemented_protocol_method; if (Diags.getDiagnosticLevel(DIAG, ImpLoc) != DiagnosticsEngine::Ignored) { |