Skip to content

Commit 0e58783

Browse files
committed
[clang-tidy] New option to remove arguments from the command line
When using clang-tidy from a compilation database, some options might not be recognized by clang if the compilation database was generated for another compiler. This forces the user to add conditional code in their CMakeLists.txt to remove those arguments when using clang-tidy. A new option was added to the .clang-tidy config to remove those unknown flags without the need to generate a second compilation_commands.json Fixes #108455
1 parent f3805fc commit 0e58783

File tree

6 files changed

+49
-0
lines changed

6 files changed

+49
-0
lines changed

clang-tools-extra/clang-tidy/ClangTidy.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,30 @@ runClangTidy(clang::tidy::ClangTidyContext &Context,
581581
return AdjustedArgs;
582582
};
583583

584+
// Remove unwanted arguments passed to the compiler
585+
ArgumentsAdjuster CompilationArgsToIgnore =
586+
[&Context](const CommandLineArguments &Args, StringRef Filename) {
587+
ClangTidyOptions Opts = Context.getOptionsForFile(Filename);
588+
CommandLineArguments AdjustedArgs = Args;
589+
590+
if (Opts.CompilationArgsToRemoveRegex) {
591+
for (StringRef ArgToIgnore : *Opts.CompilationArgsToRemoveRegex) {
592+
llvm::Regex ArgToIgnoreRegex(ArgToIgnore);
593+
AdjustedArgs.erase(
594+
std::remove_if(AdjustedArgs.begin(), AdjustedArgs.end(),
595+
[&](llvm::StringRef Arg) {
596+
return Arg.starts_with("-") &&
597+
Arg != "-fsyntax-only" &&
598+
ArgToIgnoreRegex.match(Arg);
599+
}),
600+
AdjustedArgs.end());
601+
}
602+
}
603+
604+
return AdjustedArgs;
605+
};
606+
607+
Tool.appendArgumentsAdjuster(CompilationArgsToIgnore);
584608
Tool.appendArgumentsAdjuster(PerFileExtraArgumentsInserter);
585609
Tool.appendArgumentsAdjuster(getStripPluginsAdjuster());
586610
Context.setEnableProfiling(EnableCheckProfile);

clang-tools-extra/clang-tidy/ClangTidyOptions.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ template <> struct MappingTraits<ClangTidyOptions> {
227227
Options.ExcludeHeaderFilterRegex);
228228
IO.mapOptional("FormatStyle", Options.FormatStyle);
229229
IO.mapOptional("User", Options.User);
230+
IO.mapOptional("CompilationArgsToRemoveRegex",
231+
Options.CompilationArgsToRemoveRegex);
230232
IO.mapOptional("CheckOptions", Options.CheckOptions);
231233
IO.mapOptional("ExtraArgs", Options.ExtraArgs);
232234
IO.mapOptional("ExtraArgsBefore", Options.ExtraArgsBefore);
@@ -252,6 +254,7 @@ ClangTidyOptions ClangTidyOptions::getDefaults() {
252254
Options.SystemHeaders = false;
253255
Options.FormatStyle = "none";
254256
Options.User = std::nullopt;
257+
Options.CompilationArgsToRemoveRegex = std::nullopt;
255258
for (const ClangTidyModuleRegistry::entry &Module :
256259
ClangTidyModuleRegistry::entries())
257260
Options.mergeWith(Module.instantiate()->getModuleOptions(), 0);
@@ -292,6 +295,8 @@ ClangTidyOptions &ClangTidyOptions::mergeWith(const ClangTidyOptions &Other,
292295
overrideValue(SystemHeaders, Other.SystemHeaders);
293296
overrideValue(FormatStyle, Other.FormatStyle);
294297
overrideValue(User, Other.User);
298+
overrideValue(CompilationArgsToRemoveRegex,
299+
Other.CompilationArgsToRemoveRegex);
295300
overrideValue(UseColor, Other.UseColor);
296301
mergeVectors(ExtraArgs, Other.ExtraArgs);
297302
mergeVectors(ExtraArgsBefore, Other.ExtraArgsBefore);

clang-tools-extra/clang-tidy/ClangTidyOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ struct ClangTidyOptions {
112112
/// comments in the relevant check.
113113
std::optional<std::string> User;
114114

115+
/// \brief Remove command line arguments sent to the compiler matching this
116+
/// regex.
117+
std::optional<std::vector<std::string>> CompilationArgsToRemoveRegex;
118+
115119
/// Helper structure for storing option value with priority of the value.
116120
struct ClangTidyValue {
117121
ClangTidyValue() = default;

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,14 @@ Improvements to clang-tidy
167167
scripts by adding the `-hide-progress` option to suppress progress and
168168
informational messages.
169169

170+
- Improved :program:`clang-tidy` by adding the option `RemovedArgs`
171+
to remove arguments sent to the compiler when invoking clang-tidy.
172+
170173
- Deprecated the :program:`clang-tidy` ``zircon`` module. All checks have been
171174
moved to the ``fuchsia`` module instead. The ``zircon`` module will be removed
172175
in the 24th release.
173176

177+
174178
New checks
175179
^^^^^^^^^^
176180

clang-tools-extra/docs/clang-tidy/index.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,8 @@ An overview of all the command-line options:
329329
example, to place the correct user name in
330330
TODO() comments in the relevant check.
331331
WarningsAsErrors - Same as '--warnings-as-errors'.
332+
CompilationArgsToRemoveRegex - List of arguments to remove from the command
333+
line sent to the compiler.
332334
333335
The effective configuration can be inspected using --dump-config:
334336
@@ -338,6 +340,7 @@ An overview of all the command-line options:
338340
WarningsAsErrors: ''
339341
HeaderFileExtensions: ['', 'h','hh','hpp','hxx']
340342
ImplementationFileExtensions: ['c','cc','cpp','cxx']
343+
CompilationArgsToRemoveRegex: ['-Werror', '-f.*']
341344
HeaderFilterRegex: ''
342345
FormatStyle: none
343346
InheritParentConfig: true
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: not clang-tidy %s -- -fnot-an-option | FileCheck %s -check-prefix=INVALID-A
2+
// RUN: clang-tidy %s --config="{CompilationArgsToRemoveRegex: ['-fnot-an-option']}" -- -fnot-an-option
3+
// RUN: not clang-tidy %s --config="{CompilationArgsToRemoveRegex: ['-f.*']}" -- -fnot-an-option -invalid-option | FileCheck %s -check-prefix=INVALID-B
4+
// RUN: clang-tidy %s --config="{CompilationArgsToRemoveRegex: ['-f.*', '-invalid-option']}" -- -fnot-an-option -fnot-another-option -finvalid-option -invalid-option
5+
// RUN: not clang-tidy %s --config="{CompilationArgsToRemoveRegex: ['\$invalid-option']}" -- -finvalid-option | FileCheck %s -check-prefix=INVALID-C
6+
7+
// INVALID-A: error: unknown argument: '-fnot-an-option' [clang-diagnostic-error]
8+
// INVALID-B: error: unknown argument: '-invalid-option' [clang-diagnostic-error]
9+
// INVALID-C: error: unknown argument: '-finvalid-option' [clang-diagnostic-error]

0 commit comments

Comments
 (0)