More work to integrate newly added ObjCQualifiedClassType into the type system.
This is necessary 'plumbing' to fix <rdar://problem/6497631> Message lookup is sometimes different than gcc's.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65248 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index c390f76..b17f7bc 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2734,7 +2734,9 @@
// C99 6.5.16.1p1: the left operand is a pointer and the right is
// a null pointer constant.
- if ((lhsType->isPointerType() || lhsType->isObjCQualifiedIdType() ||
+ if ((lhsType->isPointerType() ||
+ lhsType->isObjCQualifiedIdType() ||
+ lhsType->isObjCQualifiedClassType() ||
lhsType->isBlockPointerType())
&& rExpr->isNullPointerConstant(Context)) {
ImpCastExprToType(rExpr, lhsType);
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 19dc382..afa0255 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -391,7 +391,8 @@
// We allow sending a message to a qualified ID ("id<foo>"), which is ok as
// long as one of the protocols implements the selector (if not, warn).
if (ObjCQualifiedIdType *QIT = dyn_cast<ObjCQualifiedIdType>(ReceiverCType)) {
- // Search protocols
+ // Search protocols for instance methods.
+ ReceiverCType.dump();
for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
ObjCProtocolDecl *PDecl = QIT->getProtocols(i);
if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
@@ -400,6 +401,18 @@
if (!Method)
Diag(lbrac, diag::warn_method_not_found_in_protocol)
<< Sel << RExpr->getSourceRange();
+ // Check for GCC extension "Class<foo>".
+ } else if (ObjCQualifiedClassType *QIT =
+ dyn_cast<ObjCQualifiedClassType>(ReceiverCType)) {
+ // Search protocols for class methods.
+ for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
+ ObjCProtocolDecl *PDecl = QIT->getProtocols(i);
+ if (PDecl && (Method = PDecl->lookupClassMethod(Sel)))
+ break;
+ }
+ if (!Method)
+ Diag(lbrac, diag::warn_method_not_found_in_protocol)
+ << Sel << RExpr->getSourceRange();
} else if (const ObjCInterfaceType *OCIReceiver =
ReceiverCType->getAsPointerToObjCInterfaceType()) {
// We allow sending a message to a pointer to an interface (an object).