]> granicus.if.org Git - clang/commitdiff
Fixes method name lookup when method appears in
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 7 Apr 2009 18:28:06 +0000 (18:28 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 7 Apr 2009 18:28:06 +0000 (18:28 +0000)
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

lib/Sema/Sema.h
lib/Sema/SemaExpr.cpp
test/SemaObjC/property-method-lookup-impl.m [new file with mode: 0644]

index c71d8d726f6eb6100c15575dd018ea93248b6692..5582ac9f8646fb15908ffa568cb01cd3d0af7f0b 100644 (file)
@@ -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
index f348f86498469eb8a0d01632c3383069312909d5..d442b1fc583793a4b3a1547271d43e300e74e0f4 100644 (file)
@@ -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 (file)
index 0000000..ed7e9bc
--- /dev/null
@@ -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
+