Prevent invalid warnings about incomplete implementations for methods

which are inherited from base clases or protocols.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55790 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2008-09-04 20:01:15 +00:00
Родитель f557fb749e
Коммит 7ad1b1fa07
3 изменённых файлов: 84 добавлений и 15 удалений

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

@ -322,13 +322,16 @@ private:
void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
bool &IncompleteImpl);
/// CheckProtocolMethodDefs - This routine checks unimpletented methods
/// Declared in protocol, and those referenced by it.
/// CheckProtocolMethodDefs - This routine checks unimpletented
/// methods declared in protocol, and those referenced by it.
/// \param IDecl - Used for checking for methods which may have been
/// inherited.
void CheckProtocolMethodDefs(SourceLocation ImpLoc,
ObjCProtocolDecl *PDecl,
bool& IncompleteImpl,
const llvm::DenseSet<Selector> &InsMap,
const llvm::DenseSet<Selector> &ClsMap);
const llvm::DenseSet<Selector> &ClsMap,
ObjCInterfaceDecl *IDecl);
/// CheckImplementationIvars - This routine checks if the instance variables
/// listed in the implelementation match those listed in the interface.

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

@ -128,7 +128,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
}
/// ActOnCompatiblityAlias - this action is called after complete parsing of
/// @compaatibility_alias declaration. It sets up the alias relationships.
/// @compatibility_alias declaration. It sets up the alias relationships.
Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
IdentifierInfo *AliasName,
SourceLocation AliasLocation,
@ -203,8 +203,8 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
}
/// FindProtocolDeclaration - This routine looks up protocols and
/// issuer error if they are not declared. It returns list of protocol
/// declarations in its 'Protocols' argument.
/// issues an error if they are not declared. It returns list of
/// protocol declarations in its 'Protocols' argument.
void
Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
const IdentifierLocPair *ProtocolId,
@ -582,27 +582,37 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
ObjCProtocolDecl *PDecl,
bool& IncompleteImpl,
const llvm::DenseSet<Selector> &InsMap,
const llvm::DenseSet<Selector> &ClsMap) {
const llvm::DenseSet<Selector> &ClsMap,
ObjCInterfaceDecl *IDecl) {
ObjCInterfaceDecl *Super = IDecl->getSuperClass();
// If a method lookup fails locally we still need to look and see if
// the method was implemented by a base class or an inherited
// protocol. This lookup is slow, but occurs rarely in correct code
// and otherwise would terminate in a warning.
// check unimplemented instance methods.
for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
E = PDecl->instmeth_end(); I != E; ++I) {
ObjCMethodDecl *method = *I;
if (!InsMap.count(method->getSelector()) &&
method->getImplementationControl() != ObjCMethodDecl::Optional)
if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
!InsMap.count(method->getSelector()) &&
(!Super || !Super->lookupInstanceMethod(method->getSelector())))
WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
}
// check unimplemented class methods
for (ObjCProtocolDecl::classmeth_iterator I = PDecl->classmeth_begin(),
E = PDecl->classmeth_end(); I != E; ++I) {
ObjCMethodDecl *method = *I;
if (!ClsMap.count(method->getSelector()) &&
method->getImplementationControl() != ObjCMethodDecl::Optional)
if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
!ClsMap.count(method->getSelector()) &&
(!Super || !Super->lookupClassMethod(method->getSelector())))
WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
}
// Check on this protocols's referenced protocols, recursively.
for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
E = PDecl->protocol_end(); PI != E; ++PI)
CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap);
CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, IDecl);
}
void Sema::ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl,
@ -639,11 +649,11 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl,
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
E = Protocols.end(); I != E; ++I)
CheckProtocolMethodDefs(IMPDecl->getLocation(), *I,
IncompleteImpl, InsMap, ClsMap);
IncompleteImpl, InsMap, ClsMap, IDecl);
}
/// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the
/// category interface is implemented in the category @implementation.
/// category interface are implemented in the category @implementation.
void Sema::ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
ObjCCategoryDecl *CatClassDecl) {
llvm::DenseSet<Selector> InsMap;
@ -677,7 +687,7 @@ void Sema::ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
for (ObjCCategoryDecl::protocol_iterator PI = CatClassDecl->protocol_begin(),
E = CatClassDecl->protocol_end(); PI != E; ++PI)
CheckProtocolMethodDefs(CatImplDecl->getLocation(), *PI, IncompleteImpl,
InsMap, ClsMap);
InsMap, ClsMap, CatClassDecl->getClassInterface());
}
/// ActOnForwardClassDeclaration -

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

@ -0,0 +1,56 @@
// RUN: clang -fsyntax-only -verify %s
@protocol P0
-bar;
@end
@interface A <P0>
@end
/// Interface conforms to inherited protocol
@interface B0 : A <P0>
@end
@implementation B0
@end
/// Interface conforms to a protocol which extends another. The other
/// protocol is inherited, and extended methods are implemented.
@protocol P1 <P0>
-foo;
@end
@interface B1 : A <P1>
@end
@implementation B1
-foo {};
@end
/// Interface conforms to a protocol whose methods are provided by an
/// alternate inherited protocol.
@protocol P2
-bar;
@end
@interface B2 : A <P2>
@end
@implementation B2
@end
/// Interface conforms to a protocol whose methods are provided by a base class.
@interface A1
-bar;
@end
@interface B3 : A1 <P2>
@end
@implementation B3
@end