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

Reply via email to