1accaf19bc1129c0273ec50dba52318e60bc29103Benjamin Kramer//===--- TransEmptyStatements.cpp - Transformations to ARC mode -----------===// 2fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// 3fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 4fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// 5fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 6fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 7fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// 8fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 9fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// 10fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// removeEmptyStatementsAndDealloc: 11fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// 12fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// Removes empty statements that are leftovers from previous transformations. 13fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// e.g for 14fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// 15fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// [x retain]; 16fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// 17fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// removeRetainReleaseDealloc will leave an empty ";" that removeEmptyStatements 18fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// will remove. 19fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis// 20fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 21fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 22fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis#include "Transforms.h" 23fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis#include "Internals.h" 24471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/AST/ASTContext.h" 25fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis#include "clang/AST/StmtVisitor.h" 26aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis#include "clang/Basic/SourceManager.h" 27fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 28fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidisusing namespace clang; 29fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidisusing namespace arcmt; 30fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidisusing namespace trans; 31fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 32aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidisstatic bool isEmptyARCMTMacroStatement(NullStmt *S, 33aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis std::vector<SourceLocation> &MacroLocs, 34aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis ASTContext &Ctx) { 35aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis if (!S->hasLeadingEmptyMacro()) 36aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return false; 37aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis 38aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis SourceLocation SemiLoc = S->getSemiLoc(); 39aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis if (SemiLoc.isInvalid() || SemiLoc.isMacroID()) 40aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return false; 41aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis 42aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis if (MacroLocs.empty()) 43aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return false; 44aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis 45aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis SourceManager &SM = Ctx.getSourceManager(); 46aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis std::vector<SourceLocation>::iterator 47aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis I = std::upper_bound(MacroLocs.begin(), MacroLocs.end(), SemiLoc, 48aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko BeforeThanCompare<SourceLocation>(SM)); 49aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis --I; 50aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis SourceLocation 51a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis AfterMacroLoc = I->getLocWithOffset(getARCMTMacroName().size()); 52aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis assert(AfterMacroLoc.isFileID()); 53aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis 54aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis if (AfterMacroLoc == SemiLoc) 55aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return true; 56aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis 57aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis int RelOffs = 0; 58aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis if (!SM.isInSameSLocAddrSpace(AfterMacroLoc, SemiLoc, &RelOffs)) 59aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return false; 60aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis if (RelOffs < 0) 61aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return false; 62aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis 63aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis // We make the reasonable assumption that a semicolon after 100 characters 64aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis // means that it is not the next token after our macro. If this assumption 65aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis // fails it is not critical, we will just fail to clear out, e.g., an empty 66aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis // 'if'. 67aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis if (RelOffs - getARCMTMacroName().size() > 100) 68aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return false; 69aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis 70aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis SourceLocation AfterMacroSemiLoc = findSemiAfterLocation(AfterMacroLoc, Ctx); 71aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return AfterMacroSemiLoc == SemiLoc; 72aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis} 73aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis 74fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidisnamespace { 75fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 76fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis/// \brief Returns true if the statement became empty due to previous 77fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis/// transformations. 78fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidisclass EmptyChecker : public StmtVisitor<EmptyChecker, bool> { 79fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis ASTContext &Ctx; 80aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis std::vector<SourceLocation> &MacroLocs; 81fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 82fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidispublic: 83aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis EmptyChecker(ASTContext &ctx, std::vector<SourceLocation> ¯oLocs) 84fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis : Ctx(ctx), MacroLocs(macroLocs) { } 85fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 86fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitNullStmt(NullStmt *S) { 87aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis return isEmptyARCMTMacroStatement(S, MacroLocs, Ctx); 88fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 89fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitCompoundStmt(CompoundStmt *S) { 90fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (S->body_empty()) 91fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; // was already empty, not because of transformations. 92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *I : S->body()) 93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Visit(I)) 94fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 95fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return true; 96fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 97fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitIfStmt(IfStmt *S) { 98fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (S->getConditionVariable()) 99fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 100fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Expr *condE = S->getCond(); 101fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!condE) 102fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 103fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (hasSideEffects(condE, Ctx)) 104fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 105fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!S->getThen() || !Visit(S->getThen())) 106fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 10787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return !S->getElse() || Visit(S->getElse()); 108fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 109fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitWhileStmt(WhileStmt *S) { 110fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (S->getConditionVariable()) 111fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 112fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Expr *condE = S->getCond(); 113fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!condE) 114fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 115fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (hasSideEffects(condE, Ctx)) 116fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 117fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!S->getBody()) 118fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 119fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return Visit(S->getBody()); 120fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 121fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitDoStmt(DoStmt *S) { 122fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Expr *condE = S->getCond(); 123fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!condE) 124fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 125fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (hasSideEffects(condE, Ctx)) 126fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 127fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!S->getBody()) 128fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 129fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return Visit(S->getBody()); 130fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 131fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { 132fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Expr *Exp = S->getCollection(); 133fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!Exp) 134fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 135fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (hasSideEffects(Exp, Ctx)) 136fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 137fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!S->getBody()) 138fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 139fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return Visit(S->getBody()); 140fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 141fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { 142fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!S->getSubStmt()) 143fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 144fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return Visit(S->getSubStmt()); 145fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 146fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis}; 147fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 148fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidisclass EmptyStatementsRemover : 149fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis public RecursiveASTVisitor<EmptyStatementsRemover> { 150fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis MigrationPass &Pass; 151fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 152fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidispublic: 153aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis EmptyStatementsRemover(MigrationPass &pass) : Pass(pass) { } 154fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 155fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool TraverseStmtExpr(StmtExpr *E) { 156fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis CompoundStmt *S = E->getSubStmt(); 157fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis for (CompoundStmt::body_iterator 158fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis I = S->body_begin(), E = S->body_end(); I != E; ++I) { 159fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (I != E - 1) 160fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis check(*I); 161fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis TraverseStmt(*I); 162fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 163fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return true; 164fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 165fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 166fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitCompoundStmt(CompoundStmt *S) { 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *I : S->body()) 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines check(I); 169fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return true; 170fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 171fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 172fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis ASTContext &getContext() { return Pass.Ctx; } 173fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 174fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidisprivate: 175fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis void check(Stmt *S) { 176fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!S) return; 177aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis if (EmptyChecker(Pass.Ctx, Pass.ARCMTMacroLocs).Visit(S)) { 178fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Transaction Trans(Pass.TA); 179fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Pass.TA.removeStmt(S); 180fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 181fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 182fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis}; 183fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 184fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis} // anonymous namespace 185fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 186aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidisstatic bool isBodyEmpty(CompoundStmt *body, ASTContext &Ctx, 187aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis std::vector<SourceLocation> &MacroLocs) { 188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *I : body->body()) 189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!EmptyChecker(Ctx, MacroLocs).Visit(I)) 190fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 191fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 192fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return true; 193fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis} 194fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 195e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidisstatic void cleanupDeallocOrFinalize(MigrationPass &pass) { 196fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis ASTContext &Ctx = pass.Ctx; 197fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis TransformActions &TA = pass.TA; 198fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis DeclContext *DC = Ctx.getTranslationUnitDecl(); 199e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Selector FinalizeSel = 200e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize")); 201fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 202fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis typedef DeclContext::specific_decl_iterator<ObjCImplementationDecl> 203fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis impl_iterator; 204fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis for (impl_iterator I = impl_iterator(DC->decls_begin()), 205fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis E = impl_iterator(DC->decls_end()); I != E; ++I) { 2066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCMethodDecl *DeallocM = nullptr; 2076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ObjCMethodDecl *FinalizeM = nullptr; 208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *MD : I->instance_methods()) { 209e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis if (!MD->hasBody()) 210e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis continue; 211e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis 212fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (MD->getMethodFamily() == OMF_dealloc) { 213e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis DeallocM = MD; 214e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } else if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) { 215e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis FinalizeM = MD; 216e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } 217e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } 218e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis 219e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis if (DeallocM) { 220e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis if (isBodyEmpty(DeallocM->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { 221e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Transaction Trans(TA); 222e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis TA.remove(DeallocM->getSourceRange()); 223e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } 224e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis 225e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis if (FinalizeM) { 226e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Transaction Trans(TA); 227e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis TA.remove(FinalizeM->getSourceRange()); 228e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } 229e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis 230e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } else if (FinalizeM) { 231e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis if (isBodyEmpty(FinalizeM->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { 232e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Transaction Trans(TA); 233e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis TA.remove(FinalizeM->getSourceRange()); 234e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } else { 235e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Transaction Trans(TA); 236e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis TA.replaceText(FinalizeM->getSelectorStartLoc(), "finalize", "dealloc"); 237fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 238fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 239fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 240fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis} 241fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 242e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidisvoid trans::removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass) { 243aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis EmptyStatementsRemover(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl()); 244fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 245e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis cleanupDeallocOrFinalize(pass); 246fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 247fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis for (unsigned i = 0, e = pass.ARCMTMacroLocs.size(); i != e; ++i) { 248fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Transaction Trans(pass.TA); 249fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis pass.TA.remove(pass.ARCMTMacroLocs[i]); 250fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 251fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis} 252