clang-tools  15.0.0git
ConfigCompileTests.cpp
Go to the documentation of this file.
1 //===-- ConfigCompileTests.cpp --------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Config.h"
10 #include "ConfigFragment.h"
11 #include "ConfigTesting.h"
12 #include "Diagnostics.h"
13 #include "Feature.h"
14 #include "TestFS.h"
15 #include "clang/Basic/DiagnosticSema.h"
16 #include "llvm/ADT/None.h"
17 #include "llvm/ADT/Optional.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Support/Path.h"
20 #include "llvm/Support/SourceMgr.h"
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include <string>
24 
25 namespace clang {
26 namespace clangd {
27 namespace config {
28 namespace {
29 using ::testing::AllOf;
30 using ::testing::Contains;
31 using ::testing::ElementsAre;
32 using ::testing::IsEmpty;
33 using ::testing::SizeIs;
34 using ::testing::StartsWith;
35 using ::testing::UnorderedElementsAre;
36 
37 class ConfigCompileTests : public ::testing::Test {
38 protected:
39  CapturedDiags Diags;
41  Fragment Frag;
42  Params Parm;
43 
44  bool compileAndApply() {
45  Conf = Config();
46  Diags.Diagnostics.clear();
47  auto Compiled = std::move(Frag).compile(Diags.callback());
48  return Compiled(Parm, Conf);
49  }
50 };
51 
52 TEST_F(ConfigCompileTests, Condition) {
53  // No condition.
54  Frag = {};
55  Frag.CompileFlags.Add.emplace_back("X");
56  EXPECT_TRUE(compileAndApply()) << "Empty config";
57  EXPECT_THAT(Diags.Diagnostics, IsEmpty());
58  EXPECT_THAT(Conf.CompileFlags.Edits, SizeIs(1));
59 
60  // Regex with no file.
61  Frag = {};
62  Frag.If.PathMatch.emplace_back("fo*");
63  EXPECT_FALSE(compileAndApply());
64  EXPECT_THAT(Diags.Diagnostics, IsEmpty());
65  EXPECT_THAT(Conf.CompileFlags.Edits, SizeIs(0));
66 
67  // Following tests have a file path set.
68  Parm.Path = "bar";
69 
70  // Non-matching regex.
71  Frag = {};
72  Frag.If.PathMatch.emplace_back("fo*");
73  EXPECT_FALSE(compileAndApply());
74  EXPECT_THAT(Diags.Diagnostics, IsEmpty());
75 
76  // Matching regex.
77  Frag = {};
78  Frag.If.PathMatch.emplace_back("fo*");
79  Frag.If.PathMatch.emplace_back("ba*r");
80  EXPECT_TRUE(compileAndApply());
81  EXPECT_THAT(Diags.Diagnostics, IsEmpty());
82 
83  // Excluded regex.
84  Frag = {};
85  Frag.If.PathMatch.emplace_back("b.*");
86  Frag.If.PathExclude.emplace_back(".*r");
87  EXPECT_FALSE(compileAndApply()) << "Included but also excluded";
88  EXPECT_THAT(Diags.Diagnostics, IsEmpty());
89 
90  // Invalid regex.
91  Frag = {};
92  Frag.If.PathMatch.emplace_back("**]@theu");
93  EXPECT_TRUE(compileAndApply());
94  EXPECT_THAT(Diags.Diagnostics, SizeIs(1));
95  EXPECT_THAT(Diags.Diagnostics.front().Message, StartsWith("Invalid regex"));
96 
97  // Valid regex and unknown key.
98  Frag = {};
100  Frag.If.PathMatch.emplace_back("ba*r");
101  EXPECT_FALSE(compileAndApply());
102  EXPECT_THAT(Diags.Diagnostics, IsEmpty());
103 
104  // Only matches case-insensitively.
105  Frag = {};
106  Frag.If.PathMatch.emplace_back("B.*R");
107  EXPECT_THAT(Diags.Diagnostics, IsEmpty());
108 #ifdef CLANGD_PATH_CASE_INSENSITIVE
109  EXPECT_TRUE(compileAndApply());
110 #else
111  EXPECT_FALSE(compileAndApply());
112 #endif
113 
114  Frag = {};
115  Frag.If.PathExclude.emplace_back("B.*R");
116  EXPECT_THAT(Diags.Diagnostics, IsEmpty());
117 #ifdef CLANGD_PATH_CASE_INSENSITIVE
118  EXPECT_FALSE(compileAndApply());
119 #else
120  EXPECT_TRUE(compileAndApply());
121 #endif
122 }
123 
124 TEST_F(ConfigCompileTests, CompileCommands) {
125  Frag.CompileFlags.Compiler.emplace("tpc.exe");
126  Frag.CompileFlags.Add.emplace_back("-foo");
127  Frag.CompileFlags.Remove.emplace_back("--include-directory=");
128  std::vector<std::string> Argv = {"clang", "-I", "bar/", "--", "a.cc"};
129  EXPECT_TRUE(compileAndApply());
130  EXPECT_THAT(Conf.CompileFlags.Edits, SizeIs(3));
131  for (auto &Edit : Conf.CompileFlags.Edits)
132  Edit(Argv);
133  EXPECT_THAT(Argv, ElementsAre("tpc.exe", "-foo", "--", "a.cc"));
134 }
135 
136 TEST_F(ConfigCompileTests, CompilationDatabase) {
137  Frag.CompileFlags.CompilationDatabase.emplace("None");
138  EXPECT_TRUE(compileAndApply());
139  EXPECT_EQ(Conf.CompileFlags.CDBSearch.Policy,
141 
142  Frag.CompileFlags.CompilationDatabase.emplace("Ancestors");
143  EXPECT_TRUE(compileAndApply());
144  EXPECT_EQ(Conf.CompileFlags.CDBSearch.Policy,
146 
147  // Relative path not allowed without directory set.
148  Frag.CompileFlags.CompilationDatabase.emplace("Something");
149  EXPECT_TRUE(compileAndApply());
150  EXPECT_EQ(Conf.CompileFlags.CDBSearch.Policy,
152  << "default value";
153  EXPECT_THAT(Diags.Diagnostics,
154  ElementsAre(diagMessage(
155  "CompilationDatabase must be an absolute path, because this "
156  "fragment is not associated with any directory.")));
157 
158  // Relative path allowed if directory is set.
160  EXPECT_TRUE(compileAndApply());
161  EXPECT_EQ(Conf.CompileFlags.CDBSearch.Policy,
163  EXPECT_EQ(Conf.CompileFlags.CDBSearch.FixedCDBPath, testPath("Something"));
164  EXPECT_THAT(Diags.Diagnostics, IsEmpty());
165 
166  // Absolute path allowed.
167  Frag.Source.Directory.clear();
168  Frag.CompileFlags.CompilationDatabase.emplace(testPath("Something2"));
169  EXPECT_TRUE(compileAndApply());
170  EXPECT_EQ(Conf.CompileFlags.CDBSearch.Policy,
172  EXPECT_EQ(Conf.CompileFlags.CDBSearch.FixedCDBPath, testPath("Something2"));
173  EXPECT_THAT(Diags.Diagnostics, IsEmpty());
174 }
175 
176 TEST_F(ConfigCompileTests, Index) {
177  Frag.Index.Background.emplace("Skip");
178  EXPECT_TRUE(compileAndApply());
179  EXPECT_EQ(Conf.Index.Background, Config::BackgroundPolicy::Skip);
180 
181  Frag = {};
182  Frag.Index.Background.emplace("Foo");
183  EXPECT_TRUE(compileAndApply());
184  EXPECT_EQ(Conf.Index.Background, Config::BackgroundPolicy::Build)
185  << "by default";
186  EXPECT_THAT(
188  ElementsAre(diagMessage(
189  "Invalid Background value 'Foo'. Valid values are Build, Skip.")));
190 }
191 
192 TEST_F(ConfigCompileTests, PathSpecMatch) {
193  auto BarPath = llvm::sys::path::convert_to_slash(testPath("foo/bar.h"));
194  Parm.Path = BarPath;
195 
196  struct {
197  std::string Directory;
198  std::string PathSpec;
199  bool ShouldMatch;
200  } Cases[] = {
201  {
202  // Absolute path matches.
203  "",
204  llvm::sys::path::convert_to_slash(testPath("foo/bar.h")),
205  true,
206  },
207  {
208  // Absolute path fails.
209  "",
210  llvm::sys::path::convert_to_slash(testPath("bar/bar.h")),
211  false,
212  },
213  {
214  // Relative should fail to match as /foo/bar.h doesn't reside under
215  // /baz/.
216  testPath("baz"),
217  "bar\\.h",
218  false,
219  },
220  {
221  // Relative should pass with /foo as directory.
222  testPath("foo"),
223  "bar\\.h",
224  true,
225  },
226  };
227 
228  // PathMatch
229  for (const auto &Case : Cases) {
230  Frag = {};
231  Frag.If.PathMatch.emplace_back(Case.PathSpec);
232  Frag.Source.Directory = Case.Directory;
233  EXPECT_EQ(compileAndApply(), Case.ShouldMatch);
234  ASSERT_THAT(Diags.Diagnostics, IsEmpty());
235  }
236 
237  // PathEclude
238  for (const auto &Case : Cases) {
239  SCOPED_TRACE(Case.Directory);
240  SCOPED_TRACE(Case.PathSpec);
241  Frag = {};
242  Frag.If.PathExclude.emplace_back(Case.PathSpec);
243  Frag.Source.Directory = Case.Directory;
244  EXPECT_NE(compileAndApply(), Case.ShouldMatch);
245  ASSERT_THAT(Diags.Diagnostics, IsEmpty());
246  }
247 }
248 
249 TEST_F(ConfigCompileTests, DiagnosticsIncludeCleaner) {
250  // Defaults to None.
251  EXPECT_TRUE(compileAndApply());
252  EXPECT_EQ(Conf.Diagnostics.UnusedIncludes,
253  Config::UnusedIncludesPolicy::None);
254 
255  Frag = {};
256  Frag.Diagnostics.UnusedIncludes.emplace("None");
257  EXPECT_TRUE(compileAndApply());
258  EXPECT_EQ(Conf.Diagnostics.UnusedIncludes,
259  Config::UnusedIncludesPolicy::None);
260 
261  Frag = {};
262  Frag.Diagnostics.UnusedIncludes.emplace("Strict");
263  EXPECT_TRUE(compileAndApply());
264  EXPECT_EQ(Conf.Diagnostics.UnusedIncludes,
265  Config::UnusedIncludesPolicy::Strict);
266 
267  Frag = {};
268  EXPECT_TRUE(Conf.Diagnostics.Includes.IgnoreHeader.empty())
269  << Conf.Diagnostics.Includes.IgnoreHeader.size();
271  Located<std::string>("foo.h"));
273  Located<std::string>(".*inc"));
274  EXPECT_TRUE(compileAndApply());
275  auto HeaderFilter = [this](llvm::StringRef Path) {
276  for (auto &Filter : Conf.Diagnostics.Includes.IgnoreHeader) {
277  if (Filter(Path))
278  return true;
279  }
280  return false;
281  };
282  EXPECT_TRUE(HeaderFilter("foo.h"));
283  EXPECT_FALSE(HeaderFilter("bar.h"));
284 }
285 
286 TEST_F(ConfigCompileTests, DiagnosticSuppression) {
287  Frag.Diagnostics.Suppress.emplace_back("bugprone-use-after-move");
288  Frag.Diagnostics.Suppress.emplace_back("unreachable-code");
289  Frag.Diagnostics.Suppress.emplace_back("-Wunused-variable");
290  Frag.Diagnostics.Suppress.emplace_back("typecheck_bool_condition");
291  Frag.Diagnostics.Suppress.emplace_back("err_unexpected_friend");
292  Frag.Diagnostics.Suppress.emplace_back("warn_alloca");
293  EXPECT_TRUE(compileAndApply());
294  EXPECT_THAT(Conf.Diagnostics.Suppress.keys(),
295  UnorderedElementsAre("bugprone-use-after-move",
296  "unreachable-code", "unused-variable",
297  "typecheck_bool_condition",
298  "unexpected_friend", "warn_alloca"));
299  EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
300  diag::warn_unreachable, Conf.Diagnostics.Suppress, LangOptions()));
301  // Subcategory not respected/suppressed.
302  EXPECT_FALSE(isBuiltinDiagnosticSuppressed(
303  diag::warn_unreachable_break, Conf.Diagnostics.Suppress, LangOptions()));
304  EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
305  diag::warn_unused_variable, Conf.Diagnostics.Suppress, LangOptions()));
306  EXPECT_TRUE(isBuiltinDiagnosticSuppressed(diag::err_typecheck_bool_condition,
307  Conf.Diagnostics.Suppress,
308  LangOptions()));
309  EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
310  diag::err_unexpected_friend, Conf.Diagnostics.Suppress, LangOptions()));
311  EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
312  diag::warn_alloca, Conf.Diagnostics.Suppress, LangOptions()));
313 
314  Frag.Diagnostics.Suppress.emplace_back("*");
315  EXPECT_TRUE(compileAndApply());
316  EXPECT_TRUE(Conf.Diagnostics.SuppressAll);
317  EXPECT_THAT(Conf.Diagnostics.Suppress, IsEmpty());
318 }
319 
320 TEST_F(ConfigCompileTests, Tidy) {
321  auto &Tidy = Frag.Diagnostics.ClangTidy;
322  Tidy.Add.emplace_back("bugprone-use-after-move");
323  Tidy.Add.emplace_back("llvm-*");
324  Tidy.Remove.emplace_back("llvm-include-order");
325  Tidy.Remove.emplace_back("readability-*");
326  Tidy.CheckOptions.emplace_back(
327  std::make_pair(std::string("StrictMode"), std::string("true")));
328  Tidy.CheckOptions.emplace_back(std::make_pair(
329  std::string("example-check.ExampleOption"), std::string("0")));
330  EXPECT_TRUE(compileAndApply());
331  EXPECT_EQ(Conf.Diagnostics.ClangTidy.CheckOptions.size(), 2U);
332  EXPECT_EQ(Conf.Diagnostics.ClangTidy.CheckOptions.lookup("StrictMode"),
333  "true");
334  EXPECT_EQ(Conf.Diagnostics.ClangTidy.CheckOptions.lookup(
335  "example-check.ExampleOption"),
336  "0");
337 #if CLANGD_TIDY_CHECKS
338  EXPECT_EQ(
339  Conf.Diagnostics.ClangTidy.Checks,
340  "bugprone-use-after-move,llvm-*,-llvm-include-order,-readability-*");
341  EXPECT_THAT(Diags.Diagnostics, IsEmpty());
342 #else // !CLANGD_TIDY_CHECKS
343  EXPECT_EQ(Conf.Diagnostics.ClangTidy.Checks, "llvm-*,-readability-*");
344  EXPECT_THAT(
346  ElementsAre(
347  diagMessage(
348  "clang-tidy check 'bugprone-use-after-move' was not found"),
349  diagMessage("clang-tidy check 'llvm-include-order' was not found")));
350 #endif
351 }
352 
353 TEST_F(ConfigCompileTests, TidyBadChecks) {
354  auto &Tidy = Frag.Diagnostics.ClangTidy;
355  Tidy.Add.emplace_back("unknown-check");
356  Tidy.Remove.emplace_back("*");
357  Tidy.Remove.emplace_back("llvm-includeorder");
358  EXPECT_TRUE(compileAndApply());
359  // Ensure bad checks are stripped from the glob.
360  EXPECT_EQ(Conf.Diagnostics.ClangTidy.Checks, "-*");
361  EXPECT_THAT(
363  ElementsAre(
364  AllOf(diagMessage("clang-tidy check 'unknown-check' was not found"),
365  diagKind(llvm::SourceMgr::DK_Warning)),
366  AllOf(
367  diagMessage("clang-tidy check 'llvm-includeorder' was not found"),
368  diagKind(llvm::SourceMgr::DK_Warning))));
369 }
370 
371 TEST_F(ConfigCompileTests, ExternalServerNeedsTrusted) {
372  Fragment::IndexBlock::ExternalBlock External;
373  External.Server.emplace("xxx");
374  Frag.Index.External = std::move(External);
375  compileAndApply();
376  EXPECT_THAT(
378  ElementsAre(diagMessage(
379  "Remote index may not be specified by untrusted configuration. "
380  "Copy this into user config to use it.")));
381  EXPECT_EQ(Conf.Index.External.Kind, Config::ExternalIndexSpec::None);
382 }
383 
384 TEST_F(ConfigCompileTests, ExternalBlockWarnOnMultipleSource) {
385  Frag.Source.Trusted = true;
386  Fragment::IndexBlock::ExternalBlock External;
387  External.File.emplace("");
388  External.Server.emplace("");
389  Frag.Index.External = std::move(External);
390  compileAndApply();
391 #ifdef CLANGD_ENABLE_REMOTE
392  EXPECT_THAT(
394  Contains(
395  AllOf(diagMessage("Exactly one of File, Server or None must be set."),
396  diagKind(llvm::SourceMgr::DK_Error))));
397 #else
398  ASSERT_TRUE(Conf.Index.External.hasValue());
399  EXPECT_EQ(Conf.Index.External->Kind, Config::ExternalIndexSpec::File);
400 #endif
401 }
402 
403 TEST_F(ConfigCompileTests, ExternalBlockDisableWithNone) {
404  compileAndApply();
405  EXPECT_EQ(Conf.Index.External.Kind, Config::ExternalIndexSpec::None);
406 
407  Fragment::IndexBlock::ExternalBlock External;
408  External.IsNone = true;
409  Frag.Index.External = std::move(External);
410  compileAndApply();
411  EXPECT_EQ(Conf.Index.External.Kind, Config::ExternalIndexSpec::None);
412 }
413 
414 TEST_F(ConfigCompileTests, ExternalBlockErrOnNoSource) {
415  Frag.Index.External.emplace(Fragment::IndexBlock::ExternalBlock{});
416  compileAndApply();
417  EXPECT_THAT(
419  Contains(
420  AllOf(diagMessage("Exactly one of File, Server or None must be set."),
421  diagKind(llvm::SourceMgr::DK_Error))));
422 }
423 
424 TEST_F(ConfigCompileTests, ExternalBlockDisablesBackgroundIndex) {
425  auto BazPath = testPath("foo/bar/baz.h", llvm::sys::path::Style::posix);
426  Parm.Path = BazPath;
427  Frag.Index.Background.emplace("Build");
428  Fragment::IndexBlock::ExternalBlock External;
429  External.File.emplace(testPath("foo"));
430  External.MountPoint.emplace(
431  testPath("foo/bar", llvm::sys::path::Style::posix));
432  Frag.Index.External = std::move(External);
433  compileAndApply();
434  EXPECT_EQ(Conf.Index.Background, Config::BackgroundPolicy::Skip);
435 }
436 
437 TEST_F(ConfigCompileTests, ExternalBlockMountPoint) {
438  auto GetFrag = [](llvm::StringRef Directory,
439  llvm::Optional<const char *> MountPoint) {
440  Fragment Frag;
441  Frag.Source.Directory = Directory.str();
442  Fragment::IndexBlock::ExternalBlock External;
443  External.File.emplace(testPath("foo"));
444  if (MountPoint)
445  External.MountPoint.emplace(*MountPoint);
446  Frag.Index.External = std::move(External);
447  return Frag;
448  };
449 
450  auto BarPath = testPath("foo/bar.h", llvm::sys::path::Style::posix);
451  BarPath = llvm::sys::path::convert_to_slash(BarPath);
452  Parm.Path = BarPath;
453  // Non-absolute MountPoint without a directory raises an error.
454  Frag = GetFrag("", "foo");
455  compileAndApply();
456  ASSERT_THAT(
458  ElementsAre(
459  AllOf(diagMessage("MountPoint must be an absolute path, because this "
460  "fragment is not associated with any directory."),
461  diagKind(llvm::SourceMgr::DK_Error))));
462  EXPECT_EQ(Conf.Index.External.Kind, Config::ExternalIndexSpec::None);
463 
464  auto FooPath = testPath("foo/", llvm::sys::path::Style::posix);
465  FooPath = llvm::sys::path::convert_to_slash(FooPath);
466  // Ok when relative.
467  Frag = GetFrag(testRoot(), "foo/");
468  compileAndApply();
469  ASSERT_THAT(Diags.Diagnostics, IsEmpty());
470  ASSERT_EQ(Conf.Index.External.Kind, Config::ExternalIndexSpec::File);
471  EXPECT_THAT(Conf.Index.External.MountPoint, FooPath);
472 
473  // None defaults to ".".
474  Frag = GetFrag(FooPath, llvm::None);
475  compileAndApply();
476  ASSERT_THAT(Diags.Diagnostics, IsEmpty());
477  ASSERT_EQ(Conf.Index.External.Kind, Config::ExternalIndexSpec::File);
478  EXPECT_THAT(Conf.Index.External.MountPoint, FooPath);
479 
480  // Without a file, external index is empty.
481  Parm.Path = "";
482  Frag = GetFrag("", FooPath.c_str());
483  compileAndApply();
484  ASSERT_THAT(Diags.Diagnostics, IsEmpty());
485  ASSERT_EQ(Conf.Index.External.Kind, Config::ExternalIndexSpec::None);
486 
487  // File outside MountPoint, no index.
488  auto BazPath = testPath("bar/baz.h", llvm::sys::path::Style::posix);
489  BazPath = llvm::sys::path::convert_to_slash(BazPath);
490  Parm.Path = BazPath;
491  Frag = GetFrag("", FooPath.c_str());
492  compileAndApply();
493  ASSERT_THAT(Diags.Diagnostics, IsEmpty());
494  ASSERT_EQ(Conf.Index.External.Kind, Config::ExternalIndexSpec::None);
495 
496  // File under MountPoint, index should be set.
497  BazPath = testPath("foo/baz.h", llvm::sys::path::Style::posix);
498  BazPath = llvm::sys::path::convert_to_slash(BazPath);
499  Parm.Path = BazPath;
500  Frag = GetFrag("", FooPath.c_str());
501  compileAndApply();
502  ASSERT_THAT(Diags.Diagnostics, IsEmpty());
503  ASSERT_EQ(Conf.Index.External.Kind, Config::ExternalIndexSpec::File);
504  EXPECT_THAT(Conf.Index.External.MountPoint, FooPath);
505 
506  // Only matches case-insensitively.
507  BazPath = testPath("fOo/baz.h", llvm::sys::path::Style::posix);
508  BazPath = llvm::sys::path::convert_to_slash(BazPath);
509  Parm.Path = BazPath;
510 
511  FooPath = testPath("FOO/", llvm::sys::path::Style::posix);
512  FooPath = llvm::sys::path::convert_to_slash(FooPath);
513  Frag = GetFrag("", FooPath.c_str());
514  compileAndApply();
515  ASSERT_THAT(Diags.Diagnostics, IsEmpty());
516 #ifdef CLANGD_PATH_CASE_INSENSITIVE
517  ASSERT_EQ(Conf.Index.External.Kind, Config::ExternalIndexSpec::File);
518  EXPECT_THAT(Conf.Index.External.MountPoint, FooPath);
519 #else
520  ASSERT_EQ(Conf.Index.External.Kind, Config::ExternalIndexSpec::None);
521 #endif
522 }
523 
524 TEST_F(ConfigCompileTests, AllScopes) {
525  // Defaults to true.
526  EXPECT_TRUE(compileAndApply());
527  EXPECT_TRUE(Conf.Completion.AllScopes);
528 
529  Frag = {};
530  Frag.Completion.AllScopes = false;
531  EXPECT_TRUE(compileAndApply());
532  EXPECT_FALSE(Conf.Completion.AllScopes);
533 
534  Frag = {};
535  Frag.Completion.AllScopes = true;
536  EXPECT_TRUE(compileAndApply());
537  EXPECT_TRUE(Conf.Completion.AllScopes);
538 }
539 
540 TEST_F(ConfigCompileTests, Style) {
541  Frag = {};
542  Frag.Style.FullyQualifiedNamespaces.push_back(std::string("foo"));
543  Frag.Style.FullyQualifiedNamespaces.push_back(std::string("bar"));
544  EXPECT_TRUE(compileAndApply());
545  EXPECT_THAT(Conf.Style.FullyQualifiedNamespaces, ElementsAre("foo", "bar"));
546 }
547 } // namespace
548 } // namespace config
549 } // namespace clangd
550 } // namespace clang
clang::clangd::Config::BackgroundPolicy::Skip
@ Skip
clang::clangd::config::Fragment::CompileFlags
CompileFlagsBlock CompileFlags
Definition: ConfigFragment.h:173
clang::clangd::Config::CDBSearchSpec::FixedDir
@ FixedDir
Definition: Config.h:58
clang::clangd::testPath
std::string testPath(PathRef File, llvm::sys::path::Style Style)
Definition: TestFS.cpp:94
clang::clangd::config::Fragment::CompileFlagsBlock::Compiler
llvm::Optional< Located< std::string > > Compiler
Override the compiler executable name to simulate.
Definition: ConfigFragment.h:143
clang::clangd::Path
std::string Path
A typedef to represent a file path.
Definition: Path.h:26
clang::clangd::Config::ExternalIndexSpec::File
@ File
Definition: Config.h:75
clang::clangd::config::Fragment::IndexBlock::Background
llvm::Optional< Located< std::string > > Background
Whether files are built in the background to produce a project index.
Definition: ConfigFragment.h:182
Feature.h
clang::clangd::config::Fragment::IfBlock::PathMatch
std::vector< Located< std::string > > PathMatch
The file being processed must fully match a regular expression.
Definition: ConfigFragment.h:114
clang::clangd::TEST_F
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
Definition: BackgroundIndexTests.cpp:94
clang::clangd::config::Fragment::Completion
CompletionBlock Completion
Definition: ConfigFragment.h:288
clang::clangd::config::Fragment::DiagnosticsBlock::IncludesBlock::IgnoreHeader
std::vector< Located< std::string > > IgnoreHeader
Regexes that will be used to avoid diagnosing certain includes as unused or missing.
Definition: ConfigFragment.h:243
clang::clangd::config::Fragment::Diagnostics
DiagnosticsBlock Diagnostics
Definition: ConfigFragment.h:270
clang::clangd::config::Fragment::StyleBlock::FullyQualifiedNamespaces
std::vector< Located< std::string > > FullyQualifiedNamespaces
Definition: ConfigFragment.h:278
Condition
std::string Condition
Condition used after the preprocessor directive.
Definition: RedundantPreprocessorCheck.cpp:24
clang::clangd::config::Fragment::CompileFlagsBlock::CompilationDatabase
llvm::Optional< Located< std::string > > CompilationDatabase
Directory to search for compilation database (compile_comands.json etc).
Definition: ConfigFragment.h:171
clang::clangd::Config::CDBSearchSpec::NoCDBSearch
@ NoCDBSearch
Definition: Config.h:58
clang::clangd::testRoot
const char * testRoot()
Definition: TestFS.cpp:86
clang::clangd::config::Fragment::DiagnosticsBlock::Includes
IncludesBlock Includes
Definition: ConfigFragment.h:245
clang::clangd::config::Fragment::IndexBlock::External
llvm::Optional< Located< ExternalBlock > > External
Definition: ConfigFragment.h:201
Config
static cl::opt< std::string > Config("config", cl::desc(R"( Specifies a configuration in YAML/JSON format: -config="{Checks:' *', CheckOptions:{x:y}}" When the value is empty, clang-tidy will attempt to find a file named .clang-tidy for each source file in its parent directories. )"), cl::init(""), cl::cat(ClangTidyCategory))
clang::clangd::config::Fragment::DiagnosticsBlock::UnusedIncludes
llvm::Optional< Located< std::string > > UnusedIncludes
Controls how clangd will correct "unnecessary #include directives.
Definition: ConfigFragment.h:236
Conf
Config Conf
Definition: ConfigCompileTests.cpp:40
clang::clangd::config::Fragment::DiagnosticsBlock::ClangTidyBlock::Add
std::vector< Located< std::string > > Add
Definition: ConfigFragment.h:252
clang::clangd::config::Fragment::Source
SourceInfo Source
Definition: ConfigFragment.h:99
TestFS.h
Directory
llvm::StringRef Directory
Definition: Serialization.cpp:420
clang::clangd::config::Fragment::Index
IndexBlock Index
Definition: ConfigFragment.h:206
ConfigTesting.h
Diagnostics.h
Parm
Params Parm
Definition: ConfigCompileTests.cpp:42
HeaderFilter
static cl::opt< std::string > HeaderFilter("header-filter", cl::desc(R"( Regular expression matching the names of the headers to output diagnostics from. Diagnostics from the main file of each translation unit are always displayed. Can be used together with -line-filter. This option overrides the 'HeaderFilterRegex' option in .clang-tidy file, if any. )"), cl::init(""), cl::cat(ClangTidyCategory))
clang::clangd::Config::ExternalIndexSpec::None
@ None
Definition: Config.h:75
Index
const SymbolIndex * Index
Definition: Dexp.cpp:98
clang::clangd::config::Fragment::SourceInfo::Directory
std::string Directory
Absolute path to directory the fragment is associated with.
Definition: ConfigFragment.h:94
clang::clangd::config::Fragment::DiagnosticsBlock::Suppress
std::vector< Located< std::string > > Suppress
Diagnostic codes that should be suppressed.
Definition: ConfigFragment.h:222
Config.h
clang::clangd::Config::CDBSearchSpec::Ancestors
@ Ancestors
Definition: Config.h:58
Frag
Fragment Frag
Definition: ConfigCompileTests.cpp:41
clang::clangd::config::Fragment::Style
StyleBlock Style
Definition: ConfigFragment.h:280
clang::clangd::config::Fragment::CompletionBlock::AllScopes
llvm::Optional< Located< bool > > AllScopes
Whether code completion should include suggestions from scopes that are not visible.
Definition: ConfigFragment.h:286
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::config::Params::Path
llvm::StringRef Path
Absolute path to a source file we're applying the config to.
Definition: ConfigProvider.h:36
clang::clangd::config::Fragment::IfBlock::HasUnrecognizedCondition
bool HasUnrecognizedCondition
An unrecognized key was found while parsing the condition.
Definition: ConfigFragment.h:120
Diags
CapturedDiags Diags
Definition: ConfigCompileTests.cpp:39
clang::clangd::config::CapturedDiags::Diagnostics
std::vector< Diag > Diagnostics
Definition: ConfigTesting.h:59
clang::clangd::config::Fragment::IfBlock::PathExclude
std::vector< Located< std::string > > PathExclude
The file being processed must not fully match a regular expression.
Definition: ConfigFragment.h:116
clang::clangd::config::Fragment::DiagnosticsBlock::ClangTidy
ClangTidyBlock ClangTidy
Definition: ConfigFragment.h:268
clang::clangd::config::Fragment::SourceInfo::Trusted
bool Trusted
Whether this fragment is allowed to make critical security/privacy decisions.
Definition: ConfigFragment.h:97
ConfigFragment.h
clang::clangd::config::Fragment::If
IfBlock If
Definition: ConfigFragment.h:122
clang::clangd::config::Fragment::CompileFlagsBlock::Remove
std::vector< Located< std::string > > Remove
List of flags to remove from the compile command.
Definition: ConfigFragment.h:164
clang::clangd::Config::BackgroundPolicy::Build
@ Build
clang::clangd::isBuiltinDiagnosticSuppressed
bool isBuiltinDiagnosticSuppressed(unsigned ID, const llvm::StringSet<> &Suppress, const LangOptions &LangOpts)
Determine whether a (non-clang-tidy) diagnostic is suppressed by config.
Definition: Diagnostics.cpp:885
clang::clangd::config::Fragment::CompileFlagsBlock::Add
std::vector< Located< std::string > > Add
List of flags to append to the compile command.
Definition: ConfigFragment.h:146