diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp @@ -117,10 +117,48 @@ } } +struct ChecksVariant { + std::optional AsString; + std::optional> 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(IO); + if (isa(I.getCurrentNode())) { + Checks.AsString = std::string(); + yamlize(IO, *Checks.AsString, true, Ctx); + } else if (isa(I.getCurrentNode())) { + Checks.AsVector = std::vector(); + yamlize(IO, *Checks.AsVector, true, Ctx); + } else { + IO.setError("expected string or sequence"); + } + } +} + +static void mapChecks(IO &IO, std::optional &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 { 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 --- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -52,7 +52,9 @@ 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 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -98,6 +98,9 @@ `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 --- a/clang-tools-extra/docs/clang-tidy/index.rst +++ b/clang-tools-extra/docs/clang-tidy/index.rst @@ -259,7 +259,9 @@ 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 --- /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 --- /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 --- 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: