diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2010-10-29 18:26:21 +0000 | 
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-10-29 18:26:21 +0000 | 
| commit | 531a3707a9984ef23da0fddbd233ed33221a1444 (patch) | |
| tree | 6abdfd37f87e1d339b750653d17dfae7c8efabbe /clang/lib/AST | |
| parent | 0cce30fd3483980aa75c33b4c3dea3551f326ec0 (diff) | |
| download | bcm5719-llvm-531a3707a9984ef23da0fddbd233ed33221a1444.tar.gz bcm5719-llvm-531a3707a9984ef23da0fddbd233ed33221a1444.zip  | |
Qualified 'id' should implement all of static class type's
protocols, including those added to class, super class
and categories; otherewise issue a warning. This fixes
pr8453.
llvm-svn: 117678
Diffstat (limited to 'clang/lib/AST')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 53 | 
1 files changed, 33 insertions, 20 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 99023eeb7aa..107dafe70a3 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -4404,33 +4404,17 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,    if (const ObjCObjectPointerType *lhsOPT =          lhs->getAsObjCInterfacePointerType()) { -    if (lhsOPT->qual_empty()) { -      bool match = false; -      if (ObjCInterfaceDecl *lhsID = lhsOPT->getInterfaceDecl()) { -        for (ObjCObjectPointerType::qual_iterator I = rhsQID->qual_begin(), -             E = rhsQID->qual_end(); I != E; ++I) { -          // when comparing an id<P> on rhs with a static type on lhs, -          // static class must implement all of id's protocols directly or -          // indirectly through its super class. -          if (lhsID->ClassImplementsProtocol(*I, true)) { -            match = true; -            break; -          } -        } -        if (!match) -          return false; -      } -      return true; -    } -    // Both the right and left sides have qualifiers. +    // If both the right and left sides have qualifiers.      for (ObjCObjectPointerType::qual_iterator I = lhsOPT->qual_begin(),           E = lhsOPT->qual_end(); I != E; ++I) {        ObjCProtocolDecl *lhsProto = *I;        bool match = false; -      // when comparing an id<P> on lhs with a static type on rhs, +      // when comparing an id<P> on rhs with a static type on lhs,        // see if static class implements all of id's protocols, directly or        // through its super class and categories. +      // First, lhs protocols in the qualifier list must be found, direct +      // or indirect in rhs's qualifier list or it is a mismatch.        for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(),             E = rhsQID->qual_end(); J != E; ++J) {          ObjCProtocolDecl *rhsProto = *J; @@ -4443,6 +4427,35 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,        if (!match)          return false;      } +     +    // Static class's protocols, or its super class or category protocols +    // must be found, direct or indirect in rhs's qualifier list or it is a mismatch. +    if (ObjCInterfaceDecl *lhsID = lhsOPT->getInterfaceDecl()) { +      llvm::SmallPtrSet<ObjCProtocolDecl *, 8> LHSInheritedProtocols; +      CollectInheritedProtocols(lhsID, LHSInheritedProtocols); +      // This is rather dubious but matches gcc's behavior. If lhs has +      // no type qualifier and its class has no static protocol(s) assume +      // assume that it is mismatch. +      if (LHSInheritedProtocols.empty() && lhsOPT->qual_empty()) +        return false; +      for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I = +           LHSInheritedProtocols.begin(), +           E = LHSInheritedProtocols.end(); I != E; ++I) { +        bool match = false; +        ObjCProtocolDecl *lhsProto = (*I); +        for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(), +             E = rhsQID->qual_end(); J != E; ++J) { +          ObjCProtocolDecl *rhsProto = *J; +          if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || +              (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { +            match = true; +            break; +          } +        } +        if (!match) +          return false; +      } +    }      return true;    }    return false;  | 

