From ca3adf7e8cac8c9fbaf592b1e5c2be6f082de7ba Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 2 Oct 2007 20:06:01 +0000 Subject: [PATCH] Previously, I warned those methods not implemented in implementation class/category. Now, I also warn those class/categories which are incomplete because of this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42544 91177308-0d34-0410-b5e6-96231b3b80d8 --- Sema/Sema.h | 3 ++- Sema/SemaDecl.cpp | 22 ++++++++++++++++++---- include/clang/AST/DeclObjC.h | 10 +++++++--- include/clang/Basic/DiagnosticKinds.def | 5 +++++ test/Sema/method-undef-category-warn-1.m | 4 ++-- test/Sema/method-undefined-warn-1.m | 4 ++-- test/Sema/undef-protocol-methods-1.m | 2 +- 7 files changed, 37 insertions(+), 13 deletions(-) diff --git a/Sema/Sema.h b/Sema/Sema.h index a965f7f725..b1906d3a24 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -212,6 +212,7 @@ private: /// CheckProtocolMethodDefs - This routine checks unimpletented methods /// Declared in protocol, and those referenced by it. void CheckProtocolMethodDefs(ObjcProtocolDecl *PDecl, + bool& IncompleteImpl, const llvm::DenseMap& InsMap, const llvm::DenseMap& ClsMap); @@ -223,7 +224,7 @@ private: /// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the /// category interface is implemented in the category @implementation. void ImplCategoryMethodsVsIntfMethods(ObjcCategoryImplDecl *CatImplDecl, - ObjcCategoryDecl *CatClassDecl); + ObjcCategoryDecl *CatClassDecl); //===--------------------------------------------------------------------===// // Statement Parsing Callbacks: SemaStmt.cpp. diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index ed8591ddca..aff4b66f95 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1216,6 +1216,7 @@ void Sema::ActOnImpleIvarVsClassIvars(DeclTy *ClassDecl, /// CheckProtocolMethodDefs - This routine checks unimpletented methods /// Declared in protocol, and those referenced by it. void Sema::CheckProtocolMethodDefs(ObjcProtocolDecl *PDecl, + bool& IncompleteImpl, const llvm::DenseMap& InsMap, const llvm::DenseMap& ClsMap) { // check unimplemented instance methods. @@ -1225,6 +1226,7 @@ void Sema::CheckProtocolMethodDefs(ObjcProtocolDecl *PDecl, llvm::SmallString<128> buf; Diag(methods[j]->getLocation(), diag::warn_undef_method_impl, methods[j]->getSelector().getName(buf)); + IncompleteImpl = true; } // check unimplemented class methods methods = PDecl->getClsMethods(); @@ -1233,12 +1235,13 @@ void Sema::CheckProtocolMethodDefs(ObjcProtocolDecl *PDecl, llvm::SmallString<128> buf; Diag(methods[j]->getLocation(), diag::warn_undef_method_impl, methods[j]->getSelector().getName(buf)); + IncompleteImpl = true; } // Check on this protocols's referenced protocols, recursively ObjcProtocolDecl** RefPDecl = PDecl->getReferencedProtocols(); for (int i = 0; i < PDecl->getNumReferencedProtocols(); i++) - CheckProtocolMethodDefs(RefPDecl[i], InsMap, ClsMap); + CheckProtocolMethodDefs(RefPDecl[i], IncompleteImpl, InsMap, ClsMap); } void Sema::ImplMethodsVsClassMethods(ObjcImplementationDecl* IMPDecl, @@ -1251,12 +1254,14 @@ void Sema::ImplMethodsVsClassMethods(ObjcImplementationDecl* IMPDecl, InsMap[methods[i]->getSelector().getAsOpaquePtr()] = 'a'; } + bool IncompleteImpl = false; methods = IDecl->getInsMethods(); for (int j = 0; j < IDecl->getNumInsMethods(); j++) if (!InsMap.count(methods[j]->getSelector().getAsOpaquePtr())) { llvm::SmallString<128> buf; Diag(methods[j]->getLocation(), diag::warn_undef_method_impl, methods[j]->getSelector().getName(buf)); + IncompleteImpl = true; } llvm::DenseMap ClsMap; // Check and see if class methods in class interface have been @@ -1272,6 +1277,7 @@ void Sema::ImplMethodsVsClassMethods(ObjcImplementationDecl* IMPDecl, llvm::SmallString<128> buf; Diag(methods[j]->getLocation(), diag::warn_undef_method_impl, methods[j]->getSelector().getName(buf)); + IncompleteImpl = true; } // Check the protocol list for unimplemented methods in the @implementation @@ -1279,8 +1285,11 @@ void Sema::ImplMethodsVsClassMethods(ObjcImplementationDecl* IMPDecl, ObjcProtocolDecl** protocols = IDecl->getIntfRefProtocols(); for (int i = 0; i < IDecl->getNumIntfRefProtocols(); i++) { ObjcProtocolDecl* PDecl = protocols[i]; - CheckProtocolMethodDefs(PDecl, InsMap, ClsMap); + CheckProtocolMethodDefs(PDecl, IncompleteImpl, InsMap, ClsMap); } + if (IncompleteImpl) + Diag(IDecl->getLocation(), diag::warn_incomplete_impl_class, + IDecl->getName()); } /// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the @@ -1295,12 +1304,14 @@ void Sema::ImplCategoryMethodsVsIntfMethods(ObjcCategoryImplDecl *CatImplDecl, InsMap[methods[i]->getSelector().getAsOpaquePtr()] = 'a'; } + bool IncompleteImpl = false; methods = CatClassDecl->getCatInsMethods(); for (int j = 0; j < CatClassDecl->getNumCatInsMethods(); j++) if (!InsMap.count(methods[j]->getSelector().getAsOpaquePtr())) { llvm::SmallString<128> buf; Diag(methods[j]->getLocation(), diag::warn_undef_method_impl, methods[j]->getSelector().getName(buf)); + IncompleteImpl = true; } llvm::DenseMap ClsMap; // Check and see if class methods in category interface have been @@ -1316,6 +1327,7 @@ void Sema::ImplCategoryMethodsVsIntfMethods(ObjcCategoryImplDecl *CatImplDecl, llvm::SmallString<128> buf; Diag(methods[j]->getLocation(), diag::warn_undef_method_impl, methods[j]->getSelector().getName(buf)); + IncompleteImpl = true; } // Check the protocol list for unimplemented methods in the @implementation @@ -1323,9 +1335,11 @@ void Sema::ImplCategoryMethodsVsIntfMethods(ObjcCategoryImplDecl *CatImplDecl, ObjcProtocolDecl** protocols = CatClassDecl->getCatReferencedProtocols(); for (int i = 0; i < CatClassDecl->getNumCatReferencedProtocols(); i++) { ObjcProtocolDecl* PDecl = protocols[i]; - CheckProtocolMethodDefs(PDecl, InsMap, ClsMap); + CheckProtocolMethodDefs(PDecl, IncompleteImpl, InsMap, ClsMap); } - + if (IncompleteImpl) + Diag(CatClassDecl->getCatLoc(), diag::warn_incomplete_impl_category, + CatClassDecl->getCatName()->getName()); } /// ObjcClassDeclaration - diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 6099e56d7c..bd0b647abd 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -424,6 +424,9 @@ class ObjcCategoryDecl : public Decl { /// Next category belonging to this class ObjcCategoryDecl *NextClassCategory; + + /// Location of cetagory declaration + SourceLocation CatLoc; public: ObjcCategoryDecl(SourceLocation L, unsigned numRefProtocol) @@ -432,7 +435,7 @@ public: CatReferencedProtocols(0), NumCatReferencedProtocols(-1), CatInsMethods(0), NumCatInsMethods(-1), CatClsMethods(0), NumCatClsMethods(-1), - NextClassCategory(0) { + NextClassCategory(0), CatLoc(L) { if (numRefProtocol) { CatReferencedProtocols = new ObjcProtocolDecl*[numRefProtocol]; memset(CatReferencedProtocols, '\0', @@ -471,7 +474,9 @@ public: NextClassCategory = ClassInterface->getListCategories(); ClassInterface->setListCategories(this); } - + + SourceLocation getCatLoc() const { return CatLoc; } + static bool classof(const Decl *D) { return D->getKind() == ObjcCategory; } @@ -517,7 +522,6 @@ class ObjcCategoryImplDecl : public Decl { ObjcMethodDecl **getCatClsMethods() const { return CatClsMethods; } int getNumCatClsMethods() const { return NumCatClsMethods; } - void ObjcAddCatImplMethods( ObjcMethodDecl **insMethods, unsigned numInsMembers, ObjcMethodDecl **clsMethods, unsigned numClsMembers); diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 937684c7f6..313af0da0e 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -434,6 +434,11 @@ DIAG(err_conflicting_ivar_type, ERROR, "conflicting instance variable type") DIAG(warn_undef_method_impl, WARNING, "method definition for '%0' not found") +DIAG(warn_incomplete_impl_class, WARNING, + "incomplete implementation of class '%0'") +DIAG(warn_incomplete_impl_category, WARNING, + "incomplete implementation of category '%0'") + //===----------------------------------------------------------------------===// // Semantic Analysis diff --git a/test/Sema/method-undef-category-warn-1.m b/test/Sema/method-undef-category-warn-1.m index e71cfdb47c..ec68950cb3 100644 --- a/test/Sema/method-undef-category-warn-1.m +++ b/test/Sema/method-undef-category-warn-1.m @@ -12,7 +12,7 @@ @implementation MyClass1(CAT) - (void) Pmeth1{} -@end +@end // expected-warning {{incomplete implementation of category 'CAT'}} @interface MyClass1(DOG)

