[cfe-commits] r42436 - in /cfe/trunk: Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/Decl.h include/clang/Parse/Action.h test/Sema/undef-protocol-methods-1.m
Fariborz Jahanian
fjahanian at apple.com
Fri Sep 28 10:40:07 PDT 2007
Author: fjahanian
Date: Fri Sep 28 12:40:07 2007
New Revision: 42436
URL: http://llvm.org/viewvc/llvm-project?rev=42436&view=rev
Log:
Patch to warn on umimplemented methods coming from class's
protocols.
Added:
cfe/trunk/test/Sema/undef-protocol-methods-1.m
Modified:
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaDecl.cpp
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/Parse/Action.h
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=42436&r1=42435&r2=42436&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Fri Sep 28 12:40:07 2007
@@ -390,8 +390,6 @@
virtual void ActOnImpleIvarVsClassIvars(DeclTy *ClassDecl,
DeclTy **Fields, unsigned NumFields);
- virtual void ActOnImplMethodsVsClassMethods(DeclTy *ImplClass, DeclTy *Class);
-
virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
tok::TokenKind MethodType, TypeTy *ReturnType, SelectorInfo *Sel,
// optional arguments. The number of types/arguments is obtained
Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=42436&r1=42435&r2=42436&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Fri Sep 28 12:40:07 2007
@@ -1174,46 +1174,76 @@
}
-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");
+/// CheckProtocolMethodDefs - This routine checks unimpletented methods
+/// Declared in protocol, and those referenced by it.
+///
+static void CheckProtocolMethodDefs(Sema* objSema, ObjcProtocolDecl *PDecl,
+ 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));
+ }
- llvm::DenseMap<const SelectorInfo*, char> Map;
+ // Check on this protocols's referenced protocols, recursively
+ ObjcProtocolDecl** RefPDecl = PDecl->getReferencedProtocols();
+ for (int i = 0; i < PDecl->getNumReferencedProtocols(); i++)
+ CheckProtocolMethodDefs(objSema, RefPDecl[i], InsMap, ClsMap);
+}
+
+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
// implemented in the implementation class.
ObjcMethodDecl **methods = IMPDecl->getInsMethods();
for (int i=0; i < IMPDecl->getNumInsMethods(); i++) {
- Map[methods[i]->getSelector()] = 'a';
+ InsMap[methods[i]->getSelector()] = 'a';
}
methods = IDecl->getInsMethods();
for (int j = 0; j < IDecl->getNumInsMethods(); j++)
- if (!Map.count(methods[j]->getSelector())) {
+ if (!InsMap.count(methods[j]->getSelector())) {
llvm::SmallString<128> buf;
- Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
- methods[j]->getSelector()->getName(buf));
+ objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
+ methods[j]->getSelector()->getName(buf));
}
- Map.clear();
+ llvm::DenseMap<const SelectorInfo*, char> ClsMap;
// 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';
+ ClsMap[methods[i]->getSelector()] = 'a';
}
methods = IDecl->getClsMethods();
for (int j = 0; j < IDecl->getNumClsMethods(); j++)
- if (!Map.count(methods[j]->getSelector())) {
+ if (!ClsMap.count(methods[j]->getSelector())) {
llvm::SmallString<128> buf;
- Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
- methods[j]->getSelector()->getName(buf));
+ objSema->Diag(methods[j]->getLocation(), diag::warn_undef_method_impl,
+ 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;
}
@@ -1612,7 +1642,7 @@
ObjcInterfaceDecl* IDecl =
Context.getObjCInterfaceDecl(ImplClass->getIdentifier());
if (IDecl)
- ActOnImplMethodsVsClassMethods(ImplClass, IDecl);
+ ImplMethodsVsClassMethods(this, ImplClass, IDecl);
}
else
assert(0 && "Sema::ObjcAddMethodsToClass(): Unknown DeclTy");
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=42436&r1=42435&r2=42436&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri Sep 28 12:40:07 2007
@@ -588,6 +588,10 @@
NumIntfRefProtocols = numRefProtos;
}
}
+
+ ObjcProtocolDecl **getIntfRefProtocols() const { return IntfRefProtocols; }
+ int getNumIntfRefProtocols() const { return NumIntfRefProtocols; }
+
ObjcIvarDecl **getIntfDeclIvars() const { return Ivars; }
int getIntfDeclNumIvars() const { return NumIvars; }
@@ -776,6 +780,16 @@
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; }
void setIsForwardProtoDecl(bool val) { isForwardProtoDecl = val; }
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=42436&r1=42435&r2=42436&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Fri Sep 28 12:40:07 2007
@@ -451,10 +451,6 @@
DeclTy **Fields, unsigned NumFields) {
return;
}
- virtual void ActOnImplMethodsVsClassMethods(DeclTy *ImplClassDecl,
- DeclTy *ClassDecl) {
- return;
- }
virtual DeclTy *ObjcStartProtoInterface(Scope* S,
SourceLocation AtProtoInterfaceLoc,
IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
Added: cfe/trunk/test/Sema/undef-protocol-methods-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/undef-protocol-methods-1.m?rev=42436&view=auto
==============================================================================
--- cfe/trunk/test/Sema/undef-protocol-methods-1.m (added)
+++ cfe/trunk/test/Sema/undef-protocol-methods-1.m Fri Sep 28 12:40:07 2007
@@ -0,0 +1,31 @@
+ at protocol P1
+- (void) P1proto; // expected-warning {{method definition for 'P1proto' not found}}
++ (void) ClsP1Proto; // expected-warning {{method definition for 'ClsP1Proto' not found}}
+- (void) DefP1proto;
+ at end
+ at protocol P2
+- (void) P2proto; // expected-warning {{method definition for 'P2proto' not found}}
++ (void) ClsP2Proto; // expected-warning {{method definition for 'ClsP2Proto' not found}}
+ at end
+
+ at 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;
+ at end
+
+ at 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
+ at end
+
+ at interface INTF <PROTO>
+ at end
+
+ at implementation INTF
+- (void) DefP1proto{}
+
++ (void) DefClsP3Proto{}
+
+ at end
More information about the cfe-commits
mailing list