[PATCH] D156234: [clang][deps] add support for dependency scanning with cc1 command line

2023-08-04 Thread Jan Svoboda via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6b4de7b1c71b: [clang][deps] add support for dependency 
scanning with cc1 command line (authored by cpsughrue, committed by 
jansvoboda11).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156234/new/

https://reviews.llvm.org/D156234

Files:
  clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
  clang/test/ClangScanDeps/modules-cc1.cpp

Index: clang/test/ClangScanDeps/modules-cc1.cpp
===
--- /dev/null
+++ clang/test/ClangScanDeps/modules-cc1.cpp
@@ -0,0 +1,29 @@
+// Check that clang-scan-deps works with cc1 command lines
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+
+//--- modules_cc1.cpp
+#include "header.h"
+
+//--- header.h
+
+//--- module.modulemap
+module header1 { header "header.h" }
+
+//--- cdb.json.template
+[{
+  "file": "DIR/modules_cc1.cpp",
+  "directory": "DIR",
+  "command": "clang -cc1 DIR/modules_cc1.cpp -fimplicit-module-maps -o modules_cc1.o"
+}]
+
+// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
+// RUN: clang-scan-deps -compilation-database %t/cdb.json -j 1 -mode preprocess-dependency-directives > %t/result
+// RUN: cat %t/result | sed 's:\?:/:g' | FileCheck %s -DPREFIX=%/t
+
+// CHECK: modules_cc1.o:
+// CHECK-NEXT: [[PREFIX]]/modules_cc1.cpp
+// CHECK-NEXT: [[PREFIX]]/module.modulemap
+// CHECK-NEXT: [[PREFIX]]/header.h
Index: clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
===
--- clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -385,6 +385,9 @@
   if (!Compilation)
 return false;
 
+  if (Compilation->containsError())
+return false;
+
   for (const driver::Command  : Compilation->getJobs()) {
 if (!Callback(Job))
   return false;
@@ -392,6 +395,26 @@
   return true;
 }
 