- (void)ppp; // expected-warning {{method definition for 'ppp' not found}} @@ -20,7 +20,7 @@ @implementation MyClass1(DOG) - (void) Pmeth {} -@end +@end // expected-warning {{incomplete implementation of category 'DOG'}} @implementation MyClass1(CAT1) @end diff --git a/test/Sema/method-undefined-warn-1.m b/test/Sema/method-undefined-warn-1.m index 2c7cdadcf0..29faa7d840 100644 --- a/test/Sema/method-undefined-warn-1.m +++ b/test/Sema/method-undefined-warn-1.m @@ -10,7 +10,7 @@ - (void) meth {} - (void) meth : (int) arg2{} - (void) cls_meth1 : (int) arg2{} -@end +@end // expected-warning {{incomplete implementation of class 'INTF'}} @interface INTF1 @@ -25,7 +25,7 @@ - (void) meth {} - (void) meth : (int) arg2{} - (void) cls_meth1 : (int) arg2{} -@end +@end // expected-warning {{incomplete implementation of class 'INTF1'}} @interface INTF2 diff --git a/test/Sema/undef-protocol-methods-1.m b/test/Sema/undef-protocol-methods-1.m index 60203fcc24..438feb2df5 100644 --- a/test/Sema/undef-protocol-methods-1.m +++ b/test/Sema/undef-protocol-methods-1.m @@ -28,4 +28,4 @@ + (void) DefClsP3Proto{} -@end +@end // expected-warning {{ncomplete implementation of class 'INTF'}} -- 2.50.1