[PATCH] D108974: [clang][tooling] Properly initialize DiagnosticsEngine for cc1 command-line construction

2021-09-10 Thread Jan Svoboda via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG8dc76ab7995b: [clang][tooling] Properly initialize 
DiagnosticsEngine for cc1 command-lineā€¦ (authored by jansvoboda11).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D108974

Files:
  clang/lib/Tooling/Tooling.cpp
  clang/unittests/Tooling/ToolingTest.cpp

Index: clang/unittests/Tooling/ToolingTest.cpp
===
--- clang/unittests/Tooling/ToolingTest.cpp
+++ clang/unittests/Tooling/ToolingTest.cpp
@@ -224,6 +224,82 @@
   EXPECT_TRUE(Invocation.run());
 }
 
+struct ErrorCountingDiagnosticConsumer : public DiagnosticConsumer {
+  ErrorCountingDiagnosticConsumer() : NumErrorsSeen(0) {}
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+const Diagnostic ) override {
+if (DiagLevel == DiagnosticsEngine::Level::Error)
+  ++NumErrorsSeen;
+  }
+  unsigned NumErrorsSeen;
+};
+
+TEST(ToolInvocation, DiagnosticsEngineProperlyInitializedForCC1Construction) {
+  llvm::IntrusiveRefCntPtr OverlayFileSystem(
+  new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
+  llvm::IntrusiveRefCntPtr InMemoryFileSystem(
+  new llvm::vfs::InMemoryFileSystem);
+  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
+  llvm::IntrusiveRefCntPtr Files(
+  new FileManager(FileSystemOptions(), OverlayFileSystem));
+
+  std::vector Args;
+  Args.push_back("tool-executable");
+  Args.push_back("-target");
+  // Invalid argument that by default results in an error diagnostic:
+  Args.push_back("i386-apple-ios14.0-simulator");
+  // Argument that downgrades the error into a warning:
+  Args.push_back("-Wno-error=invalid-ios-deployment-target");
+  Args.push_back("-fsyntax-only");
+  Args.push_back("test.cpp");
+
+  clang::tooling::ToolInvocation Invocation(
+  Args, std::make_unique(), Files.get());
+  InMemoryFileSystem->addFile(
+  "test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int a() {}\n"));
+  ErrorCountingDiagnosticConsumer Consumer;
+  Invocation.setDiagnosticConsumer();
+  EXPECT_TRUE(Invocation.run());
+  // Check that `-Wno-error=invalid-ios-deployment-target` downgraded the error
+  // into a warning.
+  EXPECT_EQ(Consumer.NumErrorsSeen, 0u);
+}
+
+TEST(ToolInvocation, CustomDiagnosticOptionsOverwriteParsedOnes) {
+  llvm::IntrusiveRefCntPtr OverlayFileSystem(
+  new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
+  llvm::IntrusiveRefCntPtr InMemoryFileSystem(
+  new llvm::vfs::InMemoryFileSystem);
+  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
+  llvm::IntrusiveRefCntPtr Files(
+  new FileManager(FileSystemOptions(), OverlayFileSystem));
+
+  std::vector Args;
+  Args.push_back("tool-executable");
+  Args.push_back("-target");
+  // Invalid argument that by default results in an error diagnostic:
+  Args.push_back("i386-apple-ios14.0-simulator");
+  // Argument that downgrades the error into a warning:
+  Args.push_back("-Wno-error=invalid-ios-deployment-target");
+  Args.push_back("-fsyntax-only");
+  Args.push_back("test.cpp");
+
+  clang::tooling::ToolInvocation Invocation(
+  Args, std::make_unique(), Files.get());
+  InMemoryFileSystem->addFile(
+  "test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int a() {}\n"));
+  ErrorCountingDiagnosticConsumer Consumer;
+  Invocation.setDiagnosticConsumer();
+
+  auto DiagOpts = llvm::makeIntrusiveRefCnt();
+  Invocation.setDiagnosticOptions(&*DiagOpts);
+
+  EXPECT_TRUE(Invocation.run());
+  // Check that `-Wno-error=invalid-ios-deployment-target` didn't downgrade the
+  // error into a warning due to being overwritten by custom diagnostic options.
+  EXPECT_EQ(Consumer.NumErrorsSeen, 1u);
+}
+
 struct DiagnosticConsumerExpectingSourceManager : public DiagnosticConsumer {
   bool SawSourceManager;
 
Index: clang/lib/Tooling/Tooling.cpp
===
--- clang/lib/Tooling/Tooling.cpp
+++ clang/lib/Tooling/Tooling.cpp
@@ -354,16 +354,16 @@
   }
 
   TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), DiagOpts);
