зеркало из https://github.com/microsoft/clang-1.git
Patch to warn on umimplemented methods coming from class's
protocols. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42436 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
a1de8c784a
Коммит
00ae8d5955
|
@ -390,8 +390,6 @@ public:
|
||||||
virtual void ActOnImpleIvarVsClassIvars(DeclTy *ClassDecl,
|
virtual void ActOnImpleIvarVsClassIvars(DeclTy *ClassDecl,
|
||||||
DeclTy **Fields, unsigned NumFields);
|
DeclTy **Fields, unsigned NumFields);
|
||||||
|
|
||||||
virtual void ActOnImplMethodsVsClassMethods(DeclTy *ImplClass, DeclTy *Class);
|
|
||||||
|
|
||||||
virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
|
virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
|
||||||
tok::TokenKind MethodType, TypeTy *ReturnType, SelectorInfo *Sel,
|
tok::TokenKind MethodType, TypeTy *ReturnType, SelectorInfo *Sel,
|
||||||
// optional arguments. The number of types/arguments is obtained
|
// optional arguments. The number of types/arguments is obtained
|
||||||
|
|
|
@ -1174,46 +1174,76 @@ void Sema::ActOnImpleIvarVsClassIvars(DeclTy *ClassDecl,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sema::ActOnImplMethodsVsClassMethods(DeclTy* ImplClassDecl,
|
/// CheckProtocolMethodDefs - This routine checks unimpletented methods
|
||||||
DeclTy* ClassDecl) {
|
/// Declared in protocol, and those referenced by it.
|
||||||
ObjcImplementationDecl* IMPDecl =
|
///
|
||||||
cast<ObjcImplementationDecl>(static_cast<Decl*>(ImplClassDecl));
|
static void CheckProtocolMethodDefs(Sema* objSema, ObjcProtocolDecl *PDecl,
|
||||||
assert(IMPDecl && "missing implmentation class decl");
|
const llvm::DenseMap<const SelectorInfo*, char>& InsMap,
|
||||||
|
const llvm::DenseMap<const SelectorInfo*, char>& ClsMap) {
|
||||||
|
// check unimplemented instance methods.
|
||||||
|
ObjcMethodDecl** methods = PDecl->getInsMethods();
|
||||||
|
for (int j = 0; j < PDecl->getNumInsMethods(); j++)
|
||||||
|
if (!InsMap.count(methods[j]->getSelector())) {
|
||||||
|
llvm::SmallString<128> buf;
|
||||||
|
objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
|
||||||
|
methods[j]->getSelector()->getName(buf));
|
||||||
|
}
|
||||||
|
// check unimplemented class methods
|
||||||
|
methods = PDecl->getClsMethods();
|
||||||
|
for (int j = 0; j < PDecl->getNumClsMethods(); j++)
|
||||||
|
if (!ClsMap.count(methods[j]->getSelector())) {
|
||||||
|
llvm::SmallString<128> buf;
|
||||||
|
objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
|
||||||
|
methods[j]->getSelector()->getName(buf));
|
||||||
|
}
|
||||||
|
|
||||||
ObjcInterfaceDecl* IDecl =
|
// Check on this protocols's referenced protocols, recursively
|
||||||
cast<ObjcInterfaceDecl>(static_cast<Decl*>(ClassDecl));
|
ObjcProtocolDecl** RefPDecl = PDecl->getReferencedProtocols();
|
||||||
assert(IDecl && "missing interface class decl");
|
for (int i = 0; i < PDecl->getNumReferencedProtocols(); i++)
|
||||||
|
CheckProtocolMethodDefs(objSema, RefPDecl[i], InsMap, ClsMap);
|
||||||
|
}
|
||||||
|
|
||||||
llvm::DenseMap<const SelectorInfo*, char> Map;
|
static void ImplMethodsVsClassMethods(Sema* objSema,
|
||||||
|
ObjcImplementationDecl* IMPDecl,
|
||||||
|
ObjcInterfaceDecl* IDecl) {
|
||||||
|
llvm::DenseMap<const SelectorInfo*, char> InsMap;
|
||||||
// Check and see if instance methods in class interface have been
|
// Check and see if instance methods in class interface have been
|
||||||
// implemented in the implementation class.
|
// implemented in the implementation class.
|
||||||
ObjcMethodDecl **methods = IMPDecl->getInsMethods();
|
ObjcMethodDecl **methods = IMPDecl->getInsMethods();
|
||||||
for (int i=0; i < IMPDecl->getNumInsMethods(); i++) {
|
for (int i=0; i < IMPDecl->getNumInsMethods(); i++) {
|
||||||
Map[methods[i]->getSelector()] = 'a';
|
InsMap[methods[i]->getSelector()] = 'a';
|
||||||
}
|
}
|
||||||
|
|
||||||
methods = IDecl->getInsMethods();
|
methods = IDecl->getInsMethods();
|
||||||
for (int j = 0; j < IDecl->getNumInsMethods(); j++)
|
for (int j = 0; j < IDecl->getNumInsMethods(); j++)
|
||||||
if (!Map.count(methods[j]->getSelector())) {
|
if (!InsMap.count(methods[j]->getSelector())) {
|
||||||
llvm::SmallString<128> buf;
|
llvm::SmallString<128> buf;
|
||||||
Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
|
objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
|
||||||
methods[j]->getSelector()->getName(buf));
|
methods[j]->getSelector()->getName(buf));
|
||||||
}
|
}
|
||||||
Map.clear();
|
llvm::DenseMap<const SelectorInfo*, char> ClsMap;
|
||||||
// Check and see if class methods in class interface have been
|
// Check and see if class methods in class interface have been
|
||||||
// implemented in the implementation class.
|
// implemented in the implementation class.
|
||||||
methods = IMPDecl->getClsMethods();
|
methods = IMPDecl->getClsMethods();
|
||||||
for (int i=0; i < IMPDecl->getNumClsMethods(); i++) {
|
for (int i=0; i < IMPDecl->getNumClsMethods(); i++) {
|
||||||
Map[methods[i]->getSelector()] = 'a';
|
ClsMap[methods[i]->getSelector()] = 'a';
|
||||||
}
|
}
|
||||||
|
|
||||||
methods = IDecl->getClsMethods();
|
methods = IDecl->getClsMethods();
|
||||||
for (int j = 0; j < IDecl->getNumClsMethods(); j++)
|
for (int j = 0; j < IDecl->getNumClsMethods(); j++)
|
||||||
if (!Map.count(methods[j]->getSelector())) {
|
if (!ClsMap.count(methods[j]->getSelector())) {
|
||||||
llvm::SmallString<128> buf;
|
llvm::SmallString<128> buf;
|
||||||
Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
|
objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
|
||||||
methods[j]->getSelector()->getName(buf));
|
methods[j]->getSelector()->getName(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check the protocol list for unimplemented methods in the @implementation
|
||||||
|
// class.
|
||||||
|
ObjcProtocolDecl** protocols = IDecl->getIntfRefProtocols();
|
||||||
|
for (int i = 0; i < IDecl->getNumIntfRefProtocols(); i++) {
|
||||||
|
ObjcProtocolDecl* PDecl = protocols[i];
|
||||||
|
CheckProtocolMethodDefs(objSema, PDecl, InsMap, ClsMap);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1612,7 +1642,7 @@ void Sema::ObjcAddMethodsToClass(DeclTy *ClassDecl,
|
||||||
ObjcInterfaceDecl* IDecl =
|
ObjcInterfaceDecl* IDecl =
|
||||||
Context.getObjCInterfaceDecl(ImplClass->getIdentifier());
|
Context.getObjCInterfaceDecl(ImplClass->getIdentifier());
|
||||||
if (IDecl)
|
if (IDecl)
|
||||||
ActOnImplMethodsVsClassMethods(ImplClass, IDecl);
|
ImplMethodsVsClassMethods(this, ImplClass, IDecl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert(0 && "Sema::ObjcAddMethodsToClass(): Unknown DeclTy");
|
assert(0 && "Sema::ObjcAddMethodsToClass(): Unknown DeclTy");
|
||||||
|
|
|
@ -588,6 +588,10 @@ public:
|
||||||
NumIntfRefProtocols = numRefProtos;
|
NumIntfRefProtocols = numRefProtos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjcProtocolDecl **getIntfRefProtocols() const { return IntfRefProtocols; }
|
||||||
|
int getNumIntfRefProtocols() const { return NumIntfRefProtocols; }
|
||||||
|
|
||||||
ObjcIvarDecl **getIntfDeclIvars() const { return Ivars; }
|
ObjcIvarDecl **getIntfDeclIvars() const { return Ivars; }
|
||||||
int getIntfDeclNumIvars() const { return NumIvars; }
|
int getIntfDeclNumIvars() const { return NumIvars; }
|
||||||
|
|
||||||
|
@ -776,6 +780,16 @@ public:
|
||||||
ReferencedProtocols[idx] = OID;
|
ReferencedProtocols[idx] = OID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjcProtocolDecl** getReferencedProtocols() const {
|
||||||
|
return ReferencedProtocols;
|
||||||
|
}
|
||||||
|
int getNumReferencedProtocols() const { return NumReferencedProtocols; }
|
||||||
|
|
||||||
|
ObjcMethodDecl** getInsMethods() const { return ProtoInsMethods; }
|
||||||
|
int getNumInsMethods() const { return NumProtoInsMethods; }
|
||||||
|
|
||||||
|
ObjcMethodDecl** getClsMethods() const { return ProtoClsMethods; }
|
||||||
|
int getNumClsMethods() const { return NumProtoClsMethods; }
|
||||||
|
|
||||||
bool getIsForwardProtoDecl() const { return isForwardProtoDecl; }
|
bool getIsForwardProtoDecl() const { return isForwardProtoDecl; }
|
||||||
void setIsForwardProtoDecl(bool val) { isForwardProtoDecl = val; }
|
void setIsForwardProtoDecl(bool val) { isForwardProtoDecl = val; }
|
||||||
|
|
|
@ -451,10 +451,6 @@ public:
|
||||||
DeclTy **Fields, unsigned NumFields) {
|
DeclTy **Fields, unsigned NumFields) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
virtual void ActOnImplMethodsVsClassMethods(DeclTy *ImplClassDecl,
|
|
||||||
DeclTy *ClassDecl) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
virtual DeclTy *ObjcStartProtoInterface(Scope* S,
|
virtual DeclTy *ObjcStartProtoInterface(Scope* S,
|
||||||
SourceLocation AtProtoInterfaceLoc,
|
SourceLocation AtProtoInterfaceLoc,
|
||||||
IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
|
IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
@protocol P1
|
||||||
|
- (void) P1proto; // expected-warning {{method definition for 'P1proto' not found}}
|
||||||
|
+ (void) ClsP1Proto; // expected-warning {{method definition for 'ClsP1Proto' not found}}
|
||||||
|
- (void) DefP1proto;
|
||||||
|
@end
|
||||||
|
@protocol P2
|
||||||
|
- (void) P2proto; // expected-warning {{method definition for 'P2proto' not found}}
|
||||||
|
+ (void) ClsP2Proto; // expected-warning {{method definition for 'ClsP2Proto' not found}}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@protocol P3<P2>
|
||||||
|
- (void) P3proto; // expected-warning {{method definition for 'P3proto' not found}}
|
||||||
|
+ (void) ClsP3Proto; // expected-warning {{method definition for 'ClsP3Proto' not found}}
|
||||||
|
+ (void) DefClsP3Proto;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@protocol PROTO<P1, P3>
|
||||||
|
- (void) meth; // expected-warning {{method definition for 'meth' not found
|
||||||
|
- (void) meth : (int) arg1; // expected-warning {{method definition for 'meth:' not found
|
||||||
|
+ (void) cls_meth : (int) arg1; // expected-warning {{method definition for 'cls_meth:' not found
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface INTF <PROTO>
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation INTF
|
||||||
|
- (void) DefP1proto{}
|
||||||
|
|
||||||
|
+ (void) DefClsP3Proto{}
|
||||||
|
|
||||||
|
@end
|
Загрузка…
Ссылка в новой задаче