diff options
author | Manuel Klimek <klimek@google.com> | 2013-11-07 23:18:05 +0000 |
---|---|---|
committer | Manuel Klimek <klimek@google.com> | 2013-11-07 23:18:05 +0000 |
commit | 640830142100ea828ba54b42c68ccc4b3dd1d8ea (patch) | |
tree | a032fbc9681efa2972275dac50d36a7cbd62cec3 | |
parent | 594b8c934f79de7c2085a6ca7fb519648a7ff684 (diff) | |
download | bcm5719-llvm-640830142100ea828ba54b42c68ccc4b3dd1d8ea.tar.gz bcm5719-llvm-640830142100ea828ba54b42c68ccc4b3dd1d8ea.zip |
Adds the ability to inject a DiagnosticConsumer into ClangTools.
llvm-svn: 194226
-rw-r--r-- | clang/include/clang/Tooling/Tooling.h | 17 | ||||
-rw-r--r-- | clang/lib/Tooling/Tooling.cpp | 44 | ||||
-rw-r--r-- | clang/unittests/Tooling/ToolingTest.cpp | 19 |
3 files changed, 63 insertions, 17 deletions
diff --git a/clang/include/clang/Tooling/Tooling.h b/clang/include/clang/Tooling/Tooling.h index 74253fffaea..de507a7a8b2 100644 --- a/clang/include/clang/Tooling/Tooling.h +++ b/clang/include/clang/Tooling/Tooling.h @@ -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> diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp index 576989b454c..a58854d1af3 100644 --- a/clang/lib/Tooling/Tooling.cpp +++ b/clang/lib/Tooling/Tooling.cpp @@ -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::runInvocation(CompilerInvocation *Invocation, 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::runInvocation(CompilerInvocation *Invocation, 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 CompilationDatabase &Compilations, } } +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 ToolAction { 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; diff --git a/clang/unittests/Tooling/ToolingTest.cpp b/clang/unittests/Tooling/ToolingTest.cpp index 25df601df82..40360fb45e1 100644 --- a/clang/unittests/Tooling/ToolingTest.cpp +++ b/clang/unittests/Tooling/ToolingTest.cpp @@ -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 |