[clang-tools-extra] r204321 - Post-filter clang-tidy diagnostic messages.
Alexander Kornienko
alexfh at google.com
Thu Mar 20 02:38:22 PDT 2014
Author: alexfh
Date: Thu Mar 20 04:38:22 2014
New Revision: 204321
URL: http://llvm.org/viewvc/llvm-project?rev=204321&view=rev
Log:
Post-filter clang-tidy diagnostic messages.
Summary:
This patch implements filtering of clang-tidy diagnostic messages by
the check name, so that "clang-tidy -checks=^llvm-" won't output any clang
warnings, for example. This is also helpful to run specific static-analyzer
checks: static analyzer always needs core checks to be enabled, but the user may
be interested only in the checks he asked for.
This patch also exposes warning option names for built-in diagnostics. We need
to have a namespace for these names to avoid collisions and to allow convenient
filtering, so I prefix them with "-W". I'm not sure it's the best thing to do,
and maybe "W" or "clang-diagnostic-" or something like this would be better.
Reviewers: klimek
Reviewed By: klimek
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D3121
Modified:
clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp
clang-tools-extra/trunk/clang-tidy/ClangTidy.h
clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h
clang-tools-extra/trunk/clang-tidy/ClangTidyModule.cpp
clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp
clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp?rev=204321&r1=204320&r2=204321&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp Thu Mar 20 04:38:22 2014
@@ -93,10 +93,8 @@ private:
} // namespace
ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory(
- StringRef EnableChecksRegex, StringRef DisableChecksRegex,
ClangTidyContext &Context)
- : Filter(EnableChecksRegex, DisableChecksRegex), Context(Context),
- CheckFactories(new ClangTidyCheckFactories) {
+ : Context(Context), CheckFactories(new ClangTidyCheckFactories) {
for (ClangTidyModuleRegistry::iterator I = ClangTidyModuleRegistry::begin(),
E = ClangTidyModuleRegistry::end();
I != E; ++I) {
@@ -104,7 +102,7 @@ ClangTidyASTConsumerFactory::ClangTidyAS
Module->addCheckFactories(*CheckFactories);
}
- CheckFactories->createChecks(Filter, Checks);
+ CheckFactories->createChecks(Context.getChecksFilter(), Checks);
for (ClangTidyCheck *Check : Checks) {
Check->setContext(&Context);
@@ -149,7 +147,7 @@ clang::ASTConsumer *ClangTidyASTConsumer
std::vector<std::string> ClangTidyASTConsumerFactory::getCheckNames() {
std::vector<std::string> CheckNames;
for (const auto &CheckFactory : *CheckFactories) {
- if (Filter.IsCheckEnabled(CheckFactory.first))
+ if (Context.getChecksFilter().isCheckEnabled(CheckFactory.first))
CheckNames.push_back(CheckFactory.first);
}
@@ -168,7 +166,8 @@ ClangTidyASTConsumerFactory::getCheckers
for (StringRef CheckName : StaticAnalyzerChecks) {
std::string Checker((AnalyzerCheckNamePrefix + CheckName).str());
AnalyzerChecksEnabled |=
- Filter.IsCheckEnabled(Checker) && !CheckName.startswith("debug");
+ Context.getChecksFilter().isCheckEnabled(Checker) &&
+ !CheckName.startswith("debug");
}
if (AnalyzerChecksEnabled) {
@@ -183,21 +182,14 @@ ClangTidyASTConsumerFactory::getCheckers
std::string Checker((AnalyzerCheckNamePrefix + CheckName).str());
if (CheckName.startswith("core") ||
- (!CheckName.startswith("debug") && Filter.IsCheckEnabled(Checker)))
+ (!CheckName.startswith("debug") &&
+ Context.getChecksFilter().isCheckEnabled(Checker)))
List.push_back(std::make_pair(CheckName, true));
}
}
return List;
}
-ChecksFilter::ChecksFilter(StringRef EnableChecksRegex,
- StringRef DisableChecksRegex)
- : EnableChecks(EnableChecksRegex), DisableChecks(DisableChecksRegex) {}
-
-bool ChecksFilter::IsCheckEnabled(StringRef Name) {
- return EnableChecks.match(Name) && !DisableChecks.match(Name);
-}
-
DiagnosticBuilder ClangTidyCheck::diag(SourceLocation Loc, StringRef Message,
DiagnosticIDs::Level Level) {
return Context->diag(CheckName, Loc, Message, Level);
@@ -216,9 +208,9 @@ void ClangTidyCheck::setName(StringRef N
std::vector<std::string> getCheckNames(StringRef EnableChecksRegex,
StringRef DisableChecksRegex) {
SmallVector<ClangTidyError, 8> Errors;
- clang::tidy::ClangTidyContext Context(&Errors);
- ClangTidyASTConsumerFactory Factory(EnableChecksRegex, DisableChecksRegex,
- Context);
+ clang::tidy::ClangTidyContext Context(&Errors, EnableChecksRegex,
+ DisableChecksRegex);
+ ClangTidyASTConsumerFactory Factory(Context);
return Factory.getCheckNames();
}
@@ -229,7 +221,8 @@ void runClangTidy(StringRef EnableChecks
// FIXME: Ranges are currently full files. Support selecting specific
// (line-)ranges.
ClangTool Tool(Compilations, Ranges);
- clang::tidy::ClangTidyContext Context(Errors);
+ clang::tidy::ClangTidyContext Context(Errors, EnableChecksRegex,
+ DisableChecksRegex);
ClangTidyDiagnosticConsumer DiagConsumer(Context);
Tool.setDiagnosticConsumer(&DiagConsumer);
@@ -256,8 +249,7 @@ void runClangTidy(StringRef EnableChecks
ClangTidyASTConsumerFactory *ConsumerFactory;
};
- Tool.run(new ActionFactory(new ClangTidyASTConsumerFactory(
- EnableChecksRegex, DisableChecksRegex, Context)));
+ Tool.run(new ActionFactory(new ClangTidyASTConsumerFactory(Context)));
}
static SourceLocation getLocation(SourceManager &SourceMgr, StringRef FilePath,
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidy.h?rev=204321&r1=204320&r2=204321&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidy.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidy.h Thu Mar 20 04:38:22 2014
@@ -89,24 +89,11 @@ private:
std::string CheckName;
};
-/// \brief Filters checks by name.
-class ChecksFilter {
-public:
- ChecksFilter(StringRef EnableChecksRegex, StringRef DisableChecksRegex);
- bool IsCheckEnabled(StringRef Name);
-
-private:
- llvm::Regex EnableChecks;
- llvm::Regex DisableChecks;
-};
-
class ClangTidyCheckFactories;
class ClangTidyASTConsumerFactory {
public:
- ClangTidyASTConsumerFactory(StringRef EnableChecksRegex,
- StringRef DisableChecksRegex,
- ClangTidyContext &Context);
+ ClangTidyASTConsumerFactory(ClangTidyContext &Context);
~ClangTidyASTConsumerFactory();
/// \brief Returns an ASTConsumer that runs the specified clang-tidy checks.
@@ -120,7 +107,6 @@ private:
typedef std::vector<std::pair<std::string, bool> > CheckersList;
CheckersList getCheckersControlList();
- ChecksFilter Filter;
SmallVector<ClangTidyCheck *, 8> Checks;
ClangTidyContext &Context;
ast_matchers::MatchFinder Finder;
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp?rev=204321&r1=204320&r2=204321&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp Thu Mar 20 04:38:22 2014
@@ -113,6 +113,19 @@ ClangTidyMessage::ClangTidyMessage(Strin
ClangTidyError::ClangTidyError(StringRef CheckName)
: CheckName(CheckName) {}
+ChecksFilter::ChecksFilter(StringRef EnableChecksRegex,
+ StringRef DisableChecksRegex)
+ : EnableChecks(EnableChecksRegex), DisableChecks(DisableChecksRegex) {}
+
+bool ChecksFilter::isCheckEnabled(StringRef Name) {
+ return EnableChecks.match(Name) && !DisableChecks.match(Name);
+}
+
+ClangTidyContext::ClangTidyContext(SmallVectorImpl<ClangTidyError> *Errors,
+ StringRef EnableChecksRegex,
+ StringRef DisableChecksRegex)
+ : Errors(Errors), Filter(EnableChecksRegex, DisableChecksRegex) {}
+
DiagnosticBuilder ClangTidyContext::diag(
StringRef CheckName, SourceLocation Loc, StringRef Description,
DiagnosticIDs::Level Level /* = DiagnosticIDs::Warning*/) {
@@ -179,7 +192,14 @@ void ClangTidyDiagnosticConsumer::Handle
"A diagnostic note can only be appended to a message.");
} else {
finalizeLastError();
- Errors.push_back(ClangTidyError(Context.getCheckName(Info.getID())));
+ StringRef WarningOption =
+ Context.DiagEngine->getDiagnosticIDs()->getWarningOptionForDiag(
+ Info.getID());
+ std::string CheckName = !WarningOption.empty()
+ ? ("clang-diagnostic-" + WarningOption).str()
+ : Context.getCheckName(Info.getID()).str();
+
+ Errors.push_back(ClangTidyError(CheckName));
}
// FIXME: Provide correct LangOptions for each file.
@@ -218,7 +238,8 @@ void ClangTidyDiagnosticConsumer::finish
finalizeLastError();
std::set<const ClangTidyError*, LessClangTidyError> UniqueErrors;
for (const ClangTidyError &Error : Errors) {
- if (UniqueErrors.insert(&Error).second)
+ if (Context.getChecksFilter().isCheckEnabled(Error.CheckName) &&
+ UniqueErrors.insert(&Error).second)
Context.storeError(Error);
}
Errors.clear();
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h?rev=204321&r1=204320&r2=204321&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h Thu Mar 20 04:38:22 2014
@@ -14,6 +14,7 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Tooling/Refactoring.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Regex.h"
namespace clang {
@@ -55,6 +56,17 @@ struct ClangTidyError {
SmallVector<ClangTidyMessage, 1> Notes;
};
+/// \brief Filters checks by name.
+class ChecksFilter {
+public:
+ ChecksFilter(StringRef EnableChecksRegex, StringRef DisableChecksRegex);
+ bool isCheckEnabled(StringRef Name);
+
+private:
+ llvm::Regex EnableChecks;
+ llvm::Regex DisableChecks;
+};
+
/// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticEngine
/// provided by this context.
///
@@ -66,8 +78,8 @@ struct ClangTidyError {
/// \endcode
class ClangTidyContext {
public:
- ClangTidyContext(SmallVectorImpl<ClangTidyError> *Errors)
- : Errors(Errors), DiagEngine(0) {}
+ ClangTidyContext(SmallVectorImpl<ClangTidyError> *Errors,
+ StringRef EnableChecksRegex, StringRef DisableChecksRegex);
/// \brief Report any errors detected using this method.
///
@@ -93,6 +105,8 @@ public:
/// diagnostic ID.
StringRef getCheckName(unsigned DiagnosticID) const;
+ ChecksFilter &getChecksFilter() { return Filter; }
+
private:
friend class ClangTidyDiagnosticConsumer; // Calls storeError().
@@ -100,7 +114,9 @@ private:
void storeError(const ClangTidyError &Error);
SmallVectorImpl<ClangTidyError> *Errors;
- DiagnosticsEngine *DiagEngine;
+ DiagnosticsEngine *DiagEngine{nullptr};
+ ChecksFilter Filter;
+
llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
};
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyModule.cpp?rev=204321&r1=204320&r2=204321&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyModule.cpp Thu Mar 20 04:38:22 2014
@@ -29,7 +29,7 @@ void ClangTidyCheckFactories::addCheckFa
void ClangTidyCheckFactories::createChecks(
ChecksFilter &Filter, SmallVectorImpl<ClangTidyCheck *> &Checks) {
for (const auto &Factory : Factories) {
- if (Filter.IsCheckEnabled(Factory.first)) {
+ if (Filter.isCheckEnabled(Factory.first)) {
ClangTidyCheck *Check = Factory.second->createCheck();
Check->setName(Factory.first);
Checks.push_back(Check);
Modified: clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp?rev=204321&r1=204320&r2=204321&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp Thu Mar 20 04:38:22 2014
@@ -1,5 +1,21 @@
-// RUN: clang-tidy %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK1 %s
-// RUN: clang-tidy %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK2 %s
+// RUN: clang-tidy %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK1 %s
+// RUN: clang-tidy %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK2 %s
+// RUN: clang-tidy -checks='^(google-|clang-diagnostic-literal-conversion)' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK3 %s
-// CHECK1: warning: unknown argument: '-fan-unknown-option'
-// CHECK2: warning: error reading '{{.*}}.nonexistent.cpp'
+// CHECK1-NOT: warning
+// CHECK2-NOT: warning
+// CHECK3-NOT: warning
+
+// CHECK1: warning: error reading '{{.*}}.nonexistent.cpp'
+// CHECK2: warning: unknown argument: '-fan-unknown-option'
+
+// CHECK2: :[[@LINE+2]]:9: warning: implicit conversion from 'double' to 'int' changes value
+// CHECK3: :[[@LINE+1]]:9: warning: implicit conversion from 'double' to 'int' changes value
+int a = 1.5;
+
+// CHECK2: :[[@LINE+2]]:11: warning: Single-argument constructors must be explicit [google-explicit-constructor]
+// CHECK3: :[[@LINE+1]]:11: warning: Single-argument constructors must be explicit [google-explicit-constructor]
+class A { A(int) {} };
+
+// CHECK2-NOT: warning:
+// CHECK3-NOT: warning:
Modified: clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h?rev=204321&r1=204320&r2=204321&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h (original)
+++ clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h Thu Mar 20 04:38:22 2014
@@ -42,7 +42,7 @@ private:
template <typename T> std::string runCheckOnCode(StringRef Code) {
T Check;
SmallVector<ClangTidyError, 16> Errors;
- ClangTidyContext Context(&Errors);
+ ClangTidyContext Context(&Errors, ".*", "");
ClangTidyDiagnosticConsumer DiagConsumer(Context);
Check.setContext(&Context);
More information about the cfe-commits
mailing list