Skip to content

Commit 1b7e069

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 545c302 commit 1b7e069

File tree

10 files changed

+75
-2
lines changed

10 files changed

+75
-2
lines changed

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,24 @@ runClangTidy(clang::tidy::ClangTidyContext &Context,
586586
return AdjustedArgs;
587587
};
588588

589+
// Remove unwanted arguments passed to the compiler
590+
ArgumentsAdjuster PerFileArgumentRemover =
591+
[&Context](const CommandLineArguments &Args, StringRef Filename) {
592+
ClangTidyOptions Opts = Context.getOptionsForFile(Filename);
593+
CommandLineArguments AdjustedArgs = Args;
594+
595+
if (Opts.RemovedArgs) {
596+
for (StringRef ArgToRemove : *Opts.RemovedArgs) {
597+
AdjustedArgs.erase(std::remove(AdjustedArgs.begin(),
598+
AdjustedArgs.end(), ArgToRemove),
599+
AdjustedArgs.end());
600+
}
601+
}
602+
603+
return AdjustedArgs;
604+
};
605+
606+
Tool.appendArgumentsAdjuster(PerFileArgumentRemover);
589607
Tool.appendArgumentsAdjuster(PerFileExtraArgumentsInserter);
590608
Tool.appendArgumentsAdjuster(getStripPluginsAdjuster());
591609
Context.setEnableProfiling(EnableCheckProfile);

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ template <> struct MappingTraits<ClangTidyOptions> {
230230
IO.mapOptional("CheckOptions", Options.CheckOptions);
231231
IO.mapOptional("ExtraArgs", Options.ExtraArgs);
232232
IO.mapOptional("ExtraArgsBefore", Options.ExtraArgsBefore);
233+
IO.mapOptional("RemovedArgs", Options.RemovedArgs);
233234
IO.mapOptional("InheritParentConfig", Options.InheritParentConfig);
234235
IO.mapOptional("UseColor", Options.UseColor);
235236
IO.mapOptional("SystemHeaders", Options.SystemHeaders);
@@ -252,6 +253,7 @@ ClangTidyOptions ClangTidyOptions::getDefaults() {
252253
Options.SystemHeaders = false;
253254
Options.FormatStyle = "none";
254255
Options.User = std::nullopt;
256+
Options.RemovedArgs = std::nullopt;
255257
for (const ClangTidyModuleRegistry::entry &Module :
256258
ClangTidyModuleRegistry::entries())
257259
Options.mergeWith(Module.instantiate()->getModuleOptions(), 0);
@@ -295,6 +297,7 @@ ClangTidyOptions &ClangTidyOptions::mergeWith(const ClangTidyOptions &Other,
295297
overrideValue(UseColor, Other.UseColor);
296298
mergeVectors(ExtraArgs, Other.ExtraArgs);
297299
mergeVectors(ExtraArgsBefore, Other.ExtraArgsBefore);
300+
mergeVectors(RemovedArgs, Other.RemovedArgs);
298301
// FIXME: how to handle duplicate names check?
299302
mergeVectors(CustomChecks, Other.CustomChecks);
300303
for (const auto &KeyValue : Other.CheckOptions) {

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ struct ClangTidyOptions {
8585
/// main files will always be displayed.
8686
std::optional<std::string> HeaderFilterRegex;
8787

88-
/// \brief Exclude warnings from headers matching this filter, even if they
88+
/// Exclude warnings from headers matching this filter, even if they
8989
/// match \c HeaderFilterRegex.
9090
std::optional<std::string> ExcludeHeaderFilterRegex;
9191

@@ -151,6 +151,9 @@ struct ClangTidyOptions {
151151
/// Add extra compilation arguments to the start of the list.
152152
std::optional<ArgList> ExtraArgsBefore;
153153

154+
/// Remove command line arguments sent to the compiler matching this.
155+
std::optional<ArgList> RemovedArgs;
156+
154157
/// Only used in the FileOptionsProvider and ConfigOptionsProvider. If true
155158
/// and using a FileOptionsProvider, it will take a configuration file in the
156159
/// parent directory (if any exists) and apply this config file on top of the

clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "../ClangTidy.h"
1919
#include "../ClangTidyForceLinker.h"
2020
#include "../GlobList.h"
21+
#include "../utils/OptionsUtils.h"
2122
#include "clang/Tooling/CommonOptionsParser.h"
2223
#include "llvm/ADT/StringSet.h"
2324
#include "llvm/Support/CommandLine.h"
@@ -77,6 +78,7 @@ Configuration files:
7778
(if any exists) will be taken and the current
7879
config file will be applied on top of the
7980
parent one.
81+
RemovedArgs - Same as '--removed-arg'.
8082
SystemHeaders - Same as '--system-headers'.
8183
UseColor - Same as '--use-color'.
8284
User - Specifies the name or e-mail of the user
@@ -357,6 +359,16 @@ see https://clang.llvm.org/extra/clang-tidy/QueryBasedCustomChecks.html.
357359
cl::init(false),
358360
cl::cat(ClangTidyCategory));
359361

362+
static cl::list<std::string> RemovedArgs("removed-arg", desc(R"(
363+
List of arguments to remove from the command
364+
line sent to the compiler. Please note that
365+
removing arguments might change the semantic
366+
of the analzed code, possibly leading to
367+
compiler errors, false positives or
368+
false negatives. This option is applied
369+
before --extra-arg and --extra-arg-before)"),
370+
cl::cat(ClangTidyCategory));
371+
360372
namespace clang::tidy {
361373

362374
static void printStats(const ClangTidyStats &Stats) {
@@ -423,6 +435,8 @@ createOptionsProvider(llvm::IntrusiveRefCntPtr<vfs::FileSystem> FS) {
423435
OverrideOptions.FormatStyle = FormatStyle;
424436
if (UseColor.getNumOccurrences() > 0)
425437
OverrideOptions.UseColor = UseColor;
438+
if (RemovedArgs.getNumOccurrences() > 0)
439+
OverrideOptions.RemovedArgs = RemovedArgs;
426440

427441
auto LoadConfig =
428442
[&](StringRef Configuration,

clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,13 @@ def main():
228228
default=[],
229229
help="Additional argument to prepend to the compiler " "command line.",
230230
)
231+
parser.add_argument(
232+
"-removed-arg",
233+
dest="removed_arg",
234+
action="append",
235+
default=[],
236+
help="Arguments to remove from the compiler command line.",
237+
)
231238
parser.add_argument(
232239
"-quiet",
233240
action="store_true",
@@ -378,6 +385,8 @@ def main():
378385
common_clang_tidy_args.append("-extra-arg=%s" % arg)
379386
for arg in args.extra_arg_before:
380387
common_clang_tidy_args.append("-extra-arg-before=%s" % arg)
388+
for arg in args.removed_arg:
389+
common_clang_tidy_args.append("-removed-arg=%s" % arg)
381390
for plugin in args.plugins:
382391
common_clang_tidy_args.append("-load=%s" % plugin)
383392
if args.warnings_as_errors:

clang-tools-extra/clang-tidy/tool/run-clang-tidy.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ def get_tidy_invocation(
9696
allow_enabling_alpha_checkers: bool,
9797
extra_arg: List[str],
9898
extra_arg_before: List[str],
99+
removed_arg: List[str],
99100
quiet: bool,
100101
config_file_path: str,
101102
config: str,
@@ -135,6 +136,8 @@ def get_tidy_invocation(
135136
start.append(f"-extra-arg={arg}")
136137
for arg in extra_arg_before:
137138
start.append(f"-extra-arg-before={arg}")
139+
for arg in removed_arg:
140+
start.append(f"-removed-arg={arg}")
138141
start.append(f"-p={build_path}")
139142
if quiet:
140143
start.append("-quiet")
@@ -377,6 +380,7 @@ async def run_tidy(
377380
args.allow_enabling_alpha_checkers,
378381
args.extra_arg,
379382
args.extra_arg_before,
383+
args.removed_arg,
380384
args.quiet,
381385
args.config_file,
382386
args.config,
@@ -551,6 +555,13 @@ async def main() -> None:
551555
default=[],
552556
help="Additional argument to prepend to the compiler command line.",
553557
)
558+
parser.add_argument(
559+
"-removed-arg",
560+
dest="removed_arg",
561+
action="append",
562+
default=[],
563+
help="Arguments to remove from the compiler command line.",
564+
)
554565
parser.add_argument(
555566
"-quiet", action="store_true", help="Run clang-tidy in quiet mode."
556567
)
@@ -638,6 +649,7 @@ async def main() -> None:
638649
args.allow_enabling_alpha_checkers,
639650
args.extra_arg,
640651
args.extra_arg_before,
652+
args.removed_arg,
641653
args.quiet,
642654
args.config_file,
643655
args.config,

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ Improvements to clang-tidy
177177
scripts by adding the `-hide-progress` option to suppress progress and
178178
informational messages.
179179

180+
- Improved :program:`clang-tidy` by adding the `--removed-arg` option to remove
181+
arguments sent to the compiler when invoking Clang-Tidy. This option was also
182+
added to :program:`run-clang-tidy.py` and :program:`clang-tidy-diff.py` and
183+
can be configured in the config file through the `RemovedArgs` option.
184+
180185
- Deprecated the :program:`clang-tidy` ``zircon`` module. All checks have been
181186
moved to the ``fuchsia`` module instead. The ``zircon`` module will be removed
182187
in the 24th release.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ An overview of all the command-line options:
331331
example, to place the correct user name in
332332
TODO() comments in the relevant check.
333333
WarningsAsErrors - Same as '--warnings-as-errors'.
334+
RemovedArgs - Same as '--removed-arg'
334335
335336
The effective configuration can be inspected using --dump-config:
336337
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// RUN: not clang-tidy --invalid-arg 2>&1 | FileCheck %s
22

33
// CHECK: error: clang-tidy{{(\.exe)?}}: Unknown command line argument '--invalid-arg'. Try: '{{.*}}clang-tidy{{(\.exe)?}} --help'
4-
// CHECK-NEXT: clang-tidy{{(\.exe)?}}: Did you mean '--extra-arg'?
4+
// CHECK-NEXT: clang-tidy{{(\.exe)?}}: Did you mean '--removed-arg'?
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: not clang-tidy %s -- -fnot-an-option | FileCheck %s -check-prefix=INVALID-A
2+
// RUN: clang-tidy %s --config="{RemovedArgs: ['-fnot-an-option']}" -- -fnot-an-option
3+
// RUN: clang-tidy %s --config="{RemovedArgs: ['-fnot-another-option', '-fnot-an-option']}" -- -fnot-an-option -fnot-another-option
4+
// RUN: clang-tidy %s --removed-arg="-fnot-an-option" -- -fnot-an-option
5+
// RUN: not clang-tidy %s --removed-arg="-fnot-an-option" -- -fnot-an-option -fnot-another-option | FileCheck %s -check-prefix=INVALID-B
6+
7+
// INVALID-A: error: unknown argument: '-fnot-an-option' [clang-diagnostic-error]
8+
// INVALID-B: error: unknown argument: '-fnot-another-option' [clang-diagnostic-error]

0 commit comments

Comments
 (0)