-  DiagnosticsEngine Diagnostics(
-  IntrusiveRefCntPtr(new DiagnosticIDs()), &*DiagOpts,
-  DiagConsumer ? DiagConsumer : , false);
+  IntrusiveRefCntPtr Diagnostics =
+  CompilerInstance::createDiagnostics(
+  &*DiagOpts, DiagConsumer ? DiagConsumer : , false);
   // Although `Diagnostics` are used only for command-line parsing, the custom
   // `DiagConsumer` might expect a `SourceManager` to be present.
-  SourceManager SrcMgr(Diagnostics, *Files);
-  Diagnostics.setSourceManager();
+  SourceManager SrcMgr(*Diagnostics, *Files);
+  Diagnostics->setSourceManager();
 
   const std::unique_ptr Driver(
-  newDriver(, BinaryName, >getVirtualFileSystem()));
+  newDriver(&*Diagnostics, 

[PATCH] D108974: [clang][tooling] Properly initialize DiagnosticsEngine for cc1 command-line construction

2021-09-02 Thread Duncan P. N. Exon Smith via Phabricator via cfe-commits
dexonsmith added a comment.

(If you can squash the changes from https://reviews.llvm.org/D109158 into here, 
even better.)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D108974

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


[PATCH] D108974: [clang][tooling] Properly initialize DiagnosticsEngine for cc1 command-line construction

2021-09-02 Thread Duncan P. N. Exon Smith via Phabricator via cfe-commits
dexonsmith accepted this revision.
dexonsmith added a comment.
This revision is now accepted and ready to land.

LGTM.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D108974

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


[PATCH] D108974: [clang][tooling] Properly initialize DiagnosticsEngine for cc1 command-line construction

2021-09-02 Thread Jan Svoboda via Phabricator via cfe-commits
jansvoboda11 updated this revision to Diff 370262.
jansvoboda11 added a comment.

Shuffling patches around.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D108974

Files:
  clang/lib/Tooling/Tooling.cpp
  clang/unittests/Tooling/ToolingTest.cpp

Index: clang/unittests/Tooling/ToolingTest.cpp
===
--- clang/unittests/Tooling/ToolingTest.cpp
+++ clang/unittests/Tooling/ToolingTest.cpp
@@ -224,6 +224,82 @@
   EXPECT_TRUE(Invocation.run());
 }
 
