[llvm] [llvm-cov] show: include-filename-filter (PR #71716)

Viranchee Lotia via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 8 10:12:34 PST 2023


https://github.com/Viranchee created https://github.com/llvm/llvm-project/pull/71716

[tools:llvm-cov]
`llvm-cov show` add support for --include-filename-filter flag, a counterpart for --ignore-filename-filter flag

https://github.com/llvm/llvm-project/issues/71628

I have not yet tested this code. I'm looking for help / mentorship.

>From 2064a4451d9aac20fcd0ebe129db0968132ea6b5 Mon Sep 17 00:00:00 2001
From: Viranchee Lotia <viranchee at outlook.com>
Date: Wed, 8 Nov 2023 12:17:55 -0500
Subject: [PATCH 1/2] Added code. Not added tests, clang-format, documentation

---
 llvm/tools/llvm-cov/CodeCoverage.cpp | 57 +++++++++++++++++++++++-----
 1 file changed, 47 insertions(+), 10 deletions(-)

diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index b5d763d8643cd7d..ea69d3c8352dd93 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -145,7 +145,11 @@ class CodeCoverageTool {
   std::vector<StringRef> ObjectFilenames;
   CoverageViewOptions ViewOpts;
   CoverageFiltersMatchAll Filters;
-  CoverageFilters IgnoreFilenameFilters;
+  // CoverageFilters IgnoreFilenameFilters;
+  CoverageFilters FilenameFilters;
+
+  enum FileNameFilterKind { Ignore, Include, NotPresent }; // TODO: Since I'm using 
+  FileNameFilterKind FileNameFilter = FileNameFilterKind::NotPresent; // Default
 
   /// True if InputSourceFiles are provided.
   bool HadSourceFiles = false;
@@ -220,8 +224,15 @@ void CodeCoverageTool::addCollectedPath(const std::string &Path) {
     return;
   }
   sys::path::remove_dots(EffectivePath, /*remove_dot_dot=*/true);
-  if (!IgnoreFilenameFilters.matchesFilename(EffectivePath))
-    SourceFiles.emplace_back(EffectivePath.str());
+  if (FileNameFilterKind == FileNameFilterKind::Ignore) {
+    if (!FilenameFilters.matchesFilename(EffectivePath))
+      SourceFiles.emplace_back(EffectivePath.str());
+  } else if (FileNameFilterKind == FileNameFilterKind::Include) {
+    if (FilenameFilters.matchesFilename(EffectivePath))
+      SourceFiles.emplace_back(EffectivePath.str());
+  } else if (FileNameFilterKind == FileNameFilterKind::NotPresent) {
+      break;
+  }
   HadSourceFiles = !SourceFiles.empty();
 }
 
@@ -711,6 +722,12 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
                "regular expression"),
       cl::cat(FilteringCategory));
 
