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);
diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp
index 9c9f891..9a9539b 100644
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -712,18 +712,33 @@
 void PCHStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
   VisitExpr(E);
   Record.push_back(E->getNumArgs());
+  Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
+  switch (E->getReceiverKind()) {
+  case ObjCMessageExpr::Instance:
+    Writer.WriteSubStmt(E->getInstanceReceiver());
+    break;
+
+  case ObjCMessageExpr::Class:
+    Writer.AddTypeSourceInfo(E->getClassReceiverTypeInfo(), Record);
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance:
+    Writer.AddTypeRef(E->getSuperType(), Record);
+    Writer.AddSourceLocation(E->getSuperLoc(), Record);
+    break;
+  }
+
+  if (E->getMethodDecl()) {
+    Record.push_back(1);
+    Writer.AddDeclRef(E->getMethodDecl(), Record);
+  } else {
+    Record.push_back(0);
+    Writer.AddSelectorRef(E->getSelector(), Record);    
+  }
+    
   Writer.AddSourceLocation(E->getLeftLoc(), Record);
   Writer.AddSourceLocation(E->getRightLoc(), Record);
-  Writer.AddSelectorRef(E->getSelector(), Record);
-  Writer.AddDeclRef(E->getMethodDecl(), Record); // optional
-  Writer.WriteSubStmt(E->getReceiver());
-
-  if (!E->getReceiver()) {
-    ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
-    Writer.AddDeclRef(CI.Decl, Record);
-    Writer.AddIdentifierRef(CI.Name, Record);
-    Writer.AddSourceLocation(CI.Loc, Record);
-  }
 
   for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
        Arg != ArgEnd; ++Arg)
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp
index 804a5d0..65b57d6 100644
--- a/lib/Frontend/RewriteObjC.cpp
+++ b/lib/Frontend/RewriteObjC.cpp
@@ -1239,11 +1239,26 @@
     // This allows us to handle chain/nested property getters.
     Receiver = PropGetters[PRE];
   }
-  MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
-                                PDecl->getSetterName(), PDecl->getType(),
-                                PDecl->getSetterMethodDecl(),
-                                SourceLocation(), SourceLocation(),
-                                &ExprVec[0], 1);
+  if (isa<ObjCSuperExpr>(Receiver))
+    MsgExpr = ObjCMessageExpr::Create(*Context, 
+                                      PDecl->getType().getNonReferenceType(),
+                                      /*FIXME?*/SourceLocation(),
+                                      Receiver->getLocStart(),
+                                      /*IsInstanceSuper=*/true,
+                                      cast<Expr>(Receiver)->getType(),
+                                      PDecl->getSetterName(),
+                                      PDecl->getSetterMethodDecl(),
+                                      &ExprVec[0], 1,
+                                      /*FIXME:*/SourceLocation());
+  else
+    MsgExpr = ObjCMessageExpr::Create(*Context, 
+                                      PDecl->getType().getNonReferenceType(),
+                                      /*FIXME: */SourceLocation(),
+                                      cast<Expr>(Receiver),
+                                      PDecl->getSetterName(),
+                                      PDecl->getSetterMethodDecl(),
+                                      &ExprVec[0], 1,
+                                      /*FIXME:*/SourceLocation());
   Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
 
   // Now do the actual rewrite.
@@ -1268,11 +1283,27 @@
     // This allows us to handle chain/nested property getters.
     Receiver = PropGetters[PRE];
   }
-  MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
-                                PDecl->getGetterName(), PDecl->getType(),
-                                PDecl->getGetterMethodDecl(),
-                                SourceLocation(), SourceLocation(),
-                                0, 0);
+
+  if (isa<ObjCSuperExpr>(Receiver))
+    MsgExpr = ObjCMessageExpr::Create(*Context, 
+                                      PDecl->getType().getNonReferenceType(),
+                                      /*FIXME:*/SourceLocation(),
+                                      Receiver->getLocStart(),
+                                      /*IsInstanceSuper=*/true,
+                                      cast<Expr>(Receiver)->getType(),
+                                      PDecl->getGetterName(), 
+                                      PDecl->getGetterMethodDecl(),
+                                      0, 0, 
+                                      /*FIXME:*/SourceLocation());
+  else
+    MsgExpr = ObjCMessageExpr::Create(*Context, 
+                                      PDecl->getType().getNonReferenceType(),
+                                      /*FIXME:*/SourceLocation(),
+                                      cast<Expr>(Receiver),
+                                      PDecl->getGetterName(), 
+                                      PDecl->getGetterMethodDecl(),
+                                      0, 0, 
+                                      /*FIXME:*/SourceLocation());
 
   Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
 