+struct ErrorCountingDiagnosticConsumer : public DiagnosticConsumer {
+  ErrorCountingDiagnosticConsumer() : NumErrorsSeen(0) {}
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+const Diagnostic ) override {
+if (DiagLevel == DiagnosticsEngine::Level::Error)
+  ++NumErrorsSeen;
+  }
+  unsigned NumErrorsSeen;
+};
+
+TEST(ToolInvocation, DiagnosticsEngineProperlyInitializedForCC1Construction) {
+  llvm::IntrusiveRefCntPtr OverlayFileSystem(
+  new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
+  llvm::IntrusiveRefCntPtr InMemoryFileSystem(
+  new llvm::vfs::InMemoryFileSystem);
+  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
+  llvm::IntrusiveRefCntPtr Files(
+  new FileManager(FileSystemOptions(), OverlayFileSystem));
+
+  std::vector Args;
+  Args.push_back("tool-executable");
+  Args.push_back("-target");
+  // Invalid argument that by default results in an error diagnostic:
+  Args.push_back("i386-apple-ios14.0-simulator");
+  // Argument that downgrades the error into a warning:
+  Args.push_back("-Wno-error=invalid-ios-deployment-target");
+  Args.push_back("-fsyntax-only");
+  Args.push_back("test.cpp");
+
+  clang::tooling::ToolInvocation Invocation(
+  Args, std::make_unique(), Files.get());
+  InMemoryFileSystem->addFile(
+  "test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int a() {}\n"));
+  ErrorCountingDiagnosticConsumer Consumer;
+  Invocation.setDiagnosticConsumer();
+  EXPECT_TRUE(Invocation.run());
+  // Check that `-Wno-error=invalid-ios-deployment-target` downgraded the error
+  // into a warning.
+  EXPECT_EQ(Consumer.NumErrorsSeen, 0u);
+}
+
+TEST(ToolInvocation, CustomDiagnosticOptionsOverwriteParsedOnes) {
+  llvm::IntrusiveRefCntPtr OverlayFileSystem(
+  new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
+  llvm::IntrusiveRefCntPtr InMemoryFileSystem(
+  new llvm::vfs::InMemoryFileSystem);
+  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
+  llvm::IntrusiveRefCntPtr Files(
+  new FileManager(FileSystemOptions(), OverlayFileSystem));
+
+  std::vector Args;
+  Args.push_back("tool-executable");
+  Args.push_back("-target");
+  // Invalid argument that by default results in an error diagnostic:
+  Args.push_back("i386-apple-ios14.0-simulator");
+  // Argument that downgrades the error into a warning:
+  Args.push_back("-Wno-error=invalid-ios-deployment-target");
+  Args.push_back("-fsyntax-only");
+  Args.push_back("test.cpp");
+
+  clang::tooling::ToolInvocation Invocation(
+  Args, std::make_unique(), Files.get());
+  InMemoryFileSystem->addFile(
+  "test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int a() {}\n"));
+  ErrorCountingDiagnosticConsumer Consumer;
+  Invocation.setDiagnosticConsumer();
+
+  auto DiagOpts = llvm::makeIntrusiveRefCnt();
+  Invocation.setDiagnosticOptions(&*DiagOpts);
+
+  EXPECT_TRUE(Invocation.run());
+  // Check that `-Wno-error=invalid-ios-deployment-target` didn't downgrade the
+  // error into a warning due to being overwritten by custom diagnostic options.
+  EXPECT_EQ(Consumer.NumErrorsSeen, 1u);
+}
+
 struct DiagnosticConsumerExpectingSourceManager : public DiagnosticConsumer {
   bool SawSourceManager;
 
Index: clang/lib/Tooling/Tooling.cpp
===
--- clang/lib/Tooling/Tooling.cpp
+++ clang/lib/Tooling/Tooling.cpp
@@ -354,16 +354,16 @@
   }
 
   TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), DiagOpts);
-  DiagnosticsEngine Diagnostics(
-  IntrusiveRefCntPtr(new DiagnosticIDs()), &*DiagOpts,
-  DiagConsumer ? DiagConsumer : , false);
+  IntrusiveRefCntPtr Diagnostics =
+  CompilerInstance::createDiagnostics(
+  &*DiagOpts, DiagConsumer ? DiagConsumer : , false);
   // Although `Diagnostics` are used only for command-line parsing, the custom
   // `DiagConsumer` might expect a `SourceManager` to be present.
-  SourceManager SrcMgr(Diagnostics, *Files);
-  Diagnostics.setSourceManager();
+  SourceManager SrcMgr(*Diagnostics, *Files);
+  Diagnostics->setSourceManager();
 
   const std::unique_ptr Driver(
-  newDriver(, BinaryName, >getVirtualFileSystem()));
+  newDriver(&*Diagnostics, BinaryName, >getVirtualFileSystem()));
   // The "input file not found" diagnostics from the driver are useful.
   // The driver is only aware of the VFS working 

