r194226 - Adds the ability to inject a DiagnosticConsumer into ClangTools.

Manuel Klimek klimek at google.com
Thu Nov 7 15:18:05 PST 2013


Author: klimek
Date: Thu Nov  7 17:18:05 2013
New Revision: 194226

URL: http://llvm.org/viewvc/llvm-project?rev=194226&view=rev
Log:
 Adds the ability to inject a DiagnosticConsumer into ClangTools.

Modified:
    cfe/trunk/include/clang/Tooling/Tooling.h
    cfe/trunk/lib/Tooling/Tooling.cpp
    cfe/trunk/unittests/Tooling/ToolingTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Tooling.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Tooling.h?rev=194226&r1=194225&r2=194226&view=diff
==============================================================================
--- cfe/trunk/include/clang/Tooling/Tooling.h (original)
+++ cfe/trunk/include/clang/Tooling/Tooling.h Thu Nov  7 17:18:05 2013
@@ -30,6 +30,7 @@
 #ifndef LLVM_CLANG_TOOLING_TOOLING_H
 #define LLVM_CLANG_TOOLING_TOOLING_H
 
+#include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Driver/Util.h"
@@ -63,7 +64,8 @@ public:
 
   /// \brief Perform an action for an invocation.
   virtual bool runInvocation(clang::CompilerInvocation *Invocation,
-                             FileManager *Files) = 0;
+                             FileManager *Files,
+                             DiagnosticConsumer *DiagConsumer) = 0;
 };
 
 /// \brief Interface to generate clang::FrontendActions.
@@ -77,8 +79,8 @@ public:
   virtual ~FrontendActionFactory();
 
   /// \brief Invokes the compiler with a FrontendAction created by create().
-  bool runInvocation(clang::CompilerInvocation *Invocation,
-                     FileManager *Files);
+  bool runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files,
+                     DiagnosticConsumer *DiagConsumer);
 
   /// \brief Returns a new clang::FrontendAction.
   ///
@@ -197,6 +199,9 @@ class ToolInvocation {
 
   ~ToolInvocation();
 
+  /// \brief Set a \c DiagnosticConsumer to use during parsing.
+  void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer);
+
   /// \brief Map a virtual file to be used while running the tool.
   ///
   /// \param FilePath The path at which the content will be mapped.
@@ -221,6 +226,7 @@ class ToolInvocation {
   FileManager *Files;
   // Maps <file name> -> <file content>.
   llvm::StringMap<StringRef> MappedFileContents;
+  DiagnosticConsumer *DiagConsumer;
 };
 
 /// \brief Utility to run a FrontendAction over a set of files.
@@ -243,6 +249,9 @@ class ClangTool {
 
   virtual ~ClangTool() { clearArgumentsAdjusters(); }
 
+  /// \brief Set a \c DiagnosticConsumer to use during parsing.
+  void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer);
+
   /// \brief Map a virtual file to be used while running the tool.
   ///
   /// \param FilePath The path at which the content will be mapped.
@@ -289,6 +298,8 @@ class ClangTool {
   std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
 
   SmallVector<ArgumentsAdjuster *, 2> ArgsAdjusters;
+
+  DiagnosticConsumer *DiagConsumer;
 };
 
 template <typename T>

Modified: cfe/trunk/lib/Tooling/Tooling.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Tooling.cpp?rev=194226&r1=194225&r2=194226&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/Tooling.cpp (original)
+++ cfe/trunk/lib/Tooling/Tooling.cpp Thu Nov  7 17:18:05 2013
@@ -165,20 +165,29 @@ public:
 
 ToolInvocation::ToolInvocation(ArrayRef<std::string> CommandLine,
                                ToolAction *Action, FileManager *Files)
-    : CommandLine(CommandLine.vec()), Action(Action), OwnsAction(false),
-      Files(Files) {}
+    : CommandLine(CommandLine.vec()),
+      Action(Action),
+      OwnsAction(false),
+      Files(Files),
+      DiagConsumer(NULL) {}
 
 ToolInvocation::ToolInvocation(ArrayRef<std::string> CommandLine,
                                FrontendAction *FAction, FileManager *Files)
     : CommandLine(CommandLine.vec()),
-      Action(new SingleFrontendActionFactory(FAction)), OwnsAction(true),
-      Files(Files) {}
+      Action(new SingleFrontendActionFactory(FAction)),
+      OwnsAction(true),
+      Files(Files),
+      DiagConsumer(NULL) {}
 
 ToolInvocation::~ToolInvocation() {
   if (OwnsAction)
     delete Action;
 }
 
+void ToolInvocation::setDiagnosticConsumer(DiagnosticConsumer *D) {
+  DiagConsumer = D;
+}
+
 void ToolInvocation::mapVirtualFile(StringRef FilePath, StringRef Content) {
   SmallString<1024> PathStorage;
   llvm::sys::path::native(FilePath, PathStorage);
@@ -194,8 +203,8 @@ bool ToolInvocation::run() {
   TextDiagnosticPrinter DiagnosticPrinter(
       llvm::errs(), &*DiagOpts);
   DiagnosticsEngine Diagnostics(
-    IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()),
-    &*DiagOpts, &DiagnosticPrinter, false);
+      IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
+      DiagConsumer ? DiagConsumer : &DiagnosticPrinter, false);
 
   const OwningPtr<clang::driver::Driver> Driver(
       newDriver(&Diagnostics, BinaryName));
