[cfe-commits] r55790 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaDeclObjC.cpp test/SemaObjC/protocol-implementation-inherited.m

Daniel Dunbar daniel at zuster.org
Thu Sep 4 13:01:16 PDT 2008


Author: ddunbar
Date: Thu Sep  4 15:01:15 2008
New Revision: 55790

URL: http://llvm.org/viewvc/llvm-project?rev=55790&view=rev
Log:
Prevent invalid warnings about incomplete implementations for methods
which are inherited from base clases or protocols.

Added:
    cfe/trunk/test/SemaObjC/protocol-implementation-inherited.m
Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=55790&r1=55789&r2=55790&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Sep  4 15:01:15 2008
@@ -322,13 +322,16 @@
   void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
                            bool &IncompleteImpl);
                            
-  /// CheckProtocolMethodDefs - This routine checks unimpletented methods
-  /// Declared in protocol, and those referenced by it.
+  /// CheckProtocolMethodDefs - This routine checks unimpletented
+  /// methods declared in protocol, and those referenced by it.
+  /// \param IDecl - Used for checking for methods which may have been
+  /// inherited.
   void CheckProtocolMethodDefs(SourceLocation ImpLoc,
                                ObjCProtocolDecl *PDecl,
                                bool& IncompleteImpl,
                                const llvm::DenseSet<Selector> &InsMap,
-                               const llvm::DenseSet<Selector> &ClsMap);
+                               const llvm::DenseSet<Selector> &ClsMap,
+                               ObjCInterfaceDecl *IDecl);
   
   /// CheckImplementationIvars - This routine checks if the instance variables
   /// listed in the implelementation match those listed in the interface. 

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=55790&r1=55789&r2=55790&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Sep  4 15:01:15 2008
@@ -128,7 +128,7 @@
 }
 
 /// ActOnCompatiblityAlias - this action is called after complete parsing of
-/// @compaatibility_alias declaration. It sets up the alias relationships.
+/// @compatibility_alias declaration. It sets up the alias relationships.
 Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
                                            IdentifierInfo *AliasName, 
                                            SourceLocation AliasLocation,
@@ -203,8 +203,8 @@
 }
 
 /// FindProtocolDeclaration - This routine looks up protocols and
-/// issuer error if they are not declared. It returns list of protocol
-/// declarations in its 'Protocols' argument.
+/// issues an error if they are not declared. It returns list of
+/// protocol declarations in its 'Protocols' argument.
 void
 Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
                               const IdentifierLocPair *ProtocolId,
@@ -582,27 +582,37 @@
                                    ObjCProtocolDecl *PDecl,
                                    bool& IncompleteImpl,
                                    const llvm::DenseSet<Selector> &InsMap,
-                                   const llvm::DenseSet<Selector> &ClsMap) {
+                                   const llvm::DenseSet<Selector> &ClsMap,
+                                   ObjCInterfaceDecl *IDecl) {
+  ObjCInterfaceDecl *Super = IDecl->getSuperClass();
+
+  // If a method lookup fails locally we still need to look and see if
+  // the method was implemented by a base class or an inherited
+  // protocol. This lookup is slow, but occurs rarely in correct code
+  // and otherwise would terminate in a warning.
+
   // check unimplemented instance methods.
   for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(), 
        E = PDecl->instmeth_end(); I != E; ++I) {
     ObjCMethodDecl *method = *I;
-    if (!InsMap.count(method->getSelector()) && 
-        method->getImplementationControl() != ObjCMethodDecl::Optional)
+    if (method->getImplementationControl() != ObjCMethodDecl::Optional && 
+        !InsMap.count(method->getSelector()) &&
+        (!Super || !Super->lookupInstanceMethod(method->getSelector())))
       WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
   }
   // check unimplemented class methods
   for (ObjCProtocolDecl::classmeth_iterator I = PDecl->classmeth_begin(), 
        E = PDecl->classmeth_end(); I != E; ++I) {
     ObjCMethodDecl *method = *I;
-    if (!ClsMap.count(method->getSelector()) &&
-        method->getImplementationControl() != ObjCMethodDecl::Optional)
+    if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
+        !ClsMap.count(method->getSelector()) &&
+        (!Super || !Super->lookupClassMethod(method->getSelector())))
       WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
   }
   // Check on this protocols's referenced protocols, recursively.
   for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
        E = PDecl->protocol_end(); PI != E; ++PI)
-    CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap);
+    CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, IDecl);
 }
 
 void Sema::ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl, 
@@ -639,11 +649,11 @@
   for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
        E = Protocols.end(); I != E; ++I)
     CheckProtocolMethodDefs(IMPDecl->getLocation(), *I, 
-                            IncompleteImpl, InsMap, ClsMap);
+                            IncompleteImpl, InsMap, ClsMap, IDecl);
 }
 
 /// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the
-/// category interface is implemented in the category @implementation.
+/// category interface are implemented in the category @implementation.
 void Sema::ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
                                             ObjCCategoryDecl *CatClassDecl) {
   llvm::DenseSet<Selector> InsMap;
@@ -677,7 +687,7 @@
   for (ObjCCategoryDecl::protocol_iterator PI = CatClassDecl->protocol_begin(),
        E = CatClassDecl->protocol_end(); PI != E; ++PI)
     CheckProtocolMethodDefs(CatImplDecl->getLocation(), *PI, IncompleteImpl, 
-                            InsMap, ClsMap);
+                            InsMap, ClsMap, CatClassDecl->getClassInterface());
 }
 
 /// ActOnForwardClassDeclaration - 

Added: cfe/trunk/test/SemaObjC/protocol-implementation-inherited.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-implementation-inherited.m?rev=55790&view=auto

==============================================================================
--- cfe/trunk/test/SemaObjC/protocol-implementation-inherited.m (added)
+++ cfe/trunk/test/SemaObjC/protocol-implementation-inherited.m Thu Sep  4 15:01:15 2008
@@ -0,0 +1,56 @@
+// RUN: clang -fsyntax-only -verify %s
+
+ at protocol P0
+-bar;
+ at end
+
+ at interface A <P0>
+ at end
+
+/// Interface conforms to inherited protocol
+
+ at interface B0 : A <P0>
+ at end
+
+ at implementation B0
+ at end
+
+/// Interface conforms to a protocol which extends another. The other
+/// protocol is inherited, and extended methods are implemented.
+
+ at protocol P1 <P0>
+-foo;
+ at end
+
+ at interface B1 : A <P1>
+ at end
+
+ at implementation B1
+-foo {};
+ at end
+
+/// Interface conforms to a protocol whose methods are provided by an
+/// alternate inherited protocol.
+
+ at protocol P2
+-bar;
+ at end
+
+ at interface B2 : A <P2>
+ at end
+
+ at implementation B2
+ at end
+
+/// Interface conforms to a protocol whose methods are provided by a base class.
+
+ at interface A1 
+-bar;
+ at end
+
+ at interface B3 : A1 <P2>
+ at end
+
+ at implementation B3
+ at end
+





More information about the cfe-commits mailing list