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
diff --git a/Sema/Sema.h b/Sema/Sema.h
index a965f7f..b1906d3 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -212,6 +212,7 @@
/// 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 @@
/// 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 ed8591d..aff4b66 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -1216,6 +1216,7 @@
/// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 6099e56..bd0b647 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -424,6 +424,9 @@
/// Next category belonging to this class
ObjcCategoryDecl *NextClassCategory;
+
+ /// Location of cetagory declaration
+ SourceLocation CatLoc;
public:
ObjcCategoryDecl(SourceLocation L, unsigned numRefProtocol)
@@ -432,7 +435,7 @@
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 @@
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 @@
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 937684c..313af0d 100644
--- a/include/clang/Basic/DiagnosticKinds.def
+++ b/include/clang/Basic/DiagnosticKinds.def
@@ -434,6 +434,11 @@
"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 e71cfdb..ec68950 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) <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
diff --git a/test/Sema/method-undefined-warn-1.m b/test/Sema/method-undefined-warn-1.m
index 2c7cdad..29faa7d 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 60203fc..438feb2 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'}}