[clang-tools-extra] 132f1d3 - [clang-tidy] Support specifying checks as a list in the config file

Carlos Galvez via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 10 12:31:42 PDT 2023


Author: Carlos Galvez
Date: 2023-04-10T19:31:33Z
New Revision: 132f1d31fd66c30baf9773bf8f37b36a40fa7039

URL: https://github.com/llvm/llvm-project/commit/132f1d31fd66c30baf9773bf8f37b36a40fa7039
DIFF: https://github.com/llvm/llvm-project/commit/132f1d31fd66c30baf9773bf8f37b36a40fa7039.diff

LOG: [clang-tidy] Support specifying checks as a list in the config file

Specifying checks as a string is convenient for quickly using
clang-tidy to run a handful of checks. However it is not
suitable for projects that have a long list of enabled or
disabled checks. It is specially troublesome in case one
wants to interleave comments with the checks, to explain
why they are enabled or disabled.

Currently this can be achieved via multiline strings in YAML,
but it's error-prone. For example, comments must end with a
comma for clang-tidy to continue processing the list of globs;
a missing comma will make clang-tidy silently ignore the rest
of the list.

Instead, enable passing a native YAML list to the "Checks"
option in the config file. The implementation is done such
that the old behavior is kept: a user can pass a string
or a list. We can consider deprecating passing the checks
as a string altogether in a future release, to simplify
the internal logic of the YAML parser.

Fixes https://github.com/llvm/llvm-project/issues/51428

Differential Revision: https://reviews.llvm.org/D147876

Added: 
    clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-bracket
    clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-dash

Modified: 
    clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
    clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
    clang-tools-extra/docs/ReleaseNotes.rst
    clang-tools-extra/docs/clang-tidy/index.rst
    clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
index 84defccde513e..afa88cb4f80d1 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
@@ -117,10 +117,48 @@ void yamlize(IO &IO, ClangTidyOptions::OptionMap &Options, bool,
   }
 }
 