[PATCH] D108974: [clang][tooling] Properly initialize DiagnosticsEngine for cc1 command-line construction

2021-08-31 Thread Duncan P. N. Exon Smith via Phabricator via cfe-commits
dexonsmith added inline comments.



Comment at: clang/test/ClangScanDeps/strip_diag_serialize.cpp:1-3
+// FIXME: Make this pass again.
+// XFAIL: *
+

Can you clarify why a temporary regression is necessary? Is there a way of 
reordering patches to avoid it?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D108974

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


[PATCH] D108974: [clang][tooling] Properly initialize DiagnosticsEngine for cc1 command-line construction

2021-08-31 Thread Jan Svoboda via Phabricator via cfe-commits
jansvoboda11 updated this revision to Diff 369657.
jansvoboda11 added a comment.

XFAIL clang-scan-deps test


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D108974

Files:
  clang/lib/Tooling/Tooling.cpp
  clang/test/ClangScanDeps/strip_diag_serialize.cpp
  clang/unittests/Tooling/ToolingTest.cpp

Index: clang/unittests/Tooling/ToolingTest.cpp
===
--- clang/unittests/Tooling/ToolingTest.cpp
+++ clang/unittests/Tooling/ToolingTest.cpp
@@ -224,6 +224,47 @@
   EXPECT_TRUE(Invocation.run());
 }
 
+struct ErrorCountingDiagnosticConsumer : public DiagnosticConsumer {
+  ErrorCountingDiagnosticConsumer() : NumErrorsSeen(0) {}
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+const Diagnostic ) override {
+if (DiagLevel == DiagnosticsEngine::Level::Error)
+  ++NumErrorsSeen;
+  }
+  unsigned NumErrorsSeen;
+};
+
+TEST(ToolInvocation, DiagnosticsEngineProperlyInitializedForCC1Construction) {
+  llvm::IntrusiveRefCntPtr OverlayFileSystem(
+  new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
+  llvm::IntrusiveRefCntPtr InMemoryFileSystem(
+  new llvm::vfs::InMemoryFileSystem);
+  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
+  llvm::IntrusiveRefCntPtr Files(
+  new FileManager(FileSystemOptions(), OverlayFileSystem));
+
+  std::vector Args;
+  Args.push_back("tool-executable");
+  Args.push_back("-target");
+  // Invalid argument that by default results in an error diagnostic:
+  Args.push_back("i386-apple-ios14.0-simulator");
+  // Argument that downgrades the error into a warning:
+  Args.push_back("-Wno-error=invalid-ios-deployment-target");
+  Args.push_back("-fsyntax-only");
+  Args.push_back("test.cpp");
+
+  clang::tooling::ToolInvocation Invocation(
+  Args, std::make_unique(), Files.get());
+  InMemoryFileSystem->addFile(
+  "test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int a() {}\n"));
+  ErrorCountingDiagnosticConsumer Consumer;
+  Invocation.setDiagnosticConsumer();
+  EXPECT_TRUE(Invocation.run());
+  // Check that `-Wno-error=invalid-ios-deployment-target` downgraded the error
+  // into a warning.
+  EXPECT_EQ(Consumer.NumErrorsSeen, 0u);
+}
+
 struct DiagnosticConsumerExpectingSourceManager : public DiagnosticConsumer {
   bool SawSourceManager;
 
Index: clang/test/ClangScanDeps/strip_diag_serialize.cpp
===
--- clang/test/ClangScanDeps/strip_diag_serialize.cpp
+++ clang/test/ClangScanDeps/strip_diag_serialize.cpp
@@ -1,3 +1,6 @@
+// FIXME: Make this pass again.
+// XFAIL: *
+
 // RUN: rm -rf %t.dir
 // RUN: rm -rf %t.cdb
 // RUN: mkdir -p %t.dir
Index: clang/lib/Tooling/Tooling.cpp
===
--- clang/lib/Tooling/Tooling.cpp
+++ clang/lib/Tooling/Tooling.cpp
@@ -347,16 +347,16 @@
   CreateAndPopulateDiagOpts(Argv);
   TextDiagnosticPrinter DiagnosticPrinter(
   llvm::errs(), &*DiagOpts);
-  DiagnosticsEngine Diagnostics(
-  IntrusiveRefCntPtr(new DiagnosticIDs()), &*DiagOpts,
-  DiagConsumer ? DiagConsumer : , false);
+  IntrusiveRefCntPtr Diagnostics =
+  CompilerInstance::createDiagnostics(
+  &*DiagOpts, DiagConsumer ? DiagConsumer : , false);
   // Although `Diagnostics` are used only for command-line parsing, the custom
   // `DiagConsumer` might expect a `SourceManager` to be present.
-  SourceManager SrcMgr(Diagnostics, *Files);
-  Diagnostics.setSourceManager();
+  SourceManager SrcMgr(*Diagnostics, *Files);
+  Diagnostics->setSourceManager();
 
   const std::unique_ptr Driver(
-  newDriver(, BinaryName, >getVirtualFileSystem()));
+  newDriver(&*Diagnostics, BinaryName, >getVirtualFileSystem()));
   // The "input file not found" diagnostics from the driver are useful.
   // The driver is only aware of the VFS working directory, but some clients
   // change this at the FileManager level instead.
