ObjCMessageExpr objects that represent messages to class methods now can contain the ObjCInterfaceDecl* of the target class if it was available when the ObjCMessageExpr object was constructed.  The original interfaces of the class has been preserved (requiring no functionality changes from clients), but now a "getClasSInfo" method returns both the ObjCInterfaceDecl* and IdentifierInfo* of the target class.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52676 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index e18c27c..cdbafde 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1131,7 +1131,7 @@
     MethodProto(mproto) {
   NumArgs = nargs;
   SubExprs = new Stmt*[NumArgs+1];
-  SubExprs[RECEIVER] = (Expr*) ((uintptr_t) clsName | 0x1);
+  SubExprs[RECEIVER] = (Expr*) ((uintptr_t) clsName | IsClsMethDeclUnknown);
   if (NumArgs) {
     for (unsigned i = 0; i != NumArgs; ++i)
       SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
@@ -1140,6 +1140,40 @@
   RBracloc = RBrac;
 }
 
+// constructor for class messages. 
+ObjCMessageExpr::ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
+                                 QualType retType, ObjCMethodDecl *mproto,
+                                 SourceLocation LBrac, SourceLocation RBrac,
+                                 Expr **ArgExprs, unsigned nargs)
+: Expr(ObjCMessageExprClass, retType), SelName(selInfo), 
+MethodProto(mproto) {
+  NumArgs = nargs;
+  SubExprs = new Stmt*[NumArgs+1];
+  SubExprs[RECEIVER] = (Expr*) ((uintptr_t) cls | IsClsMethDeclKnown);
+  if (NumArgs) {
+    for (unsigned i = 0; i != NumArgs; ++i)
+      SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
+  }
+  LBracloc = LBrac;
+  RBracloc = RBrac;
+}
+
+ObjCMessageExpr::ClassInfo ObjCMessageExpr::getClassInfo() const {
+  uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
+  switch (x & Flags) {
+    default:
+      assert(false && "Invalid ObjCMessageExpr.");
+    case IsInstMeth:
+      return ClassInfo(0, 0);
+    case IsClsMethDeclUnknown:
+      return ClassInfo(0, (IdentifierInfo*) (x & ~Flags));
+    case IsClsMethDeclKnown: {
+      ObjCInterfaceDecl* D = (ObjCInterfaceDecl*) (x & ~Flags);
+      return ClassInfo(D, D->getIdentifier());
+    }
+  }
+}
+
 bool ChooseExpr::isConditionTrue(ASTContext &C) const {
   llvm::APSInt CondVal(32);
   bool IsConst = getCond()->isIntegerConstantExpr(CondVal, C);