+struct ChecksVariant {
+  std::optional<std::string> AsString;
+  std::optional<std::vector<std::string>> AsVector;
+};
+
+template <>
+void yamlize(IO &IO, ChecksVariant &Checks, bool, EmptyContext &Ctx) {
+  if (!IO.outputting()) {
+    // Special case for reading from YAML
+    // Must support reading from both a string or a list
+    Input &I = reinterpret_cast<Input &>(IO);
+    if (isa<ScalarNode, BlockScalarNode>(I.getCurrentNode())) {
+      Checks.AsString = std::string();
+      yamlize(IO, *Checks.AsString, true, Ctx);
+    } else if (isa<SequenceNode>(I.getCurrentNode())) {
+      Checks.AsVector = std::vector<std::string>();
+      yamlize(IO, *Checks.AsVector, true, Ctx);
+    } else {
+      IO.setError("expected string or sequence");
+    }
+  }
+}
+
+static void mapChecks(IO &IO, std::optional<std::string> &Checks) {
+  if (IO.outputting()) {
+    // Output always a string
+    IO.mapOptional("Checks", Checks);
+  } else {
+    // Input as either a string or a list
+    ChecksVariant ChecksAsVariant;
+    IO.mapOptional("Checks", ChecksAsVariant);
+    if (ChecksAsVariant.AsString)
+      Checks = ChecksAsVariant.AsString;
+    else if (ChecksAsVariant.AsVector)
+      Checks = llvm::join(*ChecksAsVariant.AsVector, ",");
+  }
+}
+
 template <> struct MappingTraits<ClangTidyOptions> {
   static void mapping(IO &IO, ClangTidyOptions &Options) {
     bool Ignored = false;
-    IO.mapOptional("Checks", Options.Checks);
+    mapChecks(IO, Options.Checks);
     IO.mapOptional("WarningsAsErrors", Options.WarningsAsErrors);
     IO.mapOptional("HeaderFileExtensions", Options.HeaderFileExtensions);
     IO.mapOptional("ImplementationFileExtensions",

diff  --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
index 09162995a0974..2bed6dfda3a0a 100644
--- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -52,7 +52,9 @@ Configuration files:
                                  options. Example:
                                    CheckOptions:
                                      some-check.SomeOption: 'some value'
-  Checks                       - Same as '--checks'.
+  Checks                       - Same as '--checks'. Additionally, the list of
+                                 globs can be specified as a list instead of a
+                                 string.
   ExtraArgs                    - Same as '--extra-args'.
   ExtraArgsBefore              - Same as '--extra-args-before'.
   FormatStyle                  - Same as '--format-style'.

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index cb10385d8e87f..9c5b86fc8606d 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -98,6 +98,9 @@ Improvements to clang-tidy
   `ImplementationFileExtensions`, replacing the check-local options of the
   same name.
 
+- Support specifying `Checks` as a YAML list in the `.clang-tidy` configuration
+  file.
+
 New checks
 ^^^^^^^^^^
 

diff  --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst
index 899c3ea6ed540..444d03d6cb08a 100644
--- a/clang-tools-extra/docs/clang-tidy/index.rst
+++ b/clang-tools-extra/docs/clang-tidy/index.rst
@@ -259,7 +259,9 @@ An overview of all the command-line options:
                                    options. Example:
                                      CheckOptions:
                                        some-check.SomeOption: 'some value'
-    Checks                       - Same as '--checks'.
+    Checks                       - Same as '--checks'. Additionally, the list of
+                                   globs can be specified as a list instead of a
+                                   string.
     ExtraArgs                    - Same as '--extra-args'.
     ExtraArgsBefore              - Same as '--extra-args-before'.
     FormatStyle                  - Same as '--format-style'.

diff  --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-bracket b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-bracket
new file mode 100644
index 0000000000000..d2bfe57880c2b
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-bracket
@@ -0,0 +1,6 @@
+Checks: [
+  "-*",
+  "hicpp-uppercase-literal-suffix",
+  "hicpp-use-auto",
+  "hicpp-use-emplace",
+]

diff  --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-dash b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-dash
new file mode 100644
index 0000000000000..ce1c88d1148cb
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-file/config-file-list-dash
@@ -0,0 +1,5 @@
+Checks:
+  - "-*"
+  - "hicpp-uppercase-literal-suffix"
+  - "hicpp-use-auto"
+  - "hicpp-use-emplace"

diff  --git a/clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp
index 16b216a1d4f69..b929fb15193d1 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/config-file.cpp
@@ -6,3 +6,15 @@
 // CHECK-SPACES-NEXT: hicpp-use-auto
 // CHECK-SPACES-NEXT: hicpp-use-emplace
 // CHECK-SPACES-EMPTY:
+// RUN: clang-tidy -config-file=%S/Inputs/config-file/config-file-list-dash --list-checks -- | FileCheck %s -check-prefix=CHECK-LIST-DASH
+// CHECK-LIST-DASH: Enabled checks:
+// CHECK-LIST-DASH-NEXT: hicpp-uppercase-literal-suffix
+// CHECK-LIST-DASH-NEXT: hicpp-use-auto
+// CHECK-LIST-DASH-NEXT: hicpp-use-emplace
+// CHECK-LIST-DASH-EMPTY:
+// RUN: clang-tidy -config-file=%S/Inputs/config-file/config-file-list-bracket --list-checks -- | FileCheck %s -check-prefix=CHECK-LIST-BRACKET
+// CHECK-LIST-BRACKET: Enabled checks:
+// CHECK-LIST-BRACKET-NEXT: hicpp-uppercase-literal-suffix
+// CHECK-LIST-BRACKET-NEXT: hicpp-use-auto
+// CHECK-LIST-BRACKET-NEXT: hicpp-use-emplace
+// CHECK-LIST-BRACKET-EMPTY:


        


More information about the cfe-commits mailing list