[cfe-commits] r70568 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaDeclObjC.cpp test/Analysis/PR2978.m test/SemaObjC/method-typecheck-2.m test/SemaObjC/props-on-prots.m test/SemaObjC/protocol-lookup.m test/SemaObjCXX/protocol-lookup.mm

Fariborz Jahanian fjahanian at apple.com
Fri May 1 13:07:13 PDT 2009


Author: fjahanian
Date: Fri May  1 15:07:12 2009
New Revision: 70568

URL: http://llvm.org/viewvc/llvm-project?rev=70568&view=rev
Log:
Check for method type conflict between declaration in
class/protocol and implementation which could be
an imm. implementation or down in the inheritance
hierarchy.

Added:
    cfe/trunk/test/SemaObjC/method-typecheck-2.m
Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/test/Analysis/PR2978.m
    cfe/trunk/test/SemaObjC/props-on-prots.m
    cfe/trunk/test/SemaObjC/protocol-lookup.m
    cfe/trunk/test/SemaObjCXX/protocol-lookup.mm

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri May  1 15:07:12 2009
@@ -1114,6 +1114,17 @@
                                   const ObjCMethodDecl *PrevMethod,
                                   bool matchBasedOnSizeAndAlignment = false); 
 
+  /// MatchAllMethodDeclarations - Check methods declaraed in interface or
+  /// or protocol against those declared in their implementations.
+  void MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
+                                  const llvm::DenseSet<Selector> &ClsMap,
+                                  llvm::DenseSet<Selector> &InsMapSeen,
+                                  llvm::DenseSet<Selector> &ClsMapSeen,
+                                  ObjCImplDecl* IMPDecl,
+                                  ObjCContainerDecl* IDecl,
+                                  bool &IncompleteImpl,
+                                  bool ImmediateClass);
+
   /// AddInstanceMethodToGlobalPool - All instance methods in a translation
   /// unit are added to a global pool. This allows us to efficiently associate
   /// a selector with a method declaraation for purposes of typechecking

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Fri May  1 15:07:12 2009
@@ -885,6 +885,79 @@
     CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, IDecl);
 }
 
+/// MatchAllMethodDeclarations - Check methods declaraed in interface or
+/// or protocol against those declared in their implementations.
+///
+void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
+                                      const llvm::DenseSet<Selector> &ClsMap,
+                                      llvm::DenseSet<Selector> &InsMapSeen,
+                                      llvm::DenseSet<Selector> &ClsMapSeen,
+                                      ObjCImplDecl* IMPDecl,
+                                      ObjCContainerDecl* CDecl,
+                                      bool &IncompleteImpl,
+                                      bool ImmediateClass)
+{
+  // Check and see if instance methods in class interface have been
+  // implemented in the implementation class. If so, their types match.
+  for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(Context),
+       E = CDecl->instmeth_end(Context); I != E; ++I) {
+    if (InsMapSeen.count((*I)->getSelector()))
+        continue;
+    InsMapSeen.insert((*I)->getSelector());
+    if (!(*I)->isSynthesized() && 
+        !InsMap.count((*I)->getSelector())) {
+      if (ImmediateClass)
+        WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
+      continue;
+    }
+    else {
+      ObjCMethodDecl *ImpMethodDecl = 
+      IMPDecl->getInstanceMethod(Context, (*I)->getSelector());
+      ObjCMethodDecl *IntfMethodDecl = 
+      CDecl->getInstanceMethod(Context, (*I)->getSelector());
+      assert(IntfMethodDecl && 
+             "IntfMethodDecl is null in ImplMethodsVsClassMethods");
+      // ImpMethodDecl may be null as in a @dynamic property.
+      if (ImpMethodDecl)
+        WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
+    }
+  }
+  
+  // Check and see if class methods in class interface have been
+  // implemented in the implementation class. If so, their types match.
+   for (ObjCInterfaceDecl::classmeth_iterator 
+       I = CDecl->classmeth_begin(Context),
+       E = CDecl->classmeth_end(Context);
+        I != E; ++I) {
+     if (ClsMapSeen.count((*I)->getSelector()))
+       continue;
+     ClsMapSeen.insert((*I)->getSelector());
+    if (!ClsMap.count((*I)->getSelector())) {
+      if (ImmediateClass)
+        WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
+    }
+    else {
+      ObjCMethodDecl *ImpMethodDecl = 
+      IMPDecl->getClassMethod(Context, (*I)->getSelector());
+      ObjCMethodDecl *IntfMethodDecl = 
+      CDecl->getClassMethod(Context, (*I)->getSelector());
+      WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
+    }
+  }
+  if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
+    // Check for any implementation of a methods declared in protocol.
+    for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
+         E = I->protocol_end(); PI != E; ++PI)
+      MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 
+                                 IMPDecl, 
+                                 (*PI), IncompleteImpl, false);
+    if (I->getSuperClass())
+      MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
+                                 IMPDecl, 
+                                 I->getSuperClass(), IncompleteImpl, false);
+  }
+}
+
 void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl, 
                                      ObjCContainerDecl* CDecl, 
                                      bool IncompleteImpl) {
@@ -933,51 +1006,26 @@
         }
       }
   
-  for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(Context),
-       E = CDecl->instmeth_end(Context); I != E; ++I) {
-    if (!(*I)->isSynthesized() && !InsMap.count((*I)->getSelector())) {
-      WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
-      continue;
-    }
-    
-    ObjCMethodDecl *ImpMethodDecl = 
-      IMPDecl->getInstanceMethod(Context, (*I)->getSelector());
-    ObjCMethodDecl *IntfMethodDecl = 
-      CDecl->getInstanceMethod(Context, (*I)->getSelector());
-    assert(IntfMethodDecl && 
-           "IntfMethodDecl is null in ImplMethodsVsClassMethods");
-    // ImpMethodDecl may be null as in a @dynamic property.
-    if (ImpMethodDecl)
-      WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
-  }
-      
   llvm::DenseSet<Selector> ClsMap;
