1*67e74705SXin Li //===--- TransUnusedInitDelegate.cpp - Transformations to ARC mode --------===// 2*67e74705SXin Li // 3*67e74705SXin Li // The LLVM Compiler Infrastructure 4*67e74705SXin Li // 5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source 6*67e74705SXin Li // License. See LICENSE.TXT for details. 7*67e74705SXin Li // 8*67e74705SXin Li //===----------------------------------------------------------------------===// 9*67e74705SXin Li // Transformations: 10*67e74705SXin Li //===----------------------------------------------------------------------===// 11*67e74705SXin Li // 12*67e74705SXin Li // rewriteUnusedInitDelegate: 13*67e74705SXin Li // 14*67e74705SXin Li // Rewrites an unused result of calling a delegate initialization, to assigning 15*67e74705SXin Li // the result to self. 16*67e74705SXin Li // e.g 17*67e74705SXin Li // [self init]; 18*67e74705SXin Li // ----> 19*67e74705SXin Li // self = [self init]; 20*67e74705SXin Li // 21*67e74705SXin Li //===----------------------------------------------------------------------===// 22*67e74705SXin Li 23*67e74705SXin Li #include "Transforms.h" 24*67e74705SXin Li #include "Internals.h" 25*67e74705SXin Li #include "clang/AST/ASTContext.h" 26*67e74705SXin Li #include "clang/Sema/SemaDiagnostic.h" 27*67e74705SXin Li 28*67e74705SXin Li using namespace clang; 29*67e74705SXin Li using namespace arcmt; 30*67e74705SXin Li using namespace trans; 31*67e74705SXin Li 32*67e74705SXin Li namespace { 33*67e74705SXin Li 34*67e74705SXin Li class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> { 35*67e74705SXin Li Stmt *Body; 36*67e74705SXin Li MigrationPass &Pass; 37*67e74705SXin Li 38*67e74705SXin Li ExprSet Removables; 39*67e74705SXin Li 40*67e74705SXin Li public: UnusedInitRewriter(MigrationPass & pass)41*67e74705SXin Li UnusedInitRewriter(MigrationPass &pass) 42*67e74705SXin Li : Body(nullptr), Pass(pass) { } 43*67e74705SXin Li transformBody(Stmt * body,Decl * ParentD)44*67e74705SXin Li void transformBody(Stmt *body, Decl *ParentD) { 45*67e74705SXin Li Body = body; 46*67e74705SXin Li collectRemovables(body, Removables); 47*67e74705SXin Li TraverseStmt(body); 48*67e74705SXin Li } 49*67e74705SXin Li VisitObjCMessageExpr(ObjCMessageExpr * ME)50*67e74705SXin Li bool VisitObjCMessageExpr(ObjCMessageExpr *ME) { 51*67e74705SXin Li if (ME->isDelegateInitCall() && 52*67e74705SXin Li isRemovable(ME) && 53*67e74705SXin Li Pass.TA.hasDiagnostic(diag::err_arc_unused_init_message, 54*67e74705SXin Li ME->getExprLoc())) { 55*67e74705SXin Li Transaction Trans(Pass.TA); 56*67e74705SXin Li Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message, 57*67e74705SXin Li ME->getExprLoc()); 58*67e74705SXin Li SourceRange ExprRange = ME->getSourceRange(); 59*67e74705SXin Li Pass.TA.insert(ExprRange.getBegin(), "if (!(self = "); 60*67e74705SXin Li std::string retStr = ")) return "; 61*67e74705SXin Li retStr += getNilString(Pass); 62*67e74705SXin Li Pass.TA.insertAfterToken(ExprRange.getEnd(), retStr); 63*67e74705SXin Li } 64*67e74705SXin Li return true; 65*67e74705SXin Li } 66*67e74705SXin Li 67*67e74705SXin Li private: isRemovable(Expr * E) const68*67e74705SXin Li bool isRemovable(Expr *E) const { 69*67e74705SXin Li return Removables.count(E); 70*67e74705SXin Li } 71*67e74705SXin Li }; 72*67e74705SXin Li 73*67e74705SXin Li } // anonymous namespace 74*67e74705SXin Li rewriteUnusedInitDelegate(MigrationPass & pass)75*67e74705SXin Livoid trans::rewriteUnusedInitDelegate(MigrationPass &pass) { 76*67e74705SXin Li BodyTransform<UnusedInitRewriter> trans(pass); 77*67e74705SXin Li trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); 78*67e74705SXin Li } 79