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 c71d8d7..5582ac9 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -950,6 +950,9 @@
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 f348f86..d442b1f 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1739,6 +1739,22 @@
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 @@
// 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 @@
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 @@
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 0000000..ed7e9bc
--- /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
+