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> &macroLocs)
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