From: Steve Naroff Date: Mon, 15 Oct 2007 03:14:16 +0000 (+0000) Subject: Teach the type checker about "id". This removes the following bogus warning... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=954ea17353d3b24be52424bc287bdb6bef787fec;p=clang Teach the type checker about "id". This removes the following bogus warning... [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 --- diff --git a/AST/Type.cpp b/AST/Type.cpp index 762bc66926..87090978b4 100644 --- a/AST/Type.cpp +++ b/AST/Type.cpp @@ -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); diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 696a14c409..2b1138c4f6 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -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;