Refactor DependencyScanningTool to its own file

Summary:
There's no behavior change - just moving DependencyScanningTool to its own file
since this tool can be reused across both clang-scan-deps binary and an interface
exposed as part of libClang APIs.

Reviewers: arphaman, jkorous, Bigcheese, dexonsmith

Subscribers: mgorny, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D69186

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@375483 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
new file mode 100644
index 0000000..0c9efcc
--- /dev/null
+++ b/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
@@ -0,0 +1,48 @@
+//===- DependencyScanningTool.h - clang-scan-deps service ------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_TOOL_H
+#define LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_TOOL_H
+
+#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
+#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h"
+#include "clang/Tooling/JSONCompilationDatabase.h"
+#include <string>
+
+namespace clang{
+namespace tooling{
+namespace dependencies{
+
+/// The high-level implementation of the dependency discovery tool that runs on
+/// an individual worker thread.
+class DependencyScanningTool {
+public:
+  /// Construct a dependency scanning tool.
+  ///
+  /// \param Compilations     The reference to the compilation database that's
+  /// used by the clang tool.
+  DependencyScanningTool(DependencyScanningService &Service, const clang::tooling::CompilationDatabase &Compilations);
+
+  /// Print out the dependency information into a string using the dependency
+  /// file format that is specified in the options (-MD is the default) and
+  /// return it.
+  ///
+  /// \returns A \c StringError with the diagnostic output if clang errors
+  /// occurred, dependency file contents otherwise.
+  llvm::Expected<std::string> getDependencyFile(const std::string &Input, StringRef CWD);
+
+private:
+  DependencyScanningWorker Worker;
+  const tooling::CompilationDatabase &Compilations;
+};
+
+} // end namespace dependencies
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_TOOL_H
diff --git a/lib/Tooling/DependencyScanning/CMakeLists.txt b/lib/Tooling/DependencyScanning/CMakeLists.txt
index 0b2c882..05e1aa5 100644
--- a/lib/Tooling/DependencyScanning/CMakeLists.txt
+++ b/lib/Tooling/DependencyScanning/CMakeLists.txt
@@ -7,6 +7,7 @@
   DependencyScanningFilesystem.cpp
   DependencyScanningService.cpp
   DependencyScanningWorker.cpp
+  DependencyScanningTool.cpp
 
   DEPENDS
   ClangDriverOptions
diff --git a/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp b/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
new file mode 100644
index 0000000..82b3ae8
--- /dev/null
+++ b/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
@@ -0,0 +1,71 @@
+//===- DependencyScanningTool.cpp - clang-scan-deps service ------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h"
+#include "clang/Frontend/Utils.h"
+
+namespace clang{
+namespace tooling{
+namespace dependencies{
+
+DependencyScanningTool::DependencyScanningTool(DependencyScanningService &Service,
+const tooling::CompilationDatabase &Compilations) : Worker(Service), Compilations(Compilations) {}
+
+llvm::Expected<std::string> DependencyScanningTool::getDependencyFile(const std::string &Input,
+                                              StringRef CWD) {
+  /// Prints out all of the gathered dependencies into a string.
+  class DependencyPrinterConsumer : public DependencyConsumer {
+  public:
+    void handleFileDependency(const DependencyOutputOptions &Opts,
+                              StringRef File) override {
+      if (!this->Opts)
+        this->Opts = std::make_unique<DependencyOutputOptions>(Opts);
+      Dependencies.push_back(File);
+    }
+
+    void printDependencies(std::string &S) {
+      if (!Opts)
+        return;
+
+      class DependencyPrinter : public DependencyFileGenerator {
+      public:
+        DependencyPrinter(DependencyOutputOptions &Opts,
+                          ArrayRef<std::string> Dependencies)
+            : DependencyFileGenerator(Opts) {
+          for (const auto &Dep : Dependencies)
+            addDependency(Dep);
+        }
+
+        void printDependencies(std::string &S) {
+          llvm::raw_string_ostream OS(S);
+          outputDependencyFile(OS);
+        }
+      };
+
+      DependencyPrinter Generator(*Opts, Dependencies);
+      Generator.printDependencies(S);
+    }
+
+  private:
+    std::unique_ptr<DependencyOutputOptions> Opts;
+    std::vector<std::string> Dependencies;
+  };
+
+  DependencyPrinterConsumer Consumer;
+  auto Result =
+      Worker.computeDependencies(Input, CWD, Compilations, Consumer);
+  if (Result)
+    return std::move(Result);
+  std::string Output;
+  Consumer.printDependencies(Output);
+  return Output;
+}
+
+} // end namespace dependencies
+} // end namespace tooling
+} // end namespace clang
diff --git a/tools/clang-scan-deps/ClangScanDeps.cpp b/tools/clang-scan-deps/ClangScanDeps.cpp
index d44e3b9..d57983e 100644
--- a/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -9,6 +9,7 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
+#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h"
 #include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h"
 #include "clang/Tooling/JSONCompilationDatabase.h"
 #include "llvm/Support/InitLLVM.h"
@@ -38,101 +39,6 @@
   raw_ostream &OS;
 };
 
-/// The high-level implementation of the dependency discovery tool that runs on
-/// an individual worker thread.
-class DependencyScanningTool {
-public:
-  /// Construct a dependency scanning tool.
-  ///
-  /// \param Compilations     The reference to the compilation database that's
-  /// used by the clang tool.
-  DependencyScanningTool(DependencyScanningService &Service,
-                         const tooling::CompilationDatabase &Compilations,
-                         SharedStream &OS, SharedStream &Errs)
-      : Worker(Service), Compilations(Compilations), OS(OS), Errs(Errs) {}
-
-  /// Print out the dependency information into a string using the dependency
-  /// file format that is specified in the options (-MD is the default) and
-  /// return it.
-  ///
-  /// \returns A \c StringError with the diagnostic output if clang errors
-  /// occurred, dependency file contents otherwise.
-  llvm::Expected<std::string> getDependencyFile(const std::string &Input,
-                                                StringRef CWD) {
-    /// Prints out all of the gathered dependencies into a string.
-    class DependencyPrinterConsumer : public DependencyConsumer {
-    public:
-      void handleFileDependency(const DependencyOutputOptions &Opts,
-                                StringRef File) override {
-        if (!this->Opts)
-          this->Opts = std::make_unique<DependencyOutputOptions>(Opts);
-        Dependencies.push_back(File);
-      }
-
-      void printDependencies(std::string &S) {
-        if (!Opts)
-          return;
-
-        class DependencyPrinter : public DependencyFileGenerator {
-        public:
-          DependencyPrinter(DependencyOutputOptions &Opts,
-                            ArrayRef<std::string> Dependencies)
-              : DependencyFileGenerator(Opts) {
-            for (const auto &Dep : Dependencies)
-              addDependency(Dep);
-          }
-
-          void printDependencies(std::string &S) {
-            llvm::raw_string_ostream OS(S);
-            outputDependencyFile(OS);
-          }
-        };
-
-        DependencyPrinter Generator(*Opts, Dependencies);
-        Generator.printDependencies(S);
-      }
-
-    private:
-      std::unique_ptr<DependencyOutputOptions> Opts;
-      std::vector<std::string> Dependencies;
-    };
-
-    DependencyPrinterConsumer Consumer;
-    auto Result =
-        Worker.computeDependencies(Input, CWD, Compilations, Consumer);
-    if (Result)
-      return std::move(Result);
-    std::string Output;
-    Consumer.printDependencies(Output);
-    return Output;
-  }
-
-  /// Computes the dependencies for the given file and prints them out.
-  ///
-  /// \returns True on error.
-  bool runOnFile(const std::string &Input, StringRef CWD) {
-    auto MaybeFile = getDependencyFile(Input, CWD);
-    if (!MaybeFile) {
-      llvm::handleAllErrors(
-          MaybeFile.takeError(), [this, &Input](llvm::StringError &Err) {
-            Errs.applyLocked([&](raw_ostream &OS) {
-              OS << "Error while scanning dependencies for " << Input << ":\n";
-              OS << Err.getMessage();
-            });
-          });
-      return true;
-    }
-    OS.applyLocked([&](raw_ostream &OS) { OS << *MaybeFile; });
-    return false;
-  }
-
-private:
-  DependencyScanningWorker Worker;
-  const tooling::CompilationDatabase &Compilations;
-  SharedStream &OS;
-  SharedStream &Errs;
-};
-
 llvm::cl::opt<bool> Help("h", llvm::cl::desc("Alias for -help"),
                          llvm::cl::Hidden);
 
@@ -191,6 +97,27 @@
   return ObjFileName.str();
 }
 