@@ -2687,205 +2718,211 @@
 
   // Synthesize a call to objc_msgSend().
   llvm::SmallVector<Expr*, 8> MsgExprs;
-  IdentifierInfo *clsName = Exp->getClassName();
+  switch (Exp->getReceiverKind()) {
+  case ObjCMessageExpr::SuperClass: {
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
 
-  // Derive/push the receiver/selector, 2 implicit arguments to objc_msgSend().
-  if (clsName) { // class message.
-    // FIXME: We need to fix Sema (and the AST for ObjCMessageExpr) to handle
-    // the 'super' idiom within a class method.
-    if (clsName->getName() == "super") {
-      MsgSendFlavor = MsgSendSuperFunctionDecl;
-      if (MsgSendStretFlavor)
-        MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
-      assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
 
-      ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+    llvm::SmallVector<Expr*, 4> InitExprs;
 
-      llvm::SmallVector<Expr*, 4> InitExprs;
+    // set the receiver to self, the first argument to all methods.
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CastExpr::CK_Unknown,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                   Context->getObjCIdType(),
+                                   SourceLocation()))
+                        ); // set the 'receiver'.
 
-      // set the receiver to self, the first argument to all methods.
-      InitExprs.push_back(
-        NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                                 CastExpr::CK_Unknown,
-                     new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
-                                     Context->getObjCIdType(),
-                                     SourceLocation()))
-                          ); // set the 'receiver'.
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    llvm::SmallVector<Expr*, 8> ClsExprs;
+    QualType argType = Context->getPointerType(Context->CharTy);
+    ClsExprs.push_back(StringLiteral::Create(*Context,
+                                   ClassDecl->getIdentifier()->getNameStart(),
+                                   ClassDecl->getIdentifier()->getLength(),
+                                   false, argType, SourceLocation()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(),
+                                                 StartLoc,
+                                                 EndLoc);
+    // (Class)objc_getClass("CurrentClass")
+    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+                                             Context->getObjCClassType(),
+                                             CastExpr::CK_Unknown, Cls);
+    ClsExprs.clear();
+    ClsExprs.push_back(ArgExpr);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back( // set 'super class', using class_getSuperclass().
+                        NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCIdType(),
+                                                 CastExpr::CK_Unknown, Cls));
+    // struct objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
 
