Remove a bunch of FIXME's related to ObjC type checking.

- Move Sema::ObjCQualifiedIdTypesAreCompatible(), Sema::QualifiedIdConformsQualifiedId(), and a couple helper functions to ASTContext.
- Change ASTContext::canAssignObjCInterfaces() to use ASTContext:: ObjCQualifiedIdTypesAreCompatible(). 
- Tweak several test cases to accommodate the new/improved type checking.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76830 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaObjC/comptypes-1.m b/test/SemaObjC/comptypes-1.m
index 8717bd0..df0785b 100644
--- a/test/SemaObjC/comptypes-1.m
+++ b/test/SemaObjC/comptypes-1.m
@@ -66,9 +66,7 @@
 
   /* Any comparison between 'MyClass *' and anything which is not an 'id'
      must generate a warning.  */
-  /* FIXME: GCC considers this a warning ("comparison of distinct pointer types"). */
-  /* There is a corresponding FIXME in ASTContext::mergeTypes() */
-  if (obj_p == obj_c) foo() ;
+  if (obj_p == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('id<MyProtocol>' and 'MyClass *')}}
 
   if (obj_c == obj_cp) foo() ; // expected-warning {{comparison of distinct pointer types ('MyClass *' and 'MyOtherClass *')}} 
   if (obj_cp == obj_c) foo() ; // expected-warning {{comparison of distinct pointer types ('MyOtherClass *' and 'MyClass *')}}
diff --git a/test/SemaObjC/comptypes-7.m b/test/SemaObjC/comptypes-7.m
index faca693..881fd2b 100644
--- a/test/SemaObjC/comptypes-7.m
+++ b/test/SemaObjC/comptypes-7.m
@@ -28,7 +28,7 @@
   obj = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'id'}}
 
   obj_p = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'id<MyProtocol>'}}
-  obj_p = j; // expected-warning {{incompatible type assigning 'int *', expected 'id<MyProtocol>'}}
+  obj_p = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'id<MyProtocol>'}}
   
   obj_c = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'MyClass *'}}
   obj_c = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'MyClass *'}}
@@ -42,7 +42,7 @@
   i = obj_C; // expected-warning {{incompatible pointer to integer conversion assigning 'Class', expected 'int'}}
   
   j = obj;   // expected-warning {{incompatible pointer types assigning 'id', expected 'int *'}}
-  j = obj_p; // expected-warning {{incompatible type assigning 'id<MyProtocol>', expected 'int *'}}
+  j = obj_p; // expected-warning {{incompatible pointer types assigning 'id<MyProtocol>', expected 'int *'}}
   j = obj_c; // expected-warning {{incompatible pointer types assigning 'MyClass *', expected 'int *'}}
   j = obj_C; // expected-warning {{incompatible pointer types assigning 'Class', expected 'int *'}}
   
diff --git a/test/SemaObjC/conditional-expr.m b/test/SemaObjC/conditional-expr.m
index 8ae1338..2043503 100644
--- a/test/SemaObjC/conditional-expr.m
+++ b/test/SemaObjC/conditional-expr.m
@@ -27,9 +27,8 @@
 @implementation DTFilterOutputStream2 // expected-warning {{incomplete implementation}} expected-warning {{method definition for 'nextOutputStream' not found}}
 - (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream {
   id <DTOutputStreams> nextOutputStream = [self nextOutputStream];
-  // GCC warns about both of these.
   self = nextOutputStream; // expected-warning {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream2 *'}}
-  return nextOutputStream ? nextOutputStream : self;
+  return nextOutputStream ? nextOutputStream : self; // expected-warning {{incompatible operand types ('id<DTOutputStreams>' and 'DTFilterOutputStream2 *')}}
 }
 @end
 
@@ -37,9 +36,8 @@
 @implementation DTFilterOutputStream3 // expected-warning {{cannot find interface declaration for 'DTFilterOutputStream3'}}
 - (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream {
   id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; // expected-warning {{method '-nextOutputStream' not found (return type defaults to 'id')}}
-  // GCC warns about both of these as well (no errors).
   self = nextOutputStream; // expected-warning {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream3 *'}}
-  return nextOutputStream ? nextOutputStream : self;
+  return nextOutputStream ? nextOutputStream : self; // expected-warning {{incompatible operand types ('id<DTOutputStreams>' and 'DTFilterOutputStream3 *')}}
 }
 @end
 
@@ -86,7 +84,7 @@
 }
 
 void f5(int cond, id<P0> x, C *y) {
-  (cond ? x : y).intProp = 1; // expected-error {{property 'intProp' not found on object of type 'C *'}}
+  (cond ? x : y).intProp = 1; // expected-warning {{incompatible operand types ('id<P0>' and 'C *')}} expected-error {{property 'intProp' not found on object of type 'id'}}
 }
 
 void f6(int cond, C *x, D *y) {