clang-tools  14.0.0git
ClangdMain.cpp
Go to the documentation of this file.
1 //===--- ClangdMain.cpp - clangd server loop ------------------------------===//
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 "ClangdLSPServer.h"
10 #include "CodeComplete.h"
11 #include "Config.h"
12 #include "ConfigProvider.h"
13 #include "Feature.h"
14 #include "PathMapping.h"
15 #include "Protocol.h"
16 #include "TidyProvider.h"
17 #include "Transport.h"
18 #include "index/Background.h"
19 #include "index/Index.h"
20 #include "index/Merge.h"
21 #include "index/ProjectAware.h"
22 #include "index/Serialization.h"
23 #include "index/remote/Client.h"
24 #include "refactor/Rename.h"
25 #include "support/Path.h"
26 #include "support/Shutdown.h"
27 #include "support/ThreadsafeFS.h"
28 #include "support/Trace.h"
29 #include "clang/Format/Format.h"
30 #include "llvm/ADT/Optional.h"
31 #include "llvm/ADT/SmallString.h"
32 #include "llvm/ADT/StringRef.h"
33 #include "llvm/Support/CommandLine.h"
34 #include "llvm/Support/FileSystem.h"
35 #include "llvm/Support/Path.h"
36 #include "llvm/Support/Process.h"
37 #include "llvm/Support/Program.h"
38 #include "llvm/Support/Signals.h"
39 #include "llvm/Support/TargetSelect.h"
40 #include "llvm/Support/raw_ostream.h"
41 #include <chrono>
42 #include <cstdlib>
43 #include <memory>
44 #include <mutex>
45 #include <string>
46 #include <thread>
47 #include <utility>
48 #include <vector>
49 
50 #ifndef _WIN32
51 #include <unistd.h>
52 #endif
53 
54 #ifdef __GLIBC__
55 #include <malloc.h>
56 #endif
57 
58 namespace clang {
59 namespace clangd {
60 
61 // Implemented in Check.cpp.
62 bool check(const llvm::StringRef File,
63  llvm::function_ref<bool(const Position &)> ShouldCheckLine,
64  const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts,
65  bool EnableCodeCompletion);
66 
67 namespace {
68 
69 using llvm::cl::cat;
70 using llvm::cl::CommaSeparated;
71 using llvm::cl::desc;
72 using llvm::cl::Hidden;
73 using llvm::cl::init;
74 using llvm::cl::list;
75 using llvm::cl::opt;
76 using llvm::cl::OptionCategory;
77 using llvm::cl::ValueOptional;
78 using llvm::cl::values;
79 
80 // All flags must be placed in a category, or they will be shown neither in
81 // --help, nor --help-hidden!
82 OptionCategory CompileCommands("clangd compilation flags options");
83 OptionCategory Features("clangd feature options");
84 OptionCategory Misc("clangd miscellaneous options");
85 OptionCategory Protocol("clangd protocol and logging options");
86 OptionCategory Retired("clangd flags no longer in use");
87 const OptionCategory *ClangdCategories[] = {&Features, &Protocol,
88  &CompileCommands, &Misc, &Retired};
89 
90 template <typename T> class RetiredFlag {
91  opt<T> Option;
92 
93 public:
94  RetiredFlag(llvm::StringRef Name)
95  : Option(Name, cat(Retired), desc("Obsolete flag, ignored"), Hidden,
96  llvm::cl::callback([Name](const T &) {
97  llvm::errs()
98  << "The flag `-" << Name << "` is obsolete and ignored.\n";
99  })) {}
100 };
101 
102 enum CompileArgsFrom { LSPCompileArgs, FilesystemCompileArgs };
103 opt<CompileArgsFrom> CompileArgsFrom{
104  "compile_args_from",
105  cat(CompileCommands),
106  desc("The source of compile commands"),
107  values(clEnumValN(LSPCompileArgs, "lsp",
108  "All compile commands come from LSP and "
109  "'compile_commands.json' files are ignored"),
110  clEnumValN(FilesystemCompileArgs, "filesystem",
111  "All compile commands come from the "
112  "'compile_commands.json' files")),
113  init(FilesystemCompileArgs),
114  Hidden,
115 };
116 
117 opt<Path> CompileCommandsDir{
118  "compile-commands-dir",
119  cat(CompileCommands),
120  desc("Specify a path to look for compile_commands.json. If path "
121  "is invalid, clangd will look in the current directory and "
122  "parent paths of each source file"),
123 };
124 
125 opt<Path> ResourceDir{
126  "resource-dir",
127  cat(CompileCommands),
128  desc("Directory for system clang headers"),
129  init(""),
130  Hidden,
131 };
132 
133 list<std::string> QueryDriverGlobs{
134  "query-driver",
135  cat(CompileCommands),
136  desc(
137  "Comma separated list of globs for white-listing gcc-compatible "
138  "drivers that are safe to execute. Drivers matching any of these globs "
139  "will be used to extract system includes. e.g. "
140  "/usr/bin/**/clang-*,/path/to/repo/**/g++-*"),
141  CommaSeparated,
142 };
143 
144 // FIXME: Flags are the wrong mechanism for user preferences.
145 // We should probably read a dotfile or similar.
146 opt<bool> AllScopesCompletion{
147  "all-scopes-completion",
148  cat(Features),
149  desc("If set to true, code completion will include index symbols that are "
150  "not defined in the scopes (e.g. "
151  "namespaces) visible from the code completion point. Such completions "
152  "can insert scope qualifiers"),
153  init(true),
154 };
155 
156 opt<bool> ShowOrigins{
157  "debug-origin",
158  cat(Features),
159  desc("Show origins of completion items"),
160  init(CodeCompleteOptions().ShowOrigins),
161  Hidden,
162 };
163 
164 opt<bool> EnableBackgroundIndex{
165  "background-index",
166  cat(Features),
167  desc("Index project code in the background and persist index on disk."),
168  init(true),
169 };
170 
171 opt<bool> EnableClangTidy{
172  "clang-tidy",
173  cat(Features),
174  desc("Enable clang-tidy diagnostics"),
175  init(true),
176 };
177 
178 opt<CodeCompleteOptions::CodeCompletionParse> CodeCompletionParse{
179  "completion-parse",
180  cat(Features),
181  desc("Whether the clang-parser is used for code-completion"),
182  values(clEnumValN(CodeCompleteOptions::AlwaysParse, "always",
183  "Block until the parser can be used"),
184  clEnumValN(CodeCompleteOptions::ParseIfReady, "auto",
185  "Use text-based completion if the parser "
186  "is not ready"),
187  clEnumValN(CodeCompleteOptions::NeverParse, "never",
188  "Always used text-based completion")),
189  init(CodeCompleteOptions().RunParser),
190  Hidden,
191 };
192 
193 opt<CodeCompleteOptions::CodeCompletionRankingModel> RankingModel{
194  "ranking-model",
195  cat(Features),
196  desc("Model to use to rank code-completion items"),
197  values(clEnumValN(CodeCompleteOptions::Heuristics, "heuristics",
198  "Use hueristics to rank code completion items"),
199  clEnumValN(CodeCompleteOptions::DecisionForest, "decision_forest",
200  "Use Decision Forest model to rank completion items")),
201  init(CodeCompleteOptions().RankingModel),
202  Hidden,
203 };
204 
205 // FIXME: also support "plain" style where signatures are always omitted.
206 enum CompletionStyleFlag { Detailed, Bundled };
207 opt<CompletionStyleFlag> CompletionStyle{
208  "completion-style",
209  cat(Features),
210  desc("Granularity of code completion suggestions"),
211  values(clEnumValN(Detailed, "detailed",
212  "One completion item for each semantically distinct "
213  "completion, with full type information"),
214  clEnumValN(Bundled, "bundled",
215  "Similar completion items (e.g. function overloads) are "
216  "combined. Type information shown where possible")),
217 };
218 
219 opt<std::string> FallbackStyle{
220  "fallback-style",
221  cat(Features),
222  desc("clang-format style to apply by default when "
223  "no .clang-format file is found"),
224  init(clang::format::DefaultFallbackStyle),
225 };
226 
227 opt<bool> EnableFunctionArgSnippets{
228  "function-arg-placeholders",
229  cat(Features),
230  desc("When disabled, completions contain only parentheses for "
231  "function calls. When enabled, completions also contain "
232  "placeholders for method parameters"),
233  init(CodeCompleteOptions().EnableFunctionArgSnippets),
234  Hidden,
235 };
236 
237 opt<CodeCompleteOptions::IncludeInsertion> HeaderInsertion{
238  "header-insertion",
239  cat(Features),
240  desc("Add #include directives when accepting code completions"),
241  init(CodeCompleteOptions().InsertIncludes),
242  values(
243  clEnumValN(CodeCompleteOptions::IWYU, "iwyu",
244  "Include what you use. "
245  "Insert the owning header for top-level symbols, unless the "
246  "header is already directly included or the symbol is "
247  "forward-declared"),
248  clEnumValN(
250  "Never insert #include directives as part of code completion")),
251 };
252 
253 opt<bool> HeaderInsertionDecorators{
254  "header-insertion-decorators",
255  cat(Features),
256  desc("Prepend a circular dot or space before the completion "
257  "label, depending on whether "
258  "an include line will be inserted or not"),
259  init(true),
260 };
261 
262 opt<bool> HiddenFeatures{
263  "hidden-features",
264  cat(Features),
265  desc("Enable hidden features mostly useful to clangd developers"),
266  init(false),
267  Hidden,
268 };
269 
270 opt<bool> IncludeIneligibleResults{
271  "include-ineligible-results",
272  cat(Features),
273  desc("Include ineligible completion results (e.g. private members)"),
274  init(CodeCompleteOptions().IncludeIneligibleResults),
275  Hidden,
276 };
277 
278 RetiredFlag<bool> EnableIndex("index");
279 RetiredFlag<bool> SuggestMissingIncludes("suggest-missing-includes");
280 RetiredFlag<bool> RecoveryAST("recovery-ast");
281 RetiredFlag<bool> RecoveryASTType("recovery-ast-type");
282 RetiredFlag<bool> AsyncPreamble("async-preamble");
283 RetiredFlag<bool> CollectMainFileRefs("collect-main-file-refs");
284 RetiredFlag<bool> CrossFileRename("cross-file-rename");
285 RetiredFlag<std::string> ClangTidyChecks("clang-tidy-checks");
286 
287 opt<int> LimitResults{
288  "limit-results",
289  cat(Features),
290  desc("Limit the number of results returned by clangd. "
291  "0 means no limit (default=100)"),
292  init(100),
293 };
294 
295 opt<int> ReferencesLimit{
296  "limit-references",
297  cat(Features),
298  desc("Limit the number of references returned by clangd. "
299  "0 means no limit (default=1000)"),
300  init(1000),
301 };
302 
303 list<std::string> TweakList{
304  "tweaks",
305  cat(Features),
306  desc("Specify a list of Tweaks to enable (only for clangd developers)."),
307  Hidden,
308  CommaSeparated,
309 };
310 
311 opt<bool> FoldingRanges{
312  "folding-ranges",
313  cat(Features),
314  desc("Enable preview of FoldingRanges feature"),
315  init(false),
316  Hidden,
317 };
318 
319 opt<bool> InlayHints{"inlay-hints", cat(Features),
320  desc("Enable preview of InlayHints feature"), init(false)};
321 
322 opt<unsigned> WorkerThreadsCount{
323  "j",
324  cat(Misc),
325  desc("Number of async workers used by clangd. Background index also "
326  "uses this many workers."),
328 };
329 
330 opt<Path> IndexFile{
331  "index-file",
332  cat(Misc),
333  desc(
334  "Index file to build the static index. The file must have been created "
335  "by a compatible clangd-indexer\n"
336  "WARNING: This option is experimental only, and will be removed "
337  "eventually. Don't rely on it"),
338  init(""),
339  Hidden,
340 };
341 
342 opt<bool> Test{
343  "lit-test",
344  cat(Misc),
345  desc("Abbreviation for -input-style=delimited -pretty -sync "
346  "-enable-test-scheme -enable-config=0 -log=verbose. "
347  "Intended to simplify lit tests"),
348  init(false),
349  Hidden,
350 };
351 
352 opt<Path> CheckFile{
353  "check",
354  cat(Misc),
355  desc("Parse one file in isolation instead of acting as a language server. "
356  "Useful to investigate/reproduce crashes or configuration problems. "
357  "With --check=<filename>, attempts to parse a particular file."),
358  init(""),
359  ValueOptional,
360 };
361 
362 opt<std::string> CheckFileLines{
363  "check-lines",
364  cat(Misc),
365  desc("If specified, limits the range of tokens in -check file on which "
366  "various features are tested. Example --check-lines=3-7 restricts "
367  "testing to lines 3 to 7 (inclusive) or --check-lines=5 to restrict "
368  "to one line. Default is testing entire file."),
369  init(""),
370  ValueOptional,
371 };
372 
373 enum PCHStorageFlag { Disk, Memory };
374 opt<PCHStorageFlag> PCHStorage{
375  "pch-storage",
376  cat(Misc),
377  desc("Storing PCHs in memory increases memory usages, but may "
378  "improve performance"),
379  values(
380  clEnumValN(PCHStorageFlag::Disk, "disk", "store PCHs on disk"),
381  clEnumValN(PCHStorageFlag::Memory, "memory", "store PCHs in memory")),
382  init(PCHStorageFlag::Disk),
383 };
384 
385 opt<bool> Sync{
386  "sync",
387  cat(Misc),
388  desc("Handle client requests on main thread. Background index still uses "
389  "its own thread."),
390  init(false),
391  Hidden,
392 };
393 
394 opt<JSONStreamStyle> InputStyle{
395  "input-style",
396  cat(Protocol),
397  desc("Input JSON stream encoding"),
398  values(
399  clEnumValN(JSONStreamStyle::Standard, "standard", "usual LSP protocol"),
400  clEnumValN(JSONStreamStyle::Delimited, "delimited",
401  "messages delimited by --- lines, with # comment support")),
403  Hidden,
404 };
405 
406 opt<bool> EnableTestScheme{
407  "enable-test-uri-scheme",
408  cat(Protocol),
409  desc("Enable 'test:' URI scheme. Only use in lit tests"),
410  init(false),
411  Hidden,
412 };
413 
414 opt<std::string> PathMappingsArg{
415  "path-mappings",
416  cat(Protocol),
417  desc(
418  "Translates between client paths (as seen by a remote editor) and "
419  "server paths (where clangd sees files on disk). "
420  "Comma separated list of '<client_path>=<server_path>' pairs, the "
421  "first entry matching a given path is used. "
422  "e.g. /home/project/incl=/opt/include,/home/project=/workarea/project"),
423  init(""),
424 };
425 
426 opt<Path> InputMirrorFile{
427  "input-mirror-file",
428  cat(Protocol),
429  desc("Mirror all LSP input to the specified file. Useful for debugging"),
430  init(""),
431  Hidden,
432 };
433 
434 opt<Logger::Level> LogLevel{
435  "log",
436  cat(Protocol),
437  desc("Verbosity of log messages written to stderr"),
438  values(clEnumValN(Logger::Error, "error", "Error messages only"),
439  clEnumValN(Logger::Info, "info", "High level execution tracing"),
440  clEnumValN(Logger::Debug, "verbose", "Low level details")),
441  init(Logger::Info),
442 };
443 
444 opt<OffsetEncoding> ForceOffsetEncoding{
445  "offset-encoding",
446  cat(Protocol),
447  desc("Force the offsetEncoding used for character positions. "
448  "This bypasses negotiation via client capabilities"),
449  values(
450  clEnumValN(OffsetEncoding::UTF8, "utf-8", "Offsets are in UTF-8 bytes"),
451  clEnumValN(OffsetEncoding::UTF16, "utf-16",
452  "Offsets are in UTF-16 code units"),
453  clEnumValN(OffsetEncoding::UTF32, "utf-32",
454  "Offsets are in unicode codepoints")),
456 };
457 
458 opt<bool> PrettyPrint{
459  "pretty",
460  cat(Protocol),
461  desc("Pretty-print JSON output"),
462  init(false),
463 };
464 
465 opt<bool> EnableConfig{
466  "enable-config",
467  cat(Misc),
468  desc(
469  "Read user and project configuration from YAML files.\n"
470  "Project config is from a .clangd file in the project directory.\n"
471  "User config is from clangd/config.yaml in the following directories:\n"
472  "\tWindows: %USERPROFILE%\\AppData\\Local\n"
473  "\tMac OS: ~/Library/Preferences/\n"
474  "\tOthers: $XDG_CONFIG_HOME, usually ~/.config\n"
475  "Configuration is documented at https://clangd.llvm.org/config.html"),
476  init(true),
477 };
478 
479 #if defined(__GLIBC__) && CLANGD_MALLOC_TRIM
480 opt<bool> EnableMallocTrim{
481  "malloc-trim",
482  cat(Misc),
483  desc("Release memory periodically via malloc_trim(3)."),
484  init(true),
485 };
486 
487 std::function<void()> getMemoryCleanupFunction() {
488  if (!EnableMallocTrim)
489  return nullptr;
490  // Leave a few MB at the top of the heap: it is insignificant
491  // and will most likely be needed by the main thread
492  constexpr size_t MallocTrimPad = 20'000'000;
493  return []() {
494  if (malloc_trim(MallocTrimPad))
495  vlog("Released memory via malloc_trim");
496  };
497 }
498 #else
499 std::function<void()> getMemoryCleanupFunction() { return nullptr; }
500 #endif
501 
502 #if CLANGD_ENABLE_REMOTE
503 opt<std::string> RemoteIndexAddress{
504  "remote-index-address",
505  cat(Features),
506  desc("Address of the remote index server"),
507 };
508 
509 // FIXME(kirillbobyrev): Should this be the location of compile_commands.json?
510 opt<std::string> ProjectRoot{
511  "project-root",
512  cat(Features),
513  desc("Path to the project root. Requires remote-index-address to be set."),
514 };
515 #endif
516 
517 /// Supports a test URI scheme with relaxed constraints for lit tests.
518 /// The path in a test URI will be combined with a platform-specific fake
519 /// directory to form an absolute path. For example, test:///a.cpp is resolved
520 /// C:\clangd-test\a.cpp on Windows and /clangd-test/a.cpp on Unix.
521 class TestScheme : public URIScheme {
522 public:
523  llvm::Expected<std::string>
524  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
525  llvm::StringRef /*HintPath*/) const override {
526  using namespace llvm::sys;
527  // Still require "/" in body to mimic file scheme, as we want lengths of an
528  // equivalent URI in both schemes to be the same.
529  if (!Body.startswith("/"))
530  return error(
531  "Expect URI body to be an absolute path starting with '/': {0}",
532  Body);
533  Body = Body.ltrim('/');
534  llvm::SmallString<16> Path(Body);
535  path::native(Path);
536  fs::make_absolute(TestScheme::TestDir, Path);
537  return std::string(Path);
538  }
539 
540  llvm::Expected<URI>
541  uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
542  llvm::StringRef Body = AbsolutePath;
543  if (!Body.consume_front(TestScheme::TestDir))
544  return error("Path {0} doesn't start with root {1}", AbsolutePath,
545  TestDir);
546 
547  return URI("test", /*Authority=*/"",
548  llvm::sys::path::convert_to_slash(Body));
549  }
550 
551 private:
552  const static char TestDir[];
553 };
554 
555 #ifdef _WIN32
556 const char TestScheme::TestDir[] = "C:\\clangd-test";
557 #else
558 const char TestScheme::TestDir[] = "/clangd-test";
559 #endif
560 
561 std::unique_ptr<SymbolIndex>
562 loadExternalIndex(const Config::ExternalIndexSpec &External,
563  AsyncTaskRunner *Tasks) {
564  static const trace::Metric RemoteIndexUsed("used_remote_index",
565  trace::Metric::Value, "address");
566  switch (External.Kind) {
568  break;
570  RemoteIndexUsed.record(1, External.Location);
571  log("Associating {0} with remote index at {1}.", External.MountPoint,
572  External.Location);
573  return remote::getClient(External.Location, External.MountPoint);
575  log("Associating {0} with monolithic index at {1}.", External.MountPoint,
576  External.Location);
577  auto NewIndex = std::make_unique<SwapIndex>(std::make_unique<MemIndex>());
578  auto IndexLoadTask = [File = External.Location,
579  PlaceHolder = NewIndex.get()] {
580  if (auto Idx = loadIndex(File, /*UseDex=*/true))
581  PlaceHolder->reset(std::move(Idx));
582  };
583  if (Tasks) {
584  Tasks->runAsync("Load-index:" + External.Location,
585  std::move(IndexLoadTask));
586  } else {
587  IndexLoadTask();
588  }
589  return std::move(NewIndex);
590  }
591  llvm_unreachable("Invalid ExternalIndexKind.");
592 }
593 
594 class FlagsConfigProvider : public config::Provider {
595 private:
597 
598  std::vector<config::CompiledFragment>
599  getFragments(const config::Params &,
600  config::DiagnosticCallback) const override {
601  return {Frag};
602  }
603 
604 public:
605  FlagsConfigProvider() {
606  llvm::Optional<Config::CDBSearchSpec> CDBSearch;
607  llvm::Optional<Config::ExternalIndexSpec> IndexSpec;
608  llvm::Optional<Config::BackgroundPolicy> BGPolicy;
609 
610  // If --compile-commands-dir arg was invoked, check value and override
611  // default path.
612  if (!CompileCommandsDir.empty()) {
613  if (llvm::sys::fs::exists(CompileCommandsDir)) {
614  // We support passing both relative and absolute paths to the
615  // --compile-commands-dir argument, but we assume the path is absolute
616  // in the rest of clangd so we make sure the path is absolute before
617  // continuing.
618  llvm::SmallString<128> Path(CompileCommandsDir);
619  if (std::error_code EC = llvm::sys::fs::make_absolute(Path)) {
620  elog("Error while converting the relative path specified by "
621  "--compile-commands-dir to an absolute path: {0}. The argument "
622  "will be ignored.",
623  EC.message());
624  } else {
625  CDBSearch = {Config::CDBSearchSpec::FixedDir, Path.str().str()};
626  }
627  } else {
628  elog("Path specified by --compile-commands-dir does not exist. The "
629  "argument will be ignored.");
630  }
631  }
632  if (!IndexFile.empty()) {
633  Config::ExternalIndexSpec Spec;
634  Spec.Kind = Spec.File;
635  Spec.Location = IndexFile;
636  IndexSpec = std::move(Spec);
637  }
638 #if CLANGD_ENABLE_REMOTE
639  if (!RemoteIndexAddress.empty()) {
640  assert(!ProjectRoot.empty() && IndexFile.empty());
641  Config::ExternalIndexSpec Spec;
642  Spec.Kind = Spec.Server;
643  Spec.Location = RemoteIndexAddress;
644  Spec.MountPoint = ProjectRoot;
645  IndexSpec = std::move(Spec);
647  }
648 #endif
649  if (!EnableBackgroundIndex) {
651  }
652 
653  Frag = [=](const config::Params &, Config &C) {
654  if (CDBSearch)
655  C.CompileFlags.CDBSearch = *CDBSearch;
656  if (IndexSpec)
657  C.Index.External = *IndexSpec;
658  if (BGPolicy)
659  C.Index.Background = *BGPolicy;
660  if (AllScopesCompletion.getNumOccurrences())
661  C.Completion.AllScopes = AllScopesCompletion;
662  return true;
663  };
664  }
665 };
666 } // namespace
667 } // namespace clangd
668 } // namespace clang
669 
670 enum class ErrorResultCode : int {
671  NoShutdownRequest = 1,
673  CheckFailed = 3
674 };
675 
676 int main(int argc, char *argv[]) {
677  using namespace clang;
678  using namespace clang::clangd;
679 
680  llvm::InitializeAllTargetInfos();
681  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
682  llvm::sys::SetInterruptFunction(&requestShutdown);
683  llvm::cl::SetVersionPrinter([](llvm::raw_ostream &OS) {
684  OS << versionString() << "\n"
685  << "Features: " << featureString() << "\n"
686  << "Platform: " << platformString() << "\n";
687  });
688  const char *FlagsEnvVar = "CLANGD_FLAGS";
689  const char *Overview =
690  R"(clangd is a language server that provides IDE-like features to editors.
691 
692 It should be used via an editor plugin rather than invoked directly. For more information, see:
693  https://clangd.llvm.org/
694  https://microsoft.github.io/language-server-protocol/
695 
696 clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment variable.
697 )";
698  llvm::cl::HideUnrelatedOptions(ClangdCategories);
699  llvm::cl::ParseCommandLineOptions(argc, argv, Overview,
700  /*Errs=*/nullptr, FlagsEnvVar);
701  if (Test) {
702  Sync = true;
703  InputStyle = JSONStreamStyle::Delimited;
704  LogLevel = Logger::Verbose;
705  PrettyPrint = true;
706  // Disable config system by default to avoid external reads.
707  if (!EnableConfig.getNumOccurrences())
708  EnableConfig = false;
709  // Disable background index on lit tests by default to prevent disk writes.
710  if (!EnableBackgroundIndex.getNumOccurrences())
711  EnableBackgroundIndex = false;
712  // Ensure background index makes progress.
713  else if (EnableBackgroundIndex)
715  }
716  if (Test || EnableTestScheme) {
717  static URISchemeRegistry::Add<TestScheme> X(
718  "test", "Test scheme for clangd lit tests.");
719  }
720 
721  if (!Sync && WorkerThreadsCount == 0) {
722  llvm::errs() << "A number of worker threads cannot be 0. Did you mean to "
723  "specify -sync?";
724  return 1;
725  }
726 
727  if (Sync) {
728  if (WorkerThreadsCount.getNumOccurrences())
729  llvm::errs() << "Ignoring -j because -sync is set.\n";
730  WorkerThreadsCount = 0;
731  }
732  if (FallbackStyle.getNumOccurrences())
733  clang::format::DefaultFallbackStyle = FallbackStyle.c_str();
734 
735  // Validate command line arguments.
736  llvm::Optional<llvm::raw_fd_ostream> InputMirrorStream;
737  if (!InputMirrorFile.empty()) {
738  std::error_code EC;
739  InputMirrorStream.emplace(InputMirrorFile, /*ref*/ EC,
740  llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
741  if (EC) {
742  InputMirrorStream.reset();
743  llvm::errs() << "Error while opening an input mirror file: "
744  << EC.message();
745  } else {
746  InputMirrorStream->SetUnbuffered();
747  }
748  }
749 
750  // Setup tracing facilities if CLANGD_TRACE is set. In practice enabling a
751  // trace flag in your editor's config is annoying, launching with
752  // `CLANGD_TRACE=trace.json vim` is easier.
753  llvm::Optional<llvm::raw_fd_ostream> TracerStream;
754  std::unique_ptr<trace::EventTracer> Tracer;
755  const char *JSONTraceFile = getenv("CLANGD_TRACE");
756  const char *MetricsCSVFile = getenv("CLANGD_METRICS");
757  const char *TracerFile = JSONTraceFile ? JSONTraceFile : MetricsCSVFile;
758  if (TracerFile) {
759  std::error_code EC;
760  TracerStream.emplace(TracerFile, /*ref*/ EC,
761  llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
762  if (EC) {
763  TracerStream.reset();
764  llvm::errs() << "Error while opening trace file " << TracerFile << ": "
765  << EC.message();
766  } else {
767  Tracer = (TracerFile == JSONTraceFile)
768  ? trace::createJSONTracer(*TracerStream, PrettyPrint)
769  : trace::createCSVMetricTracer(*TracerStream);
770  }
771  }
772 
773  llvm::Optional<trace::Session> TracingSession;
774  if (Tracer)
775  TracingSession.emplace(*Tracer);
776 
777  // If a user ran `clangd` in a terminal without redirecting anything,
778  // it's somewhat likely they're confused about how to use clangd.
779  // Show them the help overview, which explains.
780  if (llvm::outs().is_displayed() && llvm::errs().is_displayed() &&
781  !CheckFile.getNumOccurrences())
782  llvm::errs() << Overview << "\n";
783  // Use buffered stream to stderr (we still flush each log message). Unbuffered
784  // stream can cause significant (non-deterministic) latency for the logger.
785  llvm::errs().SetBuffered();
786  // Don't flush stdout when logging, this would be both slow and racy!
787  llvm::errs().tie(nullptr);
788  StreamLogger Logger(llvm::errs(), LogLevel);
790  // Write some initial logs before we start doing any real work.
791  log("{0}", versionString());
792  log("Features: {0}", featureString());
793  log("PID: {0}", llvm::sys::Process::getProcessId());
794  {
795  SmallString<128> CWD;
796  if (auto Err = llvm::sys::fs::current_path(CWD))
797  log("Working directory unknown: {0}", Err.message());
798  else
799  log("Working directory: {0}", CWD);
800  }
801  for (int I = 0; I < argc; ++I)
802  log("argv[{0}]: {1}", I, argv[I]);
803  if (auto EnvFlags = llvm::sys::Process::GetEnv(FlagsEnvVar))
804  log("{0}: {1}", FlagsEnvVar, *EnvFlags);
805 
807  Opts.UseDirBasedCDB = (CompileArgsFrom == FilesystemCompileArgs);
808 
809  switch (PCHStorage) {
810  case PCHStorageFlag::Memory:
811  Opts.StorePreamblesInMemory = true;
812  break;
813  case PCHStorageFlag::Disk:
814  Opts.StorePreamblesInMemory = false;
815  break;
816  }
817  if (!ResourceDir.empty())
818  Opts.ResourceDir = ResourceDir;
819  Opts.BuildDynamicSymbolIndex = true;
820  std::vector<std::unique_ptr<SymbolIndex>> IdxStack;
821  std::unique_ptr<SymbolIndex> StaticIdx;
822 #if CLANGD_ENABLE_REMOTE
823  if (RemoteIndexAddress.empty() != ProjectRoot.empty()) {
824  llvm::errs() << "remote-index-address and project-path have to be "
825  "specified at the same time.";
826  return 1;
827  }
828  if (!RemoteIndexAddress.empty()) {
829  if (IndexFile.empty()) {
830  log("Connecting to remote index at {0}", RemoteIndexAddress);
831  } else {
832  elog("When enabling remote index, IndexFile should not be specified. "
833  "Only one can be used at time. Remote index will ignored.");
834  }
835  }
836 #endif
837  Opts.BackgroundIndex = EnableBackgroundIndex;
838  Opts.ReferencesLimit = ReferencesLimit;
839  auto PAI = createProjectAwareIndex(loadExternalIndex, Sync);
840  if (StaticIdx) {
841  IdxStack.emplace_back(std::move(StaticIdx));
842  IdxStack.emplace_back(
843  std::make_unique<MergedIndex>(PAI.get(), IdxStack.back().get()));
844  Opts.StaticIndex = IdxStack.back().get();
845  } else {
846  Opts.StaticIndex = PAI.get();
847  }
848  Opts.AsyncThreadsCount = WorkerThreadsCount;
849  Opts.FoldingRanges = FoldingRanges;
850  Opts.InlayHints = InlayHints;
851  Opts.MemoryCleanup = getMemoryCleanupFunction();
852 
853  Opts.CodeComplete.IncludeIneligibleResults = IncludeIneligibleResults;
854  Opts.CodeComplete.Limit = LimitResults;
855  if (CompletionStyle.getNumOccurrences())
856  Opts.CodeComplete.BundleOverloads = CompletionStyle != Detailed;
857  Opts.CodeComplete.ShowOrigins = ShowOrigins;
858  Opts.CodeComplete.InsertIncludes = HeaderInsertion;
859  if (!HeaderInsertionDecorators) {
860  Opts.CodeComplete.IncludeIndicator.Insert.clear();
861  Opts.CodeComplete.IncludeIndicator.NoInsert.clear();
862  }
863  Opts.CodeComplete.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
864  Opts.CodeComplete.RunParser = CodeCompletionParse;
865  Opts.CodeComplete.RankingModel = RankingModel;
866 
867  RealThreadsafeFS TFS;
868  std::vector<std::unique_ptr<config::Provider>> ProviderStack;
869  std::unique_ptr<config::Provider> Config;
870  if (EnableConfig) {
871  ProviderStack.push_back(
873  llvm::SmallString<256> UserConfig;
874  if (llvm::sys::path::user_config_directory(UserConfig)) {
875  llvm::sys::path::append(UserConfig, "clangd", "config.yaml");
876  vlog("User config file is {0}", UserConfig);
877  ProviderStack.push_back(config::Provider::fromYAMLFile(
878  UserConfig, /*Directory=*/"", TFS, /*Trusted=*/true));
879  } else {
880  elog("Couldn't determine user config file, not loading");
881  }
882  }
883  ProviderStack.push_back(std::make_unique<FlagsConfigProvider>());
884  std::vector<const config::Provider *> ProviderPointers;
885  for (const auto &P : ProviderStack)
886  ProviderPointers.push_back(P.get());
887  Config = config::Provider::combine(std::move(ProviderPointers));
888  Opts.ConfigProvider = Config.get();
889 
890  // Create an empty clang-tidy option.
891  TidyProvider ClangTidyOptProvider;
892  if (EnableClangTidy) {
893  std::vector<TidyProvider> Providers;
894  Providers.reserve(4 + EnableConfig);
895  Providers.push_back(provideEnvironment());
896  Providers.push_back(provideClangTidyFiles(TFS));
897  if (EnableConfig)
898  Providers.push_back(provideClangdConfig());
899  Providers.push_back(provideDefaultChecks());
900  Providers.push_back(disableUnusableChecks());
901  ClangTidyOptProvider = combine(std::move(Providers));
902  Opts.ClangTidyProvider = ClangTidyOptProvider;
903  }
904  Opts.QueryDriverGlobs = std::move(QueryDriverGlobs);
905  Opts.TweakFilter = [&](const Tweak &T) {
906  if (T.hidden() && !HiddenFeatures)
907  return false;
908  if (TweakList.getNumOccurrences())
909  return llvm::is_contained(TweakList, T.id());
910  return true;
911  };
912  if (ForceOffsetEncoding != OffsetEncoding::UnsupportedEncoding)
913  Opts.Encoding = ForceOffsetEncoding;
914 
915  if (CheckFile.getNumOccurrences()) {
916  llvm::SmallString<256> Path;
917  if (auto Error =
918  llvm::sys::fs::real_path(CheckFile, Path, /*expand_tilde=*/true)) {
919  elog("Failed to resolve path {0}: {1}", CheckFile, Error.message());
920  return 1;
921  }
922  log("Entering check mode (no LSP server)");
923  uint32_t Begin = 0, End = std::numeric_limits<uint32_t>::max();
924  if (!CheckFileLines.empty()) {
925  StringRef RangeStr(CheckFileLines);
926  bool ParseError = RangeStr.consumeInteger(0, Begin);
927  if (RangeStr.empty()) {
928  End = Begin;
929  } else {
930  ParseError |= !RangeStr.consume_front("-");
931  ParseError |= RangeStr.consumeInteger(0, End);
932  }
933  if (ParseError || !RangeStr.empty()) {
934  elog("Invalid --check-line specified. Use Begin-End format, e.g. 3-17");
935  return 1;
936  }
937  }
938  auto ShouldCheckLine = [&](const Position &Pos) {
939  uint32_t Line = Pos.line + 1; // Position::line is 0-based.
940  return Line >= Begin && Line <= End;
941  };
942  // For now code completion is enabled any time the range is limited via
943  // --check-lines. If it turns out to be to slow, we can introduce a
944  // dedicated flag for that instead.
945  return check(Path, ShouldCheckLine, TFS, Opts,
946  /*EnableCodeCompletion=*/!CheckFileLines.empty())
947  ? 0
948  : static_cast<int>(ErrorResultCode::CheckFailed);
949  }
950  if (!CheckFileLines.empty()) {
951  elog("--check-lines requires --check");
952  return 1;
953  }
954 
955  // Initialize and run ClangdLSPServer.
956  // Change stdin to binary to not lose \r\n on windows.
957  llvm::sys::ChangeStdinToBinary();
958  std::unique_ptr<Transport> TransportLayer;
959  if (getenv("CLANGD_AS_XPC_SERVICE")) {
960 #if CLANGD_BUILD_XPC
961  log("Starting LSP over XPC service");
962  TransportLayer = newXPCTransport();
963 #else
964  llvm::errs() << "This clangd binary wasn't built with XPC support.\n";
965  return static_cast<int>(ErrorResultCode::CantRunAsXPCService);
966 #endif
967  } else {
968  log("Starting LSP over stdin/stdout");
969  TransportLayer = newJSONTransport(
970  stdin, llvm::outs(),
971  InputMirrorStream ? InputMirrorStream.getPointer() : nullptr,
972  PrettyPrint, InputStyle);
973  }
974  if (!PathMappingsArg.empty()) {
975  auto Mappings = parsePathMappings(PathMappingsArg);
976  if (!Mappings) {
977  elog("Invalid -path-mappings: {0}", Mappings.takeError());
978  return 1;
979  }
980  TransportLayer = createPathMappingTransport(std::move(TransportLayer),
981  std::move(*Mappings));
982  }
983 
984  ClangdLSPServer LSPServer(*TransportLayer, TFS, Opts);
985  llvm::set_thread_name("clangd.main");
986  int ExitCode = LSPServer.run()
987  ? 0
988  : static_cast<int>(ErrorResultCode::NoShutdownRequest);
989  log("LSP finished, exiting with status {0}", ExitCode);
990 
991  // There may still be lingering background threads (e.g. slow requests
992  // whose results will be dropped, background index shutting down).
993  //
994  // These should terminate quickly, and ~ClangdLSPServer blocks on them.
995  // However if a bug causes them to run forever, we want to ensure the process
996  // eventually exits. As clangd isn't directly user-facing, an editor can
997  // "leak" clangd processes. Crashing in this case contains the damage.
998  abortAfterTimeout(std::chrono::minutes(5));
999 
1000  return ExitCode;
1001 }
clang::clangd::versionString
std::string versionString()
Definition: Feature.cpp:17
Client.h
clang::clangd::ClangdLSPServer::run
bool run()
Run LSP server loop, communicating with the Transport provided in the constructor.
Definition: ClangdLSPServer.cpp:1508
clang::clangd::CodeCompleteOptions::RunParser
enum clang::clangd::CodeCompleteOptions::CodeCompletionParse RunParser
clang::clangd::Logger::Debug
@ Debug
Definition: Logger.h:29
llvm
Some operations such as code completion produce a set of candidates.
Definition: YAMLGenerator.cpp:28
Shutdown.h
clang::clangd::createProjectAwareIndex
std::unique_ptr< SymbolIndex > createProjectAwareIndex(IndexFactory Gen, bool Sync)
Returns an index that answers queries using external indices.
Definition: ProjectAware.cpp:142
clang::clangd::ErrorCode::ParseError
@ ParseError
clang::clangd::provideClangdConfig
TidyProviderRef provideClangdConfig()
Definition: TidyProvider.cpp:246
Background.h
clang::clangd::CodeCompleteOptions::IncludeInsertionIndicator::Insert
std::string Insert
Definition: CodeComplete.h:79
clang::clangd::Config::BackgroundPolicy::Skip
@ Skip
clang::clangd::Logger::Info
@ Info
Definition: Logger.h:29
clang::clangd::getDefaultAsyncThreadsCount
unsigned getDefaultAsyncThreadsCount()
Returns a number of a default async threads to use for TUScheduler.
Definition: TUScheduler.cpp:1432
CodeComplete.h
ErrorResultCode::CheckFailed
@ CheckFailed
clang::clangd::CodeCompleteOptions::ShowOrigins
bool ShowOrigins
Expose origins of completion items in the label (for debugging).
Definition: CodeComplete.h:84
clang::clangd::Path
std::string Path
A typedef to represent a file path.
Definition: Path.h:26
clang::clangd::Logger::Verbose
@ Verbose
Definition: Logger.h:29
Tracer
std::unique_ptr< trace::EventTracer > Tracer
Definition: TraceTests.cpp:164
clang::clangd::error
llvm::Error error(std::error_code EC, const char *Fmt, Ts &&... Vals)
Definition: Logger.h:80
Path.h
clang::clangd::CodeCompleteOptions::InsertIncludes
enum clang::clangd::CodeCompleteOptions::IncludeInsertion InsertIncludes
clang::clangd::Logger
Interface to allow custom logging in clangd.
Definition: Logger.h:23
clang::clangd::StreamLogger
Definition: Logger.h:120
Index.h
clang::clangd::OffsetEncoding::UTF32
@ UTF32
clang::clangd::provideClangTidyFiles
TidyProvider provideClangTidyFiles(ThreadsafeFS &TFS)
Provider that searches for .clang-tidy configuration files in the directory tree.
Definition: TidyProvider.cpp:259
clang::clangd::CodeCompleteOptions::ParseIfReady
@ ParseIfReady
Run the parser if inputs (preamble) are ready.
Definition: CodeComplete.h:117
clang::clangd::X
static URISchemeRegistry::Add< TestScheme > X(TestScheme::Scheme, "Test schema")
Feature.h
ConfigProvider.h
Trace.h
llvm::sys
Definition: BenchmarkHeader.h:10
clang::clangd::TestScheme::getAbsolutePath
llvm::Expected< std::string > getAbsolutePath(llvm::StringRef, llvm::StringRef Body, llvm::StringRef HintPath) const override
Returns the absolute path of the file corresponding to the URI authority+body in the file system.
Definition: TestFS.cpp:100
clang::clangd::CodeCompleteOptions::DecisionForest
@ DecisionForest
Definition: CodeComplete.h:135
clang::clangd::Config::ExternalIndexSpec::File
@ File
Definition: Config.h:73
clang::clangd::CodeCompleteOptions::EnableFunctionArgSnippets
bool EnableFunctionArgSnippets
Whether to generate snippets for function arguments on code-completion.
Definition: CodeComplete.h:100
clang::clangd::abortAfterTimeout
void abortAfterTimeout(std::chrono::seconds Timeout)
Causes this process to crash if still running after Timeout.
Definition: Shutdown.cpp:18
clang::clangd::featureString
std::string featureString()
Definition: Feature.cpp:32
clang::clangd::RealThreadsafeFS
Definition: ThreadsafeFS.h:49
clang::clangd::trace::createJSONTracer
std::unique_ptr< EventTracer > createJSONTracer(llvm::raw_ostream &OS, bool Pretty)
Create an instance of EventTracer that produces an output in the Trace Event format supported by Chro...
Definition: Trace.cpp:269
clang::clangd::requestShutdown
void requestShutdown()
Sets a flag to indicate that clangd was sent a shutdown signal, and the transport loop should exit at...
Definition: Shutdown.cpp:28
ProjectAware.h
clang::clangd
Definition: AST.cpp:41
clang::clangd::Config::CDBSearchSpec::FixedDir
@ FixedDir
Definition: Config.h:56
clang::clangd::OffsetEncoding::UTF8
@ UTF8
clang::clangd::Position::line
int line
Line position in a document (zero-based).
Definition: Protocol.h:150
run-clang-tidy.make_absolute
def make_absolute(f, directory)
Definition: run-clang-tidy.py:76
clang::clangd::ClangdLSPServer::Options
Definition: ClangdLSPServer.h:44
Protocol.h
ThreadsafeFS.h
clang::clangd::newXPCTransport
std::unique_ptr< Transport > newXPCTransport()
Definition: XPCTransport.cpp:212
clang::clangd::CodeCompleteOptions::IncludeIndicator
struct clang::clangd::CodeCompleteOptions::IncludeInsertionIndicator IncludeIndicator
clang::clangd::ClangdLSPServer
This class exposes ClangdServer's capabilities via Language Server Protocol.
Definition: ClangdLSPServer.h:41
Rename.h
clang::clangd::trace::createCSVMetricTracer
std::unique_ptr< EventTracer > createCSVMetricTracer(llvm::raw_ostream &OS)
Create an instance of EventTracer that outputs metric measurements as CSV.
Definition: Trace.cpp:274
clang::clangd::Position
Definition: Protocol.h:148
ClangdLSPServer.h
Line
int Line
Definition: PreprocessorTracker.cpp:514
TidyProvider.h
clang::clangd::CodeCompleteOptions::IncludeIneligibleResults
bool IncludeIneligibleResults
Include results that are not legal completions in the current context.
Definition: CodeComplete.h:56
clang::clangd::TidyProvider
llvm::unique_function< void(tidy::ClangTidyOptions &, llvm::StringRef) const > TidyProvider
A factory to modify a tidy::ClangTidyOptions.
Definition: TidyProvider.h:24
clang::clangd::OffsetEncoding::UTF16
@ UTF16
clang::clangd::provideEnvironment
TidyProviderRef provideEnvironment()
Provider that just sets the defaults.
Definition: TidyProvider.cpp:152
if
if(CLANGD_ENABLE_REMOTE) generate_protos(RemoteIndexProto "Index.proto") generate_protos(MonitoringServiceProto "MonitoringService.proto" GRPC) generate_protos(RemoteIndexServiceProto "Service.proto" DEPENDS "Index.proto" GRPC) target_link_libraries(RemoteIndexServiceProto PRIVATE RemoteIndexProto MonitoringServiceProto) include_directories($
Definition: clangd/index/remote/CMakeLists.txt:1
clang::clangd::BackgroundQueue::preventThreadStarvationInTests
static void preventThreadStarvationInTests()
Definition: BackgroundQueue.cpp:17
Name
static constexpr llvm::StringLiteral Name
Definition: UppercaseLiteralSuffixCheck.cpp:28
PathMapping.h
clang::clangd::Config::ExternalIndexSpec::None
@ None
Definition: Config.h:73
clang::clangd::loadIndex
std::unique_ptr< SymbolIndex > loadIndex(llvm::StringRef SymbolFilename, bool UseDex)
Definition: Serialization.cpp:698
ErrorResultCode
ErrorResultCode
Definition: ClangdMain.cpp:670
clang::clangd::platformString
std::string platformString()
Definition: Feature.cpp:19
main
int main(int argc, char *argv[])
Definition: ClangdMain.cpp:676
clang::clangd::remote::getClient
std::unique_ptr< clangd::SymbolIndex > getClient(llvm::StringRef Address, llvm::StringRef ProjectRoot)
Returns an SymbolIndex client that passes requests to remote index located at Address.
Definition: Client.cpp:185
clang::clangd::CodeCompleteOptions::NeverParse
@ NeverParse
Always use text-based completion.
Definition: CodeComplete.h:119
clang::clangd::LoggingSession
Only one LoggingSession can be active at a time.
Definition: Logger.h:107
Serialization.h
clang::clangd::vlog
void vlog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:73
clang::clangd::CodeCompleteOptions::BundleOverloads
llvm::Optional< bool > BundleOverloads
Combine overloads into a single completion item where possible.
Definition: CodeComplete.h:62
clang::clangd::config::Provider::fromAncestorRelativeYAMLFiles
static std::unique_ptr< Provider > fromAncestorRelativeYAMLFiles(llvm::StringRef RelPath, const ThreadsafeFS &, bool Trusted=false)
Definition: ConfigProvider.cpp:84
clang::clangd::Standard
@ Standard
Definition: Transport.h:68
ErrorResultCode::NoShutdownRequest
@ NoShutdownRequest
clang::clangd::config::CompiledFragment
std::function< bool(const Params &, Config &)> CompiledFragment
A chunk of configuration that has been fully analyzed and is ready to apply.
Definition: ConfigProvider.h:58
clang::clangd::check
bool check(llvm::StringRef File, llvm::function_ref< bool(const Position &)> ShouldCheckLine, const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts, bool EnableCodeCompletion)
Definition: Check.cpp:253
clang::clangd::log
void log(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:68
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))
clang::clangd::Logger::Error
@ Error
Definition: Logger.h:29
clang::clangd::CodeCompleteOptions::NeverInsert
@ NeverInsert
Definition: CodeComplete.h:73
Transport.h
clang::clangd::Config::ExternalIndexSpec::Server
@ Server
Definition: Config.h:73
Config.h
clang::clangd::config::Provider::fromYAMLFile
static std::unique_ptr< Provider > fromYAMLFile(llvm::StringRef AbsPath, llvm::StringRef Directory, const ThreadsafeFS &, bool Trusted=false)
Reads fragments from a single YAML file with a fixed path.
Definition: ConfigProvider.cpp:56
clang::clangd::config::Provider::combine
static std::unique_ptr< Provider > combine(std::vector< const Provider * >)
A provider that includes fragments from all the supplied providers.
Definition: ConfigProvider.cpp:147
clang::clangd::CodeCompleteOptions::RankingModel
enum clang::clangd::CodeCompleteOptions::CodeCompletionRankingModel RankingModel
clang::clangd::CodeCompleteOptions::IncludeInsertionIndicator::NoInsert
std::string NoInsert
Definition: CodeComplete.h:80
Frag
Fragment Frag
Definition: ConfigCompileTests.cpp:40
C
const Criteria C
Definition: FunctionCognitiveComplexityCheck.cpp:93
clang::clangd::CodeCompleteOptions::AlwaysParse
@ AlwaysParse
Block until we can run the parser (e.g.
Definition: CodeComplete.h:114
clang::clangd::TestScheme::uriFromAbsolutePath
llvm::Expected< URI > uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override
Definition: TestFS.cpp:113
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
OS
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:163
clang::clangd::disableUnusableChecks
TidyProvider disableUnusableChecks(llvm::ArrayRef< std::string > ExtraBadChecks)
Provider that will disable checks known to not work with clangd.
Definition: TidyProvider.cpp:197
clang::clangd::CodeCompleteOptions::Limit
size_t Limit
Limit the number of results returned (0 means no limit).
Definition: CodeComplete.h:66
clang::clangd::trace::Metric::Value
@ Value
A number whose value is meaningful, and may vary over time.
Definition: Trace.h:42
clang::clangd::Tweak
An interface base for small context-sensitive refactoring actions.
Definition: Tweak.h:49
clang::clangd::newJSONTransport
std::unique_ptr< Transport > newJSONTransport(std::FILE *In, llvm::raw_ostream &Out, llvm::raw_ostream *InMirror, bool Pretty, JSONStreamStyle Style)
Definition: JSONTransport.cpp:323
clang::clangd::provideDefaultChecks
TidyProviderRef provideDefaultChecks()
Provider that will enable a nice set of default checks if none are specified.
Definition: TidyProvider.cpp:170
clang::clangd::CodeCompleteOptions::IWYU
@ IWYU
Definition: CodeComplete.h:72
clang::clangd::OffsetEncoding::UnsupportedEncoding
@ UnsupportedEncoding
ErrorResultCode::CantRunAsXPCService
@ CantRunAsXPCService
clang::clangd::parsePathMappings
llvm::Expected< PathMappings > parsePathMappings(llvm::StringRef RawPathMappings)
Parse the command line RawPathMappings (e.g.
Definition: PathMapping.cpp:170
clang::clangd::Delimited
@ Delimited
Definition: Transport.h:70
Pos
Position Pos
Definition: SourceCode.cpp:657
Merge.h
clang::clangd::CodeCompleteOptions::Heuristics
@ Heuristics
Definition: CodeComplete.h:134
clang::clangd::elog
void elog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:62
clang::clangd::createPathMappingTransport
std::unique_ptr< Transport > createPathMappingTransport(std::unique_ptr< Transport > Transp, PathMappings Mappings)
Creates a wrapping transport over Transp that applies the Mappings to all inbound and outbound LSP me...
Definition: PathMapping.cpp:191
clang::clangd::combine
TidyProvider combine(std::vector< TidyProvider > Providers)
Definition: TidyProvider.cpp:266
clang::clangd::MessageType::Error
@ Error
An error message.
clang::clangd::config::DiagnosticCallback
llvm::function_ref< void(const llvm::SMDiagnostic &)> DiagnosticCallback
Used to report problems in parsing or interpreting a config.
Definition: ConfigProvider.h:51