Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:

  1) Send to a object instance described by an expression (e.g., [x method:5])
  2) Send to a class described by the class name (e.g., [NSString method:5])
  3) Send to a superclass class (e.g, [super method:5] in class method)
  4) Send to a superclass instance (e.g., [super method:5] in instance method)

Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:

  1) Unchanged; the object instance is represented by an Expr*.

  2) Previously stored the ObjCInterfaceDecl* referring to the class
  receiving the message. Now stores a TypeSourceInfo* so that we know
  how the class was spelled. This both maintains typedef information
  and opens the door for more complicated C++ types (e.g., dependent
  types). There was an alternative, unused representation of these
  sends by naming the class via an IdentifierInfo *. In practice, we
  either had an ObjCInterfaceDecl *, from which we would get the
  IdentifierInfo *, or we fell into the case below...

  3) Previously represented by a class message whose IdentifierInfo *
  referred to "super". Sema and CodeGen would use isStr("super") to
  determine if they had a send to super. Now represented as a
  "class super" send, where we have both the location of the "super"
  keyword and the ObjCInterfaceDecl* of the superclass we're
  targetting (statically).

  4) Previously represented by an instance message whose receiver is a
  an ObjCSuperExpr, which Sema and CodeGen would check for via
  isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
  where we have both the location of the "super" keyword and the
  ObjCInterfaceDecl* of the superclass we're targetting
  (statically). Note that ObjCSuperExpr only has one remaining use in
  the AST, which is for "super.prop" references.

The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!

This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:

  if (message has a receiver expression) {
    // instance message
    if (isa<ObjCSuperExpr>(...)) {
     // send to super
    } else {
     // send to an object
   }
  } else {
    // class message
    if (name->isStr("super")) {
      // class send to super
    } else {
      // send to class
    }
  }

with a switch

  switch (E->getReceiverKind()) {
  case ObjCMessageExpr::SuperInstance: ...
  case ObjCMessageExpr::Instance: ...
  case ObjCMessageExpr::SuperClass: ...
  case ObjCMessageExpr::Class:...
  }

There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101972 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index 60318de..d253654 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -782,25 +782,42 @@
 
 unsigned PCHStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
   VisitExpr(E);
-  E->setNumArgs(Record[Idx++]);
+  assert(Record[Idx] == E->getNumArgs());
+  ++Idx;
+  ObjCMessageExpr::ReceiverKind Kind
+    = static_cast<ObjCMessageExpr::ReceiverKind>(Record[Idx++]);
+  switch (Kind) {
+  case ObjCMessageExpr::Instance:
+    E->setInstanceReceiver(
+         cast_or_null<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
+    break;
+
+  case ObjCMessageExpr::Class:
+    E->setClassReceiver(Reader.GetTypeSourceInfo(Record, Idx));
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance: {
+    QualType T = Reader.GetType(Record[Idx++]);
+    SourceLocation SuperLoc = SourceLocation::getFromRawEncoding(Record[Idx++]);
+    E->setSuper(SuperLoc, T, Kind == ObjCMessageExpr::SuperInstance);
+    break;
+  }
+  }
+
+  assert(Kind == E->getReceiverKind());
+
+  if (Record[Idx++])
+    E->setMethodDecl(cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+  else
+    E->setSelector(Reader.GetSelector(Record, Idx));
+
   E->setLeftLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
   E->setRightLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  E->setSelector(Reader.GetSelector(Record, Idx));
-  E->setMethodDecl(cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
-
-  E->setReceiver(
-         cast_or_null<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
-  if (!E->getReceiver()) {
-    ObjCMessageExpr::ClassInfo CI;
-    CI.Decl = cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]));
-    CI.Name = Reader.GetIdentifierInfo(Record, Idx);
-    CI.Loc = SourceLocation::getFromRawEncoding(Record[Idx++]);
-    E->setClassInfo(CI);
-  }
 
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
     E->setArg(I, cast<Expr>(StmtStack[StmtStack.size() - N + I]));
-  return E->getNumArgs() + 1;
+  return E->getNumArgs() + (Kind == ObjCMessageExpr::Instance);
 }
 
 unsigned PCHStmtReader::VisitObjCSuperExpr(ObjCSuperExpr *E) {
@@ -1195,7 +1212,8 @@
       S = new (Context) ObjCImplicitSetterGetterRefExpr(Empty);
       break;
     case pch::EXPR_OBJC_MESSAGE_EXPR:
-      S = new (Context) ObjCMessageExpr(Empty);
+      S = ObjCMessageExpr::CreateEmpty(*Context,
+                                     Record[PCHStmtReader::NumExprFields]);
       break;
     case pch::EXPR_OBJC_SUPER_EXPR:
       S = new (Context) ObjCSuperExpr(Empty);