Patch for method implementation. It populates ObjcImplementationDecl object with method implementation declarations .
It checks and warns on those methods declared in class interface and not implemented.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42412 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index dd8fe22..381003f 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -1174,6 +1174,49 @@
}
+void Sema::ActOnImplMethodsVsClassMethods(DeclTy* ImplClassDecl,
+ DeclTy* ClassDecl) {
+ ObjcImplementationDecl* IMPDecl =
+ cast<ObjcImplementationDecl>(static_cast<Decl*>(ImplClassDecl));
+ assert(IMPDecl && "missing implmentation class decl");
+
+ ObjcInterfaceDecl* IDecl =
+ cast<ObjcInterfaceDecl>(static_cast<Decl*>(ClassDecl));
+ assert(IDecl && "missing interface class decl");
+
+ llvm::DenseMap<const SelectorInfo*, char> Map;
+ // Check and see if instance methods in class interface have been
+ // implemented in the implementation class.
+ ObjcMethodDecl **methods = IMPDecl->getInsMethods();
+ for (int i=0; i < IMPDecl->getNumInsMethods(); i++) {
+ Map[methods[i]->getSelector()] = 'a';
+ }
+
+ methods = IDecl->getInsMethods();
+ for (int j = 0; j < IDecl->getNumInsMethods(); j++)
+ if (!Map.count(methods[j]->getSelector())) {
+ llvm::SmallString<128> buf;
+ Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
+ methods[j]->getSelector()->getName(buf));
+ }
+ Map.clear();
+ // Check and see if class methods in class interface have been
+ // implemented in the implementation class.
+ methods = IMPDecl->getClsMethods();
+ for (int i=0; i < IMPDecl->getNumClsMethods(); i++) {
+ Map[methods[i]->getSelector()] = 'a';
+ }
+
+ methods = IDecl->getClsMethods();
+ for (int j = 0; j < IDecl->getNumClsMethods(); j++)
+ if (!Map.count(methods[j]->getSelector())) {
+ llvm::SmallString<128> buf;
+ Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
+ methods[j]->getSelector()->getName(buf));
+ }
+ return;
+}
+
/// ObjcClassDeclaration -
/// Scope will always be top level file scope.
Action::DeclTy *
@@ -1560,7 +1603,17 @@
static_cast<Decl*>(ClassDecl));
Category->ObjcAddCatMethods(&insMethods[0], insMethods.size(),
&clsMethods[0], clsMethods.size());
- }
+ }
+ else if (isa<ObjcImplementationDecl>(static_cast<Decl *>(ClassDecl))) {
+ ObjcImplementationDecl* ImplClass = cast<ObjcImplementationDecl>(
+ static_cast<Decl*>(ClassDecl));
+ ImplClass->ObjcAddImplMethods(&insMethods[0], insMethods.size(),
+ &clsMethods[0], clsMethods.size());
+ ObjcInterfaceDecl* IDecl =
+ Context.getObjCInterfaceDecl(ImplClass->getIdentifier());
+ if (IDecl)
+ ActOnImplMethodsVsClassMethods(ImplClass, IDecl);
+ }
else
assert(0 && "Sema::ObjcAddMethodsToClass(): Unknown DeclTy");
return;