diff options
| -rw-r--r-- | clang/Driver/RewriteObjC.cpp | 33 | ||||
| -rw-r--r-- | clang/include/clang/AST/Expr.h | 5 | ||||
| -rw-r--r-- | clang/lib/AST/StmtDumper.cpp | 18 | ||||
| -rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 8 | ||||
| -rw-r--r-- | clang/test/Rewriter/objc-super-test.m | 2 |
6 files changed, 25 insertions, 44 deletions
diff --git a/clang/Driver/RewriteObjC.cpp b/clang/Driver/RewriteObjC.cpp index 9a4657e522b..c369f0fcf66 100644 --- a/clang/Driver/RewriteObjC.cpp +++ b/clang/Driver/RewriteObjC.cpp @@ -1848,31 +1848,14 @@ ObjCInterfaceDecl *RewriteObjC::isSuperReceiver(Expr *recExpr) { // 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/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index e5fd7521eee..ccd20befede 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -222,7 +222,10 @@ public: enum IdentType { Func, Function, - PrettyFunction + PrettyFunction, + ObjCSelf, // self + ObjCCmd, // _cmd + ObjCSuper // super }; private: diff --git a/clang/lib/AST/StmtDumper.cpp b/clang/lib/AST/StmtDumper.cpp index 6a65fbbf897..c8f72602ef2 100644 --- a/clang/lib/AST/StmtDumper.cpp +++ b/clang/lib/AST/StmtDumper.cpp @@ -311,17 +311,13 @@ void StmtDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 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/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index dc686f9bf59..53f31028be3 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -509,6 +509,9 @@ void StmtPrinter::VisitPreDefinedExpr(PreDefinedExpr *Node) { case PreDefinedExpr::PrettyFunction: OS << "__PRETTY_FUNCTION__"; break; + case PreDefinedExpr::ObjCSuper: + OS << "super"; + break; } } diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 1f21ee0ec57..920457e00c6 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -149,14 +149,10 @@ Sema::ExprResult Sema::ActOnClassMessage( 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/clang/test/Rewriter/objc-super-test.m b/clang/test/Rewriter/objc-super-test.m index 298248519d2..fc74843e8df 100644 --- a/clang/test/Rewriter/objc-super-test.m +++ b/clang/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; |