-  // Check and see if class methods in class interface have been
-  // implemented in the implementation class.
   for (ObjCImplementationDecl::classmeth_iterator 
-         I = IMPDecl->classmeth_begin(Context),
-         E = IMPDecl->classmeth_end(Context); I != E; ++I)
+       I = IMPDecl->classmeth_begin(Context),
+       E = IMPDecl->classmeth_end(Context); I != E; ++I)
     ClsMap.insert((*I)->getSelector());
   
-  for (ObjCInterfaceDecl::classmeth_iterator 
-         I = CDecl->classmeth_begin(Context),
-         E = CDecl->classmeth_end(Context);
-       I != E; ++I)
-    if (!ClsMap.count((*I)->getSelector()))
-      WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
-    else {
-      ObjCMethodDecl *ImpMethodDecl = 
-        IMPDecl->getClassMethod(Context, (*I)->getSelector());
-      ObjCMethodDecl *IntfMethodDecl = 
-        CDecl->getClassMethod(Context, (*I)->getSelector());
-      WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
-    }
-  
+  // Check for type conflict of methods declared in a class/protocol and
+  // its implementation; if any.
+  llvm::DenseSet<Selector> InsMapSeen, ClsMapSeen;
+  MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, 
+                             IMPDecl, CDecl, 
+                             IncompleteImpl, true);
   
   // Check the protocol list for unimplemented methods in the @implementation
   // class.
+  // Check and see if class methods in class interface have been
+  // implemented in the implementation class.
+  
   if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
-    for (ObjCCategoryDecl::protocol_iterator PI = I->protocol_begin(),
+    for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
          E = I->protocol_end(); PI != E; ++PI)
       CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl, 
                               InsMap, ClsMap, I);

Modified: cfe/trunk/test/Analysis/PR2978.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/PR2978.m?rev=70568&r1=70567&r2=70568&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/PR2978.m (original)
+++ cfe/trunk/test/Analysis/PR2978.m Fri May  1 15:07:12 2009
@@ -44,7 +44,7 @@
 -(id) O{ return 0; }
 -(void) setO:(id)arg { }
 
-- (void)dealloc
+- (id)dealloc
 {
   [_X release];
   [_Z release];

Added: cfe/trunk/test/SemaObjC/method-typecheck-2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/method-typecheck-2.m?rev=70568&view=auto

==============================================================================
--- cfe/trunk/test/SemaObjC/method-typecheck-2.m (added)
+++ cfe/trunk/test/SemaObjC/method-typecheck-2.m Fri May  1 15:07:12 2009
@@ -0,0 +1,25 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+ at protocol P
+- (void) doSomethingInProtocol: (float) x; // expected-note {{previous definition is here}}
++ (void) doSomethingClassyInProtocol: (float) x; // expected-note {{previous definition is here}}
+- (void) doNothingInProtocol : (float) x;
++ (void) doNothingClassyInProtocol : (float) x;
+ at end
+
+ at interface I <P>
+- (void) doSomething: (float) x; // expected-note {{previous definition is here}}
++ (void) doSomethingClassy: (int) x; // expected-note {{previous definition is here}}
+ at end
+
+ at interface Bar : I
+ at end
+
+ at implementation Bar
+- (void) doSomething: (int) x {} // expected-warning {{conflicting parameter types}}
++ (void) doSomethingClassy: (float) x{}  // expected-warning {{conflicting parameter types}}
+- (void) doSomethingInProtocol: (id) x {}  // expected-warning {{conflicting parameter types}}
++ (void) doSomethingClassyInProtocol: (id) x {}  // expected-warning {{conflicting parameter types}}
+ at end
+
+

Modified: cfe/trunk/test/SemaObjC/props-on-prots.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/props-on-prots.m?rev=70568&r1=70567&r2=70568&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/props-on-prots.m (original)
+++ cfe/trunk/test/SemaObjC/props-on-prots.m Fri May  1 15:07:12 2009
@@ -21,7 +21,7 @@
 typedef struct _XCElementInset {} XCElementInset;
 
 @protocol XCElementP < NSObject >
--(BOOL) vertical;
+-(id) vertical;
 @end
 
 @protocol XCElementDisplayDelegateP;
@@ -60,6 +60,6 @@
   if (_marker && _marker.variableSized) {
   }
 }
-- vertical { return self; }
+- (id)vertical { return self; }
 - (BOOL)isEqual:x { return 1; }
 @end

Modified: cfe/trunk/test/SemaObjC/protocol-lookup.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-lookup.m?rev=70568&r1=70567&r2=70568&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/protocol-lookup.m (original)
+++ cfe/trunk/test/SemaObjC/protocol-lookup.m Fri May  1 15:07:12 2009
@@ -39,7 +39,7 @@
 	return self;
 }
 
-- (void)dealloc
+- dealloc
 {
 	[_foo release];
 	[_bar release];

Modified: cfe/trunk/test/SemaObjCXX/protocol-lookup.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/protocol-lookup.mm?rev=70568&r1=70567&r2=70568&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjCXX/protocol-lookup.mm (original)
+++ cfe/trunk/test/SemaObjCXX/protocol-lookup.mm Fri May  1 15:07:12 2009
@@ -39,7 +39,7 @@
 	return self;
 }
 
-- (void)dealloc
+- dealloc
 {
 	[_foo release];
 	[_bar release];





More information about the cfe-commits mailing list