+static bool createAndRunToolInvocation(
+std::vector CommandLine, DependencyScanningAction ,
+FileManager ,
+std::shared_ptr ,
+DiagnosticsEngine , DependencyConsumer ) {
+
+  // Save executable path before providing CommandLine to ToolInvocation
+  std::string Executable = CommandLine[0];
+  ToolInvocation Invocation(std::move(CommandLine), , ,
+PCHContainerOps);
+  Invocation.setDiagnosticConsumer(Diags.getClient());
+  Invocation.setDiagnosticOptions(());
+  if (!Invocation.run())
+return false;
+
+  std::vector Args = Action.takeLastCC1Arguments();
+  Consumer.handleBuildCommand({std::move(Executable), std::move(Args)});
+  return true;
+}
+
 bool DependencyScanningWorker::computeDependencies(
 StringRef WorkingDirectory, const std::vector ,
 DependencyConsumer , DependencyActionController ,
@@ -454,37 +477,37 @@
   DependencyScanningAction Action(WorkingDirectory, Consumer, Controller, DepFS,
   Format, OptimizeArgs, EagerLoadModules,
   DisableFree, ModuleName);
-  bool Success = forEachDriverJob(
-  FinalCommandLine, *Diags, *FileMgr, [&](const driver::Command ) {
-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 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), , &*FileMgr,
-  PCHContainerOps);
-Invocation.setDiagnosticConsumer(Diags->getClient());
-Invocation.setDiagnosticOptions(>getDiagnosticOptions());
-if (!Invocation.run())
-  return false;
-
-std::vector Args = Action.takeLastCC1Arguments();
-Consumer.handleBuildCommand({Cmd.getExecutable(), std::move(Args)});
-return true;
-  });
+
+  bool Success = false;
+  if (FinalCommandLine[1] == "-cc1") {
+Success = createAndRunToolInvocation(FinalCommandLine, Action, *FileMgr,
+ PCHContainerOps, *Diags, Consumer);
+  } else {
+Success = forEachDriverJob(
+FinalCommandLine, *Diags, *FileMgr, [&](const driver::Command ) {
+  if (StringRef(Cmd.getCreator().getName()) != "clang") {
+// Non-clang command. Just pass through to the dependency
+// 

[PATCH] D156234: [clang][deps] add support for dependency scanning with cc1 command line

2023-08-03 Thread Connor Sughrue via Phabricator via cfe-commits
cpsughrue updated this revision to Diff 546861.
cpsughrue added a comment.

Fixing failed test on Windows CI


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156234/new/

https://reviews.llvm.org/D156234

Files:
  clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
  clang/test/ClangScanDeps/modules-cc1.cpp

Index: clang/test/ClangScanDeps/modules-cc1.cpp
===
--- /dev/null
+++ clang/test/ClangScanDeps/modules-cc1.cpp
@@ -0,0 +1,29 @@
+// Check that clang-scan-deps works with cc1 command lines
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+
+//--- modules_cc1.cpp
+#include "header.h"
+
+//--- header.h
+
+//--- module.modulemap
+module header1 { header "header.h" }
+
+//--- cdb.json.template
+[{
+  "file": "DIR/modules_cc1.cpp",
+  "directory": "DIR",
+  "command": "clang -cc1 DIR/modules_cc1.cpp -fimplicit-module-maps -o modules_cc1.o"
+}]
+
+// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
+// RUN: clang-scan-deps -compilation-database %t/cdb.json -j 1 -mode preprocess-dependency-directives > %t/result
+// RUN: cat %t/result | sed 's:\?:/:g' | FileCheck %s -DPREFIX=%/t
+
+// CHECK: modules_cc1.o:
+// CHECK-NEXT: [[PREFIX]]/modules_cc1.cpp
+// CHECK-NEXT: [[PREFIX]]/module.modulemap
+// CHECK-NEXT: [[PREFIX]]/header.h
Index: clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
===
--- clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -385,6 +385,9 @@
   if (!Compilation)
 return false;
 
+  if (Compilation->containsError())
+return false;
+
   for (const driver::Command  : Compilation->getJobs()) {
 if (!Callback(Job))
   return false;
@@ -392,6 +395,26 @@
   return true;
 }
 
+static bool createAndRunToolInvocation(
+std::vector CommandLine, DependencyScanningAction ,
+FileManager ,
+std::shared_ptr ,
+DiagnosticsEngine , DependencyConsumer ) {
+
+  // Save executable path before providing CommandLine to ToolInvocation
+  std::string Executable = CommandLine[0];
+  ToolInvocation Invocation(std::move(CommandLine), , ,
+PCHContainerOps);
+  Invocation.setDiagnosticConsumer(Diags.getClient());
+  Invocation.setDiagnosticOptions(());
+  if (!Invocation.run())
+return false;
+
+  std::vector Args = Action.takeLastCC1Arguments();
+  Consumer.handleBuildCommand({std::move(Executable), std::move(Args)});
+  return true;
+}
+
 bool DependencyScanningWorker::computeDependencies(
 StringRef WorkingDirectory, const std::vector ,
 DependencyConsumer , DependencyActionController ,
@@ -454,37 +477,37 @@
   DependencyScanningAction Action(WorkingDirectory, Consumer, Controller, DepFS,
   Format, OptimizeArgs, EagerLoadModules,
   DisableFree, ModuleName);
-  bool Success = forEachDriverJob(
-  FinalCommandLine, *Diags, *FileMgr, [&](const driver::Command ) {
-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 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), , &*FileMgr,
-  PCHContainerOps);
-Invocation.setDiagnosticConsumer(Diags->getClient());
-Invocation.setDiagnosticOptions(>getDiagnosticOptions());
-if (!Invocation.run())
-  return false;
-
-std::vector Args = Action.takeLastCC1Arguments();
-Consumer.handleBuildCommand({Cmd.getExecutable(), std::move(Args)});
-return true;
-  });
+
+  bool Success = false;
+  if (FinalCommandLine[1] == "-cc1") {
+Success = createAndRunToolInvocation(FinalCommandLine, Action, *FileMgr,
+ PCHContainerOps, *Diags, Consumer);
+  } else {
+Success = forEachDriverJob(
+FinalCommandLine, *Diags, *FileMgr, [&](const driver::Command ) {
+  if (StringRef(Cmd.getCreator().getName()) != "clang") {
+// Non-clang command. Just pass through to the dependency
+// consumer.
+Consumer.handleBuildCommand(
+{Cmd.getExecutable(),
+ {Cmd.getArguments().begin(), 

[PATCH] D156234: [clang][deps] add support for dependency scanning with cc1 command line

2023-08-02 Thread Jan Svoboda via Phabricator via cfe-commits
jansvoboda11 accepted this revision.
jansvoboda11 added a comment.
This revision is now accepted and ready to land.

LGTM after Windows CI gets fixed.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156234/new/

https://reviews.llvm.org/D156234

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156234: [clang][deps] add support for dependency scanning with cc1 command line

2023-08-01 Thread Connor Sughrue via Phabricator via cfe-commits
cpsughrue updated this revision to Diff 546182.
cpsughrue added a comment.

Update llvm-lit test to use split-file


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156234/new/

https://reviews.llvm.org/D156234

Files:
  clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
  clang/test/ClangScanDeps/modules-cc1.cpp

Index: clang/test/ClangScanDeps/modules-cc1.cpp
===
--- /dev/null
+++ clang/test/ClangScanDeps/modules-cc1.cpp
@@ -0,0 +1,29 @@
+// Check that clang-scan-deps works with cc1 command lines
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+
+//--- modules_cc1.cpp
+#include "header.h"
+
+//--- header.h
+
+//--- module.modulemap
+module header1 { header "header.h" }
+
+//--- cdb.json.template
+[{
+  "file": "DIR/modules_cc1.cpp",
+  "directory": "DIR",
+  "command": "clang -cc1 DIR/modules_cc1.cpp -fimplicit-module-maps -o modules_cc1.o"
+}]
+
+// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
+// RUN: clang-scan-deps -compilation-database %t/cdb.json -j 1 -mode preprocess-dependency-directives | \
+// RUN:   FileCheck %s -DPREFIX=%t
+
+// CHECK: modules_cc1.o:
+// CHECK-NEXT: [[PREFIX]]/modules_cc1.cpp
+// CHECK-NEXT: [[PREFIX]]/module.modulemap
+// CHECK-NEXT: [[PREFIX]]/header.h
Index: clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
===
--- clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -385,6 +385,9 @@
   if (!Compilation)
 return false;
 
+  if (Compilation->containsError())
+return false;
+
   for (const driver::Command  : Compilation->getJobs()) {
 if (!Callback(Job))
   return false;
@@ -392,6 +395,26 @@
   return true;
 }
 
+static bool createAndRunToolInvocation(
+std::vector CommandLine, DependencyScanningAction ,
+FileManager ,
+std::shared_ptr ,
+DiagnosticsEngine , DependencyConsumer ) {
+
+  // Save executable path before providing CommandLine to ToolInvocation
+  std::string Executable = CommandLine[0];
+  ToolInvocation Invocation(std::move(CommandLine), , ,
+PCHContainerOps);
+  Invocation.setDiagnosticConsumer(Diags.getClient());
+  Invocation.setDiagnosticOptions(());
+  if (!Invocation.run())
+return false;
+
+  std::vector Args = Action.takeLastCC1Arguments();
+  Consumer.handleBuildCommand({std::move(Executable), std::move(Args)});
+  return true;
+}
+
 bool DependencyScanningWorker::computeDependencies(
 StringRef WorkingDirectory, const std::vector ,
 DependencyConsumer , DependencyActionController ,
@@ -454,37 +477,37 @@
   DependencyScanningAction Action(WorkingDirectory, Consumer, Controller, DepFS,
   Format, OptimizeArgs, EagerLoadModules,
   DisableFree, ModuleName);
-  bool Success = forEachDriverJob(
-  FinalCommandLine, *Diags, *FileMgr, [&](const driver::Command ) {
-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 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), , &*FileMgr,
-  PCHContainerOps);
-Invocation.setDiagnosticConsumer(Diags->getClient());
-Invocation.setDiagnosticOptions(>getDiagnosticOptions());
-if (!Invocation.run())
-  return false;
-
-std::vector Args = Action.takeLastCC1Arguments();
-Consumer.handleBuildCommand({Cmd.getExecutable(), std::move(Args)});
-return true;
-  });
+
+  bool Success = false;
+  if (FinalCommandLine[1] == "-cc1") {
+Success = createAndRunToolInvocation(FinalCommandLine, Action, *FileMgr,
+ PCHContainerOps, *Diags, Consumer);
+  } else {
+Success = forEachDriverJob(
+FinalCommandLine, *Diags, *FileMgr, [&](const driver::Command ) {
+  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;
+ 

[PATCH] D156234: [clang][deps] add support for dependency scanning with cc1 command line

2023-08-01 Thread Connor Sughrue via Phabricator via cfe-commits
cpsughrue added inline comments.



Comment at: 
clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp:482
+  bool Success = false;
+  if (FinalCommandLine[1] == "-cc1") {
+Success = createAndRunToolInvocation(FinalCommandLine, Action, *FileMgr,

Bigcheese wrote:
> jansvoboda11 wrote:
> > cpsughrue wrote:
> > > Is there a good way to validate cc1 command lines?
> > I think that happens in `ToolInvocation::run()` that's called by 
> > `createAndRunToolInvocation`. Are you seeing cases where we don't emit a 
> > diagnostic for an invalid `-cc1` command line?
> Not really, you just have to parse it. Was there a particular reason you 
> wanted to validate here?
@jansvoboda11 You're right, `ToolInvocation::run()` fails if there are any 
issues when the function creates the compiler invocation - I missed that. I've 
not seen any cases where diagnostics aren't outputted.



Comment at: 
clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp:482
+  bool Success = false;
+  if (FinalCommandLine[1] == "-cc1") {
+Success = createAndRunToolInvocation(FinalCommandLine, Action, *FileMgr,

cpsughrue wrote:
> Bigcheese wrote:
> > jansvoboda11 wrote:
> > > cpsughrue wrote:
> > > > Is there a good way to validate cc1 command lines?
> > > I think that happens in `ToolInvocation::run()` that's called by 
> > > `createAndRunToolInvocation`. Are you seeing cases where we don't emit a 
> > > diagnostic for an invalid `-cc1` command line?
> > Not really, you just have to parse it. Was there a particular reason you 
> > wanted to validate here?
> @jansvoboda11 You're right, `ToolInvocation::run()` fails if there are any 
> issues when the function creates the compiler invocation - I missed that. 
> I've not seen any cases where diagnostics aren't outputted.
@Bigcheese No, I just wanted to make sure some sort of validation was happening 
and missed the work being done in `ToolInvocation::run()`.



Comment at: clang/test/ClangScanDeps/Inputs/modules_cc1_cdb.json:1
+[
+{

jansvoboda11 wrote:
> I assume this was cargo-culted from 
> `clang/test/ClangScanDeps/Inputs/modules_cdb.json`. I don't think we need 
> multiple entries here and lots of the flags are unnecessary for just testing 
> out `-cc1` command lines work. I suggest having just one minimal `-cc1` 
> command line here.
That is an accurate assumption. Are you good with the following command line 
`clang -cc1 DIR/modules_cdb_input.cpp -IInputs -fimplicit-module-maps -o 
modules_cdb_input.o`?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156234/new/

https://reviews.llvm.org/D156234

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156234: [clang][deps] add support for dependency scanning with cc1 command line

2023-08-01 Thread Jan Svoboda via Phabricator via cfe-commits
jansvoboda11 added inline comments.



Comment at: 
clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp:482
+  bool Success = false;
+  if (FinalCommandLine[1] == "-cc1") {
+Success = createAndRunToolInvocation(FinalCommandLine, Action, *FileMgr,

cpsughrue wrote:
> Is there a good way to validate cc1 command lines?
I think that happens in `ToolInvocation::run()` that's called by 
`createAndRunToolInvocation`. Are you seeing cases where we don't emit a 
diagnostic for an invalid `-cc1` command line?



Comment at: clang/test/ClangScanDeps/Inputs/modules_cc1_cdb.json:1
+[
+{

I assume this was cargo-culted from 
`clang/test/ClangScanDeps/Inputs/modules_cdb.json`. I don't think we need 
multiple entries here and lots of the flags are unnecessary for just testing 
out `-cc1` command lines work. I suggest having just one minimal `-cc1` command 
line here.



Comment at: clang/test/ClangScanDeps/modules-cc1.cpp:10
+// RUN: mkdir %t.dir/Inputs
+// RUN: cp %S/Inputs/header.h %t.dir/Inputs/header.h
+// RUN: cp %S/Inputs/header2.h %t.dir/Inputs/header2.h

Recently, we've been using `split-file` to set up the file system for our 
tests. It's much easier to see what's going on in a glance. Can you transform 
the test into that format? You can take inspiration from 
`clang/test/ClangScanDeps/modules-transitive.c` for example.



Comment at: clang/test/ClangScanDeps/modules-cc1.cpp:18
+//
+// The output order is non-deterministic when using more than one thread,
+// so check the output using two runs. Note that the 'NOT' check is not used

Yeah, this is already covered by the other test, I suggest dropping this 
comment and the `-j` flag in the `clang-scan-deps` invocation below.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156234/new/

https://reviews.llvm.org/D156234

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156234: [clang][deps] add support for dependency scanning with cc1 command line

2023-08-01 Thread Michael Spencer via Phabricator via cfe-commits
Bigcheese added inline comments.



Comment at: 
clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp:482
+  bool Success = false;
+  if (FinalCommandLine[1] == "-cc1") {
+Success = createAndRunToolInvocation(FinalCommandLine, Action, *FileMgr,

cpsughrue wrote:
> Is there a good way to validate cc1 command lines?
Not really, you just have to parse it. Was there a particular reason you wanted 
to validate here?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156234/new/

https://reviews.llvm.org/D156234

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156234: [clang][deps] add support for dependency scanning with cc1 command line

2023-08-01 Thread Connor Sughrue via Phabricator via cfe-commits
cpsughrue added inline comments.



Comment at: 
clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp:482
+  bool Success = false;
+  if (FinalCommandLine[1] == "-cc1") {
+Success = createAndRunToolInvocation(FinalCommandLine, Action, *FileMgr,

Is there a good way to validate cc1 command lines?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156234/new/

https://reviews.llvm.org/D156234

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D156234: [clang][deps] add support for dependency scanning with cc1 command line

2023-07-31 Thread Connor Sughrue via Phabricator via cfe-commits
cpsughrue updated this revision to Diff 545910.
cpsughrue retitled this revision from "[clang][deps] provide support for cc1 
command line scanning" to "[clang][deps] add support for dependency scanning 
with cc1 command line".
cpsughrue edited the summary of this revision.
cpsughrue added a comment.

Added llvm-lit test for commit and removed previously created unit test


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156234/new/

https://reviews.llvm.org/D156234

Files:
  clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
  clang/test/ClangScanDeps/Inputs/modules_cc1_cdb.json
  clang/test/ClangScanDeps/modules-cc1.cpp

Index: clang/test/ClangScanDeps/modules-cc1.cpp
===
--- /dev/null
+++ clang/test/ClangScanDeps/modules-cc1.cpp
@@ -0,0 +1,44 @@
+// RUN: rm -rf %t.dir
+// RUN: rm -rf %t.cdb
+// RUN: rm -rf %t_clangcl.cdb
+// RUN: rm -rf %t.module-cache
+// RUN: rm -rf %t.module-cache_clangcl
+// RUN: mkdir -p %t.dir
+// RUN: cp %s %t.dir/modules_cdb_input.cpp
+// RUN: cp %s %t.dir/modules_cdb_input2.cpp
+// RUN: mkdir %t.dir/Inputs
+// RUN: cp %S/Inputs/header.h %t.dir/Inputs/header.h
+// RUN: cp %S/Inputs/header2.h %t.dir/Inputs/header2.h
+// RUN: cp %S/Inputs/module.modulemap %t.dir/Inputs/module.modulemap
+// RUN: sed -e "s|DIR|%/t.dir|g" %S/Inputs/modules_cc1_cdb.json > %t.cdb
+//
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 1 -mode preprocess-dependency-directives | \
+// RUN:   FileCheck --check-prefixes=CHECK1,CHECK2,CHECK2NO %s
+//
+// The output order is non-deterministic when using more than one thread,
+// so check the output using two runs. Note that the 'NOT' check is not used
+// as it might fail if the results for `modules_cdb_input.cpp` are reported before
+// `modules_cdb_input2.cpp`.
+//
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 2 -mode preprocess-dependency-directives | \
+// RUN:   FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 2 -mode preprocess | \
+// RUN:   FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 2 -mode preprocess-dependency-directives | \
+// RUN:   FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 2 -mode preprocess | \
+// RUN:   FileCheck --check-prefix=CHECK2 %s
+
+#include "header.h"
+
+// CHECK1: modules_cdb_input2.o:
+// CHECK1-NEXT: modules_cdb_input2.cpp
+// CHECK1-NEXT: Inputs{{/|\\}}module.modulemap
+// CHECK1-NEXT: Inputs{{/|\\}}header2.h
+// CHECK1: Inputs{{/|\\}}header.h
+
+// CHECK2: {{(modules_cdb_input)|(a)|(b)}}.o:
+// CHECK2-NEXT: modules_cdb_input.cpp
+// CHECK2-NEXT: Inputs{{/|\\}}module.modulemap
+// CHECK2-NEXT: Inputs{{/|\\}}header.h
+// CHECK2NO-NOT: header2
\ No newline at end of file
Index: clang/test/ClangScanDeps/Inputs/modules_cc1_cdb.json
===
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/modules_cc1_cdb.json
@@ -0,0 +1,22 @@
+[
+{
+  "directory": "DIR",
+  "command": "clang -cc1 -E DIR/modules_cdb_input2.cpp -IInputs -D INCLUDE_HEADER2 -fmodules -MT modules_cdb_input2.o -dependency-file DIR/modules_cdb2.d -fmodules-cache-path=DIR/module-cache -fcoverage-compilation-dir=DIR -fimplicit-module-maps -fmodules-validate-system-headers",
+  "file": "DIR/modules_cdb_input2.cpp"
+},
+{
+  "directory": "DIR",
+  "command": "clang -cc1 -E DIR/modules_cdb_input.cpp -IInputs -fmodules -fmodules-cache-path=DIR/module-cache -fcoverage-compilation-dir=DIR -fdebug-compilation-dir=DIR -fimplicit-module-maps -fmodules-validate-system-headers",
+  "file": "DIR/modules_cdb_input.cpp"
+},
+{
+  "directory": "DIR",
+  "command": "clang -cc1 -E DIR/modules_cdb_input.cpp -IInputs -fmodules -fmodules-cache-path=DIR/module-cache -fcoverage-compilation-dir=DIR -fdebug-compilation-dir=DIR -fimplicit-module-maps -fmodules-validate-system-headers -o a.o",
+  "file": "DIR/modules_cdb_input.cpp"
+},
+{
+  "directory": "DIR",
+  "command": "clang -cc1 -E DIR/modules_cdb_input.cpp -IInputs -fmodules -fmodules-cache-path=DIR/module-cache -fcoverage-compilation-dir=DIR -fdebug-compilation-dir=DIR -fimplicit-module-maps -fmodules-validate-system-headers -o b.o",
+  "file": "DIR/modules_cdb_input.cpp"
+}
+]
Index: clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
===
--- clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -385,6 +385,9 @@
   if (!Compilation)
 return false;
 
+  if (Compilation->containsError())
+return false;
+
   for (const driver::Command  : Compilation->getJobs()) {
 if (!Callback(Job))
   return false;
@@ -392,6 +395,26 @@
   return true;
 }
 
+static bool createAndRunToolInvocation(
+std::vector CommandLine, DependencyScanningAction ,
+FileManager ,
+