forked from OSchip/llvm-project
Fix <rdar://problem/6252129> implementation of method in category doesn't effectively declare it for methods below.
llvm-svn: 56771
This commit is contained in:
parent
4831c74d40
commit
8edb573a79
|
@ -92,10 +92,14 @@ public:
|
|||
/// This is only necessary for issuing pretty diagnostics.
|
||||
llvm::SmallVector<TypedefDecl*, 24> ExtVectorDecls;
|
||||
|
||||
/// ObjCImplementations - Keep track of all of the classes with
|
||||
/// @implementation's, so that we can emit errors on duplicates.
|
||||
/// ObjCImplementations - Keep track of all class @implementations
|
||||
/// so we can emit errors on duplicates.
|
||||
llvm::DenseMap<IdentifierInfo*, ObjCImplementationDecl*> ObjCImplementations;
|
||||
|
||||
/// ObjCCategoryImpls - Maintain a list of category implementations so
|
||||
/// we can check for duplicates and find local method declarations.
|
||||
llvm::SmallVector<ObjCCategoryImplDecl*, 8> ObjCCategoryImpls;
|
||||
|
||||
/// ObjCProtocols - Keep track of all protocol declarations declared
|
||||
/// with @protocol keyword, so that we can emit errors on duplicates and
|
||||
/// find the declarations when needed.
|
||||
|
|
|
@ -429,6 +429,7 @@ Sema::DeclTy *Sema::ActOnStartCategoryImplementation(
|
|||
|
||||
/// TODO: Check that CatName, category name, is not used in another
|
||||
// implementation.
|
||||
ObjCCategoryImpls.push_back(CDecl);
|
||||
return CDecl;
|
||||
}
|
||||
|
||||
|
|
|
@ -233,6 +233,14 @@ Sema::ExprResult Sema::ActOnClassMessage(
|
|||
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.
|
||||
if (!Method)
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// RUN: clang -fsyntax-only -verify %s
|
||||
|
||||
@interface Foo
|
||||
@end
|
||||
@implementation Foo
|
||||
@end
|
||||
|
||||
@implementation Foo(Whatever)
|
||||
+(float)returnsFloat { return 7.0; }
|
||||
@end
|
||||
|
||||
@interface Foo (MoreStuff)
|
||||
+(int)returnsInt;
|
||||
@end
|
||||
|
||||
@implementation Foo (MoreStuff)
|
||||
+(int)returnsInt {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+(void)returnsNothing {
|
||||
}
|
||||
-(int)callsReturnsInt {
|
||||
float f = [Foo returnsFloat]; // GCC doesn't find this method (which is a bug IMHO).
|
||||
[Foo returnsNothing];
|
||||
return [Foo returnsInt];
|
||||
}
|
||||
@end
|
||||
|
||||
int main() {return 0;}
|
||||
|
Loading…
Reference in New Issue