@@ -368,11 +368,11 @@
   if (!Compilation)
 return false;
   const llvm::opt::ArgStringList *const CC1Args = getCC1Arguments(
-  , Compilation.get());
+  &*Diagnostics, Compilation.get());
   if (!CC1Args)
 return false;
   std::unique_ptr Invocation(
-  newInvocation(, *CC1Args, BinaryName));
+  newInvocation(&*Diagnostics, *CC1Args, BinaryName));
   return runInvocation(BinaryName, Compilation.get(), std::move(Invocation),
std::move(PCHContainerOps));
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D108974: [clang][tooling] Properly initialize DiagnosticsEngine for cc1 command-line construction

2021-08-31 Thread Jan Svoboda via Phabricator via cfe-commits
jansvoboda11 created this revision.
jansvoboda11 added reviewers: Bigcheese, dexonsmith, arphaman.
jansvoboda11 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

In `ToolInvocation::run`, the driver -> cc1 command-line transformation uses 
`DiagnosticsEngine` that wasn't completely initialized. This patch ensures 
`ProcessWarningOptions(DiagnosticsEngine&, const DiagnosticOptions &)` is 
called.

Depends on D108918 .


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D108974

Files:
  clang/lib/Tooling/Tooling.cpp
  clang/unittests/Tooling/ToolingTest.cpp


Index: clang/unittests/Tooling/ToolingTest.cpp
===
--- clang/unittests/Tooling/ToolingTest.cpp
+++ clang/unittests/Tooling/ToolingTest.cpp
@@ -224,6 +224,47 @@
   EXPECT_TRUE(Invocation.run());
 }
 