-      // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-      llvm::SmallVector<Expr*, 8> ClsExprs;
-      QualType argType = Context->getPointerType(Context->CharTy);
-      ClsExprs.push_back(StringLiteral::Create(*Context,
-                                     ClassDecl->getIdentifier()->getNameStart(),
-                                     ClassDecl->getIdentifier()->getLength(),
-                                     false, argType, SourceLocation()));
-      CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
-                                                   &ClsExprs[0],
-                                                   ClsExprs.size(),
-                                                   StartLoc,
-                                                   EndLoc);
-      // (Class)objc_getClass("CurrentClass")
-      CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
-                                               Context->getObjCClassType(),
-                                               CastExpr::CK_Unknown, Cls);
-      ClsExprs.clear();
-      ClsExprs.push_back(ArgExpr);
-      Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
-                                         &ClsExprs[0], ClsExprs.size(),
-                                         StartLoc, EndLoc);
-      
-      // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-      // To turn off a warning, type-cast to 'id'
-      InitExprs.push_back( // set 'super class', using class_getSuperclass().
-                          NoTypeInfoCStyleCastExpr(Context,
-                                                   Context->getObjCIdType(),
-                                                   CastExpr::CK_Unknown, Cls));
-      // struct objc_super
-      QualType superType = getSuperStructType();
-      Expr *SuperRep;
-
-      if (LangOpts.Microsoft) {
-        SynthSuperContructorFunctionDecl();
-        // Simulate a contructor call...
-        DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
-                                           superType, SourceLocation());
-        SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
-                                          InitExprs.size(),
-                                          superType, SourceLocation());
-        // The code for super is a little tricky to prevent collision with
-        // the structure definition in the header. The rewriter has it's own
-        // internal definition (__rw_objc_super) that is uses. This is why
-        // we need the cast below. For example:
-        // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
-        //
-        SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
-                                 Context->getPointerType(SuperRep->getType()),
-                                 SourceLocation());
-        SuperRep = NoTypeInfoCStyleCastExpr(Context,
-                                            Context->getPointerType(superType),
-                                            CastExpr::CK_Unknown, SuperRep);
-      } else {
-        // (struct objc_super) { <exprs from above> }
-        InitListExpr *ILE =
-          new (Context) InitListExpr(*Context, SourceLocation(),
-                                     &InitExprs[0], InitExprs.size(),
-                                     SourceLocation());
-        TypeSourceInfo *superTInfo
-          = Context->getTrivialTypeSourceInfo(superType);
-        SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
-                                                     superType, ILE, false);
-        // struct objc_super *
-        SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
-                                 Context->getPointerType(SuperRep->getType()),
-                                 SourceLocation());
-      }
-      MsgExprs.push_back(SuperRep);
+    if (LangOpts.Microsoft) {
+      SynthSuperContructorFunctionDecl();
+      // Simulate a contructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
+                                         superType, SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
+                                        InitExprs.size(),
+                                        superType, SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                                          Context->getPointerType(superType),
+                                          CastExpr::CK_Unknown, SuperRep);
     } else {
-      llvm::SmallVector<Expr*, 8> ClsExprs;
-      QualType argType = Context->getPointerType(Context->CharTy);
-      ClsExprs.push_back(StringLiteral::Create(*Context,
-                                               clsName->getNameStart(),
-                                               clsName->getLength(),
-                                               false, argType,
-                                               SourceLocation()));
-      CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
-                                                   &ClsExprs[0],
-                                                   ClsExprs.size(), 
-                                                   StartLoc, EndLoc);
-      MsgExprs.push_back(Cls);
+      // (struct objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(),
+                                   &InitExprs[0], InitExprs.size(),
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, ILE, false);
+      // struct objc_super *
+      SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               SourceLocation());
     }
-  } else { // instance message.
-    Expr *recExpr = Exp->getReceiver();
-
-    if (isSuperReceiver(recExpr)) {
-      MsgSendFlavor = MsgSendSuperFunctionDecl;
-      if (MsgSendStretFlavor)
-        MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
-      assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
-      ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
-      llvm::SmallVector<Expr*, 4> InitExprs;
-
-      InitExprs.push_back(
-        NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                                 CastExpr::CK_Unknown,
-                     new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
-                                     Context->getObjCIdType(),
-                                     SourceLocation()))
-                          ); // set the 'receiver'.
-      
-      // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-      llvm::SmallVector<Expr*, 8> ClsExprs;
-      QualType argType = Context->getPointerType(Context->CharTy);
-      ClsExprs.push_back(StringLiteral::Create(*Context,
-                                     ClassDecl->getIdentifier()->getNameStart(),
-                                     ClassDecl->getIdentifier()->getLength(),
-                                     false, argType, SourceLocation()));
-      CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
-                                                   &ClsExprs[0],
-                                                   ClsExprs.size(), 
-                                                   StartLoc, EndLoc);
-      // (Class)objc_getClass("CurrentClass")
-      CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
-                                                   Context->getObjCClassType(),
-                                                   CastExpr::CK_Unknown, Cls);
-      ClsExprs.clear();
-      ClsExprs.push_back(ArgExpr);
-      Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
-                                         &ClsExprs[0], ClsExprs.size(),
-                                         StartLoc, EndLoc);
-      
-      // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-      // To turn off a warning, type-cast to 'id'
-      InitExprs.push_back(
-        // set 'super class', using class_getSuperclass().
-        NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                                 CastExpr::CK_Unknown, Cls));
-      // struct objc_super
-      QualType superType = getSuperStructType();
-      Expr *SuperRep;
-
-      if (LangOpts.Microsoft) {
-        SynthSuperContructorFunctionDecl();
-        // Simulate a contructor call...
-        DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
-                                           superType, SourceLocation());
-        SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
-                                          InitExprs.size(),
-                                          superType, SourceLocation());
-        // The code for super is a little tricky to prevent collision with
-        // the structure definition in the header. The rewriter has it's own
-        // internal definition (__rw_objc_super) that is uses. This is why
-        // we need the cast below. For example:
-        // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
-        //
-        SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
-                                 Context->getPointerType(SuperRep->getType()),
-                                 SourceLocation());
-        SuperRep = NoTypeInfoCStyleCastExpr(Context,
-                                 Context->getPointerType(superType),
-                                 CastExpr::CK_Unknown, SuperRep);
-      } else {
-        // (struct objc_super) { <exprs from above> }
-        InitListExpr *ILE =
-          new (Context) InitListExpr(*Context, SourceLocation(),
-                                     &InitExprs[0], InitExprs.size(),
-                                     SourceLocation());
-        TypeSourceInfo *superTInfo
-          = Context->getTrivialTypeSourceInfo(superType);
-        SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
-                                                     superType, ILE, false);
-      }
-      MsgExprs.push_back(SuperRep);
-    } else {
-      // Remove all type-casts because it may contain objc-style types; e.g.
-      // Foo<Proto> *.
-      while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
-        recExpr = CE->getSubExpr();
-      recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                                         CastExpr::CK_Unknown, recExpr);
-      MsgExprs.push_back(recExpr);
-    }
+    MsgExprs.push_back(SuperRep);
+    break;
   }
