[arcmt] Break apart Transforms.cpp.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133539 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ARCMigrate/TransUnusedInitDelegate.cpp b/lib/ARCMigrate/TransUnusedInitDelegate.cpp
new file mode 100644
index 0000000..2fa18a3
--- /dev/null
+++ b/lib/ARCMigrate/TransUnusedInitDelegate.cpp
@@ -0,0 +1,75 @@
+//===--- TransUnusedInitDelegate.cpp - Tranformations to ARC mode ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Transformations:
+//===----------------------------------------------------------------------===//
+//
+// rewriteUnusedInitDelegate:
+//
+// Rewrites an unused result of calling a delegate initialization, to assigning
+// the result to self.
+// e.g
+//  [self init];
+// ---->
+//  self = [self init];
+//
+//===----------------------------------------------------------------------===//
+
+#include "Transforms.h"
+#include "Internals.h"
+#include "clang/Sema/SemaDiagnostic.h"
+
+using namespace clang;
+using namespace arcmt;
+using namespace trans;
+using llvm::StringRef;
+
+namespace {
+
+class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> {
+  Decl *Dcl;
+  Stmt *Body;
+  MigrationPass &Pass;
+
+  ExprSet Removables;
+
+public:
+  UnusedInitRewriter(Decl *D, MigrationPass &pass)
+    : Dcl(D), Body(0), Pass(pass) { }
+
+  void transformBody(Stmt *body) {
+    Body = body;
+    collectRemovables(body, Removables);
+    TraverseStmt(body);
+  }
+
+  bool VisitObjCMessageExpr(ObjCMessageExpr *ME) {
+    if (ME->isDelegateInitCall() &&
+        isRemovable(ME) &&
+        Pass.TA.hasDiagnostic(diag::err_arc_unused_init_message,
+                              ME->getExprLoc())) {
+      Transaction Trans(Pass.TA);
+      Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message,
+                              ME->getExprLoc());
+      Pass.TA.insert(ME->getExprLoc(), "self = ");
+    }
+    return true;
+  }
+
+private:
+  bool isRemovable(Expr *E) const {
+    return Removables.count(E);
+  }
+};
+
+} // anonymous namespace
+
+void trans::rewriteUnusedInitDelegate(MigrationPass &pass) {
+  BodyTransform<UnusedInitRewriter> trans(pass);
+  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
+}