Eliminate usage of ObjCSuperExpr used for
'super' as receiver of property or a setter/getter
methods. //rdar: //8525788



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116483 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 708512c..98f0656 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -2348,23 +2348,35 @@
 Stmt::child_iterator ObjCIvarRefExpr::child_end() { return &Base+1; }
 
 // ObjCPropertyRefExpr
-Stmt::child_iterator ObjCPropertyRefExpr::child_begin() { return &Base; }
-Stmt::child_iterator ObjCPropertyRefExpr::child_end() { return &Base+1; }
+Stmt::child_iterator ObjCPropertyRefExpr::child_begin()
+{ 
+  if (BaseExprOrSuperType.is<Stmt*>()) {
+    // Hack alert!
+    return reinterpret_cast<Stmt**> (&BaseExprOrSuperType);
+  }
+  return child_iterator(); 
+}
+
+Stmt::child_iterator ObjCPropertyRefExpr::child_end()
+{ return BaseExprOrSuperType.is<Stmt*>() ? 
+          reinterpret_cast<Stmt**> (&BaseExprOrSuperType)+1 : 
+          child_iterator(); 
+}
 
 // ObjCImplicitSetterGetterRefExpr
 Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_begin() {
-  // If this is accessing a class member, skip that entry.
-  if (Base) return &Base;
-  return &Base+1;
+  // If this is accessing a class member or super, skip that entry.
+  // Technically, 2nd condition is sufficient. But I want to be verbose
+  if (isSuperReceiver() || !Base)
+    return child_iterator();
+  return &Base;
 }
 Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_end() {
+  if (isSuperReceiver() || !Base)
+    return child_iterator();
   return &Base+1;
 }
 
-// ObjCSuperExpr
-Stmt::child_iterator ObjCSuperExpr::child_begin() { return child_iterator(); }
-Stmt::child_iterator ObjCSuperExpr::child_end() { return child_iterator(); }
-
 // ObjCIsaExpr
 Stmt::child_iterator ObjCIsaExpr::child_begin() { return &Base; }
 Stmt::child_iterator ObjCIsaExpr::child_end() { return &Base+1; }
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index c9069f8..0ab1402 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -109,7 +109,6 @@
   case Expr::CXXThrowExprClass:
   case Expr::ShuffleVectorExprClass:
   case Expr::IntegerLiteralClass:
-  case Expr::ObjCSuperExprClass:
   case Expr::CharacterLiteralClass:
   case Expr::AddrLabelExprClass:
   case Expr::CXXDeleteExprClass:
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 69a008f..715d30e 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -2468,7 +2468,6 @@
   case Expr::ObjCIvarRefExprClass:
   case Expr::ObjCPropertyRefExprClass:
   case Expr::ObjCImplicitSetterGetterRefExprClass:
-  case Expr::ObjCSuperExprClass:
   case Expr::ObjCIsaExprClass:
   case Expr::ShuffleVectorExprClass:
   case Expr::BlockExprClass:
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index 5c236a4..8b3ad5a 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -159,7 +159,6 @@
     void VisitObjCImplicitSetterGetterRefExpr(
                                           ObjCImplicitSetterGetterRefExpr *Node);
     void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
-    void VisitObjCSuperExpr(ObjCSuperExpr *Node);
   };
 }
 
@@ -606,8 +605,11 @@
 
 void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
   DumpExpr(Node);
-
-  OS << " Kind=PropertyRef Property=\"" << Node->getProperty() << '"';
+  if (Node->isSuperReceiver())
+    OS << " Kind=PropertyRef Property=\"" << Node->getProperty() << '"'
+    << " super";
+  else
+    OS << " Kind=PropertyRef Property=\"" << Node->getProperty() << '"';
 }
 
 void StmtDumper::VisitObjCImplicitSetterGetterRefExpr(
@@ -624,11 +626,8 @@
   else
     OS << "(null)";
   OS << "\"";
-}
-
-void StmtDumper::VisitObjCSuperExpr(ObjCSuperExpr *Node) {
-  DumpExpr(Node);
-  OS << " super";
+  if (Node->isSuperReceiver())
+    OS << " super";
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 2fc08da..51289b2 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -509,16 +509,21 @@
 }
 
 void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
-  if (Node->getBase()) {
+  if (Node->isSuperReceiver())
+    OS << "super.";
+  else if (Node->getBase()) {
     PrintExpr(Node->getBase());
     OS << ".";
   }
+
   OS << Node->getProperty()->getName();
 }
 
 void StmtPrinter::VisitObjCImplicitSetterGetterRefExpr(
                                         ObjCImplicitSetterGetterRefExpr *Node) {
-  if (Node->getBase()) {
+  if (Node->isSuperReceiver())
+    OS << "super.";
+  else if (Node->getBase()) {
     PrintExpr(Node->getBase());
     OS << ".";
   }
@@ -1298,9 +1303,6 @@
   OS << "]";
 }
 
-void StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) {
-  OS << "super";
-}
 
 void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
   BlockDecl *BD = Node->getBlockDecl();
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 607cf21..3f17a2b 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -863,6 +863,10 @@
 void StmtProfiler::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *S) {
   VisitExpr(S);
   VisitDecl(S->getProperty());
+  if (S->isSuperReceiver()) {
+    ID.AddBoolean(S->isSuperReceiver());
+    VisitType(S->getSuperType());
+  }
 }
 
 void StmtProfiler::VisitObjCImplicitSetterGetterRefExpr(
@@ -871,6 +875,10 @@
   VisitDecl(S->getGetterMethod());
   VisitDecl(S->getSetterMethod());
   VisitDecl(S->getInterfaceDecl());
+  if (S->isSuperReceiver()) {
+    ID.AddBoolean(S->isSuperReceiver());
+    VisitType(S->getSuperType());
+  }
 }
 
 void StmtProfiler::VisitObjCMessageExpr(ObjCMessageExpr *S) {
@@ -879,10 +887,6 @@
   VisitDecl(S->getMethodDecl());
 }
 
-void StmtProfiler::VisitObjCSuperExpr(ObjCSuperExpr *S) {
-  VisitExpr(S);
-}
-
 void StmtProfiler::VisitObjCIsaExpr(ObjCIsaExpr *S) {
   VisitExpr(S);
   ID.AddBoolean(S->isArrow());