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