+  cl::list<std::string> IncludeFilenameRegexFilters(
+      "include-filename-regex", cl::Optional,
+      cl::desc("Include only source code files with file paths that match the given. Mutually exclusive with -ignore-filename-regex "
+               "regular expression"),
+      cl::cat(FilteringCategory));
+
   cl::opt<double> RegionCoverageLtFilter(
       "region-coverage-lt", cl::Optional,
       cl::desc("Show code coverage only for functions with region coverage "
@@ -893,10 +910,25 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
       Filters.push_back(std::move(StatFilterer));
     }
 
-    // Create the ignore filename filters.
-    for (const auto &RE : IgnoreFilenameRegexFilters)
-      IgnoreFilenameFilters.push_back(
+    // Keep include-filename-regex and ignore-filename-regex mutually exclusive.
+    if (!IncludeFilenameRegexFilters.empty() &&
+        !IgnoreFilenameRegexFilters.empty()) {
+      error("include-filename-regex and ignore-filename-regex are mutually "
+            "exclusive");
+      return 1;
+    } else if (!IncludeFilenameRegexFilters.empty()) {
+      FileNameFilterKind = FileNameFilterKind::Include;
+    // Create the include filename filters.
+      for (const auto &RE : IncludeFilenameRegexFilters)
+        FilenameFilters.push_back(
+          std::make_unique<NameRegexCoverageFilter>(RE));
+    } else if (!IgnoreFilenameRegexFilters.empty()) {
+      FileNameFilterKind = FileNameFilterKind::Ignore;
+      // Create the ignore filename filters.
+      for (const auto &RE : IgnoreFilenameRegexFilters)
+        FilenameFilters.push_back(
           std::make_unique<NameRegexCoverageFilter>(RE));
+    }
 
     if (!Arches.empty()) {
       for (const std::string &Arch : Arches) {
@@ -1100,8 +1132,12 @@ int CodeCoverageTool::doShow(int argc, const char **argv,
   if (SourceFiles.empty() && !HadSourceFiles)
     // Get the source files from the function coverage mapping.
     for (StringRef Filename : Coverage->getUniqueSourceFiles()) {
-      if (!IgnoreFilenameFilters.matchesFilename(Filename))
-        SourceFiles.push_back(std::string(Filename));
+      if ((FileNameFilterKind == FileNameFilterKind::Ignore 
+      && !FilenameFilters.matchesFilename(Filename)) 
+      || (FileNameFilterKind == FileNameFilterKind::Include 
+      && FilenameFilters.matchesFilename(Filename))) {
+          SourceFiles.push_back(std::string(Filename));
+      }
     }
 
   // Create an index out of the source files.
@@ -1210,7 +1246,8 @@ int CodeCoverageTool::doReport(int argc, const char **argv,
   CoverageReport Report(ViewOpts, *Coverage);
   if (!ShowFunctionSummaries) {
     if (SourceFiles.empty())
-      Report.renderFileReports(llvm::outs(), IgnoreFilenameFilters);
+    // Works for both -ignore-filename-regex and -include-filename-regex
+      Report.renderFileReports(llvm::outs(), FilenameFilters);
     else
       Report.renderFileReports(llvm::outs(), SourceFiles);
   } else {
@@ -1287,7 +1324,7 @@ int CodeCoverageTool::doExport(int argc, const char **argv,
   }
 
   if (SourceFiles.empty())
-    Exporter->renderRoot(IgnoreFilenameFilters);
+    Exporter->renderRoot(FilenameFilters);
   else
     Exporter->renderRoot(SourceFiles);
 

>From 146d4793b4c793205682577cd0cebaed7e7f4ff5 Mon Sep 17 00:00:00 2001
From: Viranchee Lotia <viranchee at outlook.com>
Date: Wed, 8 Nov 2023 12:56:10 -0500
Subject: [PATCH 2/2] With clang-format

---
 llvm/tools/llvm-cov/CodeCoverage.cpp | 29 ++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index ea69d3c8352dd93..0c7bc5dcbe3640c 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -148,7 +148,7 @@ class CodeCoverageTool {
   // CoverageFilters IgnoreFilenameFilters;
   CoverageFilters FilenameFilters;
 
-  enum FileNameFilterKind { Ignore, Include, NotPresent }; // TODO: Since I'm using 
+  enum FileNameFilterKind { Ignore, Include, NotPresent };
   FileNameFilterKind FileNameFilter = FileNameFilterKind::NotPresent; // Default
 
   /// True if InputSourceFiles are provided.
@@ -231,7 +231,7 @@ void CodeCoverageTool::addCollectedPath(const std::string &Path) {
     if (FilenameFilters.matchesFilename(EffectivePath))
       SourceFiles.emplace_back(EffectivePath.str());
   } else if (FileNameFilterKind == FileNameFilterKind::NotPresent) {
-      break;
+    break;
   }
   HadSourceFiles = !SourceFiles.empty();
 }
@@ -724,7 +724,8 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
 
   cl::list<std::string> IncludeFilenameRegexFilters(
       "include-filename-regex", cl::Optional,
-      cl::desc("Include only source code files with file paths that match the given. Mutually exclusive with -ignore-filename-regex "
+      cl::desc("Include only source code files with file paths that match the "
+               "given. Mutually exclusive with -ignore-filename-regex "
                "regular expression"),
       cl::cat(FilteringCategory));
 
@@ -918,16 +919,16 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
       return 1;
     } else if (!IncludeFilenameRegexFilters.empty()) {
       FileNameFilterKind = FileNameFilterKind::Include;
-    // Create the include filename filters.
+      // Create the include filename filters.
       for (const auto &RE : IncludeFilenameRegexFilters)
         FilenameFilters.push_back(
-          std::make_unique<NameRegexCoverageFilter>(RE));
+            std::make_unique<NameRegexCoverageFilter>(RE));
     } else if (!IgnoreFilenameRegexFilters.empty()) {
       FileNameFilterKind = FileNameFilterKind::Ignore;
       // Create the ignore filename filters.
       for (const auto &RE : IgnoreFilenameRegexFilters)
         FilenameFilters.push_back(
-          std::make_unique<NameRegexCoverageFilter>(RE));
+            std::make_unique<NameRegexCoverageFilter>(RE));
     }
 
     if (!Arches.empty()) {
@@ -1132,11 +1133,11 @@ int CodeCoverageTool::doShow(int argc, const char **argv,
   if (SourceFiles.empty() && !HadSourceFiles)
     // Get the source files from the function coverage mapping.
     for (StringRef Filename : Coverage->getUniqueSourceFiles()) {
-      if ((FileNameFilterKind == FileNameFilterKind::Ignore 
-      && !FilenameFilters.matchesFilename(Filename)) 
-      || (FileNameFilterKind == FileNameFilterKind::Include 
-      && FilenameFilters.matchesFilename(Filename))) {
-          SourceFiles.push_back(std::string(Filename));
+      if ((FileNameFilterKind == FileNameFilterKind::Ignore &&
+           !FilenameFilters.matchesFilename(Filename)) ||
+          (FileNameFilterKind == FileNameFilterKind::Include &&
+           FilenameFilters.matchesFilename(Filename))) {
+        SourceFiles.push_back(std::string(Filename));
       }
     }
 
@@ -1246,7 +1247,7 @@ int CodeCoverageTool::doReport(int argc, const char **argv,
   CoverageReport Report(ViewOpts, *Coverage);
   if (!ShowFunctionSummaries) {
     if (SourceFiles.empty())
-    // Works for both -ignore-filename-regex and -include-filename-regex
+      // Works for both -ignore-filename-regex and -include-filename-regex
       Report.renderFileReports(llvm::outs(), FilenameFilters);
     else
       Report.renderFileReports(llvm::outs(), SourceFiles);
@@ -1276,8 +1277,8 @@ int CodeCoverageTool::doExport(int argc, const char **argv,
                               cl::cat(ExportCategory));
 
   cl::opt<bool> SkipBranches("skip-branches", cl::Optional,
-                              cl::desc("Don't export branch data (LCOV)"),
-                              cl::cat(ExportCategory));
+                             cl::desc("Don't export branch data (LCOV)"),
+                             cl::cat(ExportCategory));
 
   auto Err = commandLineParser(argc, argv);
   if (Err)



More information about the llvm-commits mailing list