зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
f557fb749e
Коммит
7ad1b1fa07
|
@ -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
|
||||
|
Загрузка…
Ссылка в новой задаче