+struct ErrorCountingDiagnosticConsumer : public DiagnosticConsumer {
+  ErrorCountingDiagnosticConsumer() : NumErrorsSeen(0) {}
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+const Diagnostic ) override {
+if (DiagLevel == DiagnosticsEngine::Level::Error)
+  ++NumErrorsSeen;
+  }
+  unsigned NumErrorsSeen;
+};
+
+TEST(ToolInvocation, DiagnosticsEngineProperlyInitializedForCC1Construction) {
+  llvm::IntrusiveRefCntPtr OverlayFileSystem(
+  new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
+  llvm::IntrusiveRefCntPtr InMemoryFileSystem(
+  new llvm::vfs::InMemoryFileSystem);
+  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
+  llvm::IntrusiveRefCntPtr Files(
+  new FileManager(FileSystemOptions(), OverlayFileSystem));
+
+  std::vector Args;
+  Args.push_back("tool-executable");
+  Args.push_back("-target");
+  // Invalid argument that by default results in an error diagnostic:
+  Args.push_back("i386-apple-ios14.0-simulator");
+  // Argument that downgrades the error into a warning:
+  Args.push_back("-Wno-error=invalid-ios-deployment-target");
+  Args.push_back("-fsyntax-only");
+  Args.push_back("test.cpp");
+
+  clang::tooling::ToolInvocation Invocation(
+  Args, std::make_unique(), Files.get());
+  InMemoryFileSystem->addFile(
+  "test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int a() {}\n"));
+  ErrorCountingDiagnosticConsumer Consumer;
+  Invocation.setDiagnosticConsumer();
+  EXPECT_TRUE(Invocation.run());
+  // Check that `-Wno-error=invalid-ios-deployment-target` downgraded the error
+  // into a warning.
+  EXPECT_EQ(Consumer.NumErrorsSeen, 0u);
+}
+
 struct DiagnosticConsumerExpectingSourceManager : public DiagnosticConsumer {
   bool SawSourceManager;
 
Index: clang/lib/Tooling/Tooling.cpp
===
--- clang/lib/Tooling/Tooling.cpp
+++ clang/lib/Tooling/Tooling.cpp
@@ -347,16 +347,16 @@
   CreateAndPopulateDiagOpts(Argv);
   TextDiagnosticPrinter DiagnosticPrinter(
   llvm::errs(), &*DiagOpts);
-  DiagnosticsEngine Diagnostics(
-  IntrusiveRefCntPtr(new DiagnosticIDs()), &*DiagOpts,
-  DiagConsumer ? DiagConsumer : , false);
+  IntrusiveRefCntPtr Diagnostics =
+  CompilerInstance::createDiagnostics(
+  &*DiagOpts, DiagConsumer ? DiagConsumer : , false);
   // Although `Diagnostics` are used only for command-line parsing, the custom
   // `DiagConsumer` might expect a `SourceManager` to be present.
-  SourceManager SrcMgr(Diagnostics, *Files);
-  Diagnostics.setSourceManager();
+  SourceManager SrcMgr(*Diagnostics, *Files);
+  Diagnostics->setSourceManager();
 
   const std::unique_ptr Driver(
-  newDriver(, BinaryName, >getVirtualFileSystem()));
+  newDriver(&*Diagnostics, BinaryName, >getVirtualFileSystem()));
   // The "input file not found" diagnostics from the driver are useful.
   // The driver is only aware of the VFS working directory, but some clients
   // change this at the FileManager level instead.
@@ -368,11 +368,11 @@
   if (!Compilation)
 return false;
   const llvm::opt::ArgStringList *const CC1Args = getCC1Arguments(
-  , Compilation.get());
+  &*Diagnostics, Compilation.get());
   if (!CC1Args)
 return false;
   std::unique_ptr Invocation(
-  newInvocation(, *CC1Args, BinaryName));
+  newInvocation(&*Diagnostics, *CC1Args, BinaryName));
   return runInvocation(BinaryName, Compilation.get(), std::move(Invocation),
std::move(PCHContainerOps));
 }


Index: clang/unittests/Tooling/ToolingTest.cpp
===
--- clang/unittests/Tooling/ToolingTest.cpp
+++ clang/unittests/Tooling/ToolingTest.cpp
@@ -224,6 +224,47 @@
   EXPECT_TRUE(Invocation.run());
 }
 
+struct ErrorCountingDiagnosticConsumer : public DiagnosticConsumer {
+  ErrorCountingDiagnosticConsumer() : NumErrorsSeen(0) {}
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+const Diagnostic