From d0c89c4609494e4aae0afb7704c35c0e9523f532 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 21 Dec 2007 00:33:59 +0000 Subject: [PATCH] More objective-c type analysis. This time involving objective types of conforming protocols (or not). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45276 91177308-0d34-0410-b5e6-96231b3b80d8 --- AST/ASTContext.cpp | 25 +++++++++++++++++++++---- Sema/SemaExpr.cpp | 2 +- include/clang/AST/ASTContext.h | 2 +- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index 417c56570a..5ec5131074 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -1278,10 +1278,25 @@ bool ASTContext::QualifiedInterfaceTypesAreCompatible(QualType lhs, return true; } +/// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the +/// inheritance hierarchy of 'rProto'. +static bool ProtocolCompatibleWithProtocol(ObjcProtocolDecl *lProto, + ObjcProtocolDecl *rProto) { + if (lProto == rProto) + return true; + ObjcProtocolDecl** RefPDecl = rProto->getReferencedProtocols(); + for (unsigned i = 0; i < rProto->getNumReferencedProtocols(); i++) + if (ProtocolCompatibleWithProtocol(lProto, RefPDecl[i])) + return true; + return false; +} + /// ObjcQualifiedIdTypesAreCompatible - Compares two types, at least -/// one of which is a protocol qualified 'id' type. +/// one of which is a protocol qualified 'id' type. When 'compare' +/// is true it is for comparison; when false, for assignment/initialization. bool ASTContext::ObjcQualifiedIdTypesAreCompatible(QualType lhs, - QualType rhs) { + QualType rhs, + bool compare) { // match id with an 'id' type in all cases. if (const PointerType *PT = lhs->getAsPointerType()) { QualType PointeeTy = PT->getPointeeType(); @@ -1339,7 +1354,8 @@ bool ASTContext::ObjcQualifiedIdTypesAreCompatible(QualType lhs, } for (unsigned j = 0; j < numRhsProtocols; j++) { ObjcProtocolDecl *rhsProto = rhsProtoList[j]; - if (lhsProto == rhsProto) { + if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || + compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) { match = true; break; } @@ -1385,7 +1401,8 @@ bool ASTContext::ObjcQualifiedIdTypesAreCompatible(QualType lhs, ObjcProtocolDecl *lhsProto = lhsProtoList[i]; for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) { ObjcProtocolDecl *rhsProto = rhsQID->getProtocols(j); - if (lhsProto == rhsProto) { + if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || + compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto)) { match = true; break; } diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index e720c2e460..d7a89865ea 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -1400,7 +1400,7 @@ inline QualType Sema::CheckCompareOperands( // C99 6.5.8 return Context.IntTy; } if ((lType->isObjcQualifiedIdType() || rType->isObjcQualifiedIdType()) - && Context.ObjcQualifiedIdTypesAreCompatible(lType, rType)) { + && Context.ObjcQualifiedIdTypesAreCompatible(lType, rType, true)) { promoteExprToType(rex, lType); return Context.IntTy; } diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 80188e25cf..a96cb5dfdc 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -297,7 +297,7 @@ public: /// Objective-C specific type checking. bool interfaceTypesAreCompatible(QualType, QualType); bool QualifiedInterfaceTypesAreCompatible(QualType, QualType); - bool ObjcQualifiedIdTypesAreCompatible(QualType, QualType); + bool ObjcQualifiedIdTypesAreCompatible(QualType, QualType, bool = false); bool objcTypesAreCompatible(QualType, QualType); bool isObjcIdType(QualType T) const { if (!IdStructType) // ObjC isn't enabled -- 2.40.0