The ARC Migration Tool.  All the credit goes to Argyrios and Fariborz
for this.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133104 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
index 7dcbebf..5565b7b 100644
--- a/lib/Frontend/CMakeLists.txt
+++ b/lib/Frontend/CMakeLists.txt
@@ -1,4 +1,5 @@
 set( LLVM_USED_LIBS
+  clangARCMigrate
   clangAST
   clangBasic
   clangDriver
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 38fcfe3..b05c24a 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -26,6 +26,7 @@
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Frontend/VerifyDiagnosticsClient.h"
 #include "clang/Frontend/Utils.h"
+#include "clang/ARCMigrate/ARCMT.h"
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "llvm/Support/FileSystem.h"
@@ -596,6 +597,34 @@
     if (hasSourceManager())
       getSourceManager().clearIDTables();
 
+    switch (getFrontendOpts().ARCMTAction) {
+    default:
+      break;
+
+    case FrontendOptions::ARCMT_Check:
+      if (arcmt::checkForManualIssues(getInvocation(), InFile,
+                                      getFrontendOpts().Inputs[i].first,
+                                      getDiagnostics().getClient()))
+        continue;
+      // We only want to see warnings reported from arcmt::checkForManualIssues.
+      getDiagnostics().setIgnoreAllWarnings(true);
+      break;
+
+    case FrontendOptions::ARCMT_Modify:
+      if (arcmt::applyTransformations(getInvocation(), InFile,
+                                      getFrontendOpts().Inputs[i].first,
+                                      getDiagnostics().getClient()))
+        continue;
+      break;
+
+    case FrontendOptions::ARCMT_ModifyInMemory:
+      if (arcmt::applyTransformationsInMemory(getInvocation(), InFile,
+                                              getFrontendOpts().Inputs[i].first,
+                                              getDiagnostics().getClient()))
+        continue;
+      break;
+    }
+
     if (Act.BeginSourceFile(*this, InFile, getFrontendOpts().Inputs[i].first)) {
       Act.Execute();
       Act.EndSourceFile();
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 1324926..2c158fb 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -415,6 +415,19 @@
     Res.push_back("-version");
   if (Opts.FixWhatYouCan)
     Res.push_back("-fix-what-you-can");
+  switch (Opts.ARCMTAction) {
+  case FrontendOptions::ARCMT_None:
+    break;
+  case FrontendOptions::ARCMT_Check:
+    Res.push_back("-arcmt-check");
+    break;
+  case FrontendOptions::ARCMT_Modify:
+    Res.push_back("-arcmt-modify");
+    break;
+  case FrontendOptions::ARCMT_ModifyInMemory:
+    Res.push_back("-arcmt-modify-in-memory");
+    break;
+  }
 
   bool NeedLang = false;
   for (unsigned i = 0, e = Opts.Inputs.size(); i != e; ++i)
@@ -1227,6 +1240,25 @@
   Opts.FixWhatYouCan = Args.hasArg(OPT_fix_what_you_can);
   Opts.Modules = Args.getAllArgValues(OPT_import_module);
 
+  Opts.ARCMTAction = FrontendOptions::ARCMT_None;
+  if (const Arg *A = Args.getLastArg(OPT_arcmt_check,
+                                     OPT_arcmt_modify,
+                                     OPT_arcmt_modify_in_memory)) {
+    switch (A->getOption().getID()) {
+    default:
+      llvm_unreachable("missed a case");
+    case OPT_arcmt_check:
+      Opts.ARCMTAction = FrontendOptions::ARCMT_Check;
+      break;
+    case OPT_arcmt_modify:
+      Opts.ARCMTAction = FrontendOptions::ARCMT_Modify;
+      break;
+    case OPT_arcmt_modify_in_memory:
+      Opts.ARCMTAction = FrontendOptions::ARCMT_ModifyInMemory;
+      break;
+    }
+  }
+
   InputKind DashX = IK_None;
   if (const Arg *A = Args.getLastArg(OPT_x)) {
     DashX = llvm::StringSwitch<InputKind>(A->getValue(Args))