]> granicus.if.org Git - clang/commitdiff
Teach the type checker about "id". This removes the following bogus warning...
authorSteve Naroff <snaroff@apple.com>
Mon, 15 Oct 2007 03:14:16 +0000 (03:14 +0000)
committerSteve Naroff <snaroff@apple.com>
Mon, 15 Oct 2007 03:14:16 +0000 (03:14 +0000)
[dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang t.m
t.m:29:18: warning: incompatible pointer types assigning 'id' to 'NSString *'
    resultString = [[NSString alloc] initWithFormat:0 arguments:0];
    ~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42975 91177308-0d34-0410-b5e6-96231b3b80d8

AST/Type.cpp
include/clang/AST/Type.h

index 762bc66926f64cf2b764e92ab76dde425174f7d9..87090978b45eae5274a895b1e4d205b145713caa 100644 (file)
@@ -267,6 +267,21 @@ bool Type::builtinTypesAreCompatible(QualType lhs, QualType rhs) {
   return lBuiltin->getKind() == rBuiltin->getKind();
 }
 
+// FIXME: Devise a way to do this without using strcmp.
+bool Type::isObjcIdType() const {
+  if (const RecordType *RT = getAsStructureType())
+    return !strcmp(RT->getDecl()->getName(), "objc_object");
+  return false;
+}
+
+bool Type::objcTypesAreCompatible(QualType lhs, QualType rhs) {
+  if (lhs->isObjcInterfaceType() && rhs->isObjcIdType())
+    return true;
+  else if (lhs->isObjcIdType() && rhs->isObjcInterfaceType())
+    return true;
+  return false;
+}
+
 bool Type::interfaceTypesAreCompatible(QualType lhs, QualType rhs) {
   return true; // FIXME: IMPLEMENT.
 }
@@ -384,9 +399,14 @@ bool Type::typesAreCompatible(QualType lhs, QualType rhs) {
     return true;
   
   // If the canonical type classes don't match, they can't be compatible
-  if (lcanon->getTypeClass() != rcanon->getTypeClass())
+  if (lcanon->getTypeClass() != rcanon->getTypeClass()) {
+    // For Objective-C, it is possible for two types to be compatible
+    // when their classes don't match (when dealing with "id"). If either type
+    // is an interface, we defer to objcTypesAreCompatible(). 
+    if (lcanon->isObjcInterfaceType() || rcanon->isObjcInterfaceType())
+      return objcTypesAreCompatible(lcanon, rcanon);
     return false;
-
+  }
   switch (lcanon->getTypeClass()) {
     case Type::Pointer:
       return pointerTypesAreCompatible(lcanon, rcanon);
index 696a14c40946f189e6b69a921cd7e111062fcfa6..2b1138c4f64f8b50581c839a1d49a1b7a9b470a4 100644 (file)
@@ -276,6 +276,7 @@ public:
   bool isVectorType() const; // GCC vector type.
   bool isOCUVectorType() const; // OCU vector type.
   bool isObjcInterfaceType() const; // includes conforming protocol type
+  bool isObjcIdType() const;
   
   // Type Checking Functions: Check to see if this type is structurally the
   // specified type, ignoring typedefs, and return a pointer to the best type
@@ -325,6 +326,7 @@ public:
   static bool arrayTypesAreCompatible(QualType, QualType); // C99 6.7.5.2p6
   static bool builtinTypesAreCompatible(QualType, QualType);
   static bool interfaceTypesAreCompatible(QualType, QualType);
+  static bool objcTypesAreCompatible(QualType, QualType);
 private:  
   QualType getCanonicalTypeInternal() const { return CanonicalType; }
   friend class QualType;