[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
Justin Cady via cfe-commits
cfe-commits at lists.llvm.org
Thu May 9 10:28:07 PDT 2024
https://github.com/justincady updated https://github.com/llvm/llvm-project/pull/91400
>From a5de583aa94ef794a083c8b27df6dc6fc0762cb7 Mon Sep 17 00:00:00 2001
From: Justin Cady <desk at justincady.com>
Date: Tue, 7 May 2024 16:54:35 -0400
Subject: [PATCH 1/3] Add option to exclude headers from clang-tidy analysis
This is a renewed attempt to land @toddlipcon's D34654. The comments on
that patch indicate a broad desire for some ability to ignore headers.
After considering various options, including migrating to std::regex, I
believe this is the best path forward. It's intuitive to have separate
regexes for including headers versus excluding them, and this approach
has the added benefit of being completely opt-in. No existing configs
will break, regardless of existing HeaderFilterRegex values.
This functionality is useful for improving performance when analyzing a
targeted subset of code, as well as in cases where some collection of
headers cannot be modified (third party source, for example).
---
.../clang-tidy/ClangTidyDiagnosticConsumer.cpp | 10 +++++++++-
.../clang-tidy/ClangTidyDiagnosticConsumer.h | 5 +++++
.../clang-tidy/ClangTidyOptions.cpp | 4 ++++
clang-tools-extra/clang-tidy/ClangTidyOptions.h | 4 ++++
.../clang-tidy/tool/ClangTidyMain.cpp | 16 ++++++++++++++++
.../clang-tidy/infrastructure/file-filter.cpp | 7 +++++++
6 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index de2a3b51422a5..3cde0d2d68874 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -564,7 +564,8 @@ void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
StringRef FileName(File->getName());
LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
Sources.isInMainFile(Location) ||
- getHeaderFilter()->match(FileName);
+ (getHeaderFilter()->match(FileName) &&
+ !getExcludeHeaderFilter()->match(FileName));
unsigned LineNumber = Sources.getExpansionLineNumber(Location);
LastErrorPassesLineFilter =
@@ -578,6 +579,13 @@ llvm::Regex *ClangTidyDiagnosticConsumer::getHeaderFilter() {
return HeaderFilter.get();
}
+llvm::Regex *ClangTidyDiagnosticConsumer::getExcludeHeaderFilter() {
+ if (!ExcludeHeaderFilter)
+ ExcludeHeaderFilter = std::make_unique<llvm::Regex>(
+ *Context.getOptions().ExcludeHeaderFilterRegex);
+ return ExcludeHeaderFilter.get();
+}
+
void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
// Each error is modelled as the set of intervals in which it applies
// replacements. To detect overlapping replacements, we use a sweep line
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
index 9280eb1e1f218..a3add5d52778d 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -299,6 +299,10 @@ class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
/// context.
llvm::Regex *getHeaderFilter();
+ /// \brief Returns the \c ExcludeHeaderFilter constructed for the options set
+ /// in the context.
+ llvm::Regex *getExcludeHeaderFilter();
+
/// Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
/// according to the diagnostic \p Location.
void checkFilters(SourceLocation Location, const SourceManager &Sources);
@@ -313,6 +317,7 @@ class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
bool EnableNolintBlocks;
std::vector<ClangTidyError> Errors;
std::unique_ptr<llvm::Regex> HeaderFilter;
+ std::unique_ptr<llvm::Regex> ExcludeHeaderFilter;
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 cbf21a0e2ae34..254ce7fc60fc9 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
@@ -170,6 +170,8 @@ template <> struct MappingTraits<ClangTidyOptions> {
IO.mapOptional("ImplementationFileExtensions",
Options.ImplementationFileExtensions);
IO.mapOptional("HeaderFilterRegex", Options.HeaderFilterRegex);
+ IO.mapOptional("ExcludeHeaderFilterRegex",
+ Options.ExcludeHeaderFilterRegex);
IO.mapOptional("FormatStyle", Options.FormatStyle);
IO.mapOptional("User", Options.User);
IO.mapOptional("CheckOptions", Options.CheckOptions);
@@ -192,6 +194,7 @@ ClangTidyOptions ClangTidyOptions::getDefaults() {
Options.HeaderFileExtensions = {"", "h", "hh", "hpp", "hxx"};
Options.ImplementationFileExtensions = {"c", "cc", "cpp", "cxx"};
Options.HeaderFilterRegex = "";
+ Options.ExcludeHeaderFilterRegex = "";
Options.SystemHeaders = false;
Options.FormatStyle = "none";
Options.User = std::nullopt;
@@ -231,6 +234,7 @@ ClangTidyOptions &ClangTidyOptions::mergeWith(const ClangTidyOptions &Other,
overrideValue(ImplementationFileExtensions,
Other.ImplementationFileExtensions);
overrideValue(HeaderFilterRegex, Other.HeaderFilterRegex);
+ overrideValue(ExcludeHeaderFilterRegex, Other.ExcludeHeaderFilterRegex);
overrideValue(SystemHeaders, Other.SystemHeaders);
overrideValue(FormatStyle, Other.FormatStyle);
overrideValue(User, Other.User);
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.h b/clang-tools-extra/clang-tidy/ClangTidyOptions.h
index e7636cb5d9b06..85d5a02ebbc1b 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.h
@@ -83,6 +83,10 @@ struct ClangTidyOptions {
/// main files will always be displayed.
std::optional<std::string> HeaderFilterRegex;
+ /// \brief Exclude warnings from headers matching this filter, even if they
+ /// match \c HeaderFilterRegex.
+ std::optional<std::string> ExcludeHeaderFilterRegex;
+
/// Output warnings from system headers matching \c HeaderFilterRegex.
std::optional<bool> SystemHeaders;
diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
index f82f4417141d3..88c69a9991d26 100644
--- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -132,6 +132,19 @@ option in .clang-tidy file, if any.
cl::init(""),
cl::cat(ClangTidyCategory));
+static cl::opt<std::string> ExcludeHeaderFilter("exclude-header-filter",
+ cl::desc(R"(
+Regular expression matching the names of the
+headers to exclude diagnostics from. Diagnostics
+from the main file of each translation unit are
+always displayed.
+Can be used together with -line-filter.
+This option overrides the 'ExcludeHeaderFilterRegex'
+option in .clang-tidy file, if any.
+)"),
+ cl::init(""),
+ cl::cat(ClangTidyCategory));
+
static cl::opt<bool> SystemHeaders("system-headers", desc(R"(
Display the errors from system headers.
This option overrides the 'SystemHeaders' option
@@ -353,6 +366,7 @@ static std::unique_ptr<ClangTidyOptionsProvider> createOptionsProvider(
DefaultOptions.Checks = DefaultChecks;
DefaultOptions.WarningsAsErrors = "";
DefaultOptions.HeaderFilterRegex = HeaderFilter;
+ DefaultOptions.ExcludeHeaderFilterRegex = ExcludeHeaderFilter;
DefaultOptions.SystemHeaders = SystemHeaders;
DefaultOptions.FormatStyle = FormatStyle;
DefaultOptions.User = llvm::sys::Process::GetEnv("USER");
@@ -367,6 +381,8 @@ static std::unique_ptr<ClangTidyOptionsProvider> createOptionsProvider(
OverrideOptions.WarningsAsErrors = WarningsAsErrors;
if (HeaderFilter.getNumOccurrences() > 0)
OverrideOptions.HeaderFilterRegex = HeaderFilter;
+ if (ExcludeHeaderFilter.getNumOccurrences() > 0)
+ OverrideOptions.ExcludeHeaderFilterRegex = ExcludeHeaderFilter;
if (SystemHeaders.getNumOccurrences() > 0)
OverrideOptions.SystemHeaders = SystemHeaders;
if (FormatStyle.getNumOccurrences() > 0)
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/file-filter.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/file-filter.cpp
index a7498723de2bf..448ef9ddf166c 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/file-filter.cpp
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/file-filter.cpp
@@ -11,6 +11,7 @@
// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -system-headers -quiet %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK4-QUIET %s
// RUN: clang-tidy -checks='-*,cppcoreguidelines-pro-type-cstyle-cast' -header-filter='.*' -system-headers %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK5 %s
// RUN: clang-tidy -checks='-*,cppcoreguidelines-pro-type-cstyle-cast' -header-filter='.*' %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK5-NO-SYSTEM-HEADERS %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -exclude-header-filter='header1\.h' %s -- -I %S/Inputs/file-filter/ -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK6 %s
#include "header1.h"
// CHECK-NOT: warning:
@@ -21,6 +22,7 @@
// CHECK3-QUIET-NOT: warning:
// CHECK4: header1.h:1:12: warning: single-argument constructors
// CHECK4-QUIET: header1.h:1:12: warning: single-argument constructors
+// CHECK6-NOT: warning:
#include "header2.h"
// CHECK-NOT: warning:
@@ -31,6 +33,7 @@
// CHECK3-QUIET: header2.h:1:12: warning: single-argument constructors
// CHECK4: header2.h:1:12: warning: single-argument constructors
// CHECK4-QUIET: header2.h:1:12: warning: single-argument constructors
+// CHECK6: header2.h:1:12: warning: single-argument constructors
#include <system-header.h>
// CHECK-NOT: warning:
@@ -41,6 +44,7 @@
// CHECK3-QUIET-NOT: warning:
// CHECK4: system-header.h:1:12: warning: single-argument constructors
// CHECK4-QUIET: system-header.h:1:12: warning: single-argument constructors
+// CHECK6-NOT: warning:
class A { A(int); };
// CHECK: :[[@LINE-1]]:11: warning: single-argument constructors
@@ -51,6 +55,7 @@ class A { A(int); };
// CHECK3-QUIET: :[[@LINE-6]]:11: warning: single-argument constructors
// CHECK4: :[[@LINE-7]]:11: warning: single-argument constructors
// CHECK4-QUIET: :[[@LINE-8]]:11: warning: single-argument constructors
+// CHECK6: :[[@LINE-9]]:11: warning: single-argument constructors
// CHECK-NOT: warning:
// CHECK-QUIET-NOT: warning:
@@ -73,6 +78,8 @@ class A { A(int); };
// CHECK4-NOT: Suppressed {{.*}} warnings
// CHECK4-NOT: Use -header-filter=.* {{.*}}
// CHECK4-QUIET-NOT: Suppressed
+// CHECK6: Suppressed 2 warnings (2 in non-user code)
+// CHECK6: Use -header-filter=.* {{.*}}
int x = 123;
auto x_ptr = TO_FLOAT_PTR(&x);
>From c8823c82c6e1669af8505440aae9099b714c55c8 Mon Sep 17 00:00:00 2001
From: Justin Cady <desk at justincady.com>
Date: Wed, 8 May 2024 16:12:40 -0400
Subject: [PATCH 2/3] * Avoid matching on the ExcludeHeaderFilterRegex if it
was not specified by the user * Update Python wrapper to handle
`--exclude-header-filter` * Update both release notes and clang-tidy
documentation
---
.../ClangTidyDiagnosticConsumer.cpp | 22 +-
.../clang-tidy/ClangTidyDiagnosticConsumer.h | 4 -
.../clang-tidy/ClangTidyOptions.cpp | 2 +-
.../clang-tidy/tool/ClangTidyMain.cpp | 3 +-
.../clang-tidy/tool/run-clang-tidy.py | 13 +
clang-tools-extra/docs/ReleaseNotes.rst | 2 +
clang-tools-extra/docs/clang-tidy/index.rst | 234 +++++++++---------
7 files changed, 149 insertions(+), 131 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index 3cde0d2d68874..d9352dafec23f 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -311,7 +311,12 @@ ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(
: Context(Ctx), ExternalDiagEngine(ExternalDiagEngine),
RemoveIncompatibleErrors(RemoveIncompatibleErrors),
GetFixesFromNotes(GetFixesFromNotes),
- EnableNolintBlocks(EnableNolintBlocks) {}
+ EnableNolintBlocks(EnableNolintBlocks) {
+
+ if (Context.getOptions().ExcludeHeaderFilterRegex)
+ ExcludeHeaderFilter = std::make_unique<llvm::Regex>(
+ *Context.getOptions().ExcludeHeaderFilterRegex);
+}
void ClangTidyDiagnosticConsumer::finalizeLastError() {
if (!Errors.empty()) {
@@ -562,10 +567,10 @@ void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
}
StringRef FileName(File->getName());
- LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
- Sources.isInMainFile(Location) ||
- (getHeaderFilter()->match(FileName) &&
- !getExcludeHeaderFilter()->match(FileName));
+ LastErrorRelatesToUserCode =
+ LastErrorRelatesToUserCode || Sources.isInMainFile(Location) ||
+ (getHeaderFilter()->match(FileName) &&
+ (ExcludeHeaderFilter ? !ExcludeHeaderFilter->match(FileName) : true));
unsigned LineNumber = Sources.getExpansionLineNumber(Location);
LastErrorPassesLineFilter =
@@ -579,13 +584,6 @@ llvm::Regex *ClangTidyDiagnosticConsumer::getHeaderFilter() {
return HeaderFilter.get();
}
-llvm::Regex *ClangTidyDiagnosticConsumer::getExcludeHeaderFilter() {
- if (!ExcludeHeaderFilter)
- ExcludeHeaderFilter = std::make_unique<llvm::Regex>(
- *Context.getOptions().ExcludeHeaderFilterRegex);
- return ExcludeHeaderFilter.get();
-}
-
void ClangTidyDiagnosticConsumer::removeIncompatibleErrors() {
// Each error is modelled as the set of intervals in which it applies
// replacements. To detect overlapping replacements, we use a sweep line
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
index a3add5d52778d..97e16a12febd0 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -299,10 +299,6 @@ class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
/// context.
llvm::Regex *getHeaderFilter();
- /// \brief Returns the \c ExcludeHeaderFilter constructed for the options set
- /// in the context.
- llvm::Regex *getExcludeHeaderFilter();
-
/// Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
/// according to the diagnostic \p Location.
void checkFilters(SourceLocation Location, const SourceManager &Sources);
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
index 254ce7fc60fc9..ef98b7ef6e0cd 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
@@ -194,7 +194,7 @@ ClangTidyOptions ClangTidyOptions::getDefaults() {
Options.HeaderFileExtensions = {"", "h", "hh", "hpp", "hxx"};
Options.ImplementationFileExtensions = {"c", "cc", "cpp", "cxx"};
Options.HeaderFilterRegex = "";
- Options.ExcludeHeaderFilterRegex = "";
+ Options.ExcludeHeaderFilterRegex = std::nullopt;
Options.SystemHeaders = false;
Options.FormatStyle = "none";
Options.User = std::nullopt;
diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
index 88c69a9991d26..b449c2ed50bd1 100644
--- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -53,6 +53,7 @@ Configuration files:
Checks - Same as '--checks'. Additionally, the list of
globs can be specified as a list instead of a
string.
+ ExcludeHeaderFilterRegex - Same as '--exclude-header-filter'.
ExtraArgs - Same as '--extra-args'.
ExtraArgsBefore - Same as '--extra-args-before'.
FormatStyle - Same as '--format-style'.
@@ -133,7 +134,7 @@ option in .clang-tidy file, if any.
cl::cat(ClangTidyCategory));
static cl::opt<std::string> ExcludeHeaderFilter("exclude-header-filter",
- cl::desc(R"(
+ desc(R"(
Regular expression matching the names of the
headers to exclude diagnostics from. Diagnostics
from the main file of each translation unit are
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 1bd4a5b283091..f9750b2a2c56d 100755
--- a/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
+++ b/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
@@ -106,11 +106,14 @@ def get_tidy_invocation(
use_color,
plugins,
warnings_as_errors,
+ exclude_header_filter,
):
"""Gets a command line for clang-tidy."""
start = [clang_tidy_binary]
if allow_enabling_alpha_checkers:
start.append("-allow-enabling-analyzer-alpha-checkers")
+ if exclude_header_filter is not None:
+ start.append("--exclude-header-filter=" + exclude_header_filter)
if header_filter is not None:
start.append("-header-filter=" + header_filter)
if line_filter is not None:
@@ -228,6 +231,7 @@ def run_tidy(args, clang_tidy_binary, tmpdir, build_path, queue, lock, failed_fi
args.use_color,
args.plugins,
args.warnings_as_errors,
+ args.exclude_header_filter,
)
proc = subprocess.Popen(
@@ -292,6 +296,14 @@ def main():
"-config option after reading specified config file. "
"Use either -config-file or -config, not both.",
)
+ parser.add_argument(
+ "-exclude-header-filter",
+ default=None,
+ help="regular expression matching the names of the "
+ "headers to exclude diagnostics from. Diagnostics from "
+ "the main file of each translation unit are always "
+ "displayed.",
+ )
parser.add_argument(
"-header-filter",
default=None,
@@ -450,6 +462,7 @@ def main():
args.use_color,
args.plugins,
args.warnings_as_errors,
+ args.exclude_header_filter,
)
invocation.append("-list-checks")
invocation.append("-")
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 5d6d0351362e4..2e093ea1d44fe 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -113,6 +113,8 @@ Improvements to clang-tidy
- Fixed `--verify-config` option not properly parsing checks when using the
literal operator in the `.clang-tidy` config.
+- Added argument `--exclude-header-filter` to exclude headers from analysis via a RegEx.
+
New checks
^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst
index 852566f266723..f674ebfc273b5 100644
--- a/clang-tools-extra/docs/clang-tidy/index.rst
+++ b/clang-tools-extra/docs/clang-tidy/index.rst
@@ -116,122 +116,129 @@ An overview of all the command-line options:
Generic Options:
- --help - Display available options (--help-hidden for more)
- --help-list - Display list of available options (--help-list-hidden for more)
- --version - Display the version of this program
+ --help - Display available options (--help-hidden for more)
+ --help-list - Display list of available options (--help-list-hidden for more)
+ --version - Display the version of this program
clang-tidy options:
- --checks=<string> - Comma-separated list of globs with optional '-'
- prefix. Globs are processed in order of
- appearance in the list. Globs without '-'
- prefix add checks with matching names to the
- set, globs with the '-' prefix remove checks
- with matching names from the set of enabled
- checks. This option's value is appended to the
- value of the 'Checks' option in .clang-tidy
- file, if any.
- --config=<string> - Specifies a configuration in YAML/JSON format:
- -config="{Checks: '*',
- CheckOptions: {x: y}}"
- When the value is empty, clang-tidy will
- attempt to find a file named .clang-tidy for
- each source file in its parent directories.
- --config-file=<string> - Specify the path of .clang-tidy or custom config file:
- e.g. --config-file=/some/path/myTidyConfigFile
- This option internally works exactly the same way as
- --config option after reading specified config file.
- Use either --config-file or --config, not both.
- --dump-config - Dumps configuration in the YAML format to
- stdout. This option can be used along with a
- file name (and '--' if the file is outside of a
- project with configured compilation database).
- The configuration used for this file will be
- printed.
- Use along with -checks=* to include
- configuration of all checks.
- --enable-check-profile - Enable per-check timing profiles, and print a
- report to stderr.
- --enable-module-headers-parsing - Enables preprocessor-level module header parsing
- for C++20 and above, empowering specific checks
- to detect macro definitions within modules. This
- feature may cause performance and parsing issues
- and is therefore considered experimental.
- --explain-config - For each enabled check explains, where it is
- enabled, i.e. in clang-tidy binary, command
- line or a specific configuration file.
- --export-fixes=<filename> - YAML file to store suggested fixes in. The
- stored fixes can be applied to the input source
- code with clang-apply-replacements.
- --extra-arg=<string> - Additional argument to append to the compiler command line
- --extra-arg-before=<string> - Additional argument to prepend to the compiler command line
- --fix - Apply suggested fixes. Without -fix-errors
- clang-tidy will bail out if any compilation
- errors were found.
- --fix-errors - Apply suggested fixes even if compilation
- errors were found. If compiler errors have
- attached fix-its, clang-tidy will apply them as
- well.
- --fix-notes - If a warning has no fix, but a single fix can
- be found through an associated diagnostic note,
- apply the fix.
- Specifying this flag will implicitly enable the
- '--fix' flag.
- --format-style=<string> - Style for formatting code around applied fixes:
- - 'none' (default) turns off formatting
- - 'file' (literally 'file', not a placeholder)
- uses .clang-format file in the closest parent
- directory
- - '{ <json> }' specifies options inline, e.g.
- -format-style='{BasedOnStyle: llvm, IndentWidth: 8}'
- - 'llvm', 'google', 'webkit', 'mozilla'
- See clang-format documentation for the up-to-date
- information about formatting styles and options.
- This option overrides the 'FormatStyle` option in
- .clang-tidy file, if any.
- --header-filter=<string> - Regular expression matching the names of the
- headers to output diagnostics from. Diagnostics
- from the main file of each translation unit are
- always displayed.
- Can be used together with -line-filter.
- This option overrides the 'HeaderFilterRegex'
- option in .clang-tidy file, if any.
- --line-filter=<string> - List of files with line ranges to filter the
- warnings. Can be used together with
- -header-filter. The format of the list is a
- JSON array of objects:
- [
- {"name":"file1.cpp","lines":[[1,3],[5,7]]},
- {"name":"file2.h"}
- ]
- --list-checks - List all enabled checks and exit. Use with
- -checks=* to list all available checks.
- --load=<pluginfilename> - Load the specified plugin
- -p <string> - Build path
- --quiet - Run clang-tidy in quiet mode. This suppresses
- printing statistics about ignored warnings and
- warnings treated as errors if the respective
- options are specified.
- --store-check-profile=<prefix> - By default reports are printed in tabulated
- format to stderr. When this option is passed,
- these per-TU profiles are instead stored as JSON.
- --system-headers - Display the errors from system headers.
- This option overrides the 'SystemHeaders' option
- in .clang-tidy file, if any.
- --use-color - Use colors in diagnostics. If not set, colors
- will be used if the terminal connected to
- standard output supports colors.
- This option overrides the 'UseColor' option in
- .clang-tidy file, if any.
- --verify-config - Check the config files to ensure each check and
- option is recognized.
- --vfsoverlay=<filename> - Overlay the virtual filesystem described by file
- over the real file system.
- --warnings-as-errors=<string> - Upgrades warnings to errors. Same format as
- '-checks'.
- This option's value is appended to the value of
- the 'WarningsAsErrors' option in .clang-tidy
- file, if any.
+ --checks=<string> - Comma-separated list of globs with optional '-'
+ prefix. Globs are processed in order of
+ appearance in the list. Globs without '-'
+ prefix add checks with matching names to the
+ set, globs with the '-' prefix remove checks
+ with matching names from the set of enabled
+ checks. This option's value is appended to the
+ value of the 'Checks' option in .clang-tidy
+ file, if any.
+ --config=<string> - Specifies a configuration in YAML/JSON format:
+ -config="{Checks: '*',
+ CheckOptions: {x: y}}"
+ When the value is empty, clang-tidy will
+ attempt to find a file named .clang-tidy for
+ each source file in its parent directories.
+ --config-file=<string> - Specify the path of .clang-tidy or custom config file:
+ e.g. --config-file=/some/path/myTidyConfigFile
+ This option internally works exactly the same way as
+ --config option after reading specified config file.
+ Use either --config-file or --config, not both.
+ --dump-config - Dumps configuration in the YAML format to
+ stdout. This option can be used along with a
+ file name (and '--' if the file is outside of a
+ project with configured compilation database).
+ The configuration used for this file will be
+ printed.
+ Use along with -checks=* to include
+ configuration of all checks.
+ --enable-check-profile - Enable per-check timing profiles, and print a
+ report to stderr.
+ --enable-module-headers-parsing - Enables preprocessor-level module header parsing
+ for C++20 and above, empowering specific checks
+ to detect macro definitions within modules. This
+ feature may cause performance and parsing issues
+ and is therefore considered experimental.
+ --exclude-header-filter=<string> - Regular expression matching the names of the
+ headers to exclude diagnostics from. Diagnostics
+ from the main file of each translation unit are
+ always displayed.
+ Can be used together with -line-filter.
+ This option overrides the 'ExcludeHeaderFilterRegex'
+ option in .clang-tidy file, if any.
+ --explain-config - For each enabled check explains, where it is
+ enabled, i.e. in clang-tidy binary, command
+ line or a specific configuration file.
+ --export-fixes=<filename> - YAML file to store suggested fixes in. The
+ stored fixes can be applied to the input source
+ code with clang-apply-replacements.
+ --extra-arg=<string> - Additional argument to append to the compiler command line
+ --extra-arg-before=<string> - Additional argument to prepend to the compiler command line
+ --fix - Apply suggested fixes. Without -fix-errors
+ clang-tidy will bail out if any compilation
+ errors were found.
+ --fix-errors - Apply suggested fixes even if compilation
+ errors were found. If compiler errors have
+ attached fix-its, clang-tidy will apply them as
+ well.
+ --fix-notes - If a warning has no fix, but a single fix can
+ be found through an associated diagnostic note,
+ apply the fix.
+ Specifying this flag will implicitly enable the
+ '--fix' flag.
+ --format-style=<string> - Style for formatting code around applied fixes:
+ - 'none' (default) turns off formatting
+ - 'file' (literally 'file', not a placeholder)
+ uses .clang-format file in the closest parent
+ directory
+ - '{ <json> }' specifies options inline, e.g.
+ -format-style='{BasedOnStyle: llvm, IndentWidth: 8}'
+ - 'llvm', 'google', 'webkit', 'mozilla'
+ See clang-format documentation for the up-to-date
+ information about formatting styles and options.
+ This option overrides the 'FormatStyle` option in
+ .clang-tidy file, if any.
+ --header-filter=<string> - Regular expression matching the names of the
+ headers to output diagnostics from. Diagnostics
+ from the main file of each translation unit are
+ always displayed.
+ Can be used together with -line-filter.
+ This option overrides the 'HeaderFilterRegex'
+ option in .clang-tidy file, if any.
+ --line-filter=<string> - List of files with line ranges to filter the
+ warnings. Can be used together with
+ -header-filter. The format of the list is a
+ JSON array of objects:
+ [
+ {"name":"file1.cpp","lines":[[1,3],[5,7]]},
+ {"name":"file2.h"}
+ ]
+ --list-checks - List all enabled checks and exit. Use with
+ -checks=* to list all available checks.
+ --load=<pluginfilename> - Load the specified plugin
+ -p <string> - Build path
+ --quiet - Run clang-tidy in quiet mode. This suppresses
+ printing statistics about ignored warnings and
+ warnings treated as errors if the respective
+ options are specified.
+ --store-check-profile=<prefix> - By default reports are printed in tabulated
+ format to stderr. When this option is passed,
+ these per-TU profiles are instead stored as JSON.
+ --system-headers - Display the errors from system headers.
+ This option overrides the 'SystemHeaders' option
+ in .clang-tidy file, if any.
+ --use-color - Use colors in diagnostics. If not set, colors
+ will be used if the terminal connected to
+ standard output supports colors.
+ This option overrides the 'UseColor' option in
+ .clang-tidy file, if any.
+ --verify-config - Check the config files to ensure each check and
+ option is recognized.
+ --vfsoverlay=<filename> - Overlay the virtual filesystem described by file
+ over the real file system.
+ --warnings-as-errors=<string> - Upgrades warnings to errors. Same format as
+ '-checks'.
+ This option's value is appended to the value of
+ the 'WarningsAsErrors' option in .clang-tidy
+ file, if any.
-p <build-path> is used to read a compile command database.
@@ -269,6 +276,7 @@ An overview of all the command-line options:
Checks - Same as '--checks'. Additionally, the list of
globs can be specified as a list instead of a
string.
+ ExcludeHeaderFilterRegex - Same as '--exclude-header-filter'.
ExtraArgs - Same as '--extra-args'.
ExtraArgsBefore - Same as '--extra-args-before'.
FormatStyle - Same as '--format-style'.
>From 569779de7c391ae0bf85c4dd0b5fc93cc5f8f57a Mon Sep 17 00:00:00 2001
From: Justin Cady <desk at justincady.com>
Date: Thu, 9 May 2024 13:24:14 -0400
Subject: [PATCH 3/3] * Simplify the conditional for checking
ExcludeHeaderFilter * Add test for ExcludeHeaderFilterRegex in .clang-tidy *
Add tests for --dump-config with ExcludeHeaderFilterRegex set and unset
---
.../clang-tidy/ClangTidyDiagnosticConsumer.cpp | 2 +-
.../Inputs/config-files/.clang-tidy | 1 +
.../Inputs/config-files/1/.clang-tidy | 1 +
.../Inputs/config-files/3/.clang-tidy | 1 +
.../clang-tidy/infrastructure/config-files.cpp | 15 ++++++++++++++-
5 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index d9352dafec23f..e0f6eb661a9ff 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -570,7 +570,7 @@ void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location,
LastErrorRelatesToUserCode =
LastErrorRelatesToUserCode || Sources.isInMainFile(Location) ||
(getHeaderFilter()->match(FileName) &&
- (ExcludeHeaderFilter ? !ExcludeHeaderFilter->match(FileName) : true));
+ !(ExcludeHeaderFilter && ExcludeHeaderFilter->match(FileName)));
unsigned LineNumber = Sources.getExpansionLineNumber(Location);
LastErrorPassesLineFilter =
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 942169f2ec429..83605c85dd92c 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,2 +1,3 @@
Checks: 'from-parent'
HeaderFilterRegex: 'parent'
+ExcludeHeaderFilterRegex: 'exc-parent'
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 800fd4e8eb2a9..c37f16bc2d7d2 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,2 +1,3 @@
Checks: 'from-child1'
HeaderFilterRegex: 'child1'
+ExcludeHeaderFilterRegex: 'exc-child1'
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 28dc8517ac9fe..9365108255bd8 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
@@ -1,3 +1,4 @@
InheritParentConfig: true
Checks: 'from-child3'
HeaderFilterRegex: 'child3'
+ExcludeHeaderFilterRegex: 'exc-child3'
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 d287412454cad..44d43ebbf8d20 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp
@@ -1,18 +1,23 @@
// RUN: clang-tidy -dump-config %S/Inputs/config-files/- -- | FileCheck %s -check-prefix=CHECK-BASE
// CHECK-BASE: Checks: {{.*}}from-parent
// CHECK-BASE: HeaderFilterRegex: parent
+// CHECK-BASE: ExcludeHeaderFilterRegex: exc-parent
// 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
// 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
// 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
-// RUN: clang-tidy -dump-config -checks='from-command-line' -header-filter='from command line' %S/Inputs/config-files/- -- | FileCheck %s -check-prefix=CHECK-COMMAND-LINE
+// 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-COMMAND-LINE: Checks: {{.*}}from-parent,from-command-line
// CHECK-COMMAND-LINE: HeaderFilterRegex: from command line
+// CHECK-COMMAND-LINE: ExcludeHeaderFilterRegex: from_command_line
// 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
@@ -68,3 +73,11 @@
// Dumped config does not overflow for unsigned options
// RUN: clang-tidy --dump-config %S/Inputs/config-files/5/- -- | FileCheck %s -check-prefix=CHECK-OVERFLOW
// CHECK-OVERFLOW: misc-throw-by-value-catch-by-reference.MaxSize: '1152921504606846976'
+
+// RUN: clang-tidy -dump-config -checks='readability-function-size' -header-filter='foo/*' -exclude-header-filter='bar*' %S/Inputs/config-files/- -- | FileCheck %s -check-prefix=CHECK-EXCLUDE-HEADERS
+// CHECK-EXCLUDE-HEADERS: HeaderFilterRegex: 'foo/*'
+// CHECK-EXCLUDE-HEADERS: ExcludeHeaderFilterRegex: 'bar*'
+
+// RUN: clang-tidy -dump-config -checks='readability-function-size' -header-filter='' -exclude-header-filter='' %S/Inputs/config-files/- -- | FileCheck %s -check-prefix=EMPTY-CHECK-EXCLUDE-HEADERS
+// EMPTY-CHECK-EXCLUDE-HEADERS: HeaderFilterRegex: ''
+// EMPTY-CHECK-EXCLUDE-HEADERS: ExcludeHeaderFilterRegex: ''
More information about the cfe-commits
mailing list