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