]> granicus.if.org Git - clang/commitdiff
Previously, I warned those methods not implemented in implementation class/category.
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 2 Oct 2007 20:06:01 +0000 (20:06 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 2 Oct 2007 20:06:01 +0000 (20:06 +0000)
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
Sema/SemaDecl.cpp
include/clang/AST/DeclObjC.h
include/clang/Basic/DiagnosticKinds.def
test/Sema/method-undef-category-warn-1.m
test/Sema/method-undefined-warn-1.m
test/Sema/undef-protocol-methods-1.m

index a965f7f7257f593609a298679fe8fbf9b3f34921..b1906d3a24940c6339e2b741be105556cf816093 100644 (file)
@@ -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<void *, char>& InsMap,
                                const llvm::DenseMap<void *, char>& 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.
index ed8591ddca017b75064154762653b4ce34831af4..aff4b66f95344046d6f55fc45b58e5ad77041c34 100644 (file)
@@ -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<void *, char>& InsMap,
              const llvm::DenseMap<void *, char>& 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<void *, char> 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<void *, char> 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 - 
index 6099e56d7c7714ab66eb9ec1f2599be6d55f39b6..bd0b647abd37771581cad80fd58eb436494f1ad2 100644 (file)
@@ -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);
index 937684c7f6e134f429482880f26bbb54b06f7604..313af0da0e03d0a10d2809d2852df5cc0d3d9d79 100644 (file)
@@ -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
index e71cfdb47cd90f9331d3d31428d3f8b8d5389561..ec68950cb33845c26ae3235eca49bc40d76edcb9 100644 (file)
@@ -12,7 +12,7 @@
 
 @implementation MyClass1(CAT)
 - (void) Pmeth1{}
-@end
+@end  // expected-warning {{incomplete implementation of category 'CAT'}}
 
 @interface MyClass1(DOG) <P>
 - (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
index 2c7cdadcf0669d8405706fb161b1ff292a604be8..29faa7d840c0cafe046206609dc5138aec14ef00 100644 (file)
@@ -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
index 60203fcc2448c753c402dbf25b48a327e25bf250..438feb2df5de5fca86a7eb9e4024fdeee9cb0223 100644 (file)
@@ -28,4 +28,4 @@
 
 + (void) DefClsP3Proto{}
 
-@end
+@end // expected-warning {{ncomplete implementation of class 'INTF'}}