Make clang-tidy's runCheckOnCode actually use the DiagnosticConsumer.

A precondition of that was to run both the preprocessor checks and AST
checks from the same FrontendAction, otherwise we'd have needed to
duplicate all involved objects in order to not have any references to a
deleted source manager.

llvm-svn: 219212
This commit is contained in:
Manuel Klimek 2014-10-07 15:49:36 +00:00
parent 2b00d54676
commit 0551065cd1
2 changed files with 27 additions and 19 deletions

View File

@ -22,21 +22,23 @@ namespace clang {
namespace tidy {
namespace test {
class TestPPAction : public PreprocessOnlyAction {
class TestClangTidyAction : public ASTFrontendAction {
public:
TestPPAction(ClangTidyCheck &Check, ClangTidyContext *Context)
: Check(Check), Context(Context) {}
TestClangTidyAction(ClangTidyCheck &Check, ast_matchers::MatchFinder &Finder,
ClangTidyContext &Context)
: Check(Check), Finder(Finder), Context(Context) {}
private:
bool BeginSourceFileAction(CompilerInstance &Compiler,
llvm::StringRef file_name) override {
Context->setSourceManager(&Compiler.getSourceManager());
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
StringRef File) override {
Context.setSourceManager(&Compiler.getSourceManager());
Check.registerPPCallbacks(Compiler);
return true;
return Finder.newASTConsumer();
}
ClangTidyCheck &Check;
ClangTidyContext *Context;
ast_matchers::MatchFinder &Finder;
ClangTidyContext &Context;
};
template <typename T>
@ -50,19 +52,25 @@ std::string runCheckOnCode(StringRef Code,
ClangTidyGlobalOptions(), Options));
ClangTidyDiagnosticConsumer DiagConsumer(Context);
T Check("test-check", &Context);
std::vector<std::string> ArgCXX11(1, "-std=c++11");
ArgCXX11.insert(ArgCXX11.end(), ExtraArgs.begin(), ExtraArgs.end());
if (!tooling::runToolOnCodeWithArgs(new TestPPAction(Check, &Context), Code,
ArgCXX11, Filename))
return "";
ast_matchers::MatchFinder Finder;
Check.registerMatchers(&Finder);
std::unique_ptr<tooling::FrontendActionFactory> Factory(
tooling::newFrontendActionFactory(&Finder));
if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, ArgCXX11,
Filename))
std::vector<std::string> ArgCXX11(1, "clang-tidy");
ArgCXX11.push_back("-fsyntax-only");
ArgCXX11.push_back("-std=c++11");
ArgCXX11.insert(ArgCXX11.end(), ExtraArgs.begin(), ExtraArgs.end());
ArgCXX11.push_back(Filename.str());
llvm::IntrusiveRefCntPtr<FileManager> files(
new FileManager(FileSystemOptions()));
tooling::ToolInvocation Invocation(
ArgCXX11, new TestClangTidyAction(Check, Finder, Context), files.get());
SmallString<16> FileNameStorage;
StringRef FileNameRef = Filename.toNullTerminatedStringRef(FileNameStorage);
Invocation.mapVirtualFile(FileNameRef, Code);
Invocation.setDiagnosticConsumer(&DiagConsumer);
if (!Invocation.run())
return "";
DiagConsumer.finish();
tooling::Replacements Fixes;
for (const ClangTidyError &Error : Context.getErrors())

View File

@ -114,7 +114,7 @@ TEST(LLVMHeaderGuardCheckTest, FixHeaderGuards) {
"LLVM_ADT_FOO_H\n#endif \\ \n// "
"LLVM_ADT_FOO_H\n",
"include/llvm/ADT/foo.h",
/*ExpectedWarnings=*/0));
/*ExpectedWarnings=*/1));
EXPECT_EQ("#ifndef LLVM_ADT_FOO_H\n#define LLVM_ADT_FOO_H\n#endif /* "
"LLVM_ADT_FOO_H\\ \n FOO */",