The code for looking up local/private method in Sema::ActOnInstanceMessage() was not handling categories properly. Sema::ActOnClassMessage() didn't have this bug.
Created a helper with the correct logic and changed both methods to use it.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65532 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Steve Naroff 2009-02-26 15:55:06 +00:00
Родитель 2850784bda
Коммит f1afaf6fe2
3 изменённых файлов: 53 добавлений и 19 удалений

Просмотреть файл

@ -1683,6 +1683,11 @@ public:
AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
bool isVariadic = false);
// Helper method for ActOnClassMethod/ActOnInstanceMethod.
// Will search "local" class/category implementations for a method decl.
// Returns 0 if no method is found.
ObjCMethodDecl *LookupPrivateMethod(Selector Sel, ObjCInterfaceDecl *CDecl);
// ActOnClassMessage - used for both unary and keyword messages.
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from NumArgs.

Просмотреть файл

@ -202,6 +202,27 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
return anyIncompatibleArgs;
}
// Helper method for ActOnClassMethod/ActOnInstanceMethod.
// Will search "local" class/category implementations for a method decl.
// Returns 0 if no method is found.
ObjCMethodDecl *Sema::LookupPrivateMethod(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);
}
}
return Method;
}
// ActOnClassMessage - used for both unary and keyword messages.
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from Sel.getNumArgs().
@ -282,19 +303,9 @@ Sema::ExprResult Sema::ActOnClassMessage(
Method = ClassDecl->lookupClassMethod(Sel);
// If we have an implementation in scope, check "private" methods.
if (!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);
}
}
}
if (!Method)
Method = LookupPrivateMethod(Sel, ClassDecl);
// Before we give up, check if the selector is an instance method.
if (!Method)
Method = ClassDecl->lookupInstanceMethod(Sel);
@ -379,12 +390,8 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
// First check the public methods in the class interface.
Method = ClassDecl->lookupClassMethod(Sel);
if (!Method) {
// If we have an implementation in scope, check "private" methods.
if (ObjCImplementationDecl *ImpDecl =
ObjCImplementations[ClassDecl->getIdentifier()])
Method = ImpDecl->getClassMethod(Sel);
}
if (!Method)
Method = LookupPrivateMethod(Sel, ClassDecl);
}
if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
return true;

Просмотреть файл

@ -0,0 +1,22 @@
// RUN: clang -fsyntax-only -verify %s
typedef struct objc_class *Class;
@interface NSObject
- (Class)class;
@end
@interface Bar : NSObject
@end
@interface Bar (Cat)
@end
// NOTE: No class implementation for Bar precedes this category definition.
@implementation Bar (Cat)
// private method.
+ classMethod { return self; }
- instanceMethod {
[[self class] classMethod];
}
@end