[llvm] r329581 - [llvm-cov] Implement -ignore-filename-regex= option for excluding source files.

Max Moroz via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 9 08:20:36 PDT 2018


Author: dor1s
Date: Mon Apr  9 08:20:35 2018
New Revision: 329581

URL: http://llvm.org/viewvc/llvm-project?rev=329581&view=rev
Log:
[llvm-cov] Implement -ignore-filename-regex= option for excluding source files.

Summary:
The option is helpful for large projects where it's not feasible to specify sources which
user would like to see in the report. Instead, it allows to black-list specific sources via
regular expressions (e.g. now it's possible to skip all files that have "test" in its name).

This also partially fixes https://bugs.llvm.org/show_bug.cgi?id=34277

Reviewers: vsk, morehouse, liaoyuke

Reviewed By: vsk

Subscribers: kcc, mgorny, llvm-commits

Differential Revision: https://reviews.llvm.org/D43907

Added:
    llvm/trunk/test/tools/llvm-cov/ignore-filename-regex.test
Modified:
    llvm/trunk/docs/CommandGuide/llvm-cov.rst
    llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
    llvm/trunk/tools/llvm-cov/CoverageExporter.h
    llvm/trunk/tools/llvm-cov/CoverageExporterJson.cpp
    llvm/trunk/tools/llvm-cov/CoverageExporterJson.h
    llvm/trunk/tools/llvm-cov/CoverageFilters.cpp
    llvm/trunk/tools/llvm-cov/CoverageFilters.h
    llvm/trunk/tools/llvm-cov/CoverageReport.cpp
    llvm/trunk/tools/llvm-cov/CoverageReport.h

Modified: llvm/trunk/docs/CommandGuide/llvm-cov.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/llvm-cov.rst?rev=329581&r1=329580&r2=329581&view=diff
==============================================================================
--- llvm/trunk/docs/CommandGuide/llvm-cov.rst (original)
+++ llvm/trunk/docs/CommandGuide/llvm-cov.rst Mon Apr  9 08:20:35 2018
@@ -246,6 +246,10 @@ OPTIONS
 
  Show code coverage only for functions that match the given regular expression.
 
+.. option:: -ignore-filename-regex=<PATTERN>
+
+ Skip source code files with file paths that match the given regular expression.
+
 .. option:: -format=<FORMAT>
 
  Use the specified output format. The supported formats are: "text", "html".
@@ -351,6 +355,10 @@ OPTIONS
 
  Show statistics for all function instantiations. Defaults to false.
 
+.. option:: -ignore-filename-regex=<PATTERN>
+
+ Skip source code files with file paths that match the given regular expression.
+
 .. program:: llvm-cov export
 
 .. _llvm-cov-export:
@@ -390,3 +398,7 @@ OPTIONS
  will not export coverage information for smaller units such as individual
  functions or regions. The result will be the same as produced by :program:
  `llvm-cov report` command, but presented in JSON format rather than text.
+
+.. option:: -ignore-filename-regex=<PATTERN>
+
+ Skip source code files with file paths that match the given regular expression.

Added: llvm/trunk/test/tools/llvm-cov/ignore-filename-regex.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/ignore-filename-regex.test?rev=329581&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/ignore-filename-regex.test (added)
+++ llvm/trunk/test/tools/llvm-cov/ignore-filename-regex.test Mon Apr  9 08:20:35 2018
@@ -0,0 +1,71 @@
+########################
+# Test "report" command.
+########################
+# Ignore all header files.
+RUN: llvm-cov report -instr-profile %S/Inputs/sources_specified/main.profdata \
+RUN:   -path-equivalence=/tmp,%S/Inputs -ignore-filename-regex='.*\.h$' \
+RUN:   %S/Inputs/sources_specified/main.covmapping \
+RUN:   | FileCheck -check-prefix=REPORT_IGNORE_HEADERS %s
+
+REPORT_IGNORE_HEADERS-NOT: {{.*}}dec.h{{.*}}
+REPORT_IGNORE_HEADERS-NOT: {{.*}}inc.h{{.*}}
+REPORT_IGNORE_HEADERS-NOT: {{.*}}abs.h{{.*}}
+REPORT_IGNORE_HEADERS: {{^}}TOTAL 1{{.*}}100.00%{{$}}
+
+# Ignore all files from "extra" directory.
+RUN: llvm-cov report -instr-profile %S/Inputs/sources_specified/main.profdata \
+RUN:   -path-equivalence=/tmp,%S/Inputs -ignore-filename-regex='.*extra[/\\].*' \
+RUN:   %S/Inputs/sources_specified/main.covmapping \
+RUN:   | FileCheck -check-prefix=REPORT_IGNORE_DIR %s
+
+REPORT_IGNORE_DIR-NOT: {{.*}}extra{{[/\\]}}dec.h{{.*}}
+REPORT_IGNORE_DIR-NOT: {{.*}}extra{{[/\\]}}inc.h{{.*}}
+REPORT_IGNORE_DIR: {{.*}}abs.h{{.*}}
+REPORT_IGNORE_DIR: {{.*}}main.cc{{.*}}
+REPORT_IGNORE_DIR: {{^}}TOTAL 5{{.*}}100.00%{{$}}
+
+# Ignore all files from "extra" directory even when SOURCES specified.
+RUN: llvm-cov report -instr-profile %S/Inputs/sources_specified/main.profdata \
+RUN:   -path-equivalence=/tmp,%S/Inputs -ignore-filename-regex='.*extra[/\\].*' \
+RUN:   %S/Inputs/sources_specified/main.covmapping \
+RUN:   %S/Inputs/sources_specified/extra %S/Inputs/sources_specified/abs.h \
+RUN:   | FileCheck -check-prefix=REPORT_IGNORE_DIR_WITH_SOURCES %s
+
+REPORT_IGNORE_DIR_WITH_SOURCES-NOT: {{.*}}extra{{[/\\]}}dec.h{{.*}}
+REPORT_IGNORE_DIR_WITH_SOURCES-NOT: {{.*}}extra{{[/\\]}}inc.h{{.*}}
+REPORT_IGNORE_DIR_WITH_SOURCES-NOT: {{.*}}main.cc{{.*}}
+REPORT_IGNORE_DIR_WITH_SOURCES: {{.*}}abs.h{{.*}}
+REPORT_IGNORE_DIR_WITH_SOURCES: {{^}}TOTAL 4{{.*}}100.00%{{$}}
+
+########################
+# Test "show" command.
+########################
+# Ignore all ".cc" files.
+RUN: llvm-cov show -instr-profile %S/Inputs/sources_specified/main.profdata \
+RUN:   -path-equivalence=/tmp,%S/Inputs -ignore-filename-regex='.*\.cc$' \
+RUN:   %S/Inputs/sources_specified/main.covmapping \
+RUN:   | FileCheck -check-prefix=SHOW_IGNORE_CC %s
+
+# Order of files may differ, check that there are 3 files and not abs.h.
+SHOW_IGNORE_CC-NOT: {{.*}}main.cc{{.*}}
+SHOW_IGNORE_CC: {{.*}}sources_specified{{.*}}
+SHOW_IGNORE_CC: {{.*}}sources_specified{{.*}}
+SHOW_IGNORE_CC: {{.*}}sources_specified{{.*}}
+
+########################
+# Test "export" command.
+########################
+# Use a temp .json file as output in a single line. Ignore headers that have
+# name in a format of 3 symbols followed by ".h".
+RUN: llvm-cov export -instr-profile %S/Inputs/sources_specified/main.profdata \
+RUN:   -path-equivalence=/tmp,%S/Inputs -ignore-filename-regex='.*...\.h$' \
+RUN:   %S/Inputs/sources_specified/main.covmapping \
+RUN:   > %t.export.json
+
+RUN: FileCheck -check-prefix=NO-EXPORT_IGNORE_3_SYMBOLS_H %s < %t.export.json
+RUN: FileCheck -check-prefix=EXPORT_IGNORE_3_SYMBOLS_H %s < %t.export.json
+
+NO-EXPORT_IGNORE_3_SYMBOLS_H-NOT: {{"filename":"(/|\\\\)tmp(/|\\\\)sources_specified(/|\\\\)abs.h"}}
+NO-EXPORT_IGNORE_3_SYMBOLS_H-NOT: {{"filename":"(/|\\\\)tmp(/|\\\\)sources_specified(/|\\\\)inc.h"}}
+NO-EXPORT_IGNORE_3_SYMBOLS_H-NOT: {{"filename":"(/|\\\\)tmp(/|\\\\)sources_specified(/|\\\\)dec.h"}}
+EXPORT_IGNORE_3_SYMBOLS_H: {{"filename":"(/|\\\\)tmp(/|\\\\)sources_specified(/|\\\\)main.cc"}}

Modified: llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CodeCoverage.cpp?rev=329581&r1=329580&r2=329581&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CodeCoverage.cpp (original)
+++ llvm/trunk/tools/llvm-cov/CodeCoverage.cpp Mon Apr  9 08:20:35 2018
@@ -126,6 +126,7 @@ private:
   std::vector<StringRef> ObjectFilenames;
   CoverageViewOptions ViewOpts;
   CoverageFiltersMatchAll Filters;
+  CoverageFilters IgnoreFilenameFilters;
 
   /// The path to the indexed profile.
   std::string PGOFilename;
@@ -189,7 +190,8 @@ void CodeCoverageTool::addCollectedPath(
     return;
   }
   sys::path::remove_dots(EffectivePath, /*remove_dot_dots=*/true);
-  SourceFiles.emplace_back(EffectivePath.str());
+  if (!IgnoreFilenameFilters.matchesFilename(EffectivePath))
+    SourceFiles.emplace_back(EffectivePath.str());
 }
 
 void CodeCoverageTool::collectPaths(const std::string &Path) {
@@ -597,6 +599,12 @@ int CodeCoverageTool::run(Command Cmd, i
                "regular expression"),
       cl::ZeroOrMore, cl::cat(FilteringCategory));
 
