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