diff options
Diffstat (limited to 'tools/clang-check/ClangCheck.cpp')
| -rw-r--r-- | tools/clang-check/ClangCheck.cpp | 130 | 
1 files changed, 97 insertions, 33 deletions
| diff --git a/tools/clang-check/ClangCheck.cpp b/tools/clang-check/ClangCheck.cpp index 9e58077b5a0e..6c081ac0769e 100644 --- a/tools/clang-check/ClangCheck.cpp +++ b/tools/clang-check/ClangCheck.cpp @@ -1,4 +1,4 @@ -//===- tools/clang-check/ClangCheck.cpp - Clang check tool ----------------===// +//===--- tools/clang-check/ClangCheck.cpp - Clang check tool --------------===//  //  //                     The LLVM Compiler Infrastructure  // @@ -7,8 +7,8 @@  //  //===----------------------------------------------------------------------===//  // -//  This file implements a clang-check tool that runs the -//  clang::SyntaxOnlyAction over a number of translation units. +//  This file implements a clang-check tool that runs clang based on the info +//  stored in a compilation database.  //  //  This tool uses the Clang Tooling infrastructure, see  //    http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html @@ -16,20 +16,24 @@  //  //===----------------------------------------------------------------------===// -#include "llvm/Support/CommandLine.h"  #include "clang/AST/ASTConsumer.h"  #include "clang/Driver/OptTable.h"  #include "clang/Driver/Options.h"  #include "clang/Frontend/ASTConsumers.h" -#include "clang/Frontend/FrontendActions.h" -#include "clang/Tooling/CommandLineClangTool.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Rewrite/Frontend/FixItRewriter.h" +#include "clang/Rewrite/Frontend/FrontendActions.h" +#include "clang/Tooling/CommonOptionsParser.h"  #include "clang/Tooling/Tooling.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Path.h"  using namespace clang::driver;  using namespace clang::tooling;  using namespace llvm; -static const char *MoreHelpText = +static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); +static cl::extrahelp MoreHelp(      "\tFor example, to run clang-check on all files in a subtree of the\n"      "\tsource tree, use:\n"      "\n" @@ -41,26 +45,90 @@ static const char *MoreHelpText =      "\n"      "\tNote, that path/in/subtree and current directory should follow the\n"      "\trules described above.\n" -    "\n"; +    "\n" +); + +static OwningPtr<OptTable> Options(createDriverOptTable()); +static cl::opt<bool> ASTDump( +    "ast-dump", +    cl::desc(Options->getOptionHelpText(options::OPT_ast_dump))); +static cl::opt<bool> ASTList( +    "ast-list", +    cl::desc(Options->getOptionHelpText(options::OPT_ast_list))); +static cl::opt<bool> ASTPrint( +    "ast-print", +    cl::desc(Options->getOptionHelpText(options::OPT_ast_print))); +static cl::opt<std::string> ASTDumpFilter( +    "ast-dump-filter", +    cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter))); + +static cl::opt<bool> Fixit( +    "fixit", +    cl::desc(Options->getOptionHelpText(options::OPT_fixit))); +static cl::opt<bool> FixWhatYouCan( +    "fix-what-you-can", +    cl::desc(Options->getOptionHelpText(options::OPT_fix_what_you_can)));  namespace { -class ActionFactory { + +// FIXME: Move FixItRewriteInPlace from lib/Rewrite/Frontend/FrontendActions.cpp +// into a header file and reuse that. +class FixItOptions : public clang::FixItOptions { +public: +  FixItOptions() { +    FixWhatYouCan = ::FixWhatYouCan; +  } + +  std::string RewriteFilename(const std::string& filename, int &fd) { +    assert(llvm::sys::path::is_absolute(filename) && +           "clang-fixit expects absolute paths only."); + +    // We don't need to do permission checking here since clang will diagnose +    // any I/O errors itself. + +    fd = -1;  // No file descriptor for file. + +    return filename; +  } +}; + +/// \brief Subclasses \c clang::FixItRewriter to not count fixed errors/warnings +/// in the final error counts. +/// +/// This has the side-effect that clang-check -fixit exits with code 0 on +/// successfully fixing all errors. +class FixItRewriter : public clang::FixItRewriter { +public: +  FixItRewriter(clang::DiagnosticsEngine& Diags, +                clang::SourceManager& SourceMgr, +                const clang::LangOptions& LangOpts, +                clang::FixItOptions* FixItOpts) +      : clang::FixItRewriter(Diags, SourceMgr, LangOpts, FixItOpts) { +  } + +  virtual bool IncludeInDiagnosticCounts() const { return false; } +}; + +/// \brief Subclasses \c clang::FixItAction so that we can install the custom +/// \c FixItRewriter. +class FixItAction : public clang::FixItAction {  public: -  ActionFactory() -    : Options(createDriverOptTable()), -      ASTDump( -        "ast-dump", -        cl::desc(Options->getOptionHelpText(options::OPT_ast_dump))), -      ASTList( -        "ast-list", -        cl::desc(Options->getOptionHelpText(options::OPT_ast_list))), -      ASTPrint( -        "ast-print", -        cl::desc(Options->getOptionHelpText(options::OPT_ast_print))), -      ASTDumpFilter( -        "ast-dump-filter", -        cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter))) {} +  virtual bool BeginSourceFileAction(clang::CompilerInstance& CI, +                                     StringRef Filename) { +    FixItOpts.reset(new FixItOptions); +    Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(), +                                     CI.getLangOpts(), FixItOpts.get())); +    return true; +  } +}; + +} // namespace +// Anonymous namespace here causes problems with gcc <= 4.4 on MacOS 10.6. +// "Non-global symbol: ... can't be a weak_definition" +namespace clang_check { +class ClangCheckActionFactory { +public:    clang::ASTConsumer *newASTConsumer() {      if (ASTList)        return clang::CreateASTDeclNodeLister(); @@ -70,19 +138,15 @@ public:        return clang::CreateASTPrinter(&llvm::outs(), ASTDumpFilter);      return new clang::ASTConsumer();    } -private: -  OwningPtr<OptTable> Options; -  cl::opt<bool> ASTDump; -  cl::opt<bool> ASTList; -  cl::opt<bool> ASTPrint; -  cl::opt<std::string> ASTDumpFilter;  };  }  int main(int argc, const char **argv) { -  ActionFactory Factory; -  CommandLineClangTool Tool; -  cl::extrahelp MoreHelp(MoreHelpText); -  Tool.initialize(argc, argv); +  CommonOptionsParser OptionsParser(argc, argv); +  ClangTool Tool(OptionsParser.GetCompilations(), +                 OptionsParser.GetSourcePathList()); +  if (Fixit) +    return Tool.run(newFrontendActionFactory<FixItAction>()); +  clang_check::ClangCheckActionFactory Factory;    return Tool.run(newFrontendActionFactory(&Factory));  } | 
