[llvm-branch-commits] [clang-tools-extra] [include-cleaner][NFC] factor analysis bookkeeping (PR #196763)
https://github.com/unterumarmung edited https://github.com/llvm/llvm-project/pull/196763 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang-tools-extra] [include-cleaner][NFC] factor analysis bookkeeping (PR #196763)
https://github.com/unterumarmung created
https://github.com/llvm/llvm-project/pull/196763
None
>From 6e146f087045416aad4ead1c35a38db9392f469d Mon Sep 17 00:00:00 2001
From: Daniil Dudkin
Date: Sun, 10 May 2026 01:01:20 +0300
Subject: [PATCH] [include-cleaner][NFC] factor analysis bookkeeping
---
.../include/clang-include-cleaner/Analysis.h | 35 +++--
.../include-cleaner/lib/Analysis.cpp | 130 +-
.../include-cleaner/tool/IncludeCleaner.cpp | 32 +++--
.../unittests/AnalysisTest.cpp| 50 ---
4 files changed, 164 insertions(+), 83 deletions(-)
diff --git
a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
index c3241763237d1..8e4912fa7bd84 100644
--- a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
+++ b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
@@ -20,8 +20,9 @@
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include
#include
-#include
+#include
namespace clang {
class SourceLocation;
@@ -61,23 +62,33 @@ void walkUsed(llvm::ArrayRef ASTRoots,
const PragmaIncludes *PI, const Preprocessor &PP,
UsedSymbolCB CB);
+/// A missing include insertion candidate.
+struct MissingInclude {
+ std::string Spelling;
+ Header Provider;
+};
+
+/// The result of include-cleaner analysis for one main file.
struct AnalysisResults {
std::vector Unused;
- // Spellings, like "" paired with the Header that generated it.
- std::vector> Missing;
+ /// Deduplicated insertion plan, e.g. "" paired with the chosen
+ /// provider Header.
+ std::vector MissingIncludes;
+};
+
+/// Analysis configuration shared by include-cleaner consumers.
+struct AnalysisOptions {
+ /// No analysis will be performed for headers that satisfy the predicate.
+ std::function HeaderFilter;
};
/// Determine which headers should be inserted or removed from the main file.
/// This exposes conclusions but not reasons: use lower-level walkUsed for
that.
-///
-/// The HeaderFilter is a predicate that receives absolute path or spelling
-/// without quotes/brackets, when a phyiscal file doesn't exist.
-/// No analysis will be performed for headers that satisfy the predicate.
-AnalysisResults
-analyze(llvm::ArrayRef ASTRoots,
-llvm::ArrayRef MacroRefs, const Includes &I,
-const PragmaIncludes *PI, const Preprocessor &PP,
-llvm::function_ref HeaderFilter = nullptr);
+AnalysisResults analyze(llvm::ArrayRef ASTRoots,
+llvm::ArrayRef MacroRefs,
+const Includes &I, const PragmaIncludes *PI,
+const Preprocessor &PP,
+const AnalysisOptions &Options = {});
/// Removes unused includes and inserts missing ones in the main file.
/// Returns the modified main-file code.
diff --git a/clang-tools-extra/include-cleaner/lib/Analysis.cpp
b/clang-tools-extra/include-cleaner/lib/Analysis.cpp
index e48a380211af0..cd0b3396bf418 100644
--- a/clang-tools-extra/include-cleaner/lib/Analysis.cpp
+++ b/clang-tools-extra/include-cleaner/lib/Analysis.cpp
@@ -88,18 +88,90 @@ void walkUsed(llvm::ArrayRef ASTRoots,
}
}
-AnalysisResults
-analyze(llvm::ArrayRef ASTRoots,
-llvm::ArrayRef MacroRefs, const Includes &Inc,
-const PragmaIncludes *PI, const Preprocessor &PP,
-llvm::function_ref HeaderFilter) {
- auto &SM = PP.getSourceManager();
- const auto MainFile = *SM.getFileEntryRefForID(SM.getMainFileID());
+namespace {
+
+bool isFilteredInclude(const Include &I,
+ llvm::function_ref HeaderFilter,
+ const Preprocessor &PP) {
+ if (I.Angled) {
+auto Lang = PP.getLangOpts().CPlusPlus ? tooling::stdlib::Lang::CXX
+ : tooling::stdlib::Lang::C;
+if (auto StdHeader = tooling::stdlib::Header::named(I.quote(), Lang);
+StdHeader && HeaderFilter(*StdHeader))
+ return true;
+ }
+ return I.Resolved && HeaderFilter(*I.Resolved);
+}
+
+bool shouldSuppressIncludeDiagnostic(
+const Include &I, FileEntryRef MainFile,
+llvm::function_ref HeaderFilter,
+const PragmaIncludes *PI, const Preprocessor &PP,
+OptionalDirectoryEntryRef ResourceDir) {
+ if (!I.Resolved || I.Resolved->getDir() == ResourceDir ||
+ isFilteredInclude(I, HeaderFilter, PP))
+return true;
+ if (!PI)
+return false;
+ if (PI->shouldKeep(*I.Resolved))
+return true;
+ // Check if main file is the public interface for a private header. If so
+ // we shouldn't diagnose it as unused.
+ if (auto PHeader = PI->getPublic(*I.Resolved); !PHeader.empty()) {
+PHeader = PHeader.trim("<>\"");
+// Since most private -> public mappings happen in a verbatim way, we
+// check textually here. This might go wrong in pre
[llvm-branch-commits] [clang-tools-extra] [include-cleaner][NFC] factor analysis bookkeeping (PR #196763)
https://github.com/unterumarmung ready_for_review https://github.com/llvm/llvm-project/pull/196763 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang-tools-extra] [include-cleaner][NFC] factor analysis bookkeeping (PR #196763)
llvmorg-github-actions[bot] wrote:
@llvm/pr-subscribers-clang-tools-extra
Author: Daniil Dudkin (unterumarmung)
Changes
---
Full diff: https://github.com/llvm/llvm-project/pull/196763.diff
4 Files Affected:
- (modified)
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
(+23-12)
- (modified) clang-tools-extra/include-cleaner/lib/Analysis.cpp (+93-37)
- (modified) clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp (+17-15)
- (modified) clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
(+31-19)
``diff
diff --git
a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
index c3241763237d1..8e4912fa7bd84 100644
--- a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
+++ b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
@@ -20,8 +20,9 @@
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include
#include
-#include
+#include
namespace clang {
class SourceLocation;
@@ -61,23 +62,33 @@ void walkUsed(llvm::ArrayRef ASTRoots,
const PragmaIncludes *PI, const Preprocessor &PP,
UsedSymbolCB CB);
+/// A missing include insertion candidate.
+struct MissingInclude {
+ std::string Spelling;
+ Header Provider;
+};
+
+/// The result of include-cleaner analysis for one main file.
struct AnalysisResults {
std::vector Unused;
- // Spellings, like "" paired with the Header that generated it.
- std::vector> Missing;
+ /// Deduplicated insertion plan, e.g. "" paired with the chosen
+ /// provider Header.
+ std::vector MissingIncludes;
+};
+
+/// Analysis configuration shared by include-cleaner consumers.
+struct AnalysisOptions {
+ /// No analysis will be performed for headers that satisfy the predicate.
+ std::function HeaderFilter;
};
/// Determine which headers should be inserted or removed from the main file.
/// This exposes conclusions but not reasons: use lower-level walkUsed for
that.
-///
-/// The HeaderFilter is a predicate that receives absolute path or spelling
-/// without quotes/brackets, when a phyiscal file doesn't exist.
-/// No analysis will be performed for headers that satisfy the predicate.
-AnalysisResults
-analyze(llvm::ArrayRef ASTRoots,
-llvm::ArrayRef MacroRefs, const Includes &I,
-const PragmaIncludes *PI, const Preprocessor &PP,
-llvm::function_ref HeaderFilter = nullptr);
+AnalysisResults analyze(llvm::ArrayRef ASTRoots,
+llvm::ArrayRef MacroRefs,
+const Includes &I, const PragmaIncludes *PI,
+const Preprocessor &PP,
+const AnalysisOptions &Options = {});
/// Removes unused includes and inserts missing ones in the main file.
/// Returns the modified main-file code.
diff --git a/clang-tools-extra/include-cleaner/lib/Analysis.cpp
b/clang-tools-extra/include-cleaner/lib/Analysis.cpp
index e48a380211af0..cd0b3396bf418 100644
--- a/clang-tools-extra/include-cleaner/lib/Analysis.cpp
+++ b/clang-tools-extra/include-cleaner/lib/Analysis.cpp
@@ -88,18 +88,90 @@ void walkUsed(llvm::ArrayRef ASTRoots,
}
}
-AnalysisResults
-analyze(llvm::ArrayRef ASTRoots,
-llvm::ArrayRef MacroRefs, const Includes &Inc,
-const PragmaIncludes *PI, const Preprocessor &PP,
-llvm::function_ref HeaderFilter) {
- auto &SM = PP.getSourceManager();
- const auto MainFile = *SM.getFileEntryRefForID(SM.getMainFileID());
+namespace {
+
+bool isFilteredInclude(const Include &I,
+ llvm::function_ref HeaderFilter,
+ const Preprocessor &PP) {
+ if (I.Angled) {
+auto Lang = PP.getLangOpts().CPlusPlus ? tooling::stdlib::Lang::CXX
+ : tooling::stdlib::Lang::C;
+if (auto StdHeader = tooling::stdlib::Header::named(I.quote(), Lang);
+StdHeader && HeaderFilter(*StdHeader))
+ return true;
+ }
+ return I.Resolved && HeaderFilter(*I.Resolved);
+}
+
+bool shouldSuppressIncludeDiagnostic(
+const Include &I, FileEntryRef MainFile,
+llvm::function_ref HeaderFilter,
+const PragmaIncludes *PI, const Preprocessor &PP,
+OptionalDirectoryEntryRef ResourceDir) {
+ if (!I.Resolved || I.Resolved->getDir() == ResourceDir ||
+ isFilteredInclude(I, HeaderFilter, PP))
+return true;
+ if (!PI)
+return false;
+ if (PI->shouldKeep(*I.Resolved))
+return true;
+ // Check if main file is the public interface for a private header. If so
+ // we shouldn't diagnose it as unused.
+ if (auto PHeader = PI->getPublic(*I.Resolved); !PHeader.empty()) {
+PHeader = PHeader.trim("<>\"");
+// Since most private -> public mappings happen in a verbatim way, we
+// check textually here. This might go wrong in presence of symlinks or
+// h
[llvm-branch-commits] [clang-tools-extra] [include-cleaner][NFC] factor analysis bookkeeping (PR #196763)
unterumarmung wrote: > [!WARNING] > This pull request is not mergeable via GitHub because a downstack PR is > open. Once all requirements are satisfied, merge this PR as a stack href="https://app.graphite.com/github/pr/llvm/llvm-project/196763?utm_source=stack-comment-downstack-mergeability-warning"; > >on Graphite. > https://graphite.dev/docs/merge-pull-requests";>Learn more * **#196767** https://app.graphite.com/github/pr/llvm/llvm-project/196767?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * **#196766** https://app.graphite.com/github/pr/llvm/llvm-project/196766?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * **#196765** https://app.graphite.com/github/pr/llvm/llvm-project/196765?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * **#196764** https://app.graphite.com/github/pr/llvm/llvm-project/196764?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * **#196763** https://app.graphite.com/github/pr/llvm/llvm-project/196763?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> 👈 https://app.graphite.com/github/pr/llvm/llvm-project/196763?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * **#196762** https://app.graphite.com/github/pr/llvm/llvm-project/196762?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * **#196761** https://app.graphite.com/github/pr/llvm/llvm-project/196761?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/196763 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
