summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2010-11-01 20:47:16 +0000
committerFariborz Jahanian <fjahanian@apple.com>2010-11-01 20:47:16 +0000
commiteb7714c290d20c012a9986321b2bd6ddb0812671 (patch)
tree69fcbf94ea813f2b97e5c6b94985ed65b2d2a0b1 /clang/lib/AST/ASTContext.cpp
parentc6627eec1364141d1ca61ec342a70b0cd152072d (diff)
downloadbcm5719-llvm-eb7714c290d20c012a9986321b2bd6ddb0812671.tar.gz
bcm5719-llvm-eb7714c290d20c012a9986321b2bd6ddb0812671.zip
Restore patch for PR8453 which was undone in r117829
(was project bugs). llvm-svn: 117951
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
-rw-r--r--clang/lib/AST/ASTContext.cpp53
1 files changed, 33 insertions, 20 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 99023eeb7aa..366fe7d28f1 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 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;
OpenPOWER on IntegriCloud