[clang] 1392126 - [clang][deps] NFC: Expose more flexible version of `Worker::computeDependencies()`

Jan Svoboda via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 29 11:30:06 PDT 2022


Author: Jan Svoboda
Date: 2022-09-29T11:29:53-07:00
New Revision: 13921262cae0e7346e41875c1850d8861be0488e

URL: https://github.com/llvm/llvm-project/commit/13921262cae0e7346e41875c1850d8861be0488e
DIFF: https://github.com/llvm/llvm-project/commit/13921262cae0e7346e41875c1850d8861be0488e.diff

LOG: [clang][deps] NFC: Expose more flexible version of `Worker::computeDependencies()`

This patch adds new member function to `DependencyScanningWorker` that allows clients to pass custom `DiagnosticConsumer`, and returns `bool`.

This provides more flexibility compared to the existing version that automatically stringifies diagnostics and returns them in `llvm::Error`.

Reviewed By: benlangmuir

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

Added: 
    

Modified: 
    clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
    clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
index 221906f9f9382..4750c9dfa9a21 100644
--- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
+++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
@@ -73,6 +73,13 @@ class DependencyScanningWorker {
   /// ModuleName isn't empty, this function reports the dependencies of module
   /// \p ModuleName.
   ///
+  /// \returns false if clang errors occurred (with diagnostics reported to
+  /// \c DiagConsumer), true otherwise.
+  bool computeDependencies(StringRef WorkingDirectory,
+                           const std::vector<std::string> &CommandLine,
+                           DependencyConsumer &DepConsumer,
+                           DiagnosticConsumer &DiagConsumer,
+                           llvm::Optional<StringRef> ModuleName = None);
   /// \returns A \c StringError with the diagnostic output if clang errors
   /// occurred, success otherwise.
   llvm::Error computeDependencies(StringRef WorkingDirectory,

diff  --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index 7474e0272505e..329eded0e3434 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -340,19 +340,23 @@ DependencyScanningWorker::DependencyScanningWorker(
     Files = new FileManager(FileSystemOptions(), RealFS);
 }
 
-static llvm::Error
-runWithDiags(DiagnosticOptions *DiagOpts,
-             llvm::function_ref<bool(DiagnosticConsumer &, DiagnosticOptions &)>
-                 BodyShouldSucceed) {
+llvm::Error DependencyScanningWorker::computeDependencies(
+    StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
+    DependencyConsumer &Consumer, llvm::Optional<StringRef> ModuleName) {
+  std::vector<const char *> CLI;
+  for (const std::string &Arg : CommandLine)
+    CLI.push_back(Arg.c_str());
+  auto DiagOpts = CreateAndPopulateDiagOpts(CLI);
   sanitizeDiagOpts(*DiagOpts);
 
   // Capture the emitted diagnostics and report them to the client
   // in the case of a failure.
   std::string DiagnosticOutput;
   llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
-  TextDiagnosticPrinter DiagPrinter(DiagnosticsOS, DiagOpts);
+  TextDiagnosticPrinter DiagPrinter(DiagnosticsOS, DiagOpts.release());
 
-  if (BodyShouldSucceed(DiagPrinter, *DiagOpts))
+  if (computeDependencies(WorkingDirectory, CommandLine, Consumer, DiagPrinter,
+                          ModuleName))
     return llvm::Error::success();
   return llvm::make_error<llvm::StringError>(DiagnosticsOS.str(),
                                              llvm::inconvertibleErrorCode());
@@ -388,9 +392,10 @@ static bool forEachDriverJob(
   return true;
 }
 
-llvm::Error DependencyScanningWorker::computeDependencies(
+bool DependencyScanningWorker::computeDependencies(
     StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
-    DependencyConsumer &Consumer, llvm::Optional<StringRef> ModuleName) {
+    DependencyConsumer &Consumer, DiagnosticConsumer &DC,
+    llvm::Optional<StringRef> ModuleName) {
   // Reset what might have been modified in the previous worker invocation.
   RealFS->setCurrentWorkingDirectory(WorkingDirectory);
   if (Files)
@@ -413,60 +418,57 @@ llvm::Error DependencyScanningWorker::computeDependencies(
   llvm::transform(CommandLine, FinalCCommandLine.begin(),
                   [](const std::string &Str) { return Str.c_str(); });
 
-  return runWithDiags(
-      CreateAndPopulateDiagOpts(FinalCCommandLine).release(),
-      [&](DiagnosticConsumer &DC, DiagnosticOptions &DiagOpts) {
-        IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
-            CompilerInstance::createDiagnostics(&DiagOpts, &DC, false);
-        // Although `Diagnostics` are used only for command-line parsing, the
-        // custom `DiagConsumer` might expect a `SourceManager` to be present.
-        SourceManager SrcMgr(*Diags, *CurrentFiles);
-        Diags->setSourceManager(&SrcMgr);
-        // DisableFree is modified by Tooling for running
-        // in-process; preserve the original value, which is
-        // always true for a driver invocation.
-        bool DisableFree = true;
-        DependencyScanningAction Action(WorkingDirectory, Consumer, DepFS,
-                                        Format, OptimizeArgs, EagerLoadModules,
-                                        DisableFree, ModuleName);
-        bool Success = forEachDriverJob(
-            FinalCommandLine, *Diags, *CurrentFiles,
-            [&](const driver::Command &Cmd) {
-              if (StringRef(Cmd.getCreator().getName()) != "clang") {
-                // Non-clang command. Just pass through to the dependency
-                // consumer.
-                Consumer.handleBuildCommand(
-                    {Cmd.getExecutable(),
-                     {Cmd.getArguments().begin(), Cmd.getArguments().end()}});
-                return true;
-              }
-
-              std::vector<std::string> Argv;
-              Argv.push_back(Cmd.getExecutable());
-              Argv.insert(Argv.end(), Cmd.getArguments().begin(),
-                          Cmd.getArguments().end());
-
-              // Create an invocation that uses the underlying file
-              // system to ensure that any file system requests that
-              // are made by the driver do not go through the
-              // dependency scanning filesystem.
-              ToolInvocation Invocation(std::move(Argv), &Action,
-                                        &*CurrentFiles, PCHContainerOps);
-              Invocation.setDiagnosticConsumer(Diags->getClient());
-              Invocation.setDiagnosticOptions(&Diags->getDiagnosticOptions());
-              if (!Invocation.run())
-                return false;
-
-              std::vector<std::string> Args = Action.takeLastCC1Arguments();
-              Consumer.handleBuildCommand(
-                  {Cmd.getExecutable(), std::move(Args)});
-              return true;
-            });
-
-        if (Success && !Action.hasScanned()) {
-          Diags->Report(diag::err_fe_expected_compiler_job)
-              << llvm::join(FinalCommandLine, " ");
+  auto DiagOpts = CreateAndPopulateDiagOpts(FinalCCommandLine);
+  sanitizeDiagOpts(*DiagOpts);
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
+      CompilerInstance::createDiagnostics(DiagOpts.release(), &DC,
+                                          /*ShouldOwnClient=*/false);
+
+  // Although `Diagnostics` are used only for command-line parsing, the
+  // custom `DiagConsumer` might expect a `SourceManager` to be present.
+  SourceManager SrcMgr(*Diags, *CurrentFiles);
+  Diags->setSourceManager(&SrcMgr);
+  // DisableFree is modified by Tooling for running
+  // in-process; preserve the original value, which is
+  // always true for a driver invocation.
+  bool DisableFree = true;
+  DependencyScanningAction Action(WorkingDirectory, Consumer, DepFS, Format,
+                                  OptimizeArgs, EagerLoadModules, DisableFree,
+                                  ModuleName);
+  bool Success = forEachDriverJob(
+      FinalCommandLine, *Diags, *CurrentFiles, [&](const driver::Command &Cmd) {
+        if (StringRef(Cmd.getCreator().getName()) != "clang") {
+          // Non-clang command. Just pass through to the dependency
+          // consumer.
+          Consumer.handleBuildCommand(
+              {Cmd.getExecutable(),
+               {Cmd.getArguments().begin(), Cmd.getArguments().end()}});
+          return true;
         }
-        return Success && Action.hasScanned();
+
+        std::vector<std::string> Argv;
+        Argv.push_back(Cmd.getExecutable());
+        Argv.insert(Argv.end(), Cmd.getArguments().begin(),
+                    Cmd.getArguments().end());
+
+        // Create an invocation that uses the underlying file
+        // system to ensure that any file system requests that
+        // are made by the driver do not go through the
+        // dependency scanning filesystem.
+        ToolInvocation Invocation(std::move(Argv), &Action, &*CurrentFiles,
+                                  PCHContainerOps);
+        Invocation.setDiagnosticConsumer(Diags->getClient());
+        Invocation.setDiagnosticOptions(&Diags->getDiagnosticOptions());
+        if (!Invocation.run())
+          return false;
+
+        std::vector<std::string> Args = Action.takeLastCC1Arguments();
+        Consumer.handleBuildCommand({Cmd.getExecutable(), std::move(Args)});
+        return true;
       });
+
+  if (Success && !Action.hasScanned())
+    Diags->Report(diag::err_fe_expected_compiler_job)
+        << llvm::join(FinalCommandLine, " ");
+  return Success && Action.hasScanned();
 }


        


More information about the cfe-commits mailing list