PageRenderTime 1444ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/clang-check/ClangCheck.cpp

https://bitbucket.org/codefirex/external_clang
C++ | 152 lines | 105 code | 17 blank | 30 comment | 4 complexity | 59b3add606e76cdf7a03aa41a26b5ba7 MD5 | raw file
  1. //===--- tools/clang-check/ClangCheck.cpp - Clang check tool --------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements a clang-check tool that runs clang based on the info
  11. // stored in a compilation database.
  12. //
  13. // This tool uses the Clang Tooling infrastructure, see
  14. // http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
  15. // for details on setting it up with LLVM source tree.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #include "clang/AST/ASTConsumer.h"
  19. #include "clang/Driver/OptTable.h"
  20. #include "clang/Driver/Options.h"
  21. #include "clang/Frontend/ASTConsumers.h"
  22. #include "clang/Frontend/CompilerInstance.h"
  23. #include "clang/Rewrite/Frontend/FixItRewriter.h"
  24. #include "clang/Rewrite/Frontend/FrontendActions.h"
  25. #include "clang/Tooling/CommonOptionsParser.h"
  26. #include "clang/Tooling/Tooling.h"
  27. #include "llvm/Support/CommandLine.h"
  28. #include "llvm/Support/Path.h"
  29. using namespace clang::driver;
  30. using namespace clang::tooling;
  31. using namespace llvm;
  32. static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
  33. static cl::extrahelp MoreHelp(
  34. "\tFor example, to run clang-check on all files in a subtree of the\n"
  35. "\tsource tree, use:\n"
  36. "\n"
  37. "\t find path/in/subtree -name '*.cpp'|xargs clang-check\n"
  38. "\n"
  39. "\tor using a specific build path:\n"
  40. "\n"
  41. "\t find path/in/subtree -name '*.cpp'|xargs clang-check -p build/path\n"
  42. "\n"
  43. "\tNote, that path/in/subtree and current directory should follow the\n"
  44. "\trules described above.\n"
  45. "\n"
  46. );
  47. static OwningPtr<OptTable> Options(createDriverOptTable());
  48. static cl::opt<bool> ASTDump(
  49. "ast-dump",
  50. cl::desc(Options->getOptionHelpText(options::OPT_ast_dump)));
  51. static cl::opt<bool> ASTList(
  52. "ast-list",
  53. cl::desc(Options->getOptionHelpText(options::OPT_ast_list)));
  54. static cl::opt<bool> ASTPrint(
  55. "ast-print",
  56. cl::desc(Options->getOptionHelpText(options::OPT_ast_print)));
  57. static cl::opt<std::string> ASTDumpFilter(
  58. "ast-dump-filter",
  59. cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter)));
  60. static cl::opt<bool> Fixit(
  61. "fixit",
  62. cl::desc(Options->getOptionHelpText(options::OPT_fixit)));
  63. static cl::opt<bool> FixWhatYouCan(
  64. "fix-what-you-can",
  65. cl::desc(Options->getOptionHelpText(options::OPT_fix_what_you_can)));
  66. namespace {
  67. // FIXME: Move FixItRewriteInPlace from lib/Rewrite/Frontend/FrontendActions.cpp
  68. // into a header file and reuse that.
  69. class FixItOptions : public clang::FixItOptions {
  70. public:
  71. FixItOptions() {
  72. FixWhatYouCan = ::FixWhatYouCan;
  73. }
  74. std::string RewriteFilename(const std::string& filename, int &fd) {
  75. assert(llvm::sys::path::is_absolute(filename) &&
  76. "clang-fixit expects absolute paths only.");
  77. // We don't need to do permission checking here since clang will diagnose
  78. // any I/O errors itself.
  79. fd = -1; // No file descriptor for file.
  80. return filename;
  81. }
  82. };
  83. /// \brief Subclasses \c clang::FixItRewriter to not count fixed errors/warnings
  84. /// in the final error counts.
  85. ///
  86. /// This has the side-effect that clang-check -fixit exits with code 0 on
  87. /// successfully fixing all errors.
  88. class FixItRewriter : public clang::FixItRewriter {
  89. public:
  90. FixItRewriter(clang::DiagnosticsEngine& Diags,
  91. clang::SourceManager& SourceMgr,
  92. const clang::LangOptions& LangOpts,
  93. clang::FixItOptions* FixItOpts)
  94. : clang::FixItRewriter(Diags, SourceMgr, LangOpts, FixItOpts) {
  95. }
  96. virtual bool IncludeInDiagnosticCounts() const { return false; }
  97. };
  98. /// \brief Subclasses \c clang::FixItAction so that we can install the custom
  99. /// \c FixItRewriter.
  100. class FixItAction : public clang::FixItAction {
  101. public:
  102. virtual bool BeginSourceFileAction(clang::CompilerInstance& CI,
  103. StringRef Filename) {
  104. FixItOpts.reset(new FixItOptions);
  105. Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
  106. CI.getLangOpts(), FixItOpts.get()));
  107. return true;
  108. }
  109. };
  110. } // namespace
  111. // Anonymous namespace here causes problems with gcc <= 4.4 on MacOS 10.6.
  112. // "Non-global symbol: ... can't be a weak_definition"
  113. namespace clang_check {
  114. class ClangCheckActionFactory {
  115. public:
  116. clang::ASTConsumer *newASTConsumer() {
  117. if (ASTList)
  118. return clang::CreateASTDeclNodeLister();
  119. if (ASTDump)
  120. return clang::CreateASTDumper(ASTDumpFilter);
  121. if (ASTPrint)
  122. return clang::CreateASTPrinter(&llvm::outs(), ASTDumpFilter);
  123. return new clang::ASTConsumer();
  124. }
  125. };
  126. }
  127. int main(int argc, const char **argv) {
  128. CommonOptionsParser OptionsParser(argc, argv);
  129. ClangTool Tool(OptionsParser.getCompilations(),
  130. OptionsParser.getSourcePathList());
  131. if (Fixit)
  132. return Tool.run(newFrontendActionFactory<FixItAction>());
  133. clang_check::ClangCheckActionFactory Factory;
  134. return Tool.run(newFrontendActionFactory(&Factory));
  135. }