From: Fariborz Jahanian Date: Tue, 7 Apr 2009 18:28:06 +0000 (+0000) Subject: Fixes method name lookup when method appears in X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ef79bc9b079d838ba2cc91b37760d297025eb3e6;p=clang 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 --- 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 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 +