Add clang-tidy -line-filter option to filter findings by line ranges.
Summary:
This is going to be used for a clang-tidy-diff script to display
warnings in changed lines only. The option uses JSON, as its value is not
intended to be entered manually.
Reviewers: klimek
Reviewed By: klimek
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D3873
llvm-svn: 209450
diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
index a43af88..41b66d6 100644
--- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -32,6 +32,7 @@
"-clang-analyzer-alpha*," // Too many false positives.
"-llvm-include-order," // Not implemented yet.
"-google-*,"; // Doesn't apply to LLVM.
+
static cl::opt<std::string>
Checks("checks", cl::desc("Comma-separated list of globs with optional '-'\n"
"prefix. Globs are processed in order of appearance\n"
@@ -40,13 +41,28 @@
"prefix remove checks with matching names from the\n"
"set of enabled checks."),
cl::init(""), cl::cat(ClangTidyCategory));
+
static cl::opt<std::string>
HeaderFilter("header-filter",
cl::desc("Regular expression matching the names of the\n"
- "headers to output diagnostics from.\n"
- "Diagnostics from the main file of each\n"
- "translation unit are always displayed."),
+ "headers to output diagnostics from. Diagnostics\n"
+ "from the main file of each translation unit are\n"
+ "always displayed.\n"
+ "Can be used together with -line-filter."),
cl::init(""), cl::cat(ClangTidyCategory));
+
+static cl::opt<std::string>
+LineFilter("line-filter",
+ cl::desc("List of files with line ranges to filter the\n"
+ "warnings. Can be used together with\n"
+ "-header-filter. The format of the list is a JSON\n"
+ "array of objects:\n"
+ " [\n"
+ " {\"name\":\"file1.cpp\",\"lines\":[[1,3],[5,7]]},\n"
+ " {\"name\":\"file2.h\"}\n"
+ " ]"),
+ cl::init(""), cl::cat(ClangTidyCategory));
+
static cl::opt<bool> Fix("fix", cl::desc("Fix detected errors if possible."),
cl::init(false), cl::cat(ClangTidyCategory));
@@ -63,16 +79,18 @@
cl::init(false), cl::cat(ClangTidyCategory));
static void printStats(const clang::tidy::ClangTidyStats &Stats) {
- unsigned ErrorsIgnored = Stats.ErrorsIgnoredNOLINT +
- Stats.ErrorsIgnoredCheckFilter +
- Stats.ErrorsIgnoredNonUserCode;
- if (ErrorsIgnored) {
- llvm::errs() << "Suppressed " << ErrorsIgnored << " warnings (";
+ if (Stats.errorsIgnored()) {
+ llvm::errs() << "Suppressed " << Stats.errorsIgnored() << " warnings (";
StringRef Separator = "";
if (Stats.ErrorsIgnoredNonUserCode) {
llvm::errs() << Stats.ErrorsIgnoredNonUserCode << " in non-user code";
Separator = ", ";
}
+ if (Stats.ErrorsIgnoredLineFilter) {
+ llvm::errs() << Separator << Stats.ErrorsIgnoredLineFilter
+ << " due to line filter";
+ Separator = ", ";
+ }
if (Stats.ErrorsIgnoredNOLINT) {
llvm::errs() << Separator << Stats.ErrorsIgnoredNOLINT << " NOLINT";
Separator = ", ";
@@ -94,6 +112,12 @@
Options.Checks = DefaultChecks + Checks;
Options.HeaderFilterRegex = HeaderFilter;
Options.AnalyzeTemporaryDtors = AnalyzeTemporaryDtors;
+ if (llvm::error_code Err =
+ clang::tidy::parseLineFilter(LineFilter, Options)) {
+ llvm::errs() << "Invalid LineFilter: " << Err.message() << "\n\nUsage:\n";
+ llvm::cl::PrintHelpMessage(/*Hidden=*/false, /*Categorized=*/true);
+ return 1;
+ }
// FIXME: Allow using --list-checks without positional arguments.
if (ListChecks) {