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. 92fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis for (CompoundStmt::body_iterator 93fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis I = S->body_begin(), E = S->body_end(); I != E; ++I) 94fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!Visit(*I)) 95fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 96fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return true; 97fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 98fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitIfStmt(IfStmt *S) { 99fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (S->getConditionVariable()) 100fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 101fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Expr *condE = S->getCond(); 102fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!condE) 103fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 104fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (hasSideEffects(condE, Ctx)) 105fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 106fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!S->getThen() || !Visit(S->getThen())) 107fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 108fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (S->getElse() && !Visit(S->getElse())) 109fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 110fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return true; 111fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 112fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitWhileStmt(WhileStmt *S) { 113fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (S->getConditionVariable()) 114fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 115fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Expr *condE = S->getCond(); 116fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!condE) 117fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 118fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (hasSideEffects(condE, Ctx)) 119fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 120fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!S->getBody()) 121fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 122fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return Visit(S->getBody()); 123fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 124fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitDoStmt(DoStmt *S) { 125fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Expr *condE = S->getCond(); 126fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!condE) 127fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 128fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (hasSideEffects(condE, Ctx)) 129fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 130fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!S->getBody()) 131fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 132fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return Visit(S->getBody()); 133fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 134fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { 135fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Expr *Exp = S->getCollection(); 136fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!Exp) 137fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 138fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (hasSideEffects(Exp, Ctx)) 139fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 140fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!S->getBody()) 141fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 142fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return Visit(S->getBody()); 143fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 144fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { 145fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!S->getSubStmt()) 146fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 147fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return Visit(S->getSubStmt()); 148fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 149fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis}; 150fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 151fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidisclass EmptyStatementsRemover : 152fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis public RecursiveASTVisitor<EmptyStatementsRemover> { 153fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis MigrationPass &Pass; 154fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 155fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidispublic: 156aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis EmptyStatementsRemover(MigrationPass &pass) : Pass(pass) { } 157fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 158fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool TraverseStmtExpr(StmtExpr *E) { 159fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis CompoundStmt *S = E->getSubStmt(); 160fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis for (CompoundStmt::body_iterator 161fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis I = S->body_begin(), E = S->body_end(); I != E; ++I) { 162fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (I != E - 1) 163fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis check(*I); 164fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis TraverseStmt(*I); 165fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 166fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return true; 167fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 168fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 169fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis bool VisitCompoundStmt(CompoundStmt *S) { 170fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis for (CompoundStmt::body_iterator 171fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis I = S->body_begin(), E = S->body_end(); I != E; ++I) 172fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis check(*I); 173fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return true; 174fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 175fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 176fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis ASTContext &getContext() { return Pass.Ctx; } 177fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 178fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidisprivate: 179fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis void check(Stmt *S) { 180fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!S) return; 181aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis if (EmptyChecker(Pass.Ctx, Pass.ARCMTMacroLocs).Visit(S)) { 182fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Transaction Trans(Pass.TA); 183fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Pass.TA.removeStmt(S); 184fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 185fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 186fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis}; 187fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 188fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis} // anonymous namespace 189fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 190aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidisstatic bool isBodyEmpty(CompoundStmt *body, ASTContext &Ctx, 191aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis std::vector<SourceLocation> &MacroLocs) { 192fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis for (CompoundStmt::body_iterator 193fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis I = body->body_begin(), E = body->body_end(); I != E; ++I) 194fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (!EmptyChecker(Ctx, MacroLocs).Visit(*I)) 195fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return false; 196fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 197fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis return true; 198fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis} 199fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 200e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidisstatic void cleanupDeallocOrFinalize(MigrationPass &pass) { 201fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis ASTContext &Ctx = pass.Ctx; 202fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis TransformActions &TA = pass.TA; 203fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis DeclContext *DC = Ctx.getTranslationUnitDecl(); 204e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Selector FinalizeSel = 205e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize")); 206fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 207fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis typedef DeclContext::specific_decl_iterator<ObjCImplementationDecl> 208fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis impl_iterator; 209fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis for (impl_iterator I = impl_iterator(DC->decls_begin()), 210fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis E = impl_iterator(DC->decls_end()); I != E; ++I) { 211e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis ObjCMethodDecl *DeallocM = 0; 212e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis ObjCMethodDecl *FinalizeM = 0; 213fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis for (ObjCImplementationDecl::instmeth_iterator 214262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie MI = I->instmeth_begin(), 215262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie ME = I->instmeth_end(); MI != ME; ++MI) { 216fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis ObjCMethodDecl *MD = *MI; 217e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis if (!MD->hasBody()) 218e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis continue; 219e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis 220fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis if (MD->getMethodFamily() == OMF_dealloc) { 221e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis DeallocM = MD; 222e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } else if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) { 223e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis FinalizeM = MD; 224e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } 225e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } 226e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis 227e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis if (DeallocM) { 228e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis if (isBodyEmpty(DeallocM->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { 229e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Transaction Trans(TA); 230e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis TA.remove(DeallocM->getSourceRange()); 231e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } 232e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis 233e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis if (FinalizeM) { 234e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Transaction Trans(TA); 235e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis TA.remove(FinalizeM->getSourceRange()); 236e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } 237e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis 238e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } else if (FinalizeM) { 239e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis if (isBodyEmpty(FinalizeM->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { 240e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Transaction Trans(TA); 241e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis TA.remove(FinalizeM->getSourceRange()); 242e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis } else { 243e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis Transaction Trans(TA); 244e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis TA.replaceText(FinalizeM->getSelectorStartLoc(), "finalize", "dealloc"); 245fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 246fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 247fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 248fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis} 249fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 250e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidisvoid trans::removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass) { 251aec230d29835285777ecc467e268c83b33a2addeArgyrios Kyrtzidis EmptyStatementsRemover(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl()); 252fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 253e7ef8556f4ee3012a0479308c993af0fbee448dfArgyrios Kyrtzidis cleanupDeallocOrFinalize(pass); 254fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis 255fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis for (unsigned i = 0, e = pass.ARCMTMacroLocs.size(); i != e; ++i) { 256fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis Transaction Trans(pass.TA); 257fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis pass.TA.remove(pass.ARCMTMacroLocs[i]); 258fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis } 259fd3455a9ebecf67b9a1c46f0675697bf518e6b80Argyrios Kyrtzidis} 260