[cfe-commits] r66383 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExprObjC.cpp test/SemaObjC/method-lookup-4.m
Steve Naroff
snaroff at apple.com
Sun Mar 8 11:56:14 PDT 2009
Author: snaroff
Date: Sun Mar 8 13:56:13 2009
New Revision: 66383
URL: http://llvm.org/viewvc/llvm-project?rev=66383&view=rev
Log:
Improvements to private method lookup.
Patch by Jean-Daniel Dupas. Thanks!
Added:
cfe/trunk/test/SemaObjC/method-lookup-4.m
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExprObjC.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=66383&r1=66382&r2=66383&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sun Mar 8 13:56:13 2009
@@ -1786,7 +1786,10 @@
// Will search "local" class/category implementations for a method decl.
// Will also search in class's root looking for instance method.
// Returns 0 if no method is found.
- ObjCMethodDecl *LookupPrivateOrRootMethod(Selector Sel, ObjCInterfaceDecl *CDecl);
+ ObjCMethodDecl *LookupPrivateClassMethod(Selector Sel,
+ ObjCInterfaceDecl *CDecl);
+ ObjCMethodDecl *LookupPrivateInstanceMethod(Selector Sel,
+ ObjCInterfaceDecl *ClassDecl);
// ActOnClassMessage - used for both unary and keyword messages.
// ArgExprs is optional - if it is present, the number of expressions
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=66383&r1=66382&r2=66383&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Sun Mar 8 13:56:13 2009
@@ -213,29 +213,56 @@
// Will search "local" class/category implementations for a method decl.
// If failed, then we search in class's root for an instance method.
// Returns 0 if no method is found.
-ObjCMethodDecl *Sema::LookupPrivateOrRootMethod(Selector Sel,
+ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
ObjCInterfaceDecl *ClassDecl) {
ObjCMethodDecl *Method = 0;
-
- if (ObjCImplementationDecl *ImpDecl =
- ObjCImplementations[ClassDecl->getIdentifier()])
- Method = ImpDecl->getClassMethod(Sel);
-
- // Look through local category implementations associated with the class.
- if (!Method) {
- for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
- if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
- Method = ObjCCategoryImpls[i]->getClassMethod(Sel);
- }
- }
- // Before we give up, check if the selector is an instance method.
- // But only in the root. This matches gcc's behaviour and what the
- // runtime expects.
- if (!Method) {
- ObjCInterfaceDecl *Root = ClassDecl;
- while (Root->getSuperClass())
- Root = Root->getSuperClass();
- Method = Root->lookupInstanceMethod(Sel);
+ // lookup in class and all superclasses
+ while (ClassDecl && !Method) {
+ if (ObjCImplementationDecl *ImpDecl =
+ ObjCImplementations[ClassDecl->getIdentifier()])
+ Method = ImpDecl->getClassMethod(Sel);
+
+ // Look through local category implementations associated with the class.
+ if (!Method) {
+ for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
+ if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
+ Method = ObjCCategoryImpls[i]->getClassMethod(Sel);
+ }
+ }
+
+ // Before we give up, check if the selector is an instance method.
+ // But only in the root. This matches gcc's behaviour and what the
+ // runtime expects.
+ if (!Method && !ClassDecl->getSuperClass()) {
+ Method = ClassDecl->lookupInstanceMethod(Sel);
+ // Look through local category implementations associated
+ // with the root class.
+ if (!Method)
+ Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
+ }
+
+ ClassDecl = ClassDecl->getSuperClass();
+ }
+ return Method;
+}
+
+ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
+ ObjCInterfaceDecl *ClassDecl) {
+ ObjCMethodDecl *Method = 0;
+ while (ClassDecl && !Method) {
+ // If we have implementations in scope, check "private" methods.
+ if (ObjCImplementationDecl *ImpDecl =
+ ObjCImplementations[ClassDecl->getIdentifier()])
+ Method = ImpDecl->getInstanceMethod(Sel);
+
+ // Look through local category implementations associated with the class.
+ if (!Method) {
+ for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
+ if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
+ Method = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
+ }
+ }
+ ClassDecl = ClassDecl->getSuperClass();
}
return Method;
}
@@ -321,7 +348,7 @@
// If we have an implementation in scope, check "private" methods.
if (!Method)
- Method = LookupPrivateOrRootMethod(Sel, ClassDecl);
+ Method = LookupPrivateClassMethod(Sel, ClassDecl);
if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
return true;
@@ -367,8 +394,13 @@
if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
// If we have an interface in scope, check 'super' methods.
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
- if (ObjCInterfaceDecl *SuperDecl = ClassDecl->getSuperClass())
+ if (ObjCInterfaceDecl *SuperDecl = ClassDecl->getSuperClass()) {
Method = SuperDecl->lookupInstanceMethod(Sel);
+
+ if (!Method)
+ // If we have implementations in scope, check "private" methods.
+ Method = LookupPrivateInstanceMethod(Sel, SuperDecl);
+ }
}
if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
@@ -405,7 +437,7 @@
Method = ClassDecl->lookupClassMethod(Sel);
if (!Method)
- Method = LookupPrivateOrRootMethod(Sel, ClassDecl);
+ Method = LookupPrivateClassMethod(Sel, ClassDecl);
}
if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
return true;
@@ -467,24 +499,14 @@
}
}
if (!Method) {
- // If we have an implementation in scope, check "private" methods.
- if (ClassDecl) {
- if (ObjCImplementationDecl *ImpDecl =
- ObjCImplementations[ClassDecl->getIdentifier()])
- Method = ImpDecl->getInstanceMethod(Sel);
- // Look through local category implementations associated with the class.
- if (!Method) {
- for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
- if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
- Method = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
- }
- }
- }
- if (!isSelfExpr(RExpr)) {
+ // If we have implementations in scope, check "private" methods.
+ Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
+
+ if (!Method && !isSelfExpr(RExpr)) {
// If we still haven't found a method, look in the global pool. This
// behavior isn't very desirable, however we need it for GCC
// compatibility. FIXME: should we deviate??
- if (!Method && OCIType->qual_empty()) {
+ if (OCIType->qual_empty()) {
Method = LookupInstanceMethodInGlobalPool(
Sel, SourceRange(lbrac,rbrac));
if (Method && !OCIType->getDecl()->isForwardDecl())
Added: cfe/trunk/test/SemaObjC/method-lookup-4.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/method-lookup-4.m?rev=66383&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/method-lookup-4.m (added)
+++ cfe/trunk/test/SemaObjC/method-lookup-4.m Sun Mar 8 13:56:13 2009
@@ -0,0 +1,62 @@
+// RUN: clang -fsyntax-only -verify %s
+
+ at interface NSObject {}
+
+ at end
+
+ at interface MyClass : NSObject {}
+
+ at end
+
+ at interface MyClass (MyCategorie)
+
+ at end
+
+ at interface MySubClass : MyClass {}
+
+ at end
+
+ at interface MySubSubClass : MySubClass {}
+
+ at end
+
+ at implementation NSObject (NSObjectCategory)
+- (void)rootMethod {}
+ at end
+
+ at implementation MyClass
+
++ (void)myClassMethod { }
+- (void)myMethod { }
+
+ at end
+
+ at implementation MyClass (MyCategorie)
++ (void)myClassCategoryMethod { }
+- (void)categoryMethod {}
+ at end
+
+ at implementation MySubClass
+
+- (void)mySubMethod {}
+
+- (void)myTest {
+ [self mySubMethod];
+ // should lookup method in superclass implementation if available
+ [self myMethod];
+ [super myMethod];
+
+ [self categoryMethod];
+ [super categoryMethod];
+
+ // instance method of root class
+ [MyClass rootMethod];
+
+ [MyClass myClassMethod];
+ [MySubClass myClassMethod];
+
+ [MyClass myClassCategoryMethod];
+ [MySubClass myClassCategoryMethod];
+}
+
+ at end
More information about the cfe-commits
mailing list