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"),
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("Parse on main thread. If set, -j is ignored"),
312  init(false),
313  Hidden,
314 };
315 
316 opt<JSONStreamStyle> InputStyle{
317  "input-style",
318  cat(Protocol),
319  desc("Input JSON stream encoding"),
320  values(
321  clEnumValN(JSONStreamStyle::Standard, "standard", "usual LSP protocol"),
322  clEnumValN(JSONStreamStyle::Delimited, "delimited",
323  "messages delimited by --- lines, with # comment support")),
325  Hidden,
326 };
327 
328 opt<bool> EnableTestScheme{
329  "enable-test-uri-scheme",
330  cat(Protocol),
331  desc("Enable 'test:' URI scheme. Only use in lit tests"),
332  init(false),
333  Hidden,
334 };
335 
336 opt<Path> InputMirrorFile{
337  "input-mirror-file",
338  cat(Protocol),
339  desc("Mirror all LSP input to the specified file. Useful for debugging"),
340  init(""),
341  Hidden,
342 };
343 
344 opt<Logger::Level> LogLevel{
345  "log",
346  cat(Protocol),
347  desc("Verbosity of log messages written to stderr"),
348  values(clEnumValN(Logger::Error, "error", "Error messages only"),
349  clEnumValN(Logger::Info, "info", "High level execution tracing"),
350  clEnumValN(Logger::Debug, "verbose", "Low level details")),
351  init(Logger::Info),
352 };
353 
354 opt<OffsetEncoding> ForceOffsetEncoding{
355  "offset-encoding",
356  cat(Protocol),
357  desc("Force the offsetEncoding used for character positions. "
358  "This bypasses negotiation via client capabilities"),
359  values(
360  clEnumValN(OffsetEncoding::UTF8, "utf-8", "Offsets are in UTF-8 bytes"),
361  clEnumValN(OffsetEncoding::UTF16, "utf-16",
362  "Offsets are in UTF-16 code units")),
364 };
365 
366 opt<bool> PrettyPrint{
367  "pretty",
368  cat(Protocol),
369  desc("Pretty-print JSON output"),
370  init(false),
371 };
372 
373 /// \brief Supports a test URI scheme with relaxed constraints for lit tests.
374 /// The path in a test URI will be combined with a platform-specific fake
375 /// directory to form an absolute path. For example, test:///a.cpp is resolved
376 /// C:\clangd-test\a.cpp on Windows and /clangd-test/a.cpp on Unix.
377 class TestScheme : public URIScheme {
378 public:
379  llvm::Expected<std::string>
380  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
381  llvm::StringRef /*HintPath*/) const override {
382  using namespace llvm::sys;
383  // Still require "/" in body to mimic file scheme, as we want lengths of an
384  // equivalent URI in both schemes to be the same.
385  if (!Body.startswith("/"))
386  return llvm::make_error<llvm::StringError>(
387  "Expect URI body to be an absolute path starting with '/': " + Body,
388  llvm::inconvertibleErrorCode());
389  Body = Body.ltrim('/');
390  llvm::SmallVector<char, 16> Path(Body.begin(), Body.end());
391  path::native(Path);
392  fs::make_absolute(TestScheme::TestDir, Path);
393  return std::string(Path.begin(), Path.end());
394  }
395 
396  llvm::Expected<URI>
397  uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
398  llvm::StringRef Body = AbsolutePath;
399  if (!Body.consume_front(TestScheme::TestDir)) {
400  return llvm::make_error<llvm::StringError>(
401  "Path " + AbsolutePath + " doesn't start with root " + TestDir,
402  llvm::inconvertibleErrorCode());
403  }
404 
405  return URI("test", /*Authority=*/"",
406  llvm::sys::path::convert_to_slash(Body));
407  }
408 
409 private:
410  const static char TestDir[];
411 };
412 
413 #ifdef _WIN32
414 const char TestScheme::TestDir[] = "C:\\clangd-test";
415 #else
416 const char TestScheme::TestDir[] = "/clangd-test";
417 #endif
418 
419 } // namespace
420 } // namespace clangd
421 } // namespace clang
422 
423 enum class ErrorResultCode : int {
424  NoShutdownRequest = 1,
426 };
427 
428 int main(int argc, char *argv[]) {
429  using namespace clang;
430  using namespace clang::clangd;
431 
432  llvm::InitializeAllTargetInfos();
433  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
434  llvm::cl::SetVersionPrinter([](llvm::raw_ostream &OS) {
435  OS << clang::getClangToolFullVersion("clangd") << "\n";
436  });
437  const char *FlagsEnvVar = "CLANGD_FLAGS";
438  const char *Overview =
439  R"(clangd is a language server that provides IDE-like features to editors.
440 
441 It should be used via an editor plugin rather than invoked directly. For more information, see:
442  https://clang.llvm.org/extra/clangd/
443  https://microsoft.github.io/language-server-protocol/
444 
445 clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment variable.
446 )";
447  llvm::cl::HideUnrelatedOptions(ClangdCategories);
448  llvm::cl::ParseCommandLineOptions(argc, argv, Overview,
449  /*Errs=*/nullptr, FlagsEnvVar);
450  if (Test) {
451  Sync = true;
452  InputStyle = JSONStreamStyle::Delimited;
453  LogLevel = Logger::Verbose;
454  PrettyPrint = true;
455  // Ensure background index makes progress.
457  }
458  if (Test || EnableTestScheme) {
459  static URISchemeRegistry::Add<TestScheme> X(
460  "test", "Test scheme for clangd lit tests.");
461  }
462 
463  if (!Sync && WorkerThreadsCount == 0) {
464  llvm::errs() << "A number of worker threads cannot be 0. Did you mean to "
465  "specify -sync?";
466  return 1;
467  }
468 
469  if (Sync) {
470  if (WorkerThreadsCount.getNumOccurrences())
471  llvm::errs() << "Ignoring -j because -sync is set.\n";
472  WorkerThreadsCount = 0;
473  }
474  if (FallbackStyle.getNumOccurrences())
475  clang::format::DefaultFallbackStyle = FallbackStyle.c_str();
476 
477  // Validate command line arguments.
478  llvm::Optional<llvm::raw_fd_ostream> InputMirrorStream;
479  if (!InputMirrorFile.empty()) {
480  std::error_code EC;
481  InputMirrorStream.emplace(InputMirrorFile, /*ref*/ EC,
482  llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
483  if (EC) {
484  InputMirrorStream.reset();
485  llvm::errs() << "Error while opening an input mirror file: "
486  << EC.message();
487  } else {
488  InputMirrorStream->SetUnbuffered();
489  }
490  }
491 
492  // Setup tracing facilities if CLANGD_TRACE is set. In practice enabling a
493  // trace flag in your editor's config is annoying, launching with
494  // `CLANGD_TRACE=trace.json vim` is easier.
495  llvm::Optional<llvm::raw_fd_ostream> TraceStream;
496  std::unique_ptr<trace::EventTracer> Tracer;
497  if (auto *TraceFile = getenv("CLANGD_TRACE")) {
498  std::error_code EC;
499  TraceStream.emplace(TraceFile, /*ref*/ EC,
500  llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
501  if (EC) {
502  TraceStream.reset();
503  llvm::errs() << "Error while opening trace file " << TraceFile << ": "
504  << EC.message();
505  } else {
506  Tracer = trace::createJSONTracer(*TraceStream, PrettyPrint);
507  }
508  }
509 
510  llvm::Optional<trace::Session> TracingSession;
511  if (Tracer)
512  TracingSession.emplace(*Tracer);
513 
514  // If a user ran `clangd` in a terminal without redirecting anything,
515  // it's somewhat likely they're confused about how to use clangd.
516  // Show them the help overview, which explains.
517  if (llvm::outs().is_displayed() && llvm::errs().is_displayed())
518  llvm::errs() << Overview << "\n";
519  // Use buffered stream to stderr (we still flush each log message). Unbuffered
520  // stream can cause significant (non-deterministic) latency for the logger.
521  llvm::errs().SetBuffered();
522  StreamLogger Logger(llvm::errs(), LogLevel);
524  // Write some initial logs before we start doing any real work.
525  log("{0}", clang::getClangToolFullVersion("clangd"));
526  {
527  SmallString<128> CWD;
528  if (auto Err = llvm::sys::fs::current_path(CWD))
529  log("Working directory unknown: {0}", Err.message());
530  else
531  log("Working directory: {0}", CWD);
532  }
533  for (int I = 0; I < argc; ++I)
534  log("argv[{0}]: {1}", I, argv[I]);
535  if (auto EnvFlags = llvm::sys::Process::GetEnv(FlagsEnvVar))
536  log("{0}: {1}", FlagsEnvVar, *EnvFlags);
537 
538  // If --compile-commands-dir arg was invoked, check value and override default
539  // path.
540  llvm::Optional<Path> CompileCommandsDirPath;
541  if (!CompileCommandsDir.empty()) {
542  if (llvm::sys::fs::exists(CompileCommandsDir)) {
543  // We support passing both relative and absolute paths to the
544  // --compile-commands-dir argument, but we assume the path is absolute in
545  // the rest of clangd so we make sure the path is absolute before
546  // continuing.
547  llvm::SmallString<128> Path(CompileCommandsDir);
548  if (std::error_code EC = llvm::sys::fs::make_absolute(Path)) {
549  llvm::errs() << "Error while converting the relative path specified by "
550  "--compile-commands-dir to an absolute path: "
551  << EC.message() << ". The argument will be ignored.\n";
552  } else {
553  CompileCommandsDirPath = Path.str();
554  }
555  } else {
556  llvm::errs()
557  << "Path specified by --compile-commands-dir does not exist. The "
558  "argument will be ignored.\n";
559  }
560  }
561 
563  switch (PCHStorage) {
564  case PCHStorageFlag::Memory:
565  Opts.StorePreamblesInMemory = true;
566  break;
567  case PCHStorageFlag::Disk:
568  Opts.StorePreamblesInMemory = false;
569  break;
570  }
571  if (!ResourceDir.empty())
572  Opts.ResourceDir = ResourceDir;
573  Opts.BuildDynamicSymbolIndex = EnableIndex;
574  Opts.BackgroundIndex = EnableBackgroundIndex;
575  std::unique_ptr<SymbolIndex> StaticIdx;
576  std::future<void> AsyncIndexLoad; // Block exit while loading the index.
577  if (EnableIndex && !IndexFile.empty()) {
578  // Load the index asynchronously. Meanwhile SwapIndex returns no results.
579  SwapIndex *Placeholder;
580  StaticIdx.reset(Placeholder = new SwapIndex(llvm::make_unique<MemIndex>()));
581  AsyncIndexLoad = runAsync<void>([Placeholder] {
582  if (auto Idx = loadIndex(IndexFile, /*UseDex=*/true))
583  Placeholder->reset(std::move(Idx));
584  });
585  if (Sync)
586  AsyncIndexLoad.wait();
587  }
588  Opts.StaticIndex = StaticIdx.get();
589  Opts.AsyncThreadsCount = WorkerThreadsCount;
590 
592  CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;
593  CCOpts.Limit = LimitResults;
594  if (CompletionStyle.getNumOccurrences())
595  CCOpts.BundleOverloads = CompletionStyle != Detailed;
596  CCOpts.ShowOrigins = ShowOrigins;
597  CCOpts.InsertIncludes = HeaderInsertion;
598  if (!HeaderInsertionDecorators) {
599  CCOpts.IncludeIndicator.Insert.clear();
600  CCOpts.IncludeIndicator.NoInsert.clear();
601  }
602  CCOpts.SpeculativeIndexRequest = Opts.StaticIndex;
603  CCOpts.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
604  CCOpts.AllScopes = AllScopesCompletion;
605  CCOpts.RunParser = CodeCompletionParse;
606 
608  // Initialize and run ClangdLSPServer.
609  // Change stdin to binary to not lose \r\n on windows.
610  llvm::sys::ChangeStdinToBinary();
611 
612  std::unique_ptr<Transport> TransportLayer;
613  if (getenv("CLANGD_AS_XPC_SERVICE")) {
614 #if CLANGD_BUILD_XPC
615  log("Starting LSP over XPC service");
616  TransportLayer = newXPCTransport();
617 #else
618  llvm::errs() << "This clangd binary wasn't built with XPC support.\n";
620 #endif
621  } else {
622  log("Starting LSP over stdin/stdout");
623  TransportLayer = newJSONTransport(
624  stdin, llvm::outs(),
625  InputMirrorStream ? InputMirrorStream.getPointer() : nullptr,
626  PrettyPrint, InputStyle);
627  }
628 
629  // Create an empty clang-tidy option.
630  std::mutex ClangTidyOptMu;
631  std::unique_ptr<tidy::ClangTidyOptionsProvider>
632  ClangTidyOptProvider; /*GUARDED_BY(ClangTidyOptMu)*/
633  if (EnableClangTidy) {
634  auto OverrideClangTidyOptions = tidy::ClangTidyOptions::getDefaults();
635  OverrideClangTidyOptions.Checks = ClangTidyChecks;
636  ClangTidyOptProvider = llvm::make_unique<tidy::FileOptionsProvider>(
638  /* Default */ tidy::ClangTidyOptions::getDefaults(),
639  /* Override */ OverrideClangTidyOptions, FSProvider.getFileSystem());
640  Opts.GetClangTidyOptions = [&](llvm::vfs::FileSystem &,
641  llvm::StringRef File) {
642  // This function must be thread-safe and tidy option providers are not.
643  std::lock_guard<std::mutex> Lock(ClangTidyOptMu);
644  // FIXME: use the FS provided to the function.
645  return ClangTidyOptProvider->getOptions(File);
646  };
647  }
648  Opts.SuggestMissingIncludes = SuggestMissingIncludes;
649  Opts.QueryDriverGlobs = std::move(QueryDriverGlobs);
650 
651  Opts.TweakFilter = [&](const Tweak &T) {
652  if (T.hidden() && !HiddenFeatures)
653  return false;
654  if (TweakList.getNumOccurrences())
655  return llvm::is_contained(TweakList, T.id());
656  return true;
657  };
658  llvm::Optional<OffsetEncoding> OffsetEncodingFromFlag;
659  if (ForceOffsetEncoding != OffsetEncoding::UnsupportedEncoding)
660  OffsetEncodingFromFlag = ForceOffsetEncoding;
661  ClangdLSPServer LSPServer(
662  *TransportLayer, FSProvider, CCOpts, CompileCommandsDirPath,
663  /*UseDirBasedCDB=*/CompileArgsFrom == FilesystemCompileArgs,
664  OffsetEncodingFromFlag, Opts);
665  llvm::set_thread_name("clangd.main");
666  return LSPServer.run() ? 0
667  : static_cast<int>(ErrorResultCode::NoShutdownRequest);
668 }
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:423
Always use text-based completion.
Definition: CodeComplete.h:131
int main(int argc, char *argv[])
Definition: ClangdMain.cpp:428
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