[cfe-commits] r72267 - in /cfe/trunk: include/clang/AST/DeclObjC.h lib/AST/DeclObjC.cpp lib/Sema/SemaDeclObjC.cpp test/SemaObjC/no-warn-unimpl-method.m

Fariborz Jahanian fjahanian at apple.com
Fri May 22 10:12:38 PDT 2009


Author: fjahanian
Date: Fri May 22 12:12:32 2009
New Revision: 72267

URL: http://llvm.org/viewvc/llvm-project?rev=72267&view=rev
Log:
(Next runtime only) check to see if class implements forwardInvocation method 
and objects of this class are derived from 'NSProxy'.
Under such conditions, which means that every method possible is 
implemented in the class, we should not issue "Method definition not found" 
warnings.

Added:
    cfe/trunk/test/SemaObjC/no-warn-unimpl-method.m
Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=72267&r1=72266&r2=72267&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Fri May 22 12:12:32 2009
@@ -486,6 +486,7 @@
   // found, we search referenced protocols and class categories.
   ObjCMethodDecl *lookupInstanceMethod(ASTContext &Context, Selector Sel);
   ObjCMethodDecl *lookupClassMethod(ASTContext &Context, Selector Sel);
+  ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
 
   // Location information, modeled after the Stmt API. 
   SourceLocation getLocStart() const { return getLocation(); } // '@'interface

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=72267&r1=72266&r2=72267&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Fri May 22 12:12:32 2009
@@ -161,6 +161,20 @@
   return NULL;
 }
 
+/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
+/// class whose name is passed as argument. If it is not one of the super classes
+/// the it returns NULL.
+ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
+                                        const IdentifierInfo*ICName) {
+  ObjCInterfaceDecl* ClassDecl = this;
+  while (ClassDecl != NULL) {
+    if (ClassDecl->getIdentifier() == ICName)
+      return ClassDecl;
+    ClassDecl = ClassDecl->getSuperClass();
+  }
+  return NULL;
+}
+
 /// lookupInstanceMethod - This method returns an instance method by looking in
 /// the class, its categories, and its super classes (using a linear search).
 ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(ASTContext &Context,

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Fri May 22 12:12:32 2009
@@ -866,29 +866,46 @@
                                    const llvm::DenseSet<Selector> &ClsMap,
                                    ObjCInterfaceDecl *IDecl) {
   ObjCInterfaceDecl *Super = IDecl->getSuperClass();
-
+  ObjCInterfaceDecl *NSIDecl = 0;
+  if (getLangOptions().NeXTRuntime) {
+    // check to see if class implements forwardInvocation method and objects 
+    // of this class are derived from 'NSProxy' so that to forward requests 
+    // from one object to another.
+    // Under such conditions, which means that every method possible is 
+    // implemented in the class, we should not issue "Method definition not 
+    // found" warnings.
+    // FIXME: Use a general GetUnarySelector method for this.
+    IdentifierInfo* II = &Context.Idents.get("forwardInvocation");
+    Selector fISelector = Context.Selectors.getSelector(1, &II);
+    if (InsMap.count(fISelector))
+      // Is IDecl derived from 'NSProxy'? If so, no instance methods
+      // need be implemented in the implementation.
+      NSIDecl = IDecl->lookupInheritedClass(&Context.Idents.get("NSProxy"));
+  }
+  
   // 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(Context), 
-       E = PDecl->instmeth_end(Context); I != E; ++I) {
-    ObjCMethodDecl *method = *I;
-    if (method->getImplementationControl() != ObjCMethodDecl::Optional && 
-        !method->isSynthesized() && !InsMap.count(method->getSelector()) &&
-        (!Super || 
-         !Super->lookupInstanceMethod(Context, method->getSelector()))) {
-        // Ugly, but necessary. Method declared in protcol might have
-        // have been synthesized due to a property declared in the class which
-        // uses the protocol.
-        ObjCMethodDecl *MethodInClass = 
-          IDecl->lookupInstanceMethod(Context, method->getSelector());
-        if (!MethodInClass || !MethodInClass->isSynthesized())
-          WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
-      }
-  }
+  if (!NSIDecl)
+    for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(Context), 
+         E = PDecl->instmeth_end(Context); I != E; ++I) {
+      ObjCMethodDecl *method = *I;
+      if (method->getImplementationControl() != ObjCMethodDecl::Optional && 
+          !method->isSynthesized() && !InsMap.count(method->getSelector()) &&
+          (!Super || 
+           !Super->lookupInstanceMethod(Context, method->getSelector()))) {
+            // Ugly, but necessary. Method declared in protcol might have
+            // have been synthesized due to a property declared in the class which
+            // uses the protocol.
+            ObjCMethodDecl *MethodInClass = 
+            IDecl->lookupInstanceMethod(Context, method->getSelector());
+            if (!MethodInClass || !MethodInClass->isSynthesized())
+              WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
+          }
+    }
   // check unimplemented class methods
   for (ObjCProtocolDecl::classmeth_iterator 
          I = PDecl->classmeth_begin(Context),

Added: cfe/trunk/test/SemaObjC/no-warn-unimpl-method.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/no-warn-unimpl-method.m?rev=72267&view=auto

==============================================================================
--- cfe/trunk/test/SemaObjC/no-warn-unimpl-method.m (added)
+++ cfe/trunk/test/SemaObjC/no-warn-unimpl-method.m Fri May 22 12:12:32 2009
@@ -0,0 +1,42 @@
+// RUN: clang-cc -triple x86_64-apple-darwin10 -fsyntax-only -verify %s
+// This program tests that if class implements the forwardInvocation method, then
+// every method possible is implemented in the class and should not issue
+// warning of the "Method definition not found" kind. */
+
+ at interface NSObject
+ at end
+
+ at interface NSInvocation
+ at end
+
+ at interface NSProxy
+ at end
+
+ at protocol MyProtocol
+        -(void) doSomething;
+ at end
+
+ at interface DestinationClass : NSObject<MyProtocol>
+        -(void) doSomething;
+ at end
+
+ at implementation DestinationClass
+        -(void) doSomething
+        {
+        }
+ at end
+
+ at interface MyProxy : NSProxy<MyProtocol>
+{
+        DestinationClass        *mTarget;
+}
+        - (id) init;
+        - (void)forwardInvocation:(NSInvocation *)anInvocation;
+ at end
+
+ at implementation MyProxy
+        - (void)forwardInvocation:(NSInvocation *)anInvocation
+        {
+        }
+	- (id) init {}        
+ at end





More information about the cfe-commits mailing list