[clang-tools-extra] [clang-tidy] New option `CompilationArgsToRemoveRegex` to remove arguments from the command line (PR #111453)

FĂ©lix-Antoine Constantin via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 7 16:27:17 PDT 2024


https://github.com/felix642 created https://github.com/llvm/llvm-project/pull/111453

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

>From 5cdc27e543b0f4dea3dd3848d974a27614aea713 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?F=C3=A9lix-Antoine=20Constantin?=
 <felix-antoine.constantin at bidgroup.ca>
Date: Mon, 7 Oct 2024 19:22:44 -0400
Subject: [PATCH] [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
---
 clang-tools-extra/clang-tidy/ClangTidy.cpp    | 24 +++++++++++++++++++
 .../clang-tidy/ClangTidyOptions.cpp           |  5 ++++
 .../clang-tidy/ClangTidyOptions.h             |  4 ++++
 clang-tools-extra/docs/ReleaseNotes.rst       |  3 +++
 clang-tools-extra/docs/clang-tidy/index.rst   |  3 +++
 .../compilation-args-to-ignore.cpp            |  9 +++++++
 6 files changed, 48 insertions(+)
 create mode 100644 clang-tools-extra/test/clang-tidy/infrastructure/compilation-args-to-ignore.cpp

diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp
index 62f9d19b2a362f..4bd921b819260e 100644
--- a/clang-tools-extra/clang-tidy/ClangTidy.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp
@@ -552,6 +552,30 @@ runClangTidy(clang::tidy::ClangTidyContext &Context,
         return AdjustedArgs;
       };
 
+  // Remove unwanted arguments passed to the compiler
+  ArgumentsAdjuster CompilationArgsToIgnore =
+      [&Context](const CommandLineArguments &Args, StringRef Filename) {
+        ClangTidyOptions Opts = Context.getOptionsForFile(Filename);
+        CommandLineArguments AdjustedArgs = Args;
+
+        if (Opts.CompilationArgsToRemoveRegex) {
+          for (StringRef ArgToIgnore : *Opts.CompilationArgsToRemoveRegex) {
+            llvm::Regex ArgToIgnoreRegex(ArgToIgnore);
+            AdjustedArgs.erase(
+                std::remove_if(AdjustedArgs.begin(), AdjustedArgs.end(),
+                               [&](llvm::StringRef Arg) {
+                                 return Arg.starts_with("-") &&
+                                        Arg != "-fsyntax-only" &&
+                                        ArgToIgnoreRegex.match(Arg);
+                               }),
+                AdjustedArgs.end());
+          }
+        }
+
+        return AdjustedArgs;
+      };
+
+  Tool.appendArgumentsAdjuster(CompilationArgsToIgnore);
   Tool.appendArgumentsAdjuster(PerFileExtraArgumentsInserter);
   Tool.appendArgumentsAdjuster(getStripPluginsAdjuster());
   Context.setEnableProfiling(EnableCheckProfile);
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
index 445c7f85c900c6..32112db07b09d2 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
@@ -174,6 +174,8 @@ template <> struct MappingTraits<ClangTidyOptions> {
                    Options.ExcludeHeaderFilterRegex);
     IO.mapOptional("FormatStyle", Options.FormatStyle);
     IO.mapOptional("User", Options.User);
+    IO.mapOptional("CompilationArgsToRemoveRegex",
+                   Options.CompilationArgsToRemoveRegex);
     IO.mapOptional("CheckOptions", Options.CheckOptions);
     IO.mapOptional("ExtraArgs", Options.ExtraArgs);
     IO.mapOptional("ExtraArgsBefore", Options.ExtraArgsBefore);
@@ -198,6 +200,7 @@ ClangTidyOptions ClangTidyOptions::getDefaults() {
   Options.SystemHeaders = false;
   Options.FormatStyle = "none";
   Options.User = std::nullopt;
+  Options.CompilationArgsToRemoveRegex = std::nullopt;
   for (const ClangTidyModuleRegistry::entry &Module :
        ClangTidyModuleRegistry::entries())
     Options.mergeWith(Module.instantiate()->getModuleOptions(), 0);
@@ -238,6 +241,8 @@ ClangTidyOptions &ClangTidyOptions::mergeWith(const ClangTidyOptions &Other,
   overrideValue(SystemHeaders, Other.SystemHeaders);
   overrideValue(FormatStyle, Other.FormatStyle);
   overrideValue(User, Other.User);
+  overrideValue(CompilationArgsToRemoveRegex,
+                Other.CompilationArgsToRemoveRegex);
   overrideValue(UseColor, Other.UseColor);
   mergeVectors(ExtraArgs, Other.ExtraArgs);
   mergeVectors(ExtraArgsBefore, Other.ExtraArgsBefore);
diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.h b/clang-tools-extra/clang-tidy/ClangTidyOptions.h
index 85d5a02ebbc1bc..0ccdde1ff3fc31 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.h
@@ -110,6 +110,10 @@ struct ClangTidyOptions {
   /// comments in the relevant check.
   std::optional<std::string> User;
 
+  /// \brief Remove command line arguments sent to the compiler matching this
+  /// regex.
+  std::optional<std::vector<std::string>> CompilationArgsToRemoveRegex;
+
   /// Helper structure for storing option value with priority of the value.
   struct ClangTidyValue {
     ClangTidyValue() = default;
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 3e051c7db6adcc..ea3ad5356a897c 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -106,6 +106,9 @@ Improvements to clang-tidy
 - Improved :program:`run-clang-tidy.py` script. Fixed minor shutdown noise
   happening on certain platforms when interrupting the script.
 
+- Improved :program:`clang-tidy` by adding the option `CompilationArgsToRemoveRegex`
+  to remove arguments sent to the compiler when invoking clang-tidy.
+
 New checks
 ^^^^^^^^^^
 
diff --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst
index e38141bdb8be1f..65d96b29079f23 100644
--- a/clang-tools-extra/docs/clang-tidy/index.rst
+++ b/clang-tools-extra/docs/clang-tidy/index.rst
@@ -303,6 +303,8 @@ An overview of all the command-line options:
                                    example, to place the correct user name in
                                    TODO() comments in the relevant check.
     WarningsAsErrors             - Same as '--warnings-as-errors'.
+    CompilationArgsToRemoveRegex - List of arguments to remove from the command
+                                   line sent to the compiler.
 
     The effective configuration can be inspected using --dump-config:
 
@@ -312,6 +314,7 @@ An overview of all the command-line options:
       WarningsAsErrors:    ''
       HeaderFileExtensions:         ['', 'h','hh','hpp','hxx']
       ImplementationFileExtensions: ['c','cc','cpp','cxx']
+      CompilationArgsToRemoveRegex: ['-Werror', '-f.*']
       HeaderFilterRegex:   ''
       FormatStyle:         none
       InheritParentConfig: true
diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/compilation-args-to-ignore.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/compilation-args-to-ignore.cpp
new file mode 100644
index 00000000000000..33a42d416e75a7
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/compilation-args-to-ignore.cpp
@@ -0,0 +1,9 @@
+// RUN: not clang-tidy %s -- -fnot-an-option | FileCheck %s -check-prefix=INVALID-A
+// RUN: clang-tidy %s --config="{CompilationArgsToRemoveRegex: ['-fnot-an-option']}" -- -fnot-an-option
+// RUN: not clang-tidy %s --config="{CompilationArgsToRemoveRegex: ['-f.*']}" -- -fnot-an-option -invalid-option | FileCheck %s -check-prefix=INVALID-B
+// RUN: clang-tidy %s --config="{CompilationArgsToRemoveRegex: ['-f.*', '-invalid-option']}" -- -fnot-an-option -fnot-another-option -finvalid-option -invalid-option
+// RUN: not clang-tidy %s --config="{CompilationArgsToRemoveRegex: ['\$invalid-option']}" -- -finvalid-option | FileCheck %s -check-prefix=INVALID-C
+
+// INVALID-A: error: unknown argument: '-fnot-an-option' [clang-diagnostic-error]
+// INVALID-B: error: unknown argument: '-invalid-option' [clang-diagnostic-error]
+// INVALID-C: error: unknown argument: '-finvalid-option' [clang-diagnostic-error]
\ No newline at end of file



More information about the cfe-commits mailing list