+/// Takes the result of a dependency scan and prints error / dependency files
+/// based on the result.
+///
+/// \returns True on error.
+static bool handleDependencyToolResult(const std::string &Input,
+                                       llvm::Expected<std::string> &MaybeFile,
+                                       SharedStream &OS, SharedStream &Errs) {
+  if (!MaybeFile) {
+    llvm::handleAllErrors(
+        MaybeFile.takeError(), [&Input, &Errs](llvm::StringError &Err) {
+          Errs.applyLocked([&](raw_ostream &OS) {
+            OS << "Error while scanning dependencies for " << Input << ":\n";
+            OS << Err.getMessage();
+          });
+        });
+    return true;
+  }
+  OS.applyLocked([&](raw_ostream &OS) { OS << *MaybeFile; });
+  return false;
+}
+
 int main(int argc, const char **argv) {
   llvm::InitLLVM X(argc, argv);
   llvm::cl::HideUnrelatedOptions(DependencyScannerCategory);
@@ -284,7 +211,7 @@
   std::vector<std::unique_ptr<DependencyScanningTool>> WorkerTools;
   for (unsigned I = 0; I < NumWorkers; ++I)
     WorkerTools.push_back(std::make_unique<DependencyScanningTool>(
-        Service, *AdjustingCompilations, DependencyOS, Errs));
+        Service, *AdjustingCompilations));
 
   std::vector<std::thread> WorkerThreads;
   std::atomic<bool> HadErrors(false);
@@ -296,7 +223,8 @@
                  << " files using " << NumWorkers << " workers\n";
   }
   for (unsigned I = 0; I < NumWorkers; ++I) {
-    auto Worker = [I, &Lock, &Index, &Inputs, &HadErrors, &WorkerTools]() {
+    auto Worker = [I, &Lock, &Index, &Inputs, &HadErrors, &WorkerTools,
+                   &DependencyOS, &Errs]() {
       while (true) {
         std::string Input;
         StringRef CWD;
@@ -310,7 +238,8 @@
           CWD = Compilation.second;
         }
         // Run the tool on it.
-        if (WorkerTools[I]->runOnFile(Input, CWD))
+        auto MaybeFile = WorkerTools[I]->getDependencyFile(Input, CWD);
+        if (handleDependencyToolResult(Input, MaybeFile, DependencyOS, Errs))
           HadErrors = true;
       }
     };