[clang-tools-extra] [include-cleaner] Add --only-headers flag, opposite of --ignore-headers (PR #78714)

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 19 05:47:19 PST 2024


https://github.com/sam-mccall created https://github.com/llvm/llvm-project/pull/78714

None

>From 97276e961ffb146182712832a346b2ee5d13bc30 Mon Sep 17 00:00:00 2001
From: Sam McCall <sam.mccall at gmail.com>
Date: Fri, 19 Jan 2024 14:45:51 +0100
Subject: [PATCH] [include-cleaner] Add --only-headers flag, opposite of
 --ignore-headers

---
 .../include-cleaner/test/tool.cpp             |  4 +++
 .../include-cleaner/tool/IncludeCleaner.cpp   | 30 +++++++++++++++++--
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/include-cleaner/test/tool.cpp b/clang-tools-extra/include-cleaner/test/tool.cpp
index bd90679875acb8..de47b2a3f3778c 100644
--- a/clang-tools-extra/include-cleaner/test/tool.cpp
+++ b/clang-tools-extra/include-cleaner/test/tool.cpp
@@ -22,6 +22,10 @@ int x = foo();
 // IGNORE2-NOT: - "foobar.h"
 //     IGNORE2: + "foo.h"
 
+//        RUN: clang-include-cleaner -print=changes %s --only-headers="foo\.h" -- -I%S/Inputs/ | FileCheck --match-full-lines --allow-empty --check-prefix=ONLY %s
+//   ONLY-NOT: - "foobar.h"
+//       ONLY: + "foo.h"
+
 //        RUN: clang-include-cleaner -print %s -- -I%S/Inputs/ | FileCheck --match-full-lines --check-prefix=PRINT %s
 //      PRINT: #include "foo.h"
 //  PRINT-NOT: {{^}}#include "foobar.h"{{$}}
diff --git a/clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp b/clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp
index e078bfae66c3b5..132ad25411509d 100644
--- a/clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp
+++ b/clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp
@@ -57,6 +57,14 @@ cl::opt<std::string> HTMLReportPath{
     cl::cat(IncludeCleaner),
 };
 
+cl::opt<std::string> OnlyHeaders{
+    "only-headers",
+    cl::desc("A comma-separated list of regexes to match against suffix of a "
+             "header. Only headers that match will be analyzed."),
+    cl::init(""),
+    cl::cat(IncludeCleaner),
+};
+
 cl::opt<std::string> IgnoreHeaders{
     "ignore-headers",
     cl::desc("A comma-separated list of regexes to match against suffix of a "
@@ -221,11 +229,12 @@ class ActionFactory : public tooling::FrontendActionFactory {
   llvm::StringMap<std::string> EditedFiles;
 };
 
-std::function<bool(llvm::StringRef)> headerFilter() {
+// Compiles a regex list into a function that return true if any match a header.
+// Prints and returns nullptr if any regexes are invalid.
+std::function<bool(llvm::StringRef)> matchesAny(llvm::StringRef RegexFlag) {
   auto FilterRegs = std::make_shared<std::vector<llvm::Regex>>();
-
   llvm::SmallVector<llvm::StringRef> Headers;
-  llvm::StringRef(IgnoreHeaders).split(Headers, ',', -1, /*KeepEmpty=*/false);
+  RegexFlag.split(Headers, ',', -1, /*KeepEmpty=*/false);
   for (auto HeaderPattern : Headers) {
     std::string AnchoredPattern = "(" + HeaderPattern.str() + ")$";
     llvm::Regex CompiledRegex(AnchoredPattern);
@@ -246,6 +255,21 @@ std::function<bool(llvm::StringRef)> headerFilter() {
   };
 }
 
+std::function<bool(llvm::StringRef)> headerFilter() {
+  auto OnlyMatches = matchesAny(OnlyHeaders);
+  auto IgnoreMatches = matchesAny(IgnoreHeaders);
+  if (!OnlyMatches || !IgnoreMatches)
+    return nullptr;
+
+  return [OnlyMatches, IgnoreMatches](llvm::StringRef Header) {
+    if (OnlyHeaders.getNumOccurrences() && !OnlyMatches(Header))
+      return true;
+    if (IgnoreHeaders.getNumOccurrences() && IgnoreMatches(Header))
+      return true;
+    return false;
+  };
+}
+
 } // namespace
 } // namespace include_cleaner
 } // namespace clang



More information about the cfe-commits mailing list