[llvm-branch-commits] [clang] [analyzer][NFC] Forward-declare Preprocessor in AnalysisManager.h (PR #235282)
Balázs Benics via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Oct 24 04:56:38 PDT 2026
https://github.com/steakhal created https://github.com/llvm/llvm-project/pull/235282
AnalysisManager.h includes clang/Lex/Preprocessor.h, and through that
one edge the whole Lex subtree -- roughly 34 headers, among them
Basic/Module.h, HeaderSearch.h and ModuleMap.h -- is parsed by 147 of
the 197 translation units in clangStaticAnalyzerCore,
clangStaticAnalyzerCheckers and clangStaticAnalyzerFrontend. The
mechanism is transitive inclusion: AnalysisManager.h sits under almost
every analyzer source, so almost every one of them pays for the
preprocessor without naming it.
Preprocessor is used here only as a reference member, a constructor
parameter and a reference-returning accessor; no member of it is ever
named, so a forward declaration in namespace clang suffices and the
generated code is identical. The include is replaced by
clang/Basic/SourceManager.h rather than simply dropped, because
isInCodeFile() calls SM.isInMainFile(), SM.getIncludeLoc(),
SM.getFileID() and SM.getFilename(), and SourceManager is otherwise
unreachable from this header once Preprocessor.h is gone. That swap is
not just moving the problem: SourceManager.h costs 6.6 s of self time
across the measured translation units against roughly 34 s for the
Preprocessor.h subtree, and it is already parsed by 177 of the 197
anyway. One .cpp needed a compensating include:
ArrayBoundChecker.cpp uses Lexer::getImmediateMacroName and now
includes clang/Lex/Lexer.h directly. AnalysisManager.h itself broke no
translation unit.
This is the second half of a two-patch stack and it is only measurable
together with the first. Alone it measures +0.34% (rounds +0.54% and
+0.14%), i.e. nothing, because BugReporter.h's own #include of
Preprocessor.h keeps the Lex subtree alive in 161 translation units.
With the companion patch that forward-declares Preprocessor in
BugReporter.h, the pair measures -12.29% of total CSA frontend time
(rounds -12.03% and -12.55%), roughly 54 s out of a 443 s total. The
two edges are mutually redundant -- cut either alone and the other
keeps the entire Lex subtree alive -- so neither patch can be
benchmarked on its own. The cost of the new SourceManager.h include is
already inside the -12.29%.
Authored-By: Claude
---
<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
>From c7573b471834a4693559b3950e8562eec804d0b0 Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Sat, 24 Oct 2026 11:23:19 +0100
Subject: [PATCH] [analyzer][NFC] Forward-declare Preprocessor in
AnalysisManager.h
AnalysisManager.h includes clang/Lex/Preprocessor.h, and through that
one edge the whole Lex subtree -- roughly 34 headers, among them
Basic/Module.h, HeaderSearch.h and ModuleMap.h -- is parsed by 147 of
the 197 translation units in clangStaticAnalyzerCore,
clangStaticAnalyzerCheckers and clangStaticAnalyzerFrontend. The
mechanism is transitive inclusion: AnalysisManager.h sits under almost
every analyzer source, so almost every one of them pays for the
preprocessor without naming it.
Preprocessor is used here only as a reference member, a constructor
parameter and a reference-returning accessor; no member of it is ever
named, so a forward declaration in namespace clang suffices and the
generated code is identical. The include is replaced by
clang/Basic/SourceManager.h rather than simply dropped, because
isInCodeFile() calls SM.isInMainFile(), SM.getIncludeLoc(),
SM.getFileID() and SM.getFilename(), and SourceManager is otherwise
unreachable from this header once Preprocessor.h is gone. That swap is
not just moving the problem: SourceManager.h costs 6.6 s of self time
across the measured translation units against roughly 34 s for the
Preprocessor.h subtree, and it is already parsed by 177 of the 197
anyway. One .cpp needed a compensating include:
ArrayBoundChecker.cpp uses Lexer::getImmediateMacroName and now
includes clang/Lex/Lexer.h directly. AnalysisManager.h itself broke no
translation unit.
This is the second half of a two-patch stack and it is only measurable
together with the first. Alone it measures +0.34% (rounds +0.54% and
+0.14%), i.e. nothing, because BugReporter.h's own #include of
Preprocessor.h keeps the Lex subtree alive in 161 translation units.
With the companion patch that forward-declares Preprocessor in
BugReporter.h, the pair measures -12.29% of total CSA frontend time
(rounds -12.03% and -12.55%), roughly 54 s out of a 443 s total. The
two edges are mutually redundant -- cut either alone and the other
keeps the entire Lex subtree alive -- so neither patch can be
benchmarked on its own. The cost of the new SourceManager.h include is
already inside the -12.29%.
Authored-By: Claude
---
.../clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h | 3 ++-
clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index 1e87b479d1cf89..eeb015e26b3ce8 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -16,7 +16,7 @@
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
@@ -24,6 +24,7 @@
namespace clang {
class CodeInjector;
+class Preprocessor;
namespace ento {
class CheckerManager;
diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
index 25f44eebc93245..5f644237150f49 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
@@ -13,6 +13,7 @@
#include "clang/AST/CharUnits.h"
#include "clang/AST/ParentMapContext.h"
+#include "clang/Lex/Lexer.h"
#include "clang/StaticAnalyzer/Checkers/BoundsChecking.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Checkers/Taint.h"
More information about the llvm-branch-commits
mailing list