[cfe-commits] r78075 - in /cfe/trunk: lib/Sema/SemaDeclObjC.cpp test/SemaObjC/warn-superclass-method-mismatch.m

Fariborz Jahanian fjahanian at apple.com
Tue Aug 4 10:01:11 PDT 2009


Author: fjahanian
Date: Tue Aug  4 12:01:09 2009
New Revision: 78075

URL: http://llvm.org/viewvc/llvm-project?rev=78075&view=rev
Log:
Some code refactoring. Be more generous in issuance of warning
on method type mismatches per Chris's comment.

Modified:
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/test/SemaObjC/warn-superclass-method-mismatch.m

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Tue Aug  4 12:01:09 2009
@@ -1464,35 +1464,41 @@
     AddInstanceMethodToGlobalPool(SetterMethod);     
 }
 
+/// CompareMethodParamsInBaseAndSuper - This routine compares methods with
+/// identical selector names in current and its super classes and issues
+/// a warning if any of their argument types are incompatible.
 void Sema::CompareMethodParamsInBaseAndSuper(Decl *ClassDecl,
                                              ObjCMethodDecl *Method,
                                              bool IsInstance)  {
-  if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(ClassDecl))
-    while (ObjCInterfaceDecl *SD = ID->getSuperClass()) {
-      if (ObjCMethodDecl *SuperMethodDecl = 
-          SD->lookupMethod(Method->getSelector(), IsInstance)) {
-        ObjCMethodDecl::param_iterator ParamI = Method->param_begin(),
-        E = Method->param_end();
-        ObjCMethodDecl::param_iterator PrevI = 
-        SuperMethodDecl->param_begin();
-        for (; ParamI != E; ++ParamI, ++PrevI) {
-          assert(PrevI != SuperMethodDecl->param_end() && "Param mismatch");
-          QualType T1 = Context.getCanonicalType((*ParamI)->getType());
-          QualType T2 = Context.getCanonicalType((*PrevI)->getType());
-          if (T1 != T2) {
-            AssignConvertType ConvTy = CheckAssignmentConstraints(T1, T2);
-            if (ConvTy == Incompatible || ConvTy == IncompatiblePointer) {
-              Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super) 
-                << T1 << T2;
-              Diag(SuperMethodDecl->getLocation(), 
-                   diag::note_previous_declaration);
-              return;
-            }
-          }
-        }
-      }
+  ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(ClassDecl);
+  if (ID == 0) return;
+  
+  while (ObjCInterfaceDecl *SD = ID->getSuperClass()) {
+    ObjCMethodDecl *SuperMethodDecl = 
+        SD->lookupMethod(Method->getSelector(), IsInstance);
+    if (SuperMethodDecl == 0) {
       ID = SD;
+      continue;
     }
+    ObjCMethodDecl::param_iterator ParamI = Method->param_begin(),
+      E = Method->param_end();
+    ObjCMethodDecl::param_iterator PrevI = SuperMethodDecl->param_begin();
+    for (; ParamI != E; ++ParamI, ++PrevI) {
+      // Number of parameters are the same and is guaranteed by selector match.
+      assert(PrevI != SuperMethodDecl->param_end() && "Param mismatch");
+      QualType T1 = Context.getCanonicalType((*ParamI)->getType());
+      QualType T2 = Context.getCanonicalType((*PrevI)->getType());
+      // If type of arguement of method in this class does not match its
+      // respective argument type in the super class method, issue warning;
+      if (!Context.typesAreCompatible(T1, T2)) {
+        Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super) 
+          << T1 << T2;
+        Diag(SuperMethodDecl->getLocation(), diag::note_previous_declaration);
+        return;
+      }
+    }
+    ID = SD;
+  }
 }
 
 // Note: For class/category implemenations, allMethods/allProperties is
@@ -1540,6 +1546,8 @@
         InsMap[Method->getSelector()] = Method;
         /// The following allows us to typecheck messages to "id".
         AddInstanceMethodToGlobalPool(Method);
+        // verify that the instance method conforms to the same definition of 
+        // parent methods if it shadows one.
         CompareMethodParamsInBaseAndSuper(ClassDecl, Method, true);
       }
     }
@@ -1558,6 +1566,8 @@
         ClsMap[Method->getSelector()] = Method;
         /// The following allows us to typecheck messages to "Class".
         AddFactoryMethodToGlobalPool(Method);
+        // verify that the class method conforms to the same definition of 
+        // parent methods if it shadows one.
         CompareMethodParamsInBaseAndSuper(ClassDecl, Method, false);
       }
     }

Modified: cfe/trunk/test/SemaObjC/warn-superclass-method-mismatch.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/warn-superclass-method-mismatch.m?rev=78075&r1=78074&r2=78075&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/warn-superclass-method-mismatch.m (original)
+++ cfe/trunk/test/SemaObjC/warn-superclass-method-mismatch.m Tue Aug  4 12:01:09 2009
@@ -12,6 +12,8 @@
 -(void) method2: (Sub*) x;
 + method3: (int)x1 : (Base *)x2 : (float)x3; // expected-note {{previous declaration is here}}
 + mathod4: (id)x1;
+- method5: (int) x : (double) d; // expected-note {{previous declaration is here}}
+- method6: (int) x : (float) d; // expected-note {{previous declaration is here}}
 @end
 
 struct A {
@@ -25,6 +27,8 @@
 + method3: (int)x1 : (Sub *)x2 : (float)x3;	// expected-warning {{method parameter type 'Sub *' does not match super class method parameter type 'Base *'}}
 + mathod4: (Base*)x1;
 -(void) method_r: (char)ch : (float*)f1 : (Sub*) x; // expected-warning {{method parameter type 'Sub *' does not match super class method parameter type 'int *'}}
+- method5: (int) x : (float) d; // expected-warning {{method parameter type 'float' does not match super class method parameter type 'double'}}
+- method6: (int) x : (double) d; // expected-warning {{method parameter type 'double' does not match super class method parameter type 'float'}}
 @end
 
 void f(Base *base, Sub *sub) {





More information about the cfe-commits mailing list