Added a FIXME regarding the type of location used for filtering. PTAL.
http://reviews.llvm.org/D3590
Files:
clang-tidy/ClangTidyDiagnosticConsumer.cpp
clang-tidy/ClangTidyDiagnosticConsumer.h
clang-tidy/ClangTidyOptions.h
clang-tidy/tool/ClangTidyMain.cpp
test/clang-tidy/Inputs/
test/clang-tidy/Inputs/file-filter/
test/clang-tidy/Inputs/file-filter/header1.h
test/clang-tidy/Inputs/file-filter/header2.h
test/clang-tidy/file-filter.cpp
Index: clang-tidy/ClangTidyDiagnosticConsumer.cpp
===================================================================
--- clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -124,7 +124,7 @@
ClangTidyContext::ClangTidyContext(SmallVectorImpl<ClangTidyError> *Errors,
const ClangTidyOptions &Options)
- : Errors(Errors), DiagEngine(nullptr), Filter(Options) {}
+ : Errors(Errors), DiagEngine(nullptr), Options(Options), Filter(Options) {}
DiagnosticBuilder ClangTidyContext::diag(
StringRef CheckName, SourceLocation Loc, StringRef Description,
@@ -171,7 +171,8 @@
}
ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx)
- : Context(Ctx), LastErrorRelatesToUserCode(false) {
+ : Context(Ctx), HeaderFilter(Ctx.getOptions().HeaderFilterRegex),
+ LastErrorRelatesToUserCode(false) {
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
Diags.reset(new DiagnosticsEngine(
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts, this,
@@ -217,12 +218,30 @@
Sources);
// Let argument parsing-related warnings through.
- if (!Info.getLocation().isValid() ||
- !Diags->getSourceManager().isInSystemHeader(Info.getLocation())) {
+ if (relatesToUserCode(Info.getLocation())) {
LastErrorRelatesToUserCode = true;
}
}
+bool ClangTidyDiagnosticConsumer::relatesToUserCode(SourceLocation Location) {
+ // Invalid location may mean a diagnostic in a command line, don't skip these.
+ if (!Location.isValid())
+ return true;
+
+ const SourceManager &Sources = Diags->getSourceManager();
+ if (Sources.isInSystemHeader(Location))
+ return false;
+
+ // FIXME: We start with a conservative approach here, but the actual type of
+ // location needed depends on the check (in particular, where this check wants
+ // to apply fixes).
+ FileID FID = Sources.getDecomposedExpansionLoc(Location).first;
+ if (FID == Sources.getMainFileID())
+ return true;
+
+ return HeaderFilter.match(Sources.getFileEntryForID(FID)->getName());
+}
+
struct LessClangTidyError {
bool operator()(const ClangTidyError *LHS, const ClangTidyError *RHS) const {
const ClangTidyMessage &M1 = LHS->Message;
Index: clang-tidy/ClangTidyDiagnosticConsumer.h
===================================================================
--- clang-tidy/ClangTidyDiagnosticConsumer.h
+++ clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -10,6 +10,7 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H
+#include "ClangTidyOptions.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Tooling/Refactoring.h"
@@ -28,8 +29,6 @@
namespace tidy {
-struct ClangTidyOptions;
-
/// \brief A message from a clang-tidy check.
///
/// Note that this is independent of a \c SourceManager.
@@ -108,6 +107,7 @@
StringRef getCheckName(unsigned DiagnosticID) const;
ChecksFilter &getChecksFilter() { return Filter; }
+ const ClangTidyOptions &getOptions() const { return Options; }
private:
friend class ClangTidyDiagnosticConsumer; // Calls storeError().
@@ -117,6 +117,7 @@
SmallVectorImpl<ClangTidyError> *Errors;
DiagnosticsEngine *DiagEngine;
+ ClangTidyOptions Options;
ChecksFilter Filter;
llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
@@ -142,8 +143,10 @@
private:
void finalizeLastError();
+ bool relatesToUserCode(SourceLocation Location);
ClangTidyContext &Context;
+ llvm::Regex HeaderFilter;
std::unique_ptr<DiagnosticsEngine> Diags;
SmallVector<ClangTidyError, 8> Errors;
bool LastErrorRelatesToUserCode;
Index: clang-tidy/ClangTidyOptions.h
===================================================================
--- clang-tidy/ClangTidyOptions.h
+++ clang-tidy/ClangTidyOptions.h
@@ -10,14 +10,19 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_OPTIONS_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_OPTIONS_H
+#include <string>
+
namespace clang {
namespace tidy {
/// \brief Contains options for clang-tidy.
struct ClangTidyOptions {
ClangTidyOptions() : EnableChecksRegex(".*"), AnalyzeTemporaryDtors(false) {}
std::string EnableChecksRegex;
std::string DisableChecksRegex;
+ // Output warnings from headers matching this filter. Warnings from main files
+ // will always be displayed.
+ std::string HeaderFilterRegex;
bool AnalyzeTemporaryDtors;
};
Index: clang-tidy/tool/ClangTidyMain.cpp
===================================================================
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -39,6 +39,12 @@
"|llvm-namespace-comment" // Not complete.
"|google-.*)"), // Doesn't apply to LLVM.
cl::cat(ClangTidyCategory));
+static cl::opt<std::string> HeaderFilter(
+ "header-filter",
+ cl::desc("Regular expression matching the names of the headers to output\n"
+ "diagnostics from. Diagnostics from the main file of each\n"
+ "translation unit are always displayed."),
+ cl::init(""), cl::cat(ClangTidyCategory));
static cl::opt<bool> Fix("fix", cl::desc("Fix detected errors if possible."),
cl::init(false), cl::cat(ClangTidyCategory));
@@ -59,6 +65,7 @@
clang::tidy::ClangTidyOptions Options;
Options.EnableChecksRegex = Checks;
Options.DisableChecksRegex = DisableChecks;
+ Options.HeaderFilterRegex = HeaderFilter;
Options.AnalyzeTemporaryDtors = AnalyzeTemporaryDtors;
// FIXME: Allow using --list-checks without positional arguments.
Index: test/clang-tidy/Inputs/file-filter/header1.h
===================================================================
--- /dev/null
+++ test/clang-tidy/Inputs/file-filter/header1.h
@@ -0,0 +1 @@
+class A1 { A1(int); };
@@ -0,0 +1 @@
+class A1 { A1(int); };
@@ -0,0 +1 @@
+class A1 { A1(int); };
Index: test/clang-tidy/Inputs/file-filter/header2.h
===================================================================
--- /dev/null
+++ test/clang-tidy/Inputs/file-filter/header2.h
@@ -0,0 +1 @@
+class A2 { A2(int); };
@@ -0,0 +1 @@
+class A2 { A2(int); };
@@ -0,0 +1 @@
+class A2 { A2(int); };
Index: test/clang-tidy/file-filter.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/file-filter.cpp
@@ -0,0 +1,22 @@
+// RUN: clang-tidy -checks=google-explicit-constructor -disable-checks='' -header-filter='' %s -- -I %S/Inputs/file-filter | FileCheck %s
+// RUN: clang-tidy -checks=google-explicit-constructor -disable-checks='' -header-filter='.*' %s -- -I %S/Inputs/file-filter | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-tidy -checks=google-explicit-constructor -disable-checks='' -header-filter='header2\.h' %s -- -I %S/Inputs/file-filter | FileCheck --check-prefix=CHECK3 %s
+
+#include "header1.h"
+// CHECK-NOT: warning:
+// CHECK2: header1.h:1:12: warning: Single-argument constructors must be explicit [google-explicit-constructor]
+// CHECK3-NOT: warning:
+
+#include "header2.h"
+// CHECK-NOT: warning:
+// CHECK2: header2.h:1:12: warning: Single-argument constructors {{.*}}
+// CHECK3: header2.h:1:12: warning: Single-argument constructors {{.*}}
+
+class A { A(int); };
+// CHECK: :[[@LINE-1]]:11: warning: Single-argument constructors {{.*}}
+// CHECK2: :[[@LINE-2]]:11: warning: Single-argument constructors {{.*}}
+// CHECK3: :[[@LINE-3]]:11: warning: Single-argument constructors {{.*}}
+
+// CHECK-NOT: warning:
+// CHECK2-NOT: warning:
+// CHECK3-NOT: warning:
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits