diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-04-07 18:28:06 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-04-07 18:28:06 +0000 |
commit | ef79bc9b079d838ba2cc91b37760d297025eb3e6 (patch) | |
tree | 16b67d03cb302f7fcb27e7d2dc804123fd179cb5 | |
parent | ef88e58360db75cc61cf4468cb0464cc5230210e (diff) |
Fixes method name lookup when method appears in
the base implementations (and not in
current implementation).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68527 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 28 | ||||
-rw-r--r-- | test/SemaObjC/property-method-lookup-impl.m | 26 |
3 files changed, 48 insertions, 9 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index c71d8d726f..5582ac9f86 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -950,6 +950,9 @@ private: std::pair<bool, LookupResult> CppLookupName(Scope *S, DeclarationName Name, LookupNameKind NameKind, bool RedeclarationOnly); + ObjCMethodDecl *FindMethodInNestedImplementations( + const ObjCInterfaceDecl *IFace, + const Selector &Sel); public: /// Determines whether D is a suitable lookup result according to the diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index f348f86498..d442b1fc58 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1739,6 +1739,22 @@ static Decl *FindGetterNameDecl(const ObjCQualifiedIdType *QIdTy, return GDecl; } +/// FindMethodInNestedImplementations - Look up a method in current and +/// all base class implementations. +/// +ObjCMethodDecl *Sema::FindMethodInNestedImplementations( + const ObjCInterfaceDecl *IFace, + const Selector &Sel) { + ObjCMethodDecl *Method = 0; + if (ObjCImplementationDecl *ImpDecl = + Sema::ObjCImplementations[IFace->getIdentifier()]) + Method = ImpDecl->getInstanceMethod(Sel); + + if (!Method && IFace->getSuperClass()) + return FindMethodInNestedImplementations(IFace->getSuperClass(), Sel); + return Method; +} + Action::OwningExprResult Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, tok::TokenKind OpKind, SourceLocation MemberLoc, @@ -1953,9 +1969,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, // If this reference is in an @implementation, check for 'private' methods. if (!Getter) - if (ObjCImplementationDecl *ImpDecl = - ObjCImplementations[IFace->getIdentifier()]) - Getter = ImpDecl->getInstanceMethod(Sel); + Getter = FindMethodInNestedImplementations(IFace, Sel); // Look through local category implementations associated with the class. if (!Getter) { @@ -1978,9 +1992,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, if (!Setter) { // If this reference is in an @implementation, also check for 'private' // methods. - if (ObjCImplementationDecl *ImpDecl = - ObjCImplementations[IFace->getIdentifier()]) - Setter = ImpDecl->getInstanceMethod(SetterSel); + Setter = FindMethodInNestedImplementations(IFace, SetterSel); } // Look through local category implementations associated with the class. if (!Setter) { @@ -2061,9 +2073,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, if (!Setter) { // If this reference is in an @implementation, also check for 'private' // methods. - if (ObjCImplementationDecl *ImpDecl = - ObjCImplementations[IFace->getIdentifier()]) - Setter = ImpDecl->getInstanceMethod(SetterSel); + Setter = FindMethodInNestedImplementations(IFace, SetterSel); } // Look through local category implementations associated with the class. if (!Setter) { diff --git a/test/SemaObjC/property-method-lookup-impl.m b/test/SemaObjC/property-method-lookup-impl.m new file mode 100644 index 0000000000..ed7e9bcd43 --- /dev/null +++ b/test/SemaObjC/property-method-lookup-impl.m @@ -0,0 +1,26 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@interface SSyncCEList +{ + id _list; +} +@end + +@implementation SSyncCEList + +- (id) list +{ +} +@end + +@interface SSyncConflictList : SSyncCEList +@end + +@implementation SSyncConflictList + +- (id)Meth : (SSyncConflictList*)other + { + return other.list; + } +@end + |