+  cl::list<std::string> IgnoreFilenameRegexFilters(
+      "ignore-filename-regex", cl::Optional,
+      cl::desc("Skip source code files with file paths that match the given "
+               "regular expression"),
+      cl::ZeroOrMore, cl::cat(FilteringCategory));
+
   cl::opt<double> RegionCoverageLtFilter(
       "region-coverage-lt", cl::Optional,
       cl::desc("Show code coverage only for functions with region coverage "
@@ -714,6 +722,7 @@ int CodeCoverageTool::run(Command Cmd, i
             llvm::make_unique<NameRegexCoverageFilter>(Regex));
       Filters.push_back(std::move(NameFilterer));
     }
+
     if (RegionCoverageLtFilter.getNumOccurrences() ||
         RegionCoverageGtFilter.getNumOccurrences() ||
         LineCoverageLtFilter.getNumOccurrences() ||
@@ -734,6 +743,11 @@ int CodeCoverageTool::run(Command Cmd, i
       Filters.push_back(std::move(StatFilterer));
     }
 
+    // Create the ignore filename filters.
+    for (const auto &RE : IgnoreFilenameRegexFilters)
+      IgnoreFilenameFilters.push_back(
+          llvm::make_unique<NameRegexCoverageFilter>(RE));
+
     if (!Arches.empty()) {
       for (const std::string &Arch : Arches) {
         if (Triple(Arch).getArch() == llvm::Triple::ArchType::UnknownArch) {
@@ -748,6 +762,7 @@ int CodeCoverageTool::run(Command Cmd, i
       }
     }
 
+    // IgnoreFilenameFilters are applied even when InputSourceFiles specified.
     for (const std::string &File : InputSourceFiles)
       collectPaths(File);
 
@@ -862,8 +877,10 @@ int CodeCoverageTool::doShow(int argc, c
 
   if (SourceFiles.empty())
     // Get the source files from the function coverage mapping.
-    for (StringRef Filename : Coverage->getUniqueSourceFiles())
-      SourceFiles.push_back(Filename);
+    for (StringRef Filename : Coverage->getUniqueSourceFiles()) {
+      if (!IgnoreFilenameFilters.matchesFilename(Filename))
+        SourceFiles.push_back(Filename);
+    }
 
   // Create an index out of the source files.
   if (ViewOpts.hasOutputDirectory()) {
@@ -962,7 +979,7 @@ int CodeCoverageTool::doReport(int argc,
   CoverageReport Report(ViewOpts, *Coverage.get());
   if (!ShowFunctionSummaries) {
     if (SourceFiles.empty())
-      Report.renderFileReports(llvm::outs());
+      Report.renderFileReports(llvm::outs(), IgnoreFilenameFilters);
     else
       Report.renderFileReports(llvm::outs(), SourceFiles);
   } else {
@@ -998,7 +1015,7 @@ int CodeCoverageTool::doExport(int argc,
   auto Exporter = CoverageExporterJson(*Coverage.get(), ViewOpts, outs());
 
   if (SourceFiles.empty())
-    Exporter.renderRoot();
+    Exporter.renderRoot(IgnoreFilenameFilters);
   else
     Exporter.renderRoot(SourceFiles);
 

Modified: llvm/trunk/tools/llvm-cov/CoverageExporter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageExporter.h?rev=329581&r1=329580&r2=329581&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageExporter.h (original)
+++ llvm/trunk/tools/llvm-cov/CoverageExporter.h Mon Apr  9 08:20:35 2018
@@ -14,6 +14,7 @@
 #ifndef LLVM_COV_COVERAGEEXPORTER_H
 #define LLVM_COV_COVERAGEEXPORTER_H
 
+#include "CoverageFilters.h"
 #include "CoverageSummaryInfo.h"
 #include "CoverageViewOptions.h"
 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
@@ -40,7 +41,7 @@ public:
   virtual ~CoverageExporter(){};
 
   /// \brief Render the CoverageMapping object.
-  virtual void renderRoot() = 0;
+  virtual void renderRoot(const CoverageFilters &IgnoreFilenameFilters) = 0;
 
   /// \brief Render the CoverageMapping object for specified source files.
   virtual void renderRoot(const std::vector<std::string> &SourceFiles) = 0;

Modified: llvm/trunk/tools/llvm-cov/CoverageExporterJson.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageExporterJson.cpp?rev=329581&r1=329580&r2=329581&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageExporterJson.cpp (original)
+++ llvm/trunk/tools/llvm-cov/CoverageExporterJson.cpp Mon Apr  9 08:20:35 2018
@@ -117,10 +117,13 @@ void CoverageExporterJson::emitArrayEnd(
   OS << "]";
 }
 
-void CoverageExporterJson::renderRoot() {
+void CoverageExporterJson::renderRoot(
+    const CoverageFilters &IgnoreFilenameFilters) {
   std::vector<std::string> SourceFiles;
-  for (StringRef SF : Coverage.getUniqueSourceFiles())
-    SourceFiles.emplace_back(SF);
+  for (StringRef SF : Coverage.getUniqueSourceFiles()) {
+    if (!IgnoreFilenameFilters.matchesFilename(SF))
+      SourceFiles.emplace_back(SF);
+  }
   renderRoot(SourceFiles);
 }
 
@@ -218,11 +221,11 @@ void CoverageExporterJson::renderFiles(
 
 void CoverageExporterJson::renderFile(const std::string &Filename,
                                       const FileCoverageSummary &FileReport) {
-   // Start File.
+  // Start File.
   emitDictStart();
 
   emitDictElement("filename", Filename);
-  
+
   if (!Options.ExportSummaryOnly) {
     // Calculate and render detailed coverage information for given file.
     auto FileCoverage = Coverage.getCoverageForFile(Filename);

Modified: llvm/trunk/tools/llvm-cov/CoverageExporterJson.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageExporterJson.h?rev=329581&r1=329580&r2=329581&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageExporterJson.h (original)
+++ llvm/trunk/tools/llvm-cov/CoverageExporterJson.h Mon Apr  9 08:20:35 2018
@@ -101,7 +101,7 @@ public:
                        const CoverageViewOptions &Options, raw_ostream &OS);
 
   /// \brief Render the CoverageMapping object.
-  void renderRoot() override;
+  void renderRoot(const CoverageFilters &IgnoreFilenameFilters) override;
 
   /// \brief Render the CoverageMapping object for specified source files.
   void renderRoot(const std::vector<std::string> &SourceFiles) override;

Modified: llvm/trunk/tools/llvm-cov/CoverageFilters.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageFilters.cpp?rev=329581&r1=329580&r2=329581&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageFilters.cpp (original)
+++ llvm/trunk/tools/llvm-cov/CoverageFilters.cpp Mon Apr  9 08:20:35 2018
@@ -30,6 +30,10 @@ bool NameRegexCoverageFilter::matches(
   return llvm::Regex(Regex).match(Function.Name);
 }
 
+bool NameRegexCoverageFilter::matchesFilename(StringRef Filename) const {
+  return llvm::Regex(Regex).match(Filename);
+}
+
 bool NameWhitelistCoverageFilter::matches(
     const coverage::CoverageMapping &,
     const coverage::FunctionRecord &Function) const {
@@ -61,6 +65,14 @@ bool CoverageFilters::matches(const cove
       return true;
   }
   return false;
+}
+
+bool CoverageFilters::matchesFilename(StringRef Filename) const {
+  for (const auto &Filter : Filters) {
+    if (Filter->matchesFilename(Filename))
+      return true;
+  }
+  return false;
 }
 
 bool CoverageFiltersMatchAll::matches(

Modified: llvm/trunk/tools/llvm-cov/CoverageFilters.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageFilters.h?rev=329581&r1=329580&r2=329581&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageFilters.h (original)
+++ llvm/trunk/tools/llvm-cov/CoverageFilters.h Mon Apr  9 08:20:35 2018
@@ -32,6 +32,11 @@ public:
                        const coverage::FunctionRecord &Function) const {
     return true;
   }
+
+  /// \brief Return true if the filename passes the requirements of this filter.
+  virtual bool matchesFilename(StringRef Filename) const {
+    return true;
+  }
 };
 
 /// \brief Matches functions that contain a specific string in their name.
@@ -54,6 +59,8 @@ public:
 
   bool matches(const coverage::CoverageMapping &CM,
                const coverage::FunctionRecord &Function) const override;
+
+  bool matchesFilename(StringRef Filename) const override;
 };
 
 /// \brief Matches functions whose name appears in a SpecialCaseList in the
@@ -133,6 +140,8 @@ public:
 
   bool matches(const coverage::CoverageMapping &CM,
                const coverage::FunctionRecord &Function) const override;
+
+  bool matchesFilename(StringRef Filename) const override;
 };
 
 /// \brief A collection of filters.

Modified: llvm/trunk/tools/llvm-cov/CoverageReport.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageReport.cpp?rev=329581&r1=329580&r2=329581&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageReport.cpp (original)
+++ llvm/trunk/tools/llvm-cov/CoverageReport.cpp Mon Apr  9 08:20:35 2018
@@ -379,10 +379,14 @@ std::vector<FileCoverageSummary> Coverag
   return FileReports;
 }
 
-void CoverageReport::renderFileReports(raw_ostream &OS) const {
+void CoverageReport::renderFileReports(
+    raw_ostream &OS, const CoverageFilters &IgnoreFilenameFilters) const {
   std::vector<std::string> UniqueSourceFiles;
-  for (StringRef SF : Coverage.getUniqueSourceFiles())
-    UniqueSourceFiles.emplace_back(SF.str());
+  for (StringRef SF : Coverage.getUniqueSourceFiles()) {
+    // Apply ignore source files filters.
+    if (!IgnoreFilenameFilters.matchesFilename(SF))
+      UniqueSourceFiles.emplace_back(SF.str());
+  }
   renderFileReports(OS, UniqueSourceFiles);
 }
 

Modified: llvm/trunk/tools/llvm-cov/CoverageReport.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageReport.h?rev=329581&r1=329580&r2=329581&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageReport.h (original)
+++ llvm/trunk/tools/llvm-cov/CoverageReport.h Mon Apr  9 08:20:35 2018
@@ -53,7 +53,8 @@ public:
                           const CoverageFilter *Filters);
 
   /// Render file reports for every unique file in the coverage mapping.
-  void renderFileReports(raw_ostream &OS) const;
+  void renderFileReports(raw_ostream &OS,
+                         const CoverageFilters &IgnoreFilenameFilters) const;
 
   /// Render file reports for the files specified in \p Files.
   void renderFileReports(raw_ostream &OS, ArrayRef<std::string> Files) const;




More information about the llvm-commits mailing list