Clang-tidy: added --disable-checks, --list-checks options.

Summary:
Allow disabling checks by regex. By default, disable alpha.* checks,
that are not particularly good tested (e.g. IdempotentOperationChecker, see
http://llvm-reviews.chandlerc.com/D2427).

Fixed a bug, that would disable all analyzer checks, when using a regex more
strict, than 'clang-analyzer-', for example --checks='clang-analyzer-deadcode-'.

Added --list-checks to list all enabled checks. This is useful to test specific
values in --checks/--disable-checks.

Reviewers: djasper, klimek

Reviewed By: klimek

CC: cfe-commits, klimek

Differential Revision: http://llvm-reviews.chandlerc.com/D2444

llvm-svn: 197717
diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
index a71df0c..5f1c137 100644
--- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -17,7 +17,6 @@
 
 #include "../ClangTidy.h"
 #include "clang/Tooling/CommonOptionsParser.h"
-#include <vector>
 
 using namespace clang::ast_matchers;
 using namespace clang::driver;
@@ -32,16 +31,34 @@
     "checks",
     cl::desc("Regular expression matching the names of the checks to be run."),
     cl::init(".*"), cl::cat(ClangTidyCategory));
+static cl::opt<std::string> DisableChecks(
+    "disable-checks",
+    cl::desc("Regular expression matching the names of the checks to disable."),
+    cl::init("clang-analyzer-alpha.*"), cl::cat(ClangTidyCategory));
 static cl::opt<bool> Fix("fix", cl::desc("Fix detected errors if possible."),
                          cl::init(false), cl::cat(ClangTidyCategory));
 
-// FIXME: Add option to list name/description of all checks.
+static cl::opt<bool> ListChecks("list-checks",
+                                cl::desc("List all enabled checks and exit."),
+                                cl::init(false), cl::cat(ClangTidyCategory));
 
 int main(int argc, const char **argv) {
   CommonOptionsParser OptionsParser(argc, argv, ClangTidyCategory);
 
+  // FIXME: Allow using --list-checks without positional arguments.
+  if (ListChecks) {
+    std::vector<std::string> CheckNames =
+        clang::tidy::getCheckNames(Checks, DisableChecks);
+    llvm::outs() << "Enabled checks:";
+    for (unsigned i = 0; i < CheckNames.size(); ++i)
+      llvm::outs() << "\n    " << CheckNames[i];
+    llvm::outs() << "\n\n";
+    return 0;
+  }
+
   SmallVector<clang::tidy::ClangTidyError, 16> Errors;
-  clang::tidy::runClangTidy(Checks, OptionsParser.getCompilations(),
+  clang::tidy::runClangTidy(Checks, DisableChecks,
+                            OptionsParser.getCompilations(),
                             OptionsParser.getSourcePathList(), &Errors);
   clang::tidy::handleErrors(Errors, Fix);