[clang] [clang-tools-extra] [clang-tidy] Add experimental header-filter scope (PR #194370)
Vladimir Makaev via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 27 06:50:17 PDT 2026
https://github.com/VladimirMakaev updated https://github.com/llvm/llvm-project/pull/194370
>From 4bdd0af7549bb74e568a91a52ef0934311480aa8 Mon Sep 17 00:00:00 2001
From: Vladimir Makaev <vmakaev at gmail.com>
Date: Mon, 27 Apr 2026 13:37:30 +0000
Subject: [PATCH 1/2] [clang-tidy] Add experimental header-filter scope
---
clang-tools-extra/clang-tidy/ClangTidy.cpp | 11 ++++
.../ClangTidyDiagnosticConsumer.cpp | 33 ++++------
.../clang-tidy/ClangTidyDiagnosticConsumer.h | 15 ++---
.../clang-tidy/ClangTidyOptions.cpp | 5 ++
.../clang-tidy/ClangTidyOptions.h | 6 ++
.../clang-tidy/HeaderFilterHelpers.h | 64 +++++++++++++++++++
.../clang-tidy/tool/ClangTidyMain.cpp | 26 ++++++++
.../clang-tidy/tool/run-clang-tidy.py | 18 ++++++
clang-tools-extra/docs/ReleaseNotes.rst | 7 ++
clang-tools-extra/docs/clang-tidy/index.rst | 22 ++++++-
.../Inputs/config-files/.clang-tidy | 1 +
.../Inputs/config-files/1/.clang-tidy | 1 +
.../Inputs/config-files/3/.clang-tidy | 1 +
.../confusable_header.h | 1 +
.../infrastructure/config-files.cpp | 7 +-
.../clang-tidy/infrastructure/diagnostic.cpp | 2 +
.../infrastructure/dump-config-filtering.cpp | 2 +
.../experimental-header-filter-scope.cpp | 16 +++++
.../infrastructure/run-clang-tidy.cpp | 15 +++++
.../clang/ASTMatchers/ASTMatchFinder.h | 8 +++
clang/lib/ASTMatchers/ASTMatchFinder.cpp | 21 +++++-
.../ASTMatchers/ASTMatchersInternalTest.cpp | 50 +++++++++++++++
22 files changed, 296 insertions(+), 36 deletions(-)
create mode 100644 clang-tools-extra/clang-tidy/HeaderFilterHelpers.h
create mode 100644 clang-tools-extra/test/clang-tidy/infrastructure/Inputs/experimental-header-filter-scope/confusable_header.h
create mode 100644 clang-tools-extra/test/clang-tidy/infrastructure/experimental-header-filter-scope.cpp
diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp
index 05c8fd02fe86a..3292dc44b3539 100644
--- a/clang-tools-extra/clang-tidy/ClangTidy.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp
@@ -20,6 +20,7 @@
#include "ClangTidyModule.h"
#include "ClangTidyProfiling.h"
#include "ExpandModularHeadersPPCallbacks.h"
+#include "HeaderFilterHelpers.h"
#include "clang-tidy-config.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
@@ -448,6 +449,16 @@ ClangTidyASTConsumerFactory::createASTConsumer(CompilerInstance &Compiler,
if (!Context.getOptions().SystemHeaders.value_or(false))
FinderOptions.IgnoreSystemHeaders = true;
+ if (Context.getOptions().ExperimentalHeaderFilterScope.value_or(false)) {
+ auto LocationFilter = std::make_shared<HeaderFilterLocationFilter>(
+ Context.getOptions().HeaderFilterRegex.value_or(""),
+ Context.getOptions().ExcludeHeaderFilterRegex.value_or(""));
+ FinderOptions.ShouldSkipLocation =
+ [LocationFilter, SM](SourceLocation Location) {
+ return !LocationFilter->shouldInclude(Location, *SM);
+ };
+ }
+
auto Finder =
std::make_unique<ast_matchers::MatchFinder>(std::move(FinderOptions));
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index f7232645a329c..6b3569f7cad9e 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -36,7 +36,6 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/Regex.h"
#include <optional>
#include <tuple>
#include <utility>
@@ -372,6 +371,7 @@ void ClangTidyDiagnosticConsumer::BeginSourceFile(const LangOptions &LangOpts,
assert(!InSourceFile);
InSourceFile = true;
+ HeaderFilterLocation.reset();
}
void ClangTidyDiagnosticConsumer::EndSourceFile() {
@@ -568,9 +568,10 @@ void ClangTidyDiagnosticConsumer::forwardDiagnostic(const Diagnostic &Info) {
void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
const SourceManager &Sources) {
- // Invalid location may mean a diagnostic in a command line, don't skip these.
if (!Location.isValid()) {
- LastErrorRelatesToUserCode = true;
+ LastErrorRelatesToUserCode =
+ LastErrorRelatesToUserCode ||
+ getHeaderFilterLocationFilter().shouldInclude(Location, Sources);
LastErrorPassesLineFilter = true;
return;
}
@@ -579,6 +580,10 @@ void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
(Sources.isInSystemHeader(Location) || Sources.isInSystemMacro(Location)))
return;
+ LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
+ getHeaderFilterLocationFilter().shouldInclude(
+ Location, Sources);
+
// FIXME: We start with a conservative approach here, but the actual type of
// location needed depends on the check (in particular, where this check wants
// to apply fixes).
@@ -588,34 +593,24 @@ void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
// -DMACRO definitions on the command line have locations in a virtual buffer
// that doesn't have a FileEntry. Don't skip these as well.
if (!File) {
- LastErrorRelatesToUserCode = true;
LastErrorPassesLineFilter = true;
return;
}
const StringRef FileName(File->getName());
- LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
- Sources.isInMainFile(Location) ||
- (getHeaderFilter()->match(FileName) &&
- !getExcludeHeaderFilter()->match(FileName));
const unsigned LineNumber = Sources.getExpansionLineNumber(Location);
LastErrorPassesLineFilter =
LastErrorPassesLineFilter || passesLineFilter(FileName, LineNumber);
}
-llvm::Regex *ClangTidyDiagnosticConsumer::getHeaderFilter() {
- if (!HeaderFilter)
- HeaderFilter = std::make_unique<llvm::Regex>(
- Context.getOptions().HeaderFilterRegex.value_or(""));
- return HeaderFilter.get();
-}
-
-llvm::Regex *ClangTidyDiagnosticConsumer::getExcludeHeaderFilter() {
- if (!ExcludeHeaderFilter)
- ExcludeHeaderFilter = std::make_unique<llvm::Regex>(
+HeaderFilterLocationFilter &
+ClangTidyDiagnosticConsumer::getHeaderFilterLocationFilter() {
+ if (!HeaderFilterLocation)
+ HeaderFilterLocation = std::make_unique<HeaderFilterLocationFilter>(
+ Context.getOptions().HeaderFilterRegex.value_or(""),
Context.getOptions().ExcludeHeaderFilterRegex.value_or(""));
- return ExcludeHeaderFilter.get();
+ return *HeaderFilterLocation;
}
void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
index 8de5778dfefb0..241e70f915677 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -12,12 +12,12 @@
#include "ClangTidyOptions.h"
#include "ClangTidyProfiling.h"
#include "FileExtensionsSet.h"
+#include "HeaderFilterHelpers.h"
#include "NoLintDirectiveHandler.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Tooling/Core/Diagnostic.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/Support/Regex.h"
#include <optional>
#include <utility>
@@ -310,13 +310,9 @@ class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
void removeIncompatibleErrors();
void removeDuplicatedDiagnosticsOfAliasCheckers();
- /// Returns the \c HeaderFilter constructed for the options set in the
- /// context.
- llvm::Regex *getHeaderFilter();
-
- /// Returns the \c ExcludeHeaderFilter constructed for the options set in the
- /// context.
- llvm::Regex *getExcludeHeaderFilter();
+ /// Returns the cached header-filter evaluator for the current translation
+ /// unit.
+ HeaderFilterLocationFilter &getHeaderFilterLocationFilter();
/// Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
/// according to the diagnostic \p Location.
@@ -331,8 +327,7 @@ class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
bool GetFixesFromNotes;
bool EnableNolintBlocks;
std::vector<ClangTidyError> Errors;
- std::unique_ptr<llvm::Regex> HeaderFilter;
- std::unique_ptr<llvm::Regex> ExcludeHeaderFilter;
+ std::unique_ptr<HeaderFilterLocationFilter> HeaderFilterLocation;
bool LastErrorRelatesToUserCode = false;
bool LastErrorPassesLineFilter = false;
bool LastErrorWasIgnored = false;
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
index 0a0f392346f6d..fb4ae7f472547 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
@@ -242,6 +242,8 @@ template <> struct MappingTraits<ClangTidyOptions> {
IO.mapOptional("InheritParentConfig", Options.InheritParentConfig);
IO.mapOptional("UseColor", Options.UseColor);
IO.mapOptional("SystemHeaders", Options.SystemHeaders);
+ IO.mapOptional("ExperimentalHeaderFilterScope",
+ Options.ExperimentalHeaderFilterScope);
IO.mapOptional("CustomChecks", Options.CustomChecks);
}
};
@@ -259,6 +261,7 @@ ClangTidyOptions ClangTidyOptions::getDefaults() {
Options.HeaderFilterRegex = ".*";
Options.ExcludeHeaderFilterRegex = "";
Options.SystemHeaders = false;
+ Options.ExperimentalHeaderFilterScope = false;
Options.FormatStyle = "none";
Options.User = std::nullopt;
Options.RemovedArgs = std::nullopt;
@@ -300,6 +303,8 @@ ClangTidyOptions &ClangTidyOptions::mergeWith(const ClangTidyOptions &Other,
overrideValue(HeaderFilterRegex, Other.HeaderFilterRegex);
overrideValue(ExcludeHeaderFilterRegex, Other.ExcludeHeaderFilterRegex);
overrideValue(SystemHeaders, Other.SystemHeaders);
+ overrideValue(ExperimentalHeaderFilterScope,
+ Other.ExperimentalHeaderFilterScope);
overrideValue(FormatStyle, Other.FormatStyle);
overrideValue(User, Other.User);
overrideValue(UseColor, Other.UseColor);
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.h b/clang-tools-extra/clang-tidy/ClangTidyOptions.h
index 73fdbabd5bdba..4dcf9c10444d5 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.h
@@ -92,6 +92,12 @@ struct ClangTidyOptions {
/// Output warnings from system headers matching \c HeaderFilterRegex.
std::optional<bool> SystemHeaders;
+ /// When set, clang-tidy experimentally skips AST matching for declarations
+ /// in headers that do not match \c HeaderFilterRegex or that match
+ /// \c ExcludeHeaderFilterRegex. Checks that rely on declarations outside the
+ /// filtered headers can produce false negatives.
+ std::optional<bool> ExperimentalHeaderFilterScope;
+
/// Format code around applied fixes with clang-format using this
/// style.
///
diff --git a/clang-tools-extra/clang-tidy/HeaderFilterHelpers.h b/clang-tools-extra/clang-tidy/HeaderFilterHelpers.h
new file mode 100644
index 0000000000000..23fad8b9533ad
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/HeaderFilterHelpers.h
@@ -0,0 +1,64 @@
+//===--- HeaderFilterHelpers.h - clang-tidy header filtering ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HEADERFILTERHELPERS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HEADERFILTERHELPERS_H
+
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Regex.h"
+
+namespace clang::tidy {
+
+/// Evaluates clang-tidy's header filters for source locations and caches the
+/// per-file results for a translation unit.
+class HeaderFilterLocationFilter {
+public:
+ HeaderFilterLocationFilter(llvm::StringRef HeaderFilterRegex,
+ llvm::StringRef ExcludeHeaderFilterRegex)
+ : HeaderFilter(HeaderFilterRegex),
+ ExcludeHeaderFilter(ExcludeHeaderFilterRegex) {}
+
+ /// Returns true when the location should be treated as in scope for
+ /// clang-tidy's header filters.
+ ///
+ /// Main-file locations are always in scope. Invalid locations and locations
+ /// without a FileEntry (such as command-line buffers) are also treated as in
+ /// scope to match clang-tidy's diagnostic filtering behavior.
+ bool shouldInclude(SourceLocation Location, const SourceManager &Sources) {
+ if (!Location.isValid())
+ return true;
+
+ if (Sources.isInMainFile(Location))
+ return true;
+
+ const FileID FID = Sources.getDecomposedExpansionLoc(Location).first;
+ if (const auto It = Cache.find(FID); It != Cache.end())
+ return It->second;
+
+ bool Result = true;
+ if (const OptionalFileEntryRef File = Sources.getFileEntryRefForID(FID)) {
+ const llvm::StringRef FileName = File->getName();
+ Result =
+ HeaderFilter.match(FileName) && !ExcludeHeaderFilter.match(FileName);
+ }
+
+ Cache[FID] = Result;
+ return Result;
+ }
+
+private:
+ llvm::Regex HeaderFilter;
+ llvm::Regex ExcludeHeaderFilter;
+ llvm::DenseMap<FileID, bool> Cache;
+};
+
+} // namespace clang::tidy
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HEADERFILTERHELPERS_H
diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
index f61e2f40ed03b..5ed56e30ccdfc 100644
--- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -63,6 +63,9 @@ Configuration files:
CustomChecks - Array of user defined checks based on
Clang-Query syntax.
ExcludeHeaderFilterRegex - Same as '--exclude-header-filter'.
+ ExperimentalHeaderFilterScope
+ - Same as
+ '--experimental-header-filter-scope'.
ExtraArgs - Same as '--extra-arg'.
ExtraArgsBefore - Same as '--extra-arg-before'.
FormatStyle - Same as '--format-style'.
@@ -95,6 +98,7 @@ Configuration files:
HeaderFileExtensions: ['', 'h','hh','hpp','hxx']
ImplementationFileExtensions: ['c','cc','cpp','cxx']
HeaderFilterRegex: '.*'
+ ExperimentalHeaderFilterScope: false
FormatStyle: none
InheritParentConfig: true
User: user
@@ -158,6 +162,24 @@ option in .clang-tidy file, if any.
cl::init(""),
cl::cat(ClangTidyCategory));
+static cl::opt<bool>
+ ExperimentalHeaderFilterScope("experimental-header-filter-scope",
+ desc(R"(
+When enabled, clang-tidy experimentally skips
+AST matching for declarations in headers that
+do not match -header-filter or that match
+-exclude-header-filter.
+This can improve performance for narrow
+header-filter runs, but checks that rely on
+declarations outside the filtered headers can
+produce false negatives.
+This option overrides the
+'ExperimentalHeaderFilterScope' option in
+.clang-tidy file, if any.
+)"),
+ cl::init(false),
+ cl::cat(ClangTidyCategory));
+
static cl::opt<bool> SystemHeaders("system-headers", desc(R"(
Display the errors from system headers.
This option overrides the 'SystemHeaders' option
@@ -412,6 +434,7 @@ createOptionsProvider(llvm::IntrusiveRefCntPtr<vfs::FileSystem> FS) {
DefaultOptions.HeaderFilterRegex = HeaderFilter;
DefaultOptions.ExcludeHeaderFilterRegex = ExcludeHeaderFilter;
DefaultOptions.SystemHeaders = SystemHeaders;
+ DefaultOptions.ExperimentalHeaderFilterScope = ExperimentalHeaderFilterScope;
DefaultOptions.FormatStyle = FormatStyle;
DefaultOptions.User = llvm::sys::Process::GetEnv("USER");
// USERNAME is used on Windows.
@@ -429,6 +452,9 @@ createOptionsProvider(llvm::IntrusiveRefCntPtr<vfs::FileSystem> FS) {
OverrideOptions.ExcludeHeaderFilterRegex = ExcludeHeaderFilter;
if (SystemHeaders.getNumOccurrences() > 0)
OverrideOptions.SystemHeaders = SystemHeaders;
+ if (ExperimentalHeaderFilterScope.getNumOccurrences() > 0)
+ OverrideOptions.ExperimentalHeaderFilterScope =
+ ExperimentalHeaderFilterScope;
if (FormatStyle.getNumOccurrences() > 0)
OverrideOptions.FormatStyle = FormatStyle;
if (UseColor.getNumOccurrences() > 0)
diff --git a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
index f827ef492f01c..b9a387bf4b8ba 100755
--- a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
+++ b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
@@ -94,6 +94,7 @@ def get_tidy_invocation(
tmpdir: Optional[str],
build_path: str,
header_filter: Optional[str],
+ experimental_header_filter_scope: Optional[bool],
allow_enabling_alpha_checkers: bool,
extra_arg: List[str],
extra_arg_before: List[str],
@@ -117,6 +118,11 @@ def get_tidy_invocation(
start.append(f"--exclude-header-filter={exclude_header_filter}")
if header_filter is not None:
start.append(f"-header-filter={header_filter}")
+ if experimental_header_filter_scope is not None:
+ if experimental_header_filter_scope:
+ start.append("--experimental-header-filter-scope")
+ else:
+ start.append("--experimental-header-filter-scope=false")
if line_filter is not None:
start.append(f"-line-filter={line_filter}")
if use_color is not None:
@@ -378,6 +384,7 @@ async def run_tidy(
tmpdir,
build_path,
args.header_filter,
+ args.experimental_header_filter_scope,
args.allow_enabling_alpha_checkers,
args.extra_arg,
args.extra_arg_before,
@@ -478,6 +485,16 @@ async def main() -> None:
"the main file of each translation unit are always "
"displayed.",
)
+ parser.add_argument(
+ "-experimental-header-filter-scope",
+ type=strtobool,
+ nargs="?",
+ const=True,
+ default=None,
+ help="Enable experimental AST scoping to headers that "
+ "match -header-filter and do not match "
+ "-exclude-header-filter.",
+ )
parser.add_argument(
"-source-filter",
default=None,
@@ -647,6 +664,7 @@ async def main() -> None:
None,
build_path,
args.header_filter,
+ args.experimental_header_filter_scope,
args.allow_enabling_alpha_checkers,
args.extra_arg,
args.extra_arg_before,
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index c0956a29895ee..8c4ee6da63005 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -111,6 +111,13 @@ Improvements to clang-tidy
- Improved :program:`clang-tidy` ``-store-check-profile`` by generating valid
JSON when the source file path contains characters that require JSON escaping.
+- Added an experimental :program:`clang-tidy`
+ ``-experimental-header-filter-scope`` option that skips AST matching for
+ declarations in headers that do not match ``-header-filter`` (or that match
+ ``-exclude-header-filter``). This can improve performance for narrow
+ header-filter runs, but checks that need AST visibility outside the filtered
+ headers can produce false negatives.
+
New checks
^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst
index db7f2deade9ca..7dbb8142ed69e 100644
--- a/clang-tools-extra/docs/clang-tidy/index.rst
+++ b/clang-tools-extra/docs/clang-tidy/index.rst
@@ -185,6 +185,18 @@ An overview of all the command-line options:
Can be used together with -line-filter.
This option overrides the 'ExcludeHeaderFilterRegex'
option in .clang-tidy file, if any.
+ --experimental-header-filter-scope
+ - When enabled, clang-tidy experimentally
+ skips AST matching for declarations in
+ headers that do not match -header-filter
+ or that match -exclude-header-filter.
+ This can improve performance for narrow
+ header-filter runs, but checks that rely
+ on declarations outside the filtered
+ headers can produce false negatives.
+ This option overrides the
+ 'ExperimentalHeaderFilterScope' option in
+ .clang-tidy file, if any.
--experimental-custom-checks - Enable experimental clang-query based
custom checks.
see https://clang.llvm.org/extra/clang-tidy/QueryBasedCustomChecks.html.
@@ -320,6 +332,9 @@ An overview of all the command-line options:
CustomChecks - Array of user defined checks based on
Clang-Query syntax.
ExcludeHeaderFilterRegex - Same as '--exclude-header-filter'.
+ ExperimentalHeaderFilterScope
+ - Same as
+ '--experimental-header-filter-scope'.
ExtraArgs - Same as '--extra-arg'.
ExtraArgsBefore - Same as '--extra-arg-before'.
FormatStyle - Same as '--format-style'.
@@ -352,6 +367,7 @@ An overview of all the command-line options:
HeaderFileExtensions: ['', 'h','hh','hpp','hxx']
ImplementationFileExtensions: ['c','cc','cpp','cxx']
HeaderFilterRegex: '.*'
+ ExperimentalHeaderFilterScope: false
FormatStyle: none
InheritParentConfig: true
User: user
@@ -414,9 +430,9 @@ can be generated by build systems like CMake (using
``-DCMAKE_EXPORT_COMPILE_COMMANDS=ON``) or by tools like `Bear`_.
The script supports most of the same options as :program:`clang-tidy` itself,
-including ``-checks=``, ``-fix``, ``-header-filter=``, and configuration
-options. Run ``run-clang-tidy.py --help`` for a complete list of available
-options.
+including ``-checks=``, ``-fix``, ``-header-filter=``,
+``-experimental-header-filter-scope``, and configuration options. Run
+``run-clang-tidy.py --help`` for a complete list of available options.
Example invocations:
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/.clang-tidy b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/.clang-tidy
index 83605c85dd92c..64da72adc342e 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/.clang-tidy
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/.clang-tidy
@@ -1,3 +1,4 @@
Checks: 'from-parent'
HeaderFilterRegex: 'parent'
ExcludeHeaderFilterRegex: 'exc-parent'
+ExperimentalHeaderFilterScope: true
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/1/.clang-tidy b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/1/.clang-tidy
index c37f16bc2d7d2..1991cd343e076 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/1/.clang-tidy
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/1/.clang-tidy
@@ -1,3 +1,4 @@
Checks: 'from-child1'
HeaderFilterRegex: 'child1'
ExcludeHeaderFilterRegex: 'exc-child1'
+ExperimentalHeaderFilterScope: false
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/3/.clang-tidy b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/3/.clang-tidy
index 9365108255bd8..39831e357b09e 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/3/.clang-tidy
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/3/.clang-tidy
@@ -2,3 +2,4 @@ InheritParentConfig: true
Checks: 'from-child3'
HeaderFilterRegex: 'child3'
ExcludeHeaderFilterRegex: 'exc-child3'
+ExperimentalHeaderFilterScope: false
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/experimental-header-filter-scope/confusable_header.h b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/experimental-header-filter-scope/confusable_header.h
new file mode 100644
index 0000000000000..659f2a3879880
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/experimental-header-filter-scope/confusable_header.h
@@ -0,0 +1 @@
+int l0 = 0;
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp
index 44d43ebbf8d20..f17d6cf138371 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp
@@ -2,22 +2,27 @@
// CHECK-BASE: Checks: {{.*}}from-parent
// CHECK-BASE: HeaderFilterRegex: parent
// CHECK-BASE: ExcludeHeaderFilterRegex: exc-parent
+// CHECK-BASE: ExperimentalHeaderFilterScope: true
// RUN: clang-tidy -dump-config %S/Inputs/config-files/1/- -- | FileCheck %s -check-prefix=CHECK-CHILD1
// CHECK-CHILD1: Checks: {{.*}}from-child1
// CHECK-CHILD1: HeaderFilterRegex: child1
// CHECK-CHILD1: ExcludeHeaderFilterRegex: exc-child1
+// CHECK-CHILD1: ExperimentalHeaderFilterScope: false
// RUN: clang-tidy -dump-config %S/Inputs/config-files/2/- -- | FileCheck %s -check-prefix=CHECK-CHILD2
// CHECK-CHILD2: Checks: {{.*}}from-parent
// CHECK-CHILD2: HeaderFilterRegex: parent
// CHECK-CHILD2: ExcludeHeaderFilterRegex: exc-parent
+// CHECK-CHILD2: ExperimentalHeaderFilterScope: true
// RUN: clang-tidy -dump-config %S/Inputs/config-files/3/- -- | FileCheck %s -check-prefix=CHECK-CHILD3
// CHECK-CHILD3: Checks: {{.*}}from-parent,from-child3
// CHECK-CHILD3: HeaderFilterRegex: child3
// CHECK-CHILD3: ExcludeHeaderFilterRegex: exc-child3
-// RUN: clang-tidy -dump-config -checks='from-command-line' -header-filter='from command line' -exclude-header-filter='from_command_line' %S/Inputs/config-files/- -- | FileCheck %s -check-prefix=CHECK-COMMAND-LINE
+// CHECK-CHILD3: ExperimentalHeaderFilterScope: false
+// RUN: clang-tidy -dump-config -checks='from-command-line' -header-filter='from command line' -exclude-header-filter='from_command_line' -experimental-header-filter-scope=false %S/Inputs/config-files/- -- | FileCheck %s -check-prefix=CHECK-COMMAND-LINE
// CHECK-COMMAND-LINE: Checks: {{.*}}from-parent,from-command-line
// CHECK-COMMAND-LINE: HeaderFilterRegex: from command line
// CHECK-COMMAND-LINE: ExcludeHeaderFilterRegex: from_command_line
+// CHECK-COMMAND-LINE: ExperimentalHeaderFilterScope: false
// For this test we have to use names of the real checks because otherwise values are ignored.
// Running with the old key: <Key>, value: <value> CheckOptions
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp
index a9d140bc9318e..b31f57fed9eab 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp
@@ -1,4 +1,5 @@
// RUN: not clang-tidy -checks='-*,modernize-use-override' %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK1 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: not clang-tidy -checks='-*,modernize-use-override' -header-filter='' -experimental-header-filter-scope %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK1 -implicit-check-not='{{warning:|error:}}' %s
// RUN: not clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK2 -implicit-check-not='{{warning:|error:}}' %s
// RUN: not clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK3 -implicit-check-not='{{warning:|error:}}' %s
// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s
@@ -6,6 +7,7 @@
//
// Now repeat the tests and ensure no other errors appear on stderr:
// RUN: not clang-tidy -checks='-*,modernize-use-override' %s.nonexistent.cpp -- 2>&1 | FileCheck -check-prefix=CHECK1 -implicit-check-not='{{warning:|error:}}' %s
+// RUN: not clang-tidy -checks='-*,modernize-use-override' -header-filter='' -experimental-header-filter-scope %s.nonexistent.cpp -- 2>&1 | FileCheck -check-prefix=CHECK1 -implicit-check-not='{{warning:|error:}}' %s
// RUN: not clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' %s -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK2 -implicit-check-not='{{warning:|error:}}' %s
// RUN: not clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK3 -implicit-check-not='{{warning:|error:}}' %s
// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE 2>&1 | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/dump-config-filtering.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/dump-config-filtering.cpp
index f22ec7edb1775..5f88968a3d163 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/dump-config-filtering.cpp
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/dump-config-filtering.cpp
@@ -5,8 +5,10 @@
// CHECK-NEXT: misc-unused-parameters.IgnoreVirtual: 'false'
// CHECK-NEXT: misc-unused-parameters.StrictMode: 'false'
// CHECK-NEXT: SystemHeaders: false
+// CHECK-NEXT: ExperimentalHeaderFilterScope: false
// CHECK-DISABLED: CheckOptions: {}
// CHECK-DISABLED-NEXT: SystemHeaders: false
+// CHECK-DISABLED-NEXT: ExperimentalHeaderFilterScope: false
int main() { return 0; }
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/experimental-header-filter-scope.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/experimental-header-filter-scope.cpp
new file mode 100644
index 0000000000000..efac1950302ee
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/experimental-header-filter-scope.cpp
@@ -0,0 +1,16 @@
+// RUN: clang-tidy -checks='-*,misc-confusable-identifiers' -header-filter='does-not-match' %s -- -I %S/Inputs/experimental-header-filter-scope 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT
+// RUN: clang-tidy -checks='-*,misc-confusable-identifiers' -header-filter='does-not-match' -experimental-header-filter-scope %s -- -I %S/Inputs/experimental-header-filter-scope 2>&1 | FileCheck %s --check-prefix=CHECK-CLI --allow-empty
+// RUN: clang-tidy -checks='-*,misc-confusable-identifiers' -header-filter='.*' -exclude-header-filter='confusable_header\.h' %s -- -I %S/Inputs/experimental-header-filter-scope 2>&1 | FileCheck %s --check-prefix=CHECK-EXCLUDE
+// RUN: clang-tidy -checks='-*,misc-confusable-identifiers' -header-filter='.*' -exclude-header-filter='confusable_header\.h' -config='{ExperimentalHeaderFilterScope: true}' %s -- -I %S/Inputs/experimental-header-filter-scope 2>&1 | FileCheck %s --check-prefix=CHECK-CONFIG --allow-empty
+// RUN: clang-tidy -checks='-*,misc-confusable-identifiers' -header-filter='does-not-match' -line-filter='[{"name":"experimental-header-filter-scope.cpp","lines":[[1,20]]}]' %s -- -I %S/Inputs/experimental-header-filter-scope 2>&1 | FileCheck %s --check-prefix=CHECK-LINE-FILTER
+// RUN: clang-tidy -checks='-*,misc-confusable-identifiers' -header-filter='does-not-match' -line-filter='[{"name":"experimental-header-filter-scope.cpp","lines":[[1,20]]}]' -experimental-header-filter-scope %s -- -I %S/Inputs/experimental-header-filter-scope 2>&1 | FileCheck %s --check-prefix=CHECK-LINE-FILTER-SCOPED --allow-empty
+
+#include "confusable_header.h"
+
+int lO = 1;
+// CHECK-DEFAULT: :[[@LINE-1]]:5: warning: 'lO' is confusable with 'l0' [misc-confusable-identifiers]
+// CHECK-CLI-NOT: warning:
+// CHECK-EXCLUDE: :[[@LINE-3]]:5: warning: 'lO' is confusable with 'l0' [misc-confusable-identifiers]
+// CHECK-CONFIG-NOT: warning:
+// CHECK-LINE-FILTER: :[[@LINE-5]]:5: warning: 'lO' is confusable with 'l0' [misc-confusable-identifiers]
+// CHECK-LINE-FILTER-SCOPED-NOT: warning:
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/run-clang-tidy.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/run-clang-tidy.cpp
index 6337686c58518..31b71a331a7ff 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/run-clang-tidy.cpp
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/run-clang-tidy.cpp
@@ -14,6 +14,21 @@
// RUN: not %run_clang_tidy -j 1 "test.cpp" 2>&1 | FileCheck %s --check-prefix=CHECK-J1
// CHECK-J1: Running clang-tidy in 1 threads for
+// RUN: rm -rf %t-scope
+// RUN: mkdir -p %t-scope/include
+// RUN: echo "[{\"directory\":\".\",\"command\":\"clang++ -c %/t-scope/test.cpp -I%/t-scope/include\",\"file\":\"%/t-scope/test.cpp\"}]" | sed -e 's/\\/\\\\/g' > %t-scope/compile_commands.json
+// RUN: echo "Checks: '-*,misc-confusable-identifiers'" > %t-scope/.clang-tidy
+// RUN: echo "WarningsAsErrors: '*'" >> %t-scope/.clang-tidy
+// RUN: echo "int l0 = 0;" > %t-scope/include/confusable_header.h
+// RUN: echo '#include "confusable_header.h"' > %t-scope/test.cpp
+// RUN: echo 'int lO = 1;' >> %t-scope/test.cpp
+// RUN: cd "%t-scope"
+// RUN: not %run_clang_tidy -j 1 -header-filter=does-not-match "test.cpp" 2>&1 | FileCheck %s --check-prefix=CHECK-SCOPE-OFF
+// RUN: %run_clang_tidy -j 1 -header-filter=does-not-match -experimental-header-filter-scope=true "test.cpp" 2>&1 | FileCheck %s --check-prefix=CHECK-SCOPE-ON
+// CHECK-SCOPE-OFF: 'lO' is confusable with 'l0'
+// CHECK-SCOPE-ON: Running clang-tidy in 1 threads for 1 files out of 1 in compilation database
+// CHECK-SCOPE-ON-NOT: 'lO' is confusable with 'l0'
+
int main()
{
int* x = new int();
diff --git a/clang/include/clang/ASTMatchers/ASTMatchFinder.h b/clang/include/clang/ASTMatchers/ASTMatchFinder.h
index b0ccbf22a4269..43ba90062be70 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchFinder.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -44,6 +44,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Timer.h"
+#include <functional>
#include <optional>
namespace clang {
@@ -145,6 +146,13 @@ class MatchFinder {
/// Avoids matching declarations in system headers.
bool IgnoreSystemHeaders{false};
+ /// Skips matching and traversal for declarations based on location.
+ ///
+ /// When set and the callback returns true, the declaration subtree is
+ /// skipped entirely. The callback is consulted after system-header
+ /// filtering and only for declarations with a valid source location.
+ std::function<bool(SourceLocation)> ShouldSkipLocation;
+
bool SkipDeclsInModules{false};
};
diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
index 004a02c279099..107347b459ec5 100644
--- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -1366,10 +1366,19 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
return SM.isInSystemHeader(Loc);
}
- template <typename T> bool shouldSkipNode(T &Node) {
- if (Options.IgnoreSystemHeaders && isInSystemHeader(getNodeLocation(Node)))
+ bool shouldSkipNode(Decl &Node) {
+ if (shouldSkipSystemHeaders(Node))
return true;
- return false;
+
+ if (!Options.ShouldSkipLocation)
+ return false;
+
+ SourceLocation Loc = getNodeLocation(Node);
+ return Loc.isValid() && Options.ShouldSkipLocation(Loc);
+ }
+
+ template <typename T> bool shouldSkipNode(T &Node) {
+ return shouldSkipSystemHeaders(Node);
}
template <typename T> bool shouldSkipNode(T *Node) {
@@ -1380,6 +1389,12 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
bool shouldSkipNode(NestedNameSpecifier &) { return false; }
+ template <typename T> bool shouldSkipSystemHeaders(T &Node) {
+ if (Options.IgnoreSystemHeaders && isInSystemHeader(getNodeLocation(Node)))
+ return true;
+ return false;
+ }
+
/// Bucket to record map.
///
/// Used to get the appropriate bucket for each matcher.
diff --git a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
index 3fa71804710ac..9e13302005572 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
@@ -345,6 +345,56 @@ TEST(IsInlineMatcher, IsInline) {
// Windows.
#ifndef _WIN32
+TEST(MatchFinder, HonorsShouldSkipLocation) {
+ FileContentMappings M;
+ M.emplace_back("/other.h", "class HeaderDecl {};");
+ auto AST = tooling::buildASTFromCodeWithArgs(
+ "#include \"other.h\"\n"
+ "class MainDecl {};\n",
+ {"-std=gnu++11", "-target", "i386-unknown-unknown", "-I/"},
+ "input.cc", "clang-tool", std::make_shared<PCHContainerOperations>(),
+ tooling::getClangStripDependencyFileAdjuster(), M);
+ ASSERT_TRUE(AST);
+
+ auto matchRecordDecls = [&](MatchFinder::MatchFinderOptions Options) {
+ struct RecordCallback : MatchFinder::MatchCallback {
+ explicit RecordCallback(std::vector<std::string> &Names) : Names(Names) {}
+
+ void run(const MatchFinder::MatchResult &Result) override {
+ const auto *Record = Result.Nodes.getNodeAs<CXXRecordDecl>("record");
+ ASSERT_NE(nullptr, Record);
+ Names.push_back(std::string(Record->getName()));
+ }
+
+ std::vector<std::string> &Names;
+ };
+
+ std::vector<std::string> Names;
+ RecordCallback Callback(Names);
+ MatchFinder Finder(std::move(Options));
+ Finder.addMatcher(cxxRecordDecl(isDefinition(), unless(isImplicit()))
+ .bind("record"),
+ &Callback);
+ Finder.matchAST(AST->getASTContext());
+ llvm::sort(Names);
+ return Names;
+ };
+
+ const auto AllMatches = matchRecordDecls({});
+ ASSERT_EQ(2u, AllMatches.size());
+ EXPECT_EQ("HeaderDecl", AllMatches[0]);
+ EXPECT_EQ("MainDecl", AllMatches[1]);
+
+ MatchFinder::MatchFinderOptions ScopedOptions;
+ SourceManager &SM = AST->getSourceManager();
+ ScopedOptions.ShouldSkipLocation = [&SM](SourceLocation Location) {
+ return !SM.isInMainFile(Location);
+ };
+ const auto ScopedMatches = matchRecordDecls(std::move(ScopedOptions));
+ ASSERT_EQ(1u, ScopedMatches.size());
+ EXPECT_EQ("MainDecl", ScopedMatches[0]);
+}
+
TEST(Matcher, IsExpansionInMainFileMatcher) {
EXPECT_TRUE(matches("class X {};",
recordDecl(hasName("X"), isExpansionInMainFile())));
>From 1c1f26c310f92526179556a3b0b1708d5e97d3aa Mon Sep 17 00:00:00 2001
From: Vladimir Makaev <vmakaev at gmail.com>
Date: Mon, 27 Apr 2026 13:49:57 +0000
Subject: [PATCH 2/2] [clang-tidy] Fix formatting
---
clang-tools-extra/clang-tidy/ClangTidy.cpp | 8 ++++----
.../clang-tidy/ClangTidyDiagnosticConsumer.cpp | 6 +++---
clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp | 6 ++----
.../unittests/ASTMatchers/ASTMatchersInternalTest.cpp | 10 +++++-----
4 files changed, 14 insertions(+), 16 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp
index 3292dc44b3539..e2a9d41600736 100644
--- a/clang-tools-extra/clang-tidy/ClangTidy.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp
@@ -453,10 +453,10 @@ ClangTidyASTConsumerFactory::createASTConsumer(CompilerInstance &Compiler,
auto LocationFilter = std::make_shared<HeaderFilterLocationFilter>(
Context.getOptions().HeaderFilterRegex.value_or(""),
Context.getOptions().ExcludeHeaderFilterRegex.value_or(""));
- FinderOptions.ShouldSkipLocation =
- [LocationFilter, SM](SourceLocation Location) {
- return !LocationFilter->shouldInclude(Location, *SM);
- };
+ FinderOptions.ShouldSkipLocation = [LocationFilter,
+ SM](SourceLocation Location) {
+ return !LocationFilter->shouldInclude(Location, *SM);
+ };
}
auto Finder =
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index 6b3569f7cad9e..d35cd954e1fd7 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -580,9 +580,9 @@ void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
(Sources.isInSystemHeader(Location) || Sources.isInSystemMacro(Location)))
return;
- LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
- getHeaderFilterLocationFilter().shouldInclude(
- Location, Sources);
+ LastErrorRelatesToUserCode =
+ LastErrorRelatesToUserCode ||
+ getHeaderFilterLocationFilter().shouldInclude(Location, Sources);
// FIXME: We start with a conservative approach here, but the actual type of
// location needed depends on the check (in particular, where this check wants
diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
index 5ed56e30ccdfc..e5757528eef38 100644
--- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -163,8 +163,7 @@ option in .clang-tidy file, if any.
cl::cat(ClangTidyCategory));
static cl::opt<bool>
- ExperimentalHeaderFilterScope("experimental-header-filter-scope",
- desc(R"(
+ ExperimentalHeaderFilterScope("experimental-header-filter-scope", desc(R"(
When enabled, clang-tidy experimentally skips
AST matching for declarations in headers that
do not match -header-filter or that match
@@ -177,8 +176,7 @@ This option overrides the
'ExperimentalHeaderFilterScope' option in
.clang-tidy file, if any.
)"),
- cl::init(false),
- cl::cat(ClangTidyCategory));
+ cl::init(false), cl::cat(ClangTidyCategory));
static cl::opt<bool> SystemHeaders("system-headers", desc(R"(
Display the errors from system headers.
diff --git a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
index 9e13302005572..1fc184fd6de48 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
@@ -351,8 +351,8 @@ TEST(MatchFinder, HonorsShouldSkipLocation) {
auto AST = tooling::buildASTFromCodeWithArgs(
"#include \"other.h\"\n"
"class MainDecl {};\n",
- {"-std=gnu++11", "-target", "i386-unknown-unknown", "-I/"},
- "input.cc", "clang-tool", std::make_shared<PCHContainerOperations>(),
+ {"-std=gnu++11", "-target", "i386-unknown-unknown", "-I/"}, "input.cc",
+ "clang-tool", std::make_shared<PCHContainerOperations>(),
tooling::getClangStripDependencyFileAdjuster(), M);
ASSERT_TRUE(AST);
@@ -372,9 +372,9 @@ TEST(MatchFinder, HonorsShouldSkipLocation) {
std::vector<std::string> Names;
RecordCallback Callback(Names);
MatchFinder Finder(std::move(Options));
- Finder.addMatcher(cxxRecordDecl(isDefinition(), unless(isImplicit()))
- .bind("record"),
- &Callback);
+ Finder.addMatcher(
+ cxxRecordDecl(isDefinition(), unless(isImplicit())).bind("record"),
+ &Callback);
Finder.matchAST(AST->getASTContext());
llvm::sort(Names);
return Names;
More information about the cfe-commits
mailing list