clang-tools  9.0.0
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 "Features.inc"
12 #include "Path.h"
13 #include "Protocol.h"
14 #include "Trace.h"
15 #include "Transport.h"
16 #include "index/Background.h"
17 #include "index/Serialization.h"
18 #include "clang/Basic/Version.h"
19 #include "clang/Format/Format.h"
20 #include "llvm/ADT/Optional.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/Path.h"
25 #include "llvm/Support/Process.h"
26 #include "llvm/Support/Program.h"
27 #include "llvm/Support/Signals.h"
28 #include "llvm/Support/TargetSelect.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include <cstdlib>
31 #include <iostream>
32 #include <memory>
33 #include <mutex>
34 #include <string>
35 #include <thread>
36 
37 namespace clang {
38 namespace clangd {
39 namespace {
40 
41 using llvm::cl::cat;
42 using llvm::cl::CommaSeparated;
43 using llvm::cl::desc;
44 using llvm::cl::Hidden;
45 using llvm::cl::init;
46 using llvm::cl::list;
47 using llvm::cl::opt;
48 using llvm::cl::OptionCategory;
49 using llvm::cl::values;
50 
51 // All flags must be placed in a category, or they will be shown neither in
52 // --help, nor --help-hidden!
53 OptionCategory CompileCommands("clangd compilation flags options");
54 OptionCategory Features("clangd feature options");
55 OptionCategory Misc("clangd miscellaneous options");
56 OptionCategory Protocol("clangd protocol and logging options");
57 const OptionCategory *ClangdCategories[] = {&Features, &Protocol,
58  &CompileCommands, &Misc};
59 
60 enum CompileArgsFrom { LSPCompileArgs, FilesystemCompileArgs };
61 opt<CompileArgsFrom> CompileArgsFrom{
62  "compile_args_from",
63  cat(CompileCommands),
64  desc("The source of compile commands"),
65  values(clEnumValN(LSPCompileArgs, "lsp",
66  "All compile commands come from LSP and "
67  "'compile_commands.json' files are ignored"),
68  clEnumValN(FilesystemCompileArgs, "filesystem",
69  "All compile commands come from the "
70  "'compile_commands.json' files")),
71  init(FilesystemCompileArgs),
72  Hidden,
73 };
74 
75 opt<Path> CompileCommandsDir{
76  "compile-commands-dir",
77  cat(CompileCommands),
78  desc("Specify a path to look for compile_commands.json. If path "
79  "is invalid, clangd will look in the current directory and "
80  "parent paths of each source file"),
81 };
82 
83 opt<Path> ResourceDir{
84  "resource-dir",
85  cat(CompileCommands),
86  desc("Directory for system clang headers"),
87  init(""),
88  Hidden,
89 };
90 
91 list<std::string> QueryDriverGlobs{
92  "query-driver",
93  cat(CompileCommands),
94  desc(
95  "Comma separated list of globs for white-listing gcc-compatible "
96  "drivers that are safe to execute. Drivers matching any of these globs "
97  "will be used to extract system includes. e.g. "
98  "/usr/bin/**/clang-*,/path/to/repo/**/g++-*"),
99  CommaSeparated,
100 };
101 
102 // FIXME: Flags are the wrong mechanism for user preferences.
103 // We should probably read a dotfile or similar.
104 opt<bool> AllScopesCompletion{
105  "all-scopes-completion",
106  cat(Features),
107  desc("If set to true, code completion will include index symbols that are "
108  "not defined in the scopes (e.g. "
109  "namespaces) visible from the code completion point. Such completions "
110  "can insert scope qualifiers"),
111  init(true),
112 };
113 
114 opt<bool> ShowOrigins{
115  "debug-origin",
116  cat(Features),
117  desc("Show origins of completion items"),
118  init(CodeCompleteOptions().ShowOrigins),
119  Hidden,
120 };
121 
122 opt<bool> EnableBackgroundIndex{
123  "background-index",
124  cat(Features),
125  desc("Index project code in the background and persist index on disk."),
126  init(true),
127 };
128 
129 opt<bool> EnableClangTidy{
130  "clang-tidy",
131  cat(Features),
132  desc("Enable clang-tidy diagnostics"),
133  init(true),
134 };
135 
136 opt<std::string> ClangTidyChecks{
137  "clang-tidy-checks",
138  cat(Features),
139  desc("List of clang-tidy checks to run (this will override "
140  ".clang-tidy files). Only meaningful when -clang-tidy flag is on"),
141  init(""),
142 };
143 
144 opt<CodeCompleteOptions::CodeCompletionParse> CodeCompletionParse{
145  "completion-parse",
146  cat(Features),
147  desc("Whether the clang-parser is used for code-completion"),
148  values(clEnumValN(CodeCompleteOptions::AlwaysParse, "always",
149  "Block until the parser can be used"),
150  clEnumValN(CodeCompleteOptions::ParseIfReady, "auto",
151  "Use text-based completion if the parser "
152  "is not ready"),
153  clEnumValN(CodeCompleteOptions::NeverParse, "never",
154  "Always used text-based completion")),
155  init(CodeCompleteOptions().RunParser),
156  Hidden,
157 };
158 
159 // FIXME: also support "plain" style where signatures are always omitted.
160 enum CompletionStyleFlag { Detailed, Bundled };
161 opt<CompletionStyleFlag> CompletionStyle{
162  "completion-style",
163  cat(Features),
164  desc("Granularity of code completion suggestions"),
165  values(clEnumValN(Detailed, "detailed",
166  "One completion item for each semantically distinct "
167  "completion, with full type information"),
168  clEnumValN(Bundled, "bundled",
169  "Similar completion items (e.g. function overloads) are "
170  "combined. Type information shown where possible")),
171 };
172 
173 opt<std::string> FallbackStyle{
174  "fallback-style",
175  cat(Features),
176  desc("clang-format style to apply by default when "
177  "no .clang-format file is found"),
178  init(clang::format::DefaultFallbackStyle),
179 };
180 
181 opt<bool> EnableFunctionArgSnippets{
182  "function-arg-placeholders",
183  cat(Features),
184  desc("When disabled, completions contain only parentheses for "
185  "function calls. When enabled, completions also contain "
186  "placeholders for method parameters"),
187  init(CodeCompleteOptions().EnableFunctionArgSnippets),
188  Hidden,
189 };
190 
191 opt<CodeCompleteOptions::IncludeInsertion> HeaderInsertion{
192  "header-insertion",
193  cat(Features),
194  desc("Add #include directives when accepting code completions"),
195  init(CodeCompleteOptions().InsertIncludes),
196  values(
197  clEnumValN(CodeCompleteOptions::IWYU, "iwyu",
198  "Include what you use. "
199  "Insert the owning header for top-level symbols, unless the "
200  "header is already directly included or the symbol is "
201  "forward-declared"),
202  clEnumValN(
204  "Never insert #include directives as part of code completion")),
205 };
206 
207 opt<bool> HeaderInsertionDecorators{
208  "header-insertion-decorators",
209  cat(Features),
210  desc("Prepend a circular dot or space before the completion "
211  "label, depending on whether "
212  "an include line will be inserted or not"),
213  init(true),
214 };
215 
216 opt<bool> HiddenFeatures{
217  "hidden-features",
218  cat(Features),
219  desc("Enable hidden features mostly useful to clangd developers"),
220  init(false),
221  Hidden,
222 };
223 
224 opt<bool> IncludeIneligibleResults{
225  "include-ineligible-results",
226  cat(Features),
227  desc("Include ineligible completion results (e.g. private members)"),
228  init(CodeCompleteOptions().IncludeIneligibleResults),
229  Hidden,
230 };
231 
232 opt<bool> EnableIndex{
233  "index",
234  cat(Features),
235  desc("Enable index-based features. By default, clangd maintains an index "
236  "built from symbols in opened files. Global index support needs to "
237  "enabled separatedly"),
238  init(true),
239  Hidden,
240 };
241 
242 opt<int> LimitResults{
243  "limit-results",
244  cat(Features),
245  desc("Limit the number of results returned by clangd. "
246  "0 means no limit (default=100)"),
247  init(100),
248 };
249 
250 opt<bool> SuggestMissingIncludes{
251  "suggest-missing-includes",
252  cat(Features),
253  desc("Attempts to fix diagnostic errors caused by missing "
254  "includes using index"),
255  init(true),
256 };
257 
258 list<std::string> TweakList{
259  "tweaks",
260  cat(Features),
261  desc("Specify a list of Tweaks to enable (only for clangd developers)."),
262  Hidden,
263  CommaSeparated,
264 };
265 
266 opt<unsigned> WorkerThreadsCount{
267  "j",
268  cat(Misc),
269  desc("Number of async workers used by clangd. Background index also "
270  "uses this many workers."),
272 };
273 
274 opt<Path> IndexFile{
275  "index-file",
276  cat(Misc),
277  desc(
278  "Index file to build the static index. The file must have been created "
279  "by a compatible clangd-indexer\n"
280  "WARNING: This option is experimental only, and will be removed "
281  "eventually. Don't rely on it"),
282  init(""),
283  Hidden,
284 };
285 
286 opt<bool> Test{
287  "lit-test",
288  cat(Misc),
289  desc("Abbreviation for -input-style=delimited -pretty -sync "
290  "-enable-test-scheme -log=verbose. "
291  "Intended to simplify lit tests"),
292  init(false),
293  Hidden,
294 };
295 
296 enum PCHStorageFlag { Disk, Memory };
297 opt<PCHStorageFlag> PCHStorage{
298  "pch-storage",
299  cat(Misc),
300  desc("Storing PCHs in memory increases memory usages, but may "
301  "improve performance"),
302  values(
303  clEnumValN(PCHStorageFlag::Disk, "disk", "store PCHs on disk"),
304  clEnumValN(PCHStorageFlag::Memory, "memory", "store PCHs in memory")),
305  init(PCHStorageFlag::Disk),
306 };
307 
308 opt<bool> Sync{
309  "sync",
310  cat(Misc),
311  desc("Handle client requests on main thread. Background index still uses "
312  "its own thread."),
313  init(false),
314  Hidden,
315 };
316 
317 opt<JSONStreamStyle> InputStyle{
318  "input-style",
319  cat(Protocol),
320  desc("Input JSON stream encoding"),
321  values(
322  clEnumValN(JSONStreamStyle::Standard, "standard", "usual LSP protocol"),
323  clEnumValN(JSONStreamStyle::Delimited, "delimited",
324  "messages delimited by --- lines, with # comment support")),
326  Hidden,
327 };
328 
329 opt<bool> EnableTestScheme{
330  "enable-test-uri-scheme",
331  cat(Protocol),
332  desc("Enable 'test:' URI scheme. Only use in lit tests"),
333  init(false),
334  Hidden,
335 };
336 
337 opt<Path> InputMirrorFile{
338  "input-mirror-file",
339  cat(Protocol),
340  desc("Mirror all LSP input to the specified file. Useful for debugging"),
341  init(""),
342  Hidden,
343 };
344 
345 opt<Logger::Level> LogLevel{
346  "log",
347  cat(Protocol),
348  desc("Verbosity of log messages written to stderr"),
349  values(clEnumValN(Logger::Error, "error", "Error messages only"),
350  clEnumValN(Logger::Info, "info", "High level execution tracing"),
351  clEnumValN(Logger::Debug, "verbose", "Low level details")),
352  init(Logger::Info),
353 };
354 
355 opt<OffsetEncoding> ForceOffsetEncoding{
356  "offset-encoding",
357  cat(Protocol),
358  desc("Force the offsetEncoding used for character positions. "
359  "This bypasses negotiation via client capabilities"),
360  values(
361  clEnumValN(OffsetEncoding::UTF8, "utf-8", "Offsets are in UTF-8 bytes"),
362  clEnumValN(OffsetEncoding::UTF16, "utf-16",
363  "Offsets are in UTF-16 code units")),
365 };
366 
367 opt<bool> PrettyPrint{
368  "pretty",
369  cat(Protocol),
370  desc("Pretty-print JSON output"),
371  init(false),
372 };
373 
374 /// \brief Supports a test URI scheme with relaxed constraints for lit tests.
375 /// The path in a test URI will be combined with a platform-specific fake
376 /// directory to form an absolute path. For example, test:///a.cpp is resolved
377 /// C:\clangd-test\a.cpp on Windows and /clangd-test/a.cpp on Unix.
378 class TestScheme : public URIScheme {
379 public:
380  llvm::Expected<std::string>
381  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
382  llvm::StringRef /*HintPath*/) const override {
383  using namespace llvm::sys;
384  // Still require "/" in body to mimic file scheme, as we want lengths of an
385  // equivalent URI in both schemes to be the same.
386  if (!Body.startswith("/"))
387  return llvm::make_error<llvm::StringError>(
388  "Expect URI body to be an absolute path starting with '/': " + Body,
389  llvm::inconvertibleErrorCode());
390  Body = Body.ltrim('/');
391  llvm::SmallVector<char, 16> Path(Body.begin(), Body.end());
392  path::native(Path);
393  fs::make_absolute(TestScheme::TestDir, Path);
394  return std::string(Path.begin(), Path.end());
395  }
396 
397  llvm::Expected<URI>
398  uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
399  llvm::StringRef Body = AbsolutePath;
400  if (!Body.consume_front(TestScheme::TestDir)) {
401  return llvm::make_error<llvm::StringError>(
402  "Path " + AbsolutePath + " doesn't start with root " + TestDir,
403  llvm::inconvertibleErrorCode());
404  }
405 
406  return URI("test", /*Authority=*/"",
407  llvm::sys::path::convert_to_slash(Body));
408  }
409 
410 private:
411  const static char TestDir[];
412 };
413 
414 #ifdef _WIN32
415 const char TestScheme::TestDir[] = "C:\\clangd-test";
416 #else
417 const char TestScheme::TestDir[] = "/clangd-test";
418 #endif
419 
420 } // namespace
421 } // namespace clangd
422 } // namespace clang
423 
424 enum class ErrorResultCode : int {
425  NoShutdownRequest = 1,
427 };
428 
429 int main(int argc, char *argv[]) {
430  using namespace clang;
431  using namespace clang::clangd;
432 
433  llvm::InitializeAllTargetInfos();
434  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
435  llvm::cl::SetVersionPrinter([](llvm::raw_ostream &OS) {
436  OS << clang::getClangToolFullVersion("clangd") << "\n";
437  });
438  const char *FlagsEnvVar = "CLANGD_FLAGS";
439  const char *Overview =
440  R"(clangd is a language server that provides IDE-like features to editors.
441 
442 It should be used via an editor plugin rather than invoked directly. For more information, see:
443  https://clang.llvm.org/extra/clangd/
444  https://microsoft.github.io/language-server-protocol/
445 
446 clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment variable.
447 )";
448  llvm::cl::HideUnrelatedOptions(ClangdCategories);
449  llvm::cl::ParseCommandLineOptions(argc, argv, Overview,
450  /*Errs=*/nullptr, FlagsEnvVar);
451  if (Test) {
452  Sync = true;
453  InputStyle = JSONStreamStyle::Delimited;
454  LogLevel = Logger::Verbose;
455  PrettyPrint = true;
456  // Ensure background index makes progress.
458  }
459  if (Test || EnableTestScheme) {
460  static URISchemeRegistry::Add<TestScheme> X(
461  "test", "Test scheme for clangd lit tests.");
462  }
463 
464  if (!Sync && WorkerThreadsCount == 0) {
465  llvm::errs() << "A number of worker threads cannot be 0. Did you mean to "
466  "specify -sync?";
467  return 1;
468  }
469 
470  if (Sync) {
471  if (WorkerThreadsCount.getNumOccurrences())
472  llvm::errs() << "Ignoring -j because -sync is set.\n";
473  WorkerThreadsCount = 0;
474  }
475  if (FallbackStyle.getNumOccurrences())
476  clang::format::DefaultFallbackStyle = FallbackStyle.c_str();
477 
478  // Validate command line arguments.
479  llvm::Optional<llvm::raw_fd_ostream> InputMirrorStream;
480  if (!InputMirrorFile.empty()) {
481  std::error_code EC;
482  InputMirrorStream.emplace(InputMirrorFile, /*ref*/ EC,
483  llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
484  if (EC) {
485  InputMirrorStream.reset();
486  llvm::errs() << "Error while opening an input mirror file: "
487  << EC.message();
488  } else {
489  InputMirrorStream->SetUnbuffered();
490  }
491  }
492 
493  // Setup tracing facilities if CLANGD_TRACE is set. In practice enabling a
494  // trace flag in your editor's config is annoying, launching with
495  // `CLANGD_TRACE=trace.json vim` is easier.
496  llvm::Optional<llvm::raw_fd_ostream> TraceStream;
497  std::unique_ptr<trace::EventTracer> Tracer;
498  if (auto *TraceFile = getenv("CLANGD_TRACE")) {
499  std::error_code EC;
500  TraceStream.emplace(TraceFile, /*ref*/ EC,
501  llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
502  if (EC) {
503  TraceStream.reset();
504  llvm::errs() << "Error while opening trace file " << TraceFile << ": "
505  << EC.message();
506  } else {
507  Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint);
508  }
509  }
510 
511  llvm::Optional<trace::Session> TracingSession;
512  if (Tracer)
513  TracingSession.emplace(*Tracer);
514 
515  // If a user ran `clangd` in a terminal without redirecting anything,
516  // it's somewhat likely they're confused about how to use clangd.
517  // Show them the help overview, which explains.
518  if (llvm::outs().is_displayed() && llvm::errs().is_displayed())
519  llvm::errs() << Overview << "\n";
520  // Use buffered stream to stderr (we still flush each log message). Unbuffered
521  // stream can cause significant (non-deterministic) latency for the logger.
522  llvm::errs().SetBuffered();
523  StreamLogger Logger(llvm::errs(), LogLevel);
525  // Write some initial logs before we start doing any real work.
526  log("{0}", clang::getClangToolFullVersion("clangd"));
527  {
528  SmallString<128> CWD;
529  if (auto Err = llvm::sys::fs::current_path(CWD))
530  log("Working directory unknown: {0}", Err.message());
531  else
532  log("Working directory: {0}", CWD);
533  }
534  for (int I = 0; I < argc; ++I)
535  log("argv[{0}]: {1}", I, argv[I]);
536  if (auto EnvFlags = llvm::sys::Process::GetEnv(FlagsEnvVar))
537  log("{0}: {1}", FlagsEnvVar, *EnvFlags);
538 
539  // If --compile-commands-dir arg was invoked, check value and override default
540  // path.
541  llvm::Optional<Path> CompileCommandsDirPath;
542  if (!CompileCommandsDir.empty()) {
543  if (llvm::sys::fs::exists(CompileCommandsDir)) {
544  // We support passing both relative and absolute paths to the
545  // --compile-commands-dir argument, but we assume the path is absolute in
546  // the rest of clangd so we make sure the path is absolute before
547  // continuing.
548  llvm::SmallString<128> Path(CompileCommandsDir);
549  if (std::error_code EC = llvm::sys::fs::make_absolute(Path)) {
550  llvm::errs() << "Error while converting the relative path specified by "
551  "--compile-commands-dir to an absolute path: "
552  << EC.message() << ". The argument will be ignored.\n";
553  } else {
554  CompileCommandsDirPath = Path.str();
555  }
556  } else {
557  llvm::errs()
558  << "Path specified by --compile-commands-dir does not exist. The "
559  "argument will be ignored.\n";
560  }
561  }
562 
564  switch (PCHStorage) {
565  case PCHStorageFlag::Memory:
566  Opts.StorePreamblesInMemory = true;
567  break;
568  case PCHStorageFlag::Disk:
569  Opts.StorePreamblesInMemory = false;
570  break;
571  }
572  if (!ResourceDir.empty())
573  Opts.ResourceDir = ResourceDir;
574  Opts.BuildDynamicSymbolIndex = EnableIndex;
575  Opts.BackgroundIndex = EnableBackgroundIndex;
576  std::unique_ptr<SymbolIndex> StaticIdx;
577  std::future<void> AsyncIndexLoad; // Block exit while loading the index.
578  if (EnableIndex && !IndexFile.empty()) {
579  // Load the index asynchronously. Meanwhile SwapIndex returns no results.
580  SwapIndex *Placeholder;
581  StaticIdx.reset(Placeholder = new SwapIndex(llvm::make_unique<MemIndex>()));
582  AsyncIndexLoad = runAsync<void>([Placeholder] {
583  if (auto Idx = loadIndex(IndexFile, /*UseDex=*/true))
584  Placeholder->reset(std::move(Idx));
585  });
586  if (Sync)
587  AsyncIndexLoad.wait();
588  }
589  Opts.StaticIndex = StaticIdx.get();
590  Opts.AsyncThreadsCount = WorkerThreadsCount;
591 
593  CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;
594  CCOpts.Limit = LimitResults;
595  if (CompletionStyle.getNumOccurrences())
596  CCOpts.BundleOverloads = CompletionStyle != Detailed;
597  CCOpts.ShowOrigins = ShowOrigins;
598  CCOpts.InsertIncludes = HeaderInsertion;
599  if (!HeaderInsertionDecorators) {
600  CCOpts.IncludeIndicator.Insert.clear();
601  CCOpts.IncludeIndicator.NoInsert.clear();
602  }
603  CCOpts.SpeculativeIndexRequest = Opts.StaticIndex;
604  CCOpts.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
605  CCOpts.AllScopes = AllScopesCompletion;
606  CCOpts.RunParser = CodeCompletionParse;
607 
609  // Initialize and run ClangdLSPServer.
610  // Change stdin to binary to not lose \r\n on windows.
611  llvm::sys::ChangeStdinToBinary();
612 
613  std::unique_ptr<Transport> TransportLayer;
614  if (getenv("CLANGD_AS_XPC_SERVICE")) {
615 #if CLANGD_BUILD_XPC
616  log("Starting LSP over XPC service");
617  TransportLayer = newXPCTransport();
618 #else
619  llvm::errs() << "This clangd binary wasn't built with XPC support.\n";
621 #endif
622  } else {
623  log("Starting LSP over stdin/stdout");
624  TransportLayer = newJSONTransport(
625  stdin, llvm::outs(),
626  InputMirrorStream ? InputMirrorStream.getPointer() : nullptr,
627  PrettyPrint, InputStyle);
628  }
629 
630  // Create an empty clang-tidy option.
631  std::mutex ClangTidyOptMu;
632  std::unique_ptr<tidy::ClangTidyOptionsProvider>
633  ClangTidyOptProvider; /*GUARDED_BY(ClangTidyOptMu)*/
634  if (EnableClangTidy) {
635  auto OverrideClangTidyOptions = tidy::ClangTidyOptions::getDefaults();
636  OverrideClangTidyOptions.Checks = ClangTidyChecks;
637  ClangTidyOptProvider = llvm::make_unique<tidy::FileOptionsProvider>(
639  /* Default */ tidy::ClangTidyOptions::getDefaults(),
640  /* Override */ OverrideClangTidyOptions, FSProvider.getFileSystem());
641  Opts.GetClangTidyOptions = [&](llvm::vfs::FileSystem &,
642  llvm::StringRef File) {
643  // This function must be thread-safe and tidy option providers are not.
644  std::lock_guard<std::mutex> Lock(ClangTidyOptMu);
645  // FIXME: use the FS provided to the function.
646  return ClangTidyOptProvider->getOptions(File);
647  };
648  }
649  Opts.SuggestMissingIncludes = SuggestMissingIncludes;
650  Opts.QueryDriverGlobs = std::move(QueryDriverGlobs);
651 
652  Opts.TweakFilter = [&](const Tweak &T) {
653  if (T.hidden() && !HiddenFeatures)
654  return false;
655  if (TweakList.getNumOccurrences())
656  return llvm::is_contained(TweakList, T.id());
657  return true;
658  };
659  llvm::Optional<OffsetEncoding> OffsetEncodingFromFlag;
660  if (ForceOffsetEncoding != OffsetEncoding::UnsupportedEncoding)
661  OffsetEncodingFromFlag = ForceOffsetEncoding;
662  ClangdLSPServer LSPServer(
663  *TransportLayer, FSProvider, CCOpts, CompileCommandsDirPath,
664  /*UseDirBasedCDB=*/CompileArgsFrom == FilesystemCompileArgs,
665  OffsetEncodingFromFlag, Opts);
666  llvm::set_thread_name("clangd.main");
667  return LSPServer.run() ? 0
668  : static_cast<int>(ErrorResultCode::NoShutdownRequest);
669 }
bool ShowOrigins
Expose origins of completion items in the label (for debugging).
Definition: CodeComplete.h:87
std::function< bool(const Tweak &)> TweakFilter
Returns true if the tweak should be enabled.
Definition: ClangdServer.h:137
size_t Limit
Limit the number of results returned (0 means no limit).
Definition: CodeComplete.h:72
ErrorResultCode
Definition: ClangdMain.cpp:424
Always use text-based completion.
Definition: CodeComplete.h:131
int main(int argc, char *argv[])
Definition: ClangdMain.cpp:429
std::unique_ptr< SymbolIndex > loadIndex(llvm::StringRef SymbolFilename, bool UseDex)
bool BackgroundIndex
If true, ClangdServer automatically indexes files in the current project on background threads...
Definition: ClangdServer.h:100
URIScheme is an extension point for teaching clangd to recognize a custom URI scheme.
Definition: URI.h:104
std::unique_ptr< Transport > newXPCTransport()
bool run()
Run LSP server loop, communicating with the Transport provided in the constructor.
Run the parser if inputs (preamble) are ready.
Definition: CodeComplete.h:129
def make_absolute(f, directory)
unsigned AsyncThreadsCount
To process requests asynchronously, ClangdServer spawns worker threads.
Definition: ClangdServer.h:85
bool BuildDynamicSymbolIndex
If true, ClangdServer builds a dynamic in-memory index for symbols in opened files and uses the index...
Definition: ClangdServer.h:95
MockFSProvider FSProvider
static void preventThreadStarvationInTests()
Interface to allow custom logging in clangd.
Definition: Logger.h:23
bool SpeculativeIndexRequest
If set to true, this will send an asynchronous speculative index request, based on the index request ...
Definition: CodeComplete.h:97
void log(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:62
std::string Path
A typedef to represent a file path.
Definition: Path.h:20
Only one LoggingSession can be active at a time.
Definition: Logger.h:77
bool IncludeIneligibleResults
Include results that are not legal completions in the current context.
Definition: CodeComplete.h:62
enum clang::clangd::CodeCompleteOptions::CodeCompletionParse RunParser
std::unique_ptr< Transport > newJSONTransport(std::FILE *In, llvm::raw_ostream &Out, llvm::raw_ostream *InMirror, bool Pretty, JSONStreamStyle Style)
llvm::Optional< bool > BundleOverloads
Combine overloads into a single completion item where possible.
Definition: CodeComplete.h:68
unsigned getDefaultAsyncThreadsCount()
Returns a number of a default async threads to use for TUScheduler.
Block until we can run the parser (e.g.
Definition: CodeComplete.h:126
bool StorePreamblesInMemory
Cached preambles are potentially large. If false, store them on disk.
Definition: ClangdServer.h:91
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static URISchemeRegistry::Add< TestScheme > X(TestScheme::Scheme, "Test schema")
llvm::Optional< std::string > ResourceDir
The resource directory is used to find internal headers, overriding defaults and -resource-dir compil...
Definition: ClangdServer.h:121
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:201
struct clang::clangd::CodeCompleteOptions::IncludeInsertionIndicator IncludeIndicator
std::vector< std::string > QueryDriverGlobs
Clangd will execute compiler drivers matching one of these globs to fetch system include path...
Definition: ClangdServer.h:131
A URI describes the location of a source file.
Definition: URI.h:28
An interface base for small context-sensitive refactoring actions.
Definition: Tweak.h:39
bool EnableFunctionArgSnippets
Whether to generate snippets for function arguments on code-completion.
Definition: CodeComplete.h:112
ClangTidyOptionsBuilder GetClangTidyOptions
If set, enable clang-tidy in clangd and use to it get clang-tidy configurations for a particular file...
Definition: ClangdServer.h:110
bool AllScopes
Whether to include index symbols that are not defined in the scopes visible from the code completion ...
Definition: CodeComplete.h:119
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getFileSystem() const override
Called by ClangdServer to obtain a vfs::FileSystem to be used for parsing.
Definition: FSProvider.cpp:72
static ClangTidyOptions getDefaults()
These options are used for all settings that haven&#39;t been overridden by the OptionsProvider.
This class exposes ClangdServer&#39;s capabilities via Language Server Protocol.
SymbolIndex * StaticIndex
If set, use this index to augment code completion results.
Definition: ClangdServer.h:103
void reset(std::unique_ptr< SymbolIndex >)
Definition: Index.cpp:20
enum clang::clangd::CodeCompleteOptions::IncludeInsertion InsertIncludes