+
+  case ObjCMessageExpr::Class: {
+    llvm::SmallVector<Expr*, 8> ClsExprs;
+    QualType argType = Context->getPointerType(Context->CharTy);
+    ObjCInterfaceDecl *Class
+      = Exp->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+    IdentifierInfo *clsName = Class->getIdentifier();
+    ClsExprs.push_back(StringLiteral::Create(*Context,
+                                             clsName->getNameStart(),
+                                             clsName->getLength(),
+                                             false, argType,
+                                             SourceLocation()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    MsgExprs.push_back(Cls);
+    break;
+  }
+
+  case ObjCMessageExpr::SuperInstance:{
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+    llvm::SmallVector<Expr*, 4> InitExprs;
+
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CastExpr::CK_Unknown,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                   Context->getObjCIdType(),
+                                   SourceLocation()))
+                        ); // set the 'receiver'.
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    llvm::SmallVector<Expr*, 8> ClsExprs;
+    QualType argType = Context->getPointerType(Context->CharTy);
+    ClsExprs.push_back(StringLiteral::Create(*Context,
+                                   ClassDecl->getIdentifier()->getNameStart(),
+                                   ClassDecl->getIdentifier()->getLength(),
+                                   false, argType, SourceLocation()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    // (Class)objc_getClass("CurrentClass")
+    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCClassType(),
+                                                 CastExpr::CK_Unknown, Cls);
+    ClsExprs.clear();
+    ClsExprs.push_back(ArgExpr);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back(
+      // set 'super class', using class_getSuperclass().
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CastExpr::CK_Unknown, Cls));
+    // struct objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
+
+    if (LangOpts.Microsoft) {
+      SynthSuperContructorFunctionDecl();
+      // Simulate a contructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
+                                         superType, SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
+                                        InitExprs.size(),
+                                        superType, SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                               Context->getPointerType(superType),
+                               CastExpr::CK_Unknown, SuperRep);
+    } else {
+      // (struct objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(),
+                                   &InitExprs[0], InitExprs.size(),
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, ILE, false);
+    }
+    MsgExprs.push_back(SuperRep);
+    break;
+  }
+
+  case ObjCMessageExpr::Instance: {
+    // Remove all type-casts because it may contain objc-style types; e.g.
+    // Foo<Proto> *.
+    Expr *recExpr = Exp->getInstanceReceiver();
+    while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
+      recExpr = CE->getSubExpr();
+    recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                       CastExpr::CK_Unknown, recExpr);
+    MsgExprs.push_back(recExpr);
+    break;
+  }
+  }
+
   // Create a call to sel_registerName("selName"), it will be the 2nd argument.
   llvm::SmallVector<Expr*, 8> SelExprs;
   QualType argType = Context->getPointerType(Context->CharTy);