diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2014-08-27 20:34:29 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2014-08-27 20:34:29 +0000 |
commit | 7e3e291b333df01902ed79482c39d0f330bb60a9 (patch) | |
tree | ec70d917d49759d51c67bcdc900774440cae2bf0 | |
parent | 1d23bac843fd9f1df8473041d44af80550e436a6 (diff) | |
download | bcm5719-llvm-7e3e291b333df01902ed79482c39d0f330bb60a9.tar.gz bcm5719-llvm-7e3e291b333df01902ed79482c39d0f330bb60a9.zip |
Objective-C. Change to method lookup rules to look
into primary class's named categories before looking
into their protocols. This is because categories are
part of the public interface and , just as primary class,
preference should be given to them before class
(and category) protocols. // rdar://18013929
llvm-svn: 216610
-rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 27 | ||||
-rw-r--r-- | clang/test/SemaObjC/warn-category-method-deprecated.m | 17 |
2 files changed, 32 insertions, 12 deletions
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index e753feb3d9e..cc6560787ca 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -558,36 +558,39 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, LoadExternalDefinition(); while (ClassDecl) { + // 1. Look through primary class. if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance))) return MethodDecl; - - // Didn't find one yet - look through protocols. - for (const auto *I : ClassDecl->protocols()) - if ((MethodDecl = I->lookupMethod(Sel, isInstance))) - return MethodDecl; - // Didn't find one yet - now look through categories. - for (const auto *Cat : ClassDecl->visible_categories()) { + // 2. Didn't find one yet - now look through categories. + for (const auto *Cat : ClassDecl->visible_categories()) if ((MethodDecl = Cat->getMethod(Sel, isInstance))) if (C != Cat || !MethodDecl->isImplicit()) return MethodDecl; - if (!shallowCategoryLookup) { + // 3. Didn't find one yet - look through primary class's protocols. + for (const auto *I : ClassDecl->protocols()) + if ((MethodDecl = I->lookupMethod(Sel, isInstance))) + return MethodDecl; + + // 4. Didn't find one yet - now look through categories' protocols + if (!shallowCategoryLookup) + for (const auto *Cat : ClassDecl->visible_categories()) { // Didn't find one yet - look through protocols. const ObjCList<ObjCProtocolDecl> &Protocols = - Cat->getReferencedProtocols(); + Cat->getReferencedProtocols(); for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), E = Protocols.end(); I != E; ++I) if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance))) if (C != Cat || !MethodDecl->isImplicit()) return MethodDecl; } - } - + + if (!followSuper) return nullptr; - // Get the super class (if any). + // 5. Get to the super class (if any). ClassDecl = ClassDecl->getSuperClass(); } return nullptr; diff --git a/clang/test/SemaObjC/warn-category-method-deprecated.m b/clang/test/SemaObjC/warn-category-method-deprecated.m new file mode 100644 index 00000000000..349a27a795c --- /dev/null +++ b/clang/test/SemaObjC/warn-category-method-deprecated.m @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s +// rdar://18013929 + +@protocol P +- (void)meth; +@end + +@interface I <P> +@end + +@interface I(cat) +- (void)meth __attribute__((deprecated)); // expected-note {{'meth' has been explicitly marked deprecated here}} +@end + +void foo(I *i) { + [i meth]; // expected-warning {{'meth' is deprecated}} +} |