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  "Experimental"),
127  init(true),
128 };
129 
130 opt<bool> EnableClangTidy{
131  "clang-tidy",
132  cat(Features),
133  desc("Enable clang-tidy diagnostics"),
134  init(true),
135 };
136 
137 opt<std::string> ClangTidyChecks{
138  "clang-tidy-checks",
139  cat(Features),
140  desc("List of clang-tidy checks to run (this will override "
141  ".clang-tidy files). Only meaningful when -clang-tidy flag is on"),
142  init(""),
143 };
144 
145 opt<CodeCompleteOptions::CodeCompletionParse> CodeCompletionParse{
146  "completion-parse",
147  cat(Features),
148  desc("Whether the clang-parser is used for code-completion"),
149  values(clEnumValN(CodeCompleteOptions::AlwaysParse, "always",
150  "Block until the parser can be used"),
151  clEnumValN(CodeCompleteOptions::ParseIfReady, "auto",
152  "Use text-based completion if the parser "
153  "is not ready"),
154  clEnumValN(CodeCompleteOptions::NeverParse, "never",
155  "Always used text-based completion")),
156  init(CodeCompleteOptions().RunParser),
157  Hidden,
158 };
159 
160 // FIXME: also support "plain" style where signatures are always omitted.
161 enum CompletionStyleFlag { Detailed, Bundled };
162 opt<CompletionStyleFlag> CompletionStyle{
163  "completion-style",
164  cat(Features),
165  desc("Granularity of code completion suggestions"),
166  values(clEnumValN(Detailed, "detailed",
167  "One completion item for each semantically distinct "
168  "completion, with full type information"),
169  clEnumValN(Bundled, "bundled",
170  "Similar completion items (e.g. function overloads) are "
171  "combined. Type information shown where possible")),
172 };
173 
174 opt<std::string> FallbackStyle{
175  "fallback-style",
176  cat(Features),
177  desc("clang-format style to apply by default when "
178  "no .clang-format file is found"),
179  init(clang::format::DefaultFallbackStyle),
180 };
181 
182 opt<bool> EnableFunctionArgSnippets{
183  "function-arg-placeholders",
184  cat(Features),
185  desc("When disabled, completions contain only parentheses for "
186  "function calls. When enabled, completions also contain "
187  "placeholders for method parameters"),
188  init(CodeCompleteOptions().EnableFunctionArgSnippets),
189  Hidden,
190 };
191 
192 opt<CodeCompleteOptions::IncludeInsertion> HeaderInsertion{
193  "header-insertion",
194  cat(Features),
195  desc("Add #include directives when accepting code completions"),
196  init(CodeCompleteOptions().InsertIncludes),
197  values(
198  clEnumValN(CodeCompleteOptions::IWYU, "iwyu",
199  "Include what you use. "
200  "Insert the owning header for top-level symbols, unless the "
201  "header is already directly included or the symbol is "
202  "forward-declared"),
203  clEnumValN(
205  "Never insert #include directives as part of code completion")),
206 };
207 
208 opt<bool> HeaderInsertionDecorators{
209  "header-insertion-decorators",
210  cat(Features),
211  desc("Prepend a circular dot or space before the completion "
212  "label, depending on whether "
213  "an include line will be inserted or not"),
214  init(true),
215 };
216 
217 opt<bool> HiddenFeatures{
218  "hidden-features",
219  cat(Features),
220  desc("Enable hidden features mostly useful to clangd developers"),
221  init(false),
222  Hidden,
223 };
224 
225 opt<bool> IncludeIneligibleResults{
226  "include-ineligible-results",
227  cat(Features),
228  desc("Include ineligible completion results (e.g. private members)"),
229  init(CodeCompleteOptions().IncludeIneligibleResults),
230  Hidden,
231 };
232 
233 opt<bool> EnableIndex{
234  "index",
235  cat(Features),
236  desc("Enable index-based features. By default, clangd maintains an index "
237  "built from symbols in opened files. Global index support needs to "
238  "enabled separatedly"),
239  init(true),
240  Hidden,
241 };
242 
243 opt<int> LimitResults{
244  "limit-results",
245  cat(Features),
246  desc("Limit the number of results returned by clangd. "
247  "0 means no limit (default=100)"),
248  init(100),
249 };
250 
251 opt<bool> SuggestMissingIncludes{
252  "suggest-missing-includes",
253  cat(Features),
254  desc("Attempts to fix diagnostic errors caused by missing "
255  "includes using index"),
256  init(true),
257 };
258 
259 list<std::string> TweakList{
260  "tweaks",
261  cat(Features),
262  desc("Specify a list of Tweaks to enable (only for clangd developers)."),
263  Hidden,
264  CommaSeparated,
265 };
266 
267 opt<unsigned> WorkerThreadsCount{
268  "j",
269  cat(Misc),
270  desc("Number of async workers used by clangd. Background index also "
271  "uses this many workers."),
273 };
274 
275 opt<Path> IndexFile{
276  "index-file",
277  cat(Misc),
278  desc(
279  "Index file to build the static index. The file must have been created "
280  "by a compatible clangd-indexer\n"
281  "WARNING: This option is experimental only, and will be removed "
282  "eventually. Don't rely on it"),
283  init(""),
284  Hidden,
285 };
286 
287 opt<bool> Test{
288  "lit-test",
289  cat(Misc),
290  desc("Abbreviation for -input-style=delimited -pretty -sync "
291  "-enable-test-scheme -log=verbose. "
292  "Intended to simplify lit tests"),
293  init(false),
294  Hidden,
295 };
296 
297 enum PCHStorageFlag { Disk, Memory };
298 opt<PCHStorageFlag> PCHStorage{
299  "pch-storage",
300  cat(Misc),
301  desc("Storing PCHs in memory increases memory usages, but may "
302  "improve performance"),
303  values(
304  clEnumValN(PCHStorageFlag::Disk, "disk", "store PCHs on disk"),
305  clEnumValN(PCHStorageFlag::Memory, "memory", "store PCHs in memory")),
306  init(PCHStorageFlag::Disk),
307 };
308 
309 opt<bool> Sync{
310  "sync",
311  cat(Misc),
312  desc("Handle client requests on main thread. Background index still uses "
313  "its own thread."),
314  init(false),
315  Hidden,
316 };
317 
318 opt<JSONStreamStyle> InputStyle{
319  "input-style",
320  cat(Protocol),
321  desc("Input JSON stream encoding"),
322  values(
323  clEnumValN(JSONStreamStyle::Standard, "standard", "usual LSP protocol"),
324  clEnumValN(JSONStreamStyle::Delimited, "delimited",
325  "messages delimited by --- lines, with # comment support")),
327  Hidden,
328 };
329 
330 opt<bool> EnableTestScheme{
331  "enable-test-uri-scheme",
332  cat(Protocol),
333  desc("Enable 'test:' URI scheme. Only use in lit tests"),
334  init(false),
335  Hidden,
336 };
337 
338 opt<Path> InputMirrorFile{
339  "input-mirror-file",
340  cat(Protocol),
341  desc("Mirror all LSP input to the specified file. Useful for debugging"),
342  init(""),
343  Hidden,
344 };
345 
346 opt<Logger::Level> LogLevel{
347  "log",
348  cat(Protocol),
349  desc("Verbosity of log messages written to stderr"),
350  values(clEnumValN(Logger::Error, "error", "Error messages only"),
351  clEnumValN(Logger::Info, "info", "High level execution tracing"),
352  clEnumValN(Logger::Debug, "verbose", "Low level details")),
353  init(Logger::Info),
354 };
355 
356 opt<OffsetEncoding> ForceOffsetEncoding{
357  "offset-encoding",
358  cat(Protocol),
359  desc("Force the offsetEncoding used for character positions. "
360  "This bypasses negotiation via client capabilities"),
361  values(
362  clEnumValN(OffsetEncoding::UTF8, "utf-8", "Offsets are in UTF-8 bytes"),
363  clEnumValN(OffsetEncoding::UTF16, "utf-16",
364  "Offsets are in UTF-16 code units")),
366 };
367 
368 opt<bool> PrettyPrint{
369  "pretty",
370  cat(Protocol),
371  desc("Pretty-print JSON output"),
372  init(false),
373 };
374 
375 /// \brief Supports a test URI scheme with relaxed constraints for lit tests.
376 /// The path in a test URI will be combined with a platform-specific fake
377 /// directory to form an absolute path. For example, test:///a.cpp is resolved
378 /// C:\clangd-test\a.cpp on Windows and /clangd-test/a.cpp on Unix.
379 class TestScheme : public URIScheme {
380 public:
381  llvm::Expected<std::string>
382  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
383  llvm::StringRef /*HintPath*/) const override {
384  using namespace llvm::sys;
385  // Still require "/" in body to mimic file scheme, as we want lengths of an
386  // equivalent URI in both schemes to be the same.
387  if (!Body.startswith("/"))
388  return llvm::make_error<llvm::StringError>(
389  "Expect URI body to be an absolute path starting with '/': " + Body,
390  llvm::inconvertibleErrorCode());
391  Body = Body.ltrim('/');
392  llvm::SmallVector<char, 16> Path(Body.begin(), Body.end());
393  path::native(Path);
394  fs::make_absolute(TestScheme::TestDir, Path);
395  return std::string(Path.begin(), Path.end());
396  }
397 
398  llvm::Expected<URI>
399  uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
400  llvm::StringRef Body = AbsolutePath;
401  if (!Body.consume_front(TestScheme::TestDir)) {
402  return llvm::make_error<llvm::StringError>(
403  "Path " + AbsolutePath + " doesn't start with root " + TestDir,
404  llvm::inconvertibleErrorCode());
405  }
406 
407  return URI("test", /*Authority=*/"",
408  llvm::sys::path::convert_to_slash(Body));
409  }
410 
411 private:
412  const static char TestDir[];
413 };
414 
415 #ifdef _WIN32
416 const char TestScheme::TestDir[] = "C:\\clangd-test";
417 #else
418 const char TestScheme::TestDir[] = "/clangd-test";
419 #endif
420 
421 } // namespace
422 } // namespace clangd
423 } // namespace clang
424 
425 enum class ErrorResultCode : int {
426  NoShutdownRequest = 1,
428 };
429 
430 int main(int argc, char *argv[]) {
431  using namespace clang;
432  using namespace clang::clangd;
433 
434  llvm::InitializeAllTargetInfos();
435  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
436  llvm::cl::SetVersionPrinter([](llvm::raw_ostream &OS) {
437  OS << clang::getClangToolFullVersion("clangd") << "\n";
438  });
439  const char *FlagsEnvVar = "CLANGD_FLAGS";
440  const char *Overview =
441  R"(clangd is a language server that provides IDE-like features to editors.
442 
443 It should be used via an editor plugin rather than invoked directly. For more information, see:
444  https://clang.llvm.org/extra/clangd/
445  https://microsoft.github.io/language-server-protocol/
446 
447 clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment variable.
448 )";
449  llvm::cl::HideUnrelatedOptions(ClangdCategories);
450  llvm::cl::ParseCommandLineOptions(argc, argv, Overview,
451  /*Errs=*/nullptr, FlagsEnvVar);
452  if (Test) {
453  Sync = true;
454  InputStyle = JSONStreamStyle::Delimited;
455  LogLevel = Logger::Verbose;
456  PrettyPrint = true;
457  // Ensure background index makes progress.
459  }
460  if (Test || EnableTestScheme) {
461  static URISchemeRegistry::Add<TestScheme> X(
462  "test", "Test scheme for clangd lit tests.");
463  }
464 
465  if (!Sync && WorkerThreadsCount == 0) {
466  llvm::errs() << "A number of worker threads cannot be 0. Did you mean to "
467  "specify -sync?";
468  return 1;
469  }
470 
471  if (Sync) {
472  if (WorkerThreadsCount.getNumOccurrences())
473  llvm::errs() << "Ignoring -j because -sync is set.\n";
474  WorkerThreadsCount = 0;
475  }
476  if (FallbackStyle.getNumOccurrences())
477  clang::format::DefaultFallbackStyle = FallbackStyle.c_str();
478 
479  // Validate command line arguments.
480  llvm::Optional<llvm::raw_fd_ostream> InputMirrorStream;
481  if (!InputMirrorFile.empty()) {
482  std::error_code EC;
483  InputMirrorStream.emplace(InputMirrorFile, /*ref*/ EC,
484  llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
485  if (EC) {
486  InputMirrorStream.reset();
487  llvm::errs() << "Error while opening an input mirror file: "
488  << EC.message();
489  } else {
490  InputMirrorStream->SetUnbuffered();
491  }
492  }
493 
494  // Setup tracing facilities if CLANGD_TRACE is set. In practice enabling a
495  // trace flag in your editor's config is annoying, launching with
496  // `CLANGD_TRACE=trace.json vim` is easier.
497  llvm::Optional<llvm::raw_fd_ostream> TraceStream;
498  std::unique_ptr<trace::EventTracer> Tracer;
499  if (auto *TraceFile = getenv("CLANGD_TRACE")) {
500  std::error_code EC;
501  TraceStream.emplace(TraceFile, /*ref*/ EC,
502  llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
503  if (EC) {
504  TraceStream.reset();
505  llvm::errs() << "Error while opening trace file " << TraceFile << ": "
506  << EC.message();
507  } else {
508  Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint);
509  }
510  }
511 
512  llvm::Optional<trace::Session> TracingSession;
513  if (Tracer)
514  TracingSession.emplace(*Tracer);
515 
516  // If a user ran `clangd` in a terminal without redirecting anything,
517  // it's somewhat likely they're confused about how to use clangd.
518  // Show them the help overview, which explains.
519  if (llvm::outs().is_displayed() && llvm::errs().is_displayed())
520  llvm::errs() << Overview << "\n";
521  // Use buffered stream to stderr (we still flush each log message). Unbuffered
522  // stream can cause significant (non-deterministic) latency for the logger.
523  llvm::errs().SetBuffered();
524  StreamLogger Logger(llvm::errs(), LogLevel);
526  // Write some initial logs before we start doing any real work.
527  log("{0}", clang::getClangToolFullVersion("clangd"));
528  {
529  SmallString<128> CWD;
530  if (auto Err = llvm::sys::fs::current_path(CWD))
531  log("Working directory unknown: {0}", Err.message());
532  else
533  log("Working directory: {0}", CWD);
534  }
535  for (int I = 0; I < argc; ++I)
536  log("argv[{0}]: {1}", I, argv[I]);
537  if (auto EnvFlags = llvm::sys::Process::GetEnv(FlagsEnvVar))
538  log("{0}: {1}", FlagsEnvVar, *EnvFlags);
539 
540  // If --compile-commands-dir arg was invoked, check value and override default
541  // path.
542  llvm::Optional<Path> CompileCommandsDirPath;
543  if (!CompileCommandsDir.empty()) {
544  if (llvm::sys::fs::exists(CompileCommandsDir)) {
545  // We support passing both relative and absolute paths to the
546  // --compile-commands-dir argument, but we assume the path is absolute in
547  // the rest of clangd so we make sure the path is absolute before
548  // continuing.
549  llvm::SmallString<128> Path(CompileCommandsDir);
550  if (std::error_code EC = llvm::sys::fs::make_absolute(Path)) {
551  llvm::errs() << "Error while converting the relative path specified by "
552  "--compile-commands-dir to an absolute path: "
553  << EC.message() << ". The argument will be ignored.\n";
554  } else {
555  CompileCommandsDirPath = Path.str();
556  }
557  } else {
558  llvm::errs()
559  << "Path specified by --compile-commands-dir does not exist. The "
560  "argument will be ignored.\n";
561  }
562  }
563 
565  switch (PCHStorage) {
566  case PCHStorageFlag::Memory:
567  Opts.StorePreamblesInMemory = true;
568  break;
569  case PCHStorageFlag::Disk:
570  Opts.StorePreamblesInMemory = false;
571  break;
572  }
573  if (!ResourceDir.empty())
574  Opts.ResourceDir = ResourceDir;
575  Opts.BuildDynamicSymbolIndex = EnableIndex;
576  Opts.BackgroundIndex = EnableBackgroundIndex;
577  std::unique_ptr<SymbolIndex> StaticIdx;
578  std::future<void> AsyncIndexLoad; // Block exit while loading the index.
579  if (EnableIndex && !IndexFile.empty()) {
580  // Load the index asynchronously. Meanwhile SwapIndex returns no results.
581  SwapIndex *Placeholder;
582  StaticIdx.reset(Placeholder = new SwapIndex(llvm::make_unique<MemIndex>()));
583  AsyncIndexLoad = runAsync<void>([Placeholder] {
584  if (auto Idx = loadIndex(IndexFile, /*UseDex=*/true))
585  Placeholder->reset(std::move(Idx));
586  });
587  if (Sync)
588  AsyncIndexLoad.wait();
589  }
590  Opts.StaticIndex = StaticIdx.get();
591  Opts.AsyncThreadsCount = WorkerThreadsCount;
592 
594  CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;
595  CCOpts.Limit = LimitResults;
596  if (CompletionStyle.getNumOccurrences())
597  CCOpts.BundleOverloads = CompletionStyle != Detailed;
598  CCOpts.ShowOrigins = ShowOrigins;
599  CCOpts.InsertIncludes = HeaderInsertion;
600  if (!HeaderInsertionDecorators) {
601  CCOpts.IncludeIndicator.Insert.clear();
602  CCOpts.IncludeIndicator.NoInsert.clear();
603  }
604  CCOpts.SpeculativeIndexRequest = Opts.StaticIndex;
605  CCOpts.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
606  CCOpts.AllScopes = AllScopesCompletion;
607  CCOpts.RunParser = CodeCompletionParse;
608 
610  // Initialize and run ClangdLSPServer.
611  // Change stdin to binary to not lose \r\n on windows.
612  llvm::sys::ChangeStdinToBinary();
613 
614  std::unique_ptr<Transport> TransportLayer;
615  if (getenv("CLANGD_AS_XPC_SERVICE")) {
616 #if CLANGD_BUILD_XPC
617  log("Starting LSP over XPC service");
618  TransportLayer = newXPCTransport();
619 #else
620  llvm::errs() << "This clangd binary wasn't built with XPC support.\n";
622 #endif
623  } else {
624  log("Starting LSP over stdin/stdout");
625  TransportLayer = newJSONTransport(
626  stdin, llvm::outs(),
627  InputMirrorStream ? InputMirrorStream.getPointer() : nullptr,
628  PrettyPrint, InputStyle);
629  }
630 
631  // Create an empty clang-tidy option.
632  std::mutex ClangTidyOptMu;
633  std::unique_ptr<tidy::ClangTidyOptionsProvider>
634  ClangTidyOptProvider; /*GUARDED_BY(ClangTidyOptMu)*/
635  if (EnableClangTidy) {
636  auto OverrideClangTidyOptions = tidy::ClangTidyOptions::getDefaults();
637  OverrideClangTidyOptions.Checks = ClangTidyChecks;
638  ClangTidyOptProvider = llvm::make_unique<tidy::FileOptionsProvider>(
640  /* Default */ tidy::ClangTidyOptions::getDefaults(),
641  /* Override */ OverrideClangTidyOptions, FSProvider.getFileSystem());
642  Opts.GetClangTidyOptions = [&](llvm::vfs::FileSystem &,
643  llvm::StringRef File) {
644  // This function must be thread-safe and tidy option providers are not.
645  std::lock_guard<std::mutex> Lock(ClangTidyOptMu);
646  // FIXME: use the FS provided to the function.
647  return ClangTidyOptProvider->getOptions(File);
648  };
649  }
650  Opts.SuggestMissingIncludes = SuggestMissingIncludes;
651  Opts.QueryDriverGlobs = std::move(QueryDriverGlobs);
652 
653  Opts.TweakFilter = [&](const Tweak &T) {
654  if (T.hidden() && !HiddenFeatures)
655  return false;
656  if (TweakList.getNumOccurrences())
657  return llvm::is_contained(TweakList, T.id());
658  return true;
659  };
660  llvm::Optional<OffsetEncoding> OffsetEncodingFromFlag;
661  if (ForceOffsetEncoding != OffsetEncoding::UnsupportedEncoding)
662  OffsetEncodingFromFlag = ForceOffsetEncoding;
663  ClangdLSPServer LSPServer(
664  *TransportLayer, FSProvider, CCOpts, CompileCommandsDirPath,
665  /*UseDirBasedCDB=*/CompileArgsFrom == FilesystemCompileArgs,
666  OffsetEncodingFromFlag, Opts);
667  llvm::set_thread_name("clangd.main");
668  return LSPServer.run() ? 0
669  : static_cast<int>(ErrorResultCode::NoShutdownRequest);
670 }
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:425
Always use text-based completion.
Definition: CodeComplete.h:131
int main(int argc, char *argv[])
Definition: ClangdMain.cpp:430
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