continue cleaning up code, and disable sending a message directly to an
interface.  This fixes a bug where we used to accept:

void test2(NSNumber x) {
	[x METH];
}

which doesn't make sense and GCC rejects.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53841 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index bcd3975..0e5de3a 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -226,14 +226,13 @@
   Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
   Expr *RExpr = static_cast<Expr *>(receiver);
   QualType returnType;
-  ObjCMethodDecl *Method = 0;
 
   QualType receiverType = 
     RExpr->getType().getCanonicalType().getUnqualifiedType();
   
   // Handle messages to id.
   if (receiverType == Context.getObjCIdType().getCanonicalType()) {
-    Method = InstanceMethodPool[Sel].Method;
+    ObjCMethodDecl *Method = InstanceMethodPool[Sel].Method;
     if (!Method)
       Method = FactoryMethodPool[Sel].Method;
     if (!Method) {
@@ -252,6 +251,7 @@
   
   // Handle messages to Class.
   if (receiverType == Context.getObjCClassType().getCanonicalType()) {
+    ObjCMethodDecl *Method = 0;
     if (getCurMethodDecl()) {
       ObjCInterfaceDecl* ClassDecl = getCurMethodDecl()->getClassInterface();
       // If we have an implementation in scope, check "private" methods.
@@ -279,18 +279,14 @@
                                ArgExprs, NumArgs);
   }
   
-  // We allow sending a message to a qualified ID ("id<foo>") to an interface
-  // directly ("[NSNumber foo]") and to a pointer to an interface (an object).
-  if (!isa<ObjCQualifiedIdType>(receiverType) &&
-      !isa<ObjCInterfaceType>(receiverType))
-    if (const PointerType *PTy = receiverType->getAsPointerType())
-      receiverType = PTy->getPointeeType();
-    // else error, invalid receiver.
-  
+  ObjCMethodDecl *Method = 0;
   ObjCInterfaceDecl* ClassDecl = 0;
+  
+  // 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>(receiverType)) {
-    // search protocols
+    // Search protocols
     for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
       ObjCProtocolDecl *PDecl = QIT->getProtocols(i);
       if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
@@ -300,13 +296,9 @@
       Diag(lbrac, diag::warn_method_not_found_in_protocol, 
            std::string("-"), Sel.getName(),
            SourceRange(lbrac, rbrac));
-  } else {
-    ObjCInterfaceType *OCIReceiver =dyn_cast<ObjCInterfaceType>(receiverType);
-    if (OCIReceiver == 0) {
-      Diag(lbrac, diag::error_bad_receiver_type,
-           RExpr->getType().getAsString());
-      return true;
-    }
+  } else if (const ObjCInterfaceType *OCIReceiver = 
+                receiverType->getAsPointerToObjCInterfaceType()) {
+    // We allow sending a message to a pointer to an interface (an object).
     
     ClassDecl = OCIReceiver->getDecl();
     // FIXME: consider using InstanceMethodPool, since it will be faster
@@ -327,6 +319,10 @@
       Diag(lbrac, diag::warn_method_not_found_in_protocol, 
            std::string("-"), Sel.getName(),
            SourceRange(lbrac, rbrac));
+  } else {
+    Diag(lbrac, diag::error_bad_receiver_type,
+         RExpr->getType().getAsString());
+    return true;
   }
   
   if (!Method) {