diff options
Diffstat (limited to 'clang-tools-extra/clang-tidy')
4 files changed, 65 insertions, 27 deletions
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp index 8a47cd9f63e..65f801cf65b 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -111,16 +111,49 @@ ClangTidyMessage::ClangTidyMessage(StringRef Message, ClangTidyError::ClangTidyError(StringRef CheckName) : CheckName(CheckName) {} -ChecksFilter::ChecksFilter(const ClangTidyOptions &Options) - : EnableChecks(Options.EnableChecksRegex), - DisableChecks(Options.DisableChecksRegex) {} +// Returns true if GlobList starts with the negative indicator ('-'), removes it +// from the GlobList. +static bool ConsumeNegativeIndicator(StringRef &GlobList) { + if (GlobList.startswith("-")) { + GlobList = GlobList.substr(1); + return true; + } + return false; +} +// Converts first glob from the comma-separated list of globs to Regex and +// removes it and the trailing comma from the GlobList. +static llvm::Regex ConsumeGlob(StringRef &GlobList) { + StringRef Glob = GlobList.substr(0, GlobList.find(',')); + GlobList = GlobList.substr(Glob.size() + 1); + llvm::SmallString<128> RegexText("^"); + StringRef MetaChars("()^$|*+?.[]\\{}"); + for (char C : Glob) { + if (C == '*') + RegexText.push_back('.'); + else if (MetaChars.find(C)) + RegexText.push_back('\\'); + RegexText.push_back(C); + } + RegexText.push_back('$'); + return llvm::Regex(RegexText); +} + +ChecksFilter::ChecksFilter(StringRef GlobList) + : Positive(!ConsumeNegativeIndicator(GlobList)), + Regex(ConsumeGlob(GlobList)), + NextFilter(GlobList.empty() ? nullptr : new ChecksFilter(GlobList)) {} + +bool ChecksFilter::isCheckEnabled(StringRef Name, bool Enabled) { + if (Regex.match(Name)) + Enabled = Positive; -bool ChecksFilter::isCheckEnabled(StringRef Name) { - return EnableChecks.match(Name) && !DisableChecks.match(Name); + if (NextFilter) + Enabled = NextFilter->isCheckEnabled(Name, Enabled); + return Enabled; } ClangTidyContext::ClangTidyContext(const ClangTidyOptions &Options) - : DiagEngine(nullptr), Options(Options), Filter(Options) {} + : DiagEngine(nullptr), Options(Options), Filter(Options.Checks) {} DiagnosticBuilder ClangTidyContext::diag( StringRef CheckName, SourceLocation Loc, StringRef Description, diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h index 425075df552..90e0610ba85 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h @@ -60,12 +60,20 @@ struct ClangTidyError { /// \brief Filters checks by name. class ChecksFilter { public: - ChecksFilter(const ClangTidyOptions& Options); - bool isCheckEnabled(StringRef Name); + // GlobList is a comma-separated list of globs (only '*' metacharacter is + // supported) with optional '-' prefix to denote exclusion. + ChecksFilter(StringRef GlobList); + // Returns true if the check with the specified Name should be enabled. + // The result is the last matching glob's Positive flag. If Name is not + // matched by any globs, the check is not enabled. + bool isCheckEnabled(StringRef Name) { return isCheckEnabled(Name, false); } private: - llvm::Regex EnableChecks; - llvm::Regex DisableChecks; + bool isCheckEnabled(StringRef Name, bool Enabled); + + bool Positive; + llvm::Regex Regex; + std::unique_ptr<ChecksFilter> NextFilter; }; struct ClangTidyStats { diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.h b/clang-tools-extra/clang-tidy/ClangTidyOptions.h index f3e5fd22df9..b7397fabe0c 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.h +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.h @@ -17,9 +17,8 @@ namespace tidy { /// \brief Contains options for clang-tidy. struct ClangTidyOptions { - ClangTidyOptions() : EnableChecksRegex(".*"), AnalyzeTemporaryDtors(false) {} - std::string EnableChecksRegex; - std::string DisableChecksRegex; + ClangTidyOptions() : Checks("*"), AnalyzeTemporaryDtors(false) {} + std::string Checks; // Output warnings from headers matching this filter. Warnings from main files // will always be displayed. std::string HeaderFilterRegex; diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp index 5c136bc3a52..4e815c0d174 100644 --- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -27,18 +27,17 @@ static cl::OptionCategory ClangTidyCategory("clang-tidy options"); static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); -static cl::opt<std::string> Checks( - "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.*" // Too many false positives. - "|llvm-include-order" // Not implemented yet. - "|llvm-namespace-comment" // Not complete. - "|google-.*)"), // Doesn't apply to LLVM. - cl::cat(ClangTidyCategory)); +const char DefaultChecks[] = + "*," // Enable all checks, except these: + "-clang-analyzer-alpha*," // Too many false positives. + "-llvm-include-order," // Not implemented yet. + "-llvm-namespace-comment," // Not complete. + "-google-*,"; // Doesn't apply to LLVM. +static cl::opt<std::string> +Checks("checks", + cl::desc("Comma-separated list of positive and negative globs matching\n" + "the names of the checks to be run."), + cl::init(""), cl::cat(ClangTidyCategory)); static cl::opt<std::string> HeaderFilter( "header-filter", cl::desc("Regular expression matching the names of the headers to output\n" @@ -88,8 +87,7 @@ int main(int argc, const char **argv) { CommonOptionsParser OptionsParser(argc, argv, ClangTidyCategory); clang::tidy::ClangTidyOptions Options; - Options.EnableChecksRegex = Checks; - Options.DisableChecksRegex = DisableChecks; + Options.Checks = DefaultChecks + Checks; Options.HeaderFilterRegex = HeaderFilter; Options.AnalyzeTemporaryDtors = AnalyzeTemporaryDtors; |