Teach -fixit to modify all of its inputs instead of just the main file, unless
-fixit-at specified a particular fixit to fix, or the -o flag was used.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101359 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index 6d7c6a8..ce3e841 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -134,6 +134,23 @@
     FixItRewrite.addFixItLocation(Requested);
   }
 
+  const std::string &OutputFile = CI.getFrontendOpts().OutputFile;
+  if (Locs.empty() && !OutputFile.empty()) {
+    // FIXME: we will issue "FIX-IT applied suggested code changes" for every
+    // input, but only the main file will actually be rewritten.
+    const std::vector<std::pair<FrontendOptions::InputKind, std::string> > &Inputs =
+      CI.getFrontendOpts().Inputs;
+    for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
+      const FileEntry *File = CI.getFileManager().getFile(Inputs[i].second);
+      assert(File && "Input file not found in FileManager");
+      RequestedSourceLocation Requested;
+      Requested.File = File;
+      Requested.Line = 0;
+      Requested.Column = 0;
+      FixItRewrite.addFixItLocation(Requested);
+    }
+  }
+
   return true;
 }
 
@@ -149,7 +166,34 @@
 
 void FixItAction::EndSourceFileAction() {
   const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts();
-  Rewriter->WriteFixedFile(getCurrentFile(), FEOpts.OutputFile);
+  if (!FEOpts.OutputFile.empty()) {
+    // When called with 'clang -fixit -o filename' output only the main file.
+
+    const SourceManager &SM = getCompilerInstance().getSourceManager();
+    FileID MainFileID = SM.getMainFileID();
+    if (!Rewriter->IsModified(MainFileID)) {
+      getCompilerInstance().getDiagnostics().Report(
+          diag::note_fixit_main_file_unchanged);
+      return;
+    }
+
+    llvm::OwningPtr<llvm::raw_ostream> OwnedStream;
+    llvm::raw_ostream *OutFile;
+    if (FEOpts.OutputFile == "-") {
+      OutFile = &llvm::outs();
+    } else {
+      std::string Err;
+      OutFile = new llvm::raw_fd_ostream(FEOpts.OutputFile.c_str(), Err,
+                                         llvm::raw_fd_ostream::F_Binary);
+      OwnedStream.reset(OutFile);
+    }
+
+    Rewriter->WriteFixedFile(MainFileID, *OutFile);
+    return;
+  }
+
+  // Otherwise rewrite all files.
+  Rewriter->WriteFixedFiles();
 }
 
 ASTConsumer *RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI,