Home | History | Annotate | Line # | Download | only in ARCMigrate
TransUnusedInitDelegate.cpp revision 1.1
      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