[arcmt] Break apart Transforms.cpp.
[clang/stm8.git] / lib / ARCMigrate / TransEmptyStatements.cpp
blob1b62bbf0354a1daa394c92d048146c4ce6450ee8
1 //===--- TransEmptyStatements.cpp - Tranformations to ARC mode ------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // removeEmptyStatements:
12 // Removes empty statements that are leftovers from previous transformations.
13 // e.g for
15 // [x retain];
17 // removeRetainReleaseDealloc will leave an empty ";" that removeEmptyStatements
18 // will remove.
20 //===----------------------------------------------------------------------===//
22 #include "Transforms.h"
23 #include "Internals.h"
24 #include "clang/AST/StmtVisitor.h"
26 using namespace clang;
27 using namespace arcmt;
28 using namespace trans;
29 using llvm::StringRef;
31 namespace {
33 class EmptyStatementsRemover :
34 public RecursiveASTVisitor<EmptyStatementsRemover> {
35 MigrationPass &Pass;
36 llvm::DenseSet<unsigned> MacroLocs;
38 public:
39 EmptyStatementsRemover(MigrationPass &pass) : Pass(pass) {
40 for (unsigned i = 0, e = Pass.ARCMTMacroLocs.size(); i != e; ++i)
41 MacroLocs.insert(Pass.ARCMTMacroLocs[i].getRawEncoding());
44 bool TraverseStmtExpr(StmtExpr *E) {
45 CompoundStmt *S = E->getSubStmt();
46 for (CompoundStmt::body_iterator
47 I = S->body_begin(), E = S->body_end(); I != E; ++I) {
48 if (I != E - 1)
49 check(*I);
50 TraverseStmt(*I);
52 return true;
55 bool VisitCompoundStmt(CompoundStmt *S) {
56 for (CompoundStmt::body_iterator
57 I = S->body_begin(), E = S->body_end(); I != E; ++I)
58 check(*I);
59 return true;
62 bool isMacroLoc(SourceLocation loc) {
63 if (loc.isInvalid()) return false;
64 return MacroLocs.count(loc.getRawEncoding());
67 ASTContext &getContext() { return Pass.Ctx; }
69 private:
70 /// \brief Returns true if the statement became empty due to previous
71 /// transformations.
72 class EmptyChecker : public StmtVisitor<EmptyChecker, bool> {
73 EmptyStatementsRemover &Trans;
75 public:
76 EmptyChecker(EmptyStatementsRemover &trans) : Trans(trans) { }
78 bool VisitNullStmt(NullStmt *S) {
79 return Trans.isMacroLoc(S->getLeadingEmptyMacroLoc());
81 bool VisitCompoundStmt(CompoundStmt *S) {
82 if (S->body_empty())
83 return false; // was already empty, not because of transformations.
84 for (CompoundStmt::body_iterator
85 I = S->body_begin(), E = S->body_end(); I != E; ++I)
86 if (!Visit(*I))
87 return false;
88 return true;
90 bool VisitIfStmt(IfStmt *S) {
91 if (S->getConditionVariable())
92 return false;
93 Expr *condE = S->getCond();
94 if (!condE)
95 return false;
96 if (hasSideEffects(condE, Trans.getContext()))
97 return false;
98 if (!S->getThen() || !Visit(S->getThen()))
99 return false;
100 if (S->getElse() && !Visit(S->getElse()))
101 return false;
102 return true;
104 bool VisitWhileStmt(WhileStmt *S) {
105 if (S->getConditionVariable())
106 return false;
107 Expr *condE = S->getCond();
108 if (!condE)
109 return false;
110 if (hasSideEffects(condE, Trans.getContext()))
111 return false;
112 if (!S->getBody())
113 return false;
114 return Visit(S->getBody());
116 bool VisitDoStmt(DoStmt *S) {
117 Expr *condE = S->getCond();
118 if (!condE)
119 return false;
120 if (hasSideEffects(condE, Trans.getContext()))
121 return false;
122 if (!S->getBody())
123 return false;
124 return Visit(S->getBody());
126 bool VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
127 Expr *Exp = S->getCollection();
128 if (!Exp)
129 return false;
130 if (hasSideEffects(Exp, Trans.getContext()))
131 return false;
132 if (!S->getBody())
133 return false;
134 return Visit(S->getBody());
136 bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
137 if (!S->getSubStmt())
138 return false;
139 return Visit(S->getSubStmt());
143 void check(Stmt *S) {
144 if (!S) return;
145 if (EmptyChecker(*this).Visit(S)) {
146 Transaction Trans(Pass.TA);
147 Pass.TA.removeStmt(S);
152 } // anonymous namespace
154 void trans::removeEmptyStatements(MigrationPass &pass) {
155 EmptyStatementsRemover(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl());
157 for (unsigned i = 0, e = pass.ARCMTMacroLocs.size(); i != e; ++i) {
158 Transaction Trans(pass.TA);
159 pass.TA.remove(pass.ARCMTMacroLocs[i]);