@@ -232,11 +241,12 @@ bool ToolInvocation::runInvocation(
     llvm::errs() << "\n";
   }
 
-  return Action->runInvocation(Invocation, Files);
+  return Action->runInvocation(Invocation, Files, DiagConsumer);
 }
 
 bool FrontendActionFactory::runInvocation(CompilerInvocation *Invocation,
-                                          FileManager *Files) {
+                                          FileManager *Files,
+                                          DiagnosticConsumer *DiagConsumer) {
   // Create a compiler instance to handle the actual work.
   clang::CompilerInstance Compiler;
   Compiler.setInvocation(Invocation);
@@ -248,7 +258,7 @@ bool FrontendActionFactory::runInvocatio
   OwningPtr<FrontendAction> ScopedToolAction(create());
 
   // Create the compilers actual diagnostics engine.
-  Compiler.createDiagnostics();
+  Compiler.createDiagnostics(DiagConsumer, /*ShouldOwnClient=*/false);
   if (!Compiler.hasDiagnostics())
     return false;
 
@@ -262,7 +272,7 @@ bool FrontendActionFactory::runInvocatio
 
 ClangTool::ClangTool(const CompilationDatabase &Compilations,
                      ArrayRef<std::string> SourcePaths)
-    : Files(new FileManager(FileSystemOptions())) {
+    : Files(new FileManager(FileSystemOptions())), DiagConsumer(NULL) {
   ArgsAdjusters.push_back(new ClangStripOutputAdjuster());
   ArgsAdjusters.push_back(new ClangSyntaxOnlyAdjuster());
   for (unsigned I = 0, E = SourcePaths.size(); I != E; ++I) {
@@ -286,6 +296,10 @@ ClangTool::ClangTool(const CompilationDa
   }
 }
 
+void ClangTool::setDiagnosticConsumer(DiagnosticConsumer *D) {
+  DiagConsumer = D;
+}
+
 void ClangTool::mapVirtualFile(StringRef FilePath, StringRef Content) {
   MappedFileContents.push_back(std::make_pair(FilePath, Content));
 }
@@ -341,6 +355,7 @@ int ClangTool::run(ToolAction *Action) {
       llvm::dbgs() << "Processing: " << File << ".\n";
     });
     ToolInvocation Invocation(CommandLine, Action, Files.getPtr());
+    Invocation.setDiagnosticConsumer(DiagConsumer);
     for (int I = 0, E = MappedFileContents.size(); I != E; ++I) {
       Invocation.mapVirtualFile(MappedFileContents[I].first,
                                 MappedFileContents[I].second);
@@ -362,12 +377,13 @@ class ASTBuilderAction : public ToolActi
 public:
   ASTBuilderAction(std::vector<ASTUnit *> &ASTs) : ASTs(ASTs) {}
 
-  bool runInvocation(CompilerInvocation *Invocation,
-                     FileManager *Files) {
+  bool runInvocation(CompilerInvocation *Invocation, FileManager *Files,
+                     DiagnosticConsumer *DiagConsumer) {
     // FIXME: This should use the provided FileManager.
     ASTUnit *AST = ASTUnit::LoadFromCompilerInvocation(
-        Invocation,
-        CompilerInstance::createDiagnostics(&Invocation->getDiagnosticOpts()));
+        Invocation, CompilerInstance::createDiagnostics(
+                        &Invocation->getDiagnosticOpts(), DiagConsumer,
+                        /*ShouldOwnClient=*/false));
     if (!AST)
       return false;
 

Modified: cfe/trunk/unittests/Tooling/ToolingTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/ToolingTest.cpp?rev=194226&r1=194225&r2=194226&view=diff
==============================================================================
--- cfe/trunk/unittests/Tooling/ToolingTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/ToolingTest.cpp Thu Nov  7 17:18:05 2013
@@ -302,5 +302,24 @@ TEST(ClangToolTest, BuildASTs) {
 }
 #endif
 
+struct TestDiagnosticConsumer : public DiagnosticConsumer {
+  TestDiagnosticConsumer() : NumDiagnosticsSeen(0) {}
+  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                                const Diagnostic &Info) {
+    ++NumDiagnosticsSeen;
+  }
+  unsigned NumDiagnosticsSeen;
+};
+
+TEST(ClangToolTest, InjectDiagnosticConsumer) {
+  FixedCompilationDatabase Compilations("/", std::vector<std::string>());
+  ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
+  Tool.mapVirtualFile("/a.cc", "int x = undeclared;");
+  TestDiagnosticConsumer Consumer;
+  Tool.setDiagnosticConsumer(&Consumer);
+  Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());
+  EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen);
+}
+
 } // end namespace tooling
 } // end namespace clang





More information about the cfe-commits mailing list