diff --git a/clang-tools-extra/clangd/Config.h b/clang-tools-extra/clangd/Config.h --- a/clang-tools-extra/clangd/Config.h +++ b/clang-tools-extra/clangd/Config.h @@ -90,6 +90,13 @@ struct { bool SuppressAll = false; llvm::StringSet<> Suppress; + + /// Configures what clang-tidy checks to run and options to use with them. + struct { + // A comma-seperated list of globs specify which clang-tidy checks to run. + std::string Checks; + llvm::StringMap CheckOptions; + } ClangTidy; } Diagnostics; /// Style of the codebase. @@ -99,14 +106,6 @@ // ::). All nested namespaces are affected as well. std::vector FullyQualifiedNamespaces; } Style; - - /// Configures what clang-tidy checks to run and options to use with them. - struct { - // A comma-seperated list of globs to specify which clang-tidy checks to - // run. - std::string Checks; - llvm::StringMap CheckOptions; - } ClangTidy; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp --- a/clang-tools-extra/clangd/ConfigCompile.cpp +++ b/clang-tools-extra/clangd/ConfigCompile.cpp @@ -189,7 +189,6 @@ compile(std::move(F.CompileFlags)); compile(std::move(F.Index)); compile(std::move(F.Diagnostics)); - compile(std::move(F.ClangTidy)); } void compile(Fragment::IfBlock &&F) { @@ -379,6 +378,8 @@ for (llvm::StringRef N : Normalized) C.Diagnostics.Suppress.insert(N); }); + + compile(std::move(F.ClangTidy)); } void compile(Fragment::StyleBlock &&F) { @@ -422,7 +423,7 @@ CurSpec += Str; } - void compile(Fragment::ClangTidyBlock &&F) { + void compile(Fragment::DiagnosticsBlock::ClangTidyBlock &&F) { std::string Checks; for (auto &CheckGlob : F.Add) appendTidyCheckSpec(Checks, CheckGlob, true); @@ -433,8 +434,9 @@ if (!Checks.empty()) Out.Apply.push_back( [Checks = std::move(Checks)](const Params &, Config &C) { - C.ClangTidy.Checks.append( - Checks, C.ClangTidy.Checks.empty() ? /*skip comma*/ 1 : 0, + C.Diagnostics.ClangTidy.Checks.append( + Checks, + C.Diagnostics.ClangTidy.Checks.empty() ? /*skip comma*/ 1 : 0, std::string::npos); }); if (!F.CheckOptions.empty()) { @@ -445,8 +447,8 @@ Out.Apply.push_back( [CheckOptions = std::move(CheckOptions)](const Params &, Config &C) { for (auto &StringPair : CheckOptions) - C.ClangTidy.CheckOptions.insert_or_assign(StringPair.first, - StringPair.second); + C.Diagnostics.ClangTidy.CheckOptions.insert_or_assign( + StringPair.first, StringPair.second); }); } } diff --git a/clang-tools-extra/clangd/ConfigFragment.h b/clang-tools-extra/clangd/ConfigFragment.h --- a/clang-tools-extra/clangd/ConfigFragment.h +++ b/clang-tools-extra/clangd/ConfigFragment.h @@ -203,6 +203,29 @@ /// (e.g. by disabling a clang-tidy check, or the -Wunused compile flag). /// This often has other advantages, such as skipping some analysis. std::vector> Suppress; + + /// Controls how clang-tidy will run over the code base. + /// + /// The settings are merged with any settings found in .clang-tidy + /// configiration files with these ones taking precedence. + struct ClangTidyBlock { + std::vector> Add; + /// List of checks to disable. + /// Takes precedence over Add. To enable all llvm checks except include + /// order: + /// Add: llvm-* + /// Remove: llvm-include-onder + std::vector> Remove; + + /// A Key-Value pair list of options to pass to clang-tidy checks + /// These take precedence over options specified in clang-tidy + /// configuration files. Example: + /// CheckOptions: + /// readability-braces-around-statements.ShortStatementLines: 2 + std::vector, Located>> + CheckOptions; + }; + ClangTidyBlock ClangTidy; }; DiagnosticsBlock Diagnostics; @@ -215,30 +238,6 @@ std::vector> FullyQualifiedNamespaces; }; StyleBlock Style; - - /// Controls how clang-tidy will run over the code base. - /// - /// The settings are merged with any settings found in .clang-tidy - /// configiration files with these ones taking precedence. - // FIXME: move this to Diagnostics.Tidy. - struct ClangTidyBlock { - std::vector> Add; - /// List of checks to disable. - /// Takes precedence over Add. To enable all llvm checks except include - /// order: - /// Add: llvm-* - /// Remove: llvm-include-onder - std::vector> Remove; - - /// A Key-Value pair list of options to pass to clang-tidy checks - /// These take precedence over options specified in clang-tidy configuration - /// files. Example: - /// CheckOptions: - /// readability-braces-around-statements.ShortStatementLines: 2 - std::vector, Located>> - CheckOptions; - }; - ClangTidyBlock ClangTidy; }; } // namespace config diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp b/clang-tools-extra/clangd/ConfigYAML.cpp --- a/clang-tools-extra/clangd/ConfigYAML.cpp +++ b/clang-tools-extra/clangd/ConfigYAML.cpp @@ -62,7 +62,7 @@ Dict.handle("CompileFlags", [&](Node &N) { parse(F.CompileFlags, N); }); Dict.handle("Index", [&](Node &N) { parse(F.Index, N); }); Dict.handle("Style", [&](Node &N) { parse(F.Style, N); }); - Dict.handle("ClangTidy", [&](Node &N) { parse(F.ClangTidy, N); }); + Dict.handle("Diagnostics", [&](Node &N) { parse(F.Diagnostics, N); }); Dict.parse(N); return !(N.failed() || HadError); } @@ -110,7 +110,17 @@ Dict.parse(N); } - void parse(Fragment::ClangTidyBlock &F, Node &N) { + void parse(Fragment::DiagnosticsBlock &F, Node &N) { + DictParser Dict("Diagnostics", this); + Dict.handle("Suppress", [&](Node &N) { + if (auto Values = scalarValues(N)) + F.Suppress = std::move(*Values); + }); + Dict.handle("ClangTidy", [&](Node &N) { parse(F.ClangTidy, N); }); + Dict.parse(N); + } + + void parse(Fragment::DiagnosticsBlock::ClangTidyBlock &F, Node &N) { DictParser Dict("ClangTidy", this); Dict.handle("Add", [&](Node &N) { if (auto Values = scalarValues(N)) diff --git a/clang-tools-extra/clangd/TidyProvider.cpp b/clang-tools-extra/clangd/TidyProvider.cpp --- a/clang-tools-extra/clangd/TidyProvider.cpp +++ b/clang-tools-extra/clangd/TidyProvider.cpp @@ -255,7 +255,7 @@ TidyProviderRef provideClangdConfig() { return [](tidy::ClangTidyOptions &Opts, llvm::StringRef) { - const auto &CurTidyConfig = Config::current().ClangTidy; + const auto &CurTidyConfig = Config::current().Diagnostics.ClangTidy; if (!CurTidyConfig.Checks.empty()) mergeCheckList(Opts.Checks, CurTidyConfig.Checks); diff --git a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp --- a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp +++ b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp @@ -259,32 +259,36 @@ } TEST_F(ConfigCompileTests, Tidy) { - Frag.ClangTidy.Add.emplace_back("bugprone-use-after-move"); - Frag.ClangTidy.Add.emplace_back("llvm-*"); - Frag.ClangTidy.Remove.emplace_back("llvm-include-order"); - Frag.ClangTidy.Remove.emplace_back("readability-*"); - Frag.ClangTidy.CheckOptions.emplace_back( + auto &Tidy = Frag.Diagnostics.ClangTidy; + Tidy.Add.emplace_back("bugprone-use-after-move"); + Tidy.Add.emplace_back("llvm-*"); + Tidy.Remove.emplace_back("llvm-include-order"); + Tidy.Remove.emplace_back("readability-*"); + Tidy.CheckOptions.emplace_back( std::make_pair(std::string("StrictMode"), std::string("true"))); - Frag.ClangTidy.CheckOptions.emplace_back(std::make_pair( + Tidy.CheckOptions.emplace_back(std::make_pair( std::string("example-check.ExampleOption"), std::string("0"))); EXPECT_TRUE(compileAndApply()); EXPECT_EQ( - Conf.ClangTidy.Checks, + Conf.Diagnostics.ClangTidy.Checks, "bugprone-use-after-move,llvm-*,-llvm-include-order,-readability-*"); - EXPECT_EQ(Conf.ClangTidy.CheckOptions.size(), 2U); - EXPECT_EQ(Conf.ClangTidy.CheckOptions.lookup("StrictMode"), "true"); - EXPECT_EQ(Conf.ClangTidy.CheckOptions.lookup("example-check.ExampleOption"), + EXPECT_EQ(Conf.Diagnostics.ClangTidy.CheckOptions.size(), 2U); + EXPECT_EQ(Conf.Diagnostics.ClangTidy.CheckOptions.lookup("StrictMode"), + "true"); + EXPECT_EQ(Conf.Diagnostics.ClangTidy.CheckOptions.lookup( + "example-check.ExampleOption"), "0"); EXPECT_THAT(Diags.Diagnostics, IsEmpty()); } TEST_F(ConfigCompileTests, TidyBadChecks) { - Frag.ClangTidy.Add.emplace_back("unknown-check"); - Frag.ClangTidy.Remove.emplace_back("*"); - Frag.ClangTidy.Remove.emplace_back("llvm-includeorder"); + auto &Tidy = Frag.Diagnostics.ClangTidy; + Tidy.Add.emplace_back("unknown-check"); + Tidy.Remove.emplace_back("*"); + Tidy.Remove.emplace_back("llvm-includeorder"); EXPECT_TRUE(compileAndApply()); // Ensure bad checks are stripped from the glob. - EXPECT_EQ(Conf.ClangTidy.Checks, "-*"); + EXPECT_EQ(Conf.Diagnostics.ClangTidy.Checks, "-*"); EXPECT_THAT( Diags.Diagnostics, ElementsAre( diff --git a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp --- a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp +++ b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp @@ -60,10 +60,11 @@ Index: Background: Skip --- -ClangTidy: - CheckOptions: - IgnoreMacros: true - example-check.ExampleOption: 0 +Diagnostics: + ClangTidy: + CheckOptions: + IgnoreMacros: true + example-check.ExampleOption: 0 )yaml"; auto Results = Fragment::parseYAML(YAML, "config.yaml", Diags.callback()); EXPECT_THAT(Diags.Diagnostics, IsEmpty()); @@ -77,7 +78,7 @@ ASSERT_TRUE(Results[2].Index.Background); EXPECT_EQ("Skip", *Results[2].Index.Background.getValue()); - EXPECT_THAT(Results[3].ClangTidy.CheckOptions, + EXPECT_THAT(Results[3].Diagnostics.ClangTidy.CheckOptions, ElementsAre(PairVal("IgnoreMacros", "true"), PairVal("example-check.ExampleOption", "0"))); }