Switch 'super' from being a weird cast thing to being a predefined expr node.
Patch by David Chisnall with objc rewriter and stmtdumper updates from me.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52580 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/RewriteObjC.cpp b/Driver/RewriteObjC.cpp
index 9a4657e..c369f0f 100644
--- a/Driver/RewriteObjC.cpp
+++ b/Driver/RewriteObjC.cpp
@@ -1848,31 +1848,14 @@
   // check if we are sending a message to 'super'
   if (!CurMethodDecl || !CurMethodDecl->isInstance()) return 0;
   
-  CastExpr *CE = dyn_cast<CastExpr>(recExpr);
-  if (!CE) return 0;
-  
-  DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr());
-  if (!DRE) return 0;
-  
-  ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl());
-  if (!PVD) return 0;
-  
-  if (strcmp(PVD->getName(), "self") != 0)
-    return 0;
-          
-  // is this id<P1..> type?
-  if (CE->getType()->isObjCQualifiedIdType())
-    return 0;
-  const PointerType *PT = CE->getType()->getAsPointerType();
-  if (!PT) return 0;
-  
-  ObjCInterfaceType *IT = dyn_cast<ObjCInterfaceType>(PT->getPointeeType());
-  if (!IT) return 0;
-  
-  if (IT->getDecl() != CurMethodDecl->getClassInterface()->getSuperClass())
-    return 0;
-              
-  return IT->getDecl();
+  if (PreDefinedExpr *PDE = dyn_cast<PreDefinedExpr>(recExpr))
+    if (PDE->getIdentType() == PreDefinedExpr::ObjCSuper) {
+      const PointerType *PT = PDE->getType()->getAsPointerType();
+      assert(PT);
+      ObjCInterfaceType *IT = cast<ObjCInterfaceType>(PT->getPointeeType());
+      return IT->getDecl();
+    }
+  return 0;
 }
 
 // struct objc_super { struct objc_object *receiver; struct objc_class *super; };
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index e5fd752..ccd20be 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -222,7 +222,10 @@
   enum IdentType {
     Func,
     Function,
-    PrettyFunction
+    PrettyFunction,
+    ObjCSelf, // self
+    ObjCCmd,  // _cmd
+    ObjCSuper // super
   };
   
 private:
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index 6a65fbb..c8f7260 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -311,17 +311,13 @@
 void StmtDumper::VisitPreDefinedExpr(PreDefinedExpr *Node) {
   DumpExpr(Node);
   switch (Node->getIdentType()) {
-  default:
-    assert(0 && "unknown case");
-  case PreDefinedExpr::Func:
-    fprintf(F, " __func__");
-    break;
-  case PreDefinedExpr::Function:
-    fprintf(F, " __FUNCTION__");
-    break;
-  case PreDefinedExpr::PrettyFunction:
-    fprintf(F, " __PRETTY_FUNCTION__");
-    break;
+  default: assert(0 && "unknown case");
+  case PreDefinedExpr::Func:           fprintf(F, " __func__"); break;
+  case PreDefinedExpr::Function:       fprintf(F, " __FUNCTION__"); break;
+  case PreDefinedExpr::PrettyFunction: fprintf(F, " __PRETTY_FUNCTION__");break;
+  case PreDefinedExpr::ObjCSelf:       fprintf(F, "self"); break;
+  case PreDefinedExpr::ObjCCmd:        fprintf(F, "_cmd"); break;
+  case PreDefinedExpr::ObjCSuper:      fprintf(F, "super"); break;
   }
 }
 
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index dc686f9..53f3102 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -509,6 +509,9 @@
     case PreDefinedExpr::PrettyFunction:
       OS << "__PRETTY_FUNCTION__";
       break;
+    case PreDefinedExpr::ObjCSuper:
+      OS << "super";
+      break;
   }
 }
 
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 1f21ee0..920457e 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -149,14 +149,10 @@
       return Diag(lbrac, diag::error_no_super_class,
                   CurMethodDecl->getClassInterface()->getName());
     if (CurMethodDecl->isInstance()) {
-      // Synthesize a cast to the super class. This hack allows us to loosely
-      // represent super without creating a special expression node.
-      IdentifierInfo &II = Context.Idents.get("self");
-      ExprResult ReceiverExpr = ActOnIdentifierExpr(S, lbrac, II, false);
       QualType superTy = Context.getObjCInterfaceType(ClassDecl);
       superTy = Context.getPointerType(superTy);
-      ReceiverExpr = ActOnCastExpr(SourceLocation(), superTy.getAsOpaquePtr(),
-                                   SourceLocation(), ReceiverExpr.Val);
+      ExprResult ReceiverExpr = new PreDefinedExpr(SourceLocation(), superTy,
+          PreDefinedExpr::ObjCSuper);
       // We are really in an instance method, redirect.
       return ActOnInstanceMessage(ReceiverExpr.Val, Sel, lbrac, rbrac,
                                   Args, NumArgs);
diff --git a/test/Rewriter/objc-super-test.m b/test/Rewriter/objc-super-test.m
index 2982485..fc74843 100644
--- a/test/Rewriter/objc-super-test.m
+++ b/test/Rewriter/objc-super-test.m
@@ -1,4 +1,4 @@
-// RUN: clang -rewrite-objc %s -o=-
+// RUN: clang -rewrite-objc %s -o - | grep objc_msgSendSuper | grep MainMethod
 
 @interface SUPER
 - (int) MainMethod;