clang-tools  17.0.0git
Check.cpp
Go to the documentation of this file.
1 //===--- Check.cpp - clangd self-diagnostics ------------------------------===//
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 // Many basic problems can occur processing a file in clangd, e.g.:
10 // - system includes are not found
11 // - crash when indexing its AST
12 // clangd --check provides a simplified, isolated way to reproduce these,
13 // with no editor, LSP, threads, background indexing etc to contend with.
14 //
15 // One important use case is gathering information for bug reports.
16 // Another is reproducing crashes, and checking which setting prevent them.
17 //
18 // It simulates opening a file (determining compile command, parsing, indexing)
19 // and then running features at many locations.
20 //
21 // Currently it adds some basic logging of progress and results.
22 // We should consider extending it to also recognize common symptoms and
23 // recommend solutions (e.g. standard library installation issues).
24 //
25 //===----------------------------------------------------------------------===//
26 
27 #include "../clang-tidy/ClangTidyModuleRegistry.h"
28 #include "../clang-tidy/GlobList.h"
29 #include "ClangdLSPServer.h"
30 #include "CodeComplete.h"
31 #include "CompileCommands.h"
32 #include "Config.h"
33 #include "Feature.h"
35 #include "Hover.h"
36 #include "InlayHints.h"
37 #include "ParsedAST.h"
38 #include "Preamble.h"
39 #include "Protocol.h"
40 #include "SemanticHighlighting.h"
41 #include "SourceCode.h"
42 #include "XRefs.h"
44 #include "index/FileIndex.h"
45 #include "refactor/Tweak.h"
46 #include "support/ThreadsafeFS.h"
47 #include "support/Trace.h"
48 #include "clang/AST/ASTContext.h"
49 #include "clang/Basic/Diagnostic.h"
50 #include "clang/Format/Format.h"
51 #include "clang/Frontend/CompilerInvocation.h"
52 #include "clang/Tooling/CompilationDatabase.h"
53 #include "llvm/ADT/ArrayRef.h"
54 #include "llvm/Support/Path.h"
55 #include "llvm/Support/Process.h"
56 #include <optional>
57 
58 namespace clang {
59 namespace clangd {
60 namespace {
61 
62 // These will never be shown in --help, ClangdMain doesn't list the category.
63 llvm::cl::opt<std::string> CheckTidyTime{
64  "check-tidy-time",
65  llvm::cl::desc("Print the overhead of checks matching this glob"),
66  llvm::cl::init("")};
67 llvm::cl::opt<std::string> CheckFileLines{
68  "check-lines",
69  llvm::cl::desc(
70  "Limits the range of tokens in -check file on which "
71  "various features are tested. Example --check-lines=3-7 restricts "
72  "testing to lines 3 to 7 (inclusive) or --check-lines=5 to restrict "
73  "to one line. Default is testing entire file."),
74  llvm::cl::init("")};
75 llvm::cl::opt<bool> CheckLocations{
76  "check-locations",
77  llvm::cl::desc(
78  "Runs certain features (e.g. hover) at each point in the file. "
79  "Somewhat slow."),
80  llvm::cl::init(true)};
81 llvm::cl::opt<bool> CheckCompletion{
82  "check-completion",
83  llvm::cl::desc("Run code-completion at each point (slow)"),
84  llvm::cl::init(false)};
85 
86 // Print (and count) the error-level diagnostics (warnings are ignored).
87 unsigned showErrors(llvm::ArrayRef<Diag> Diags) {
88  unsigned ErrCount = 0;
89  for (const auto &D : Diags) {
90  if (D.Severity >= DiagnosticsEngine::Error) {
91  elog("[{0}] Line {1}: {2}", D.Name, D.Range.start.line + 1, D.Message);
92  ++ErrCount;
93  }
94  }
95  return ErrCount;
96 }
97 
98 std::vector<std::string> listTidyChecks(llvm::StringRef Glob) {
99  tidy::GlobList G(Glob);
100  tidy::ClangTidyCheckFactories CTFactories;
101  for (const auto &E : tidy::ClangTidyModuleRegistry::entries())
102  E.instantiate()->addCheckFactories(CTFactories);
103  std::vector<std::string> Result;
104  for (const auto &E : CTFactories)
105  if (G.contains(E.getKey()))
106  Result.push_back(E.getKey().str());
107  llvm::sort(Result);
108  return Result;
109 }
110 
111 // This class is just a linear pipeline whose functions get called in sequence.
112 // Each exercises part of clangd's logic on our test file and logs results.
113 // Later steps depend on state built in earlier ones (such as the AST).
114 // Many steps can fatally fail (return false), then subsequent ones cannot run.
115 // Nonfatal failures are logged and tracked in ErrCount.
116 class Checker {
117  // from constructor
118  std::string File;
119  ClangdLSPServer::Options Opts;
120  // from buildCommand
121  tooling::CompileCommand Cmd;
122  // from buildInvocation
123  ParseInputs Inputs;
124  std::unique_ptr<CompilerInvocation> Invocation;
125  format::FormatStyle Style;
126  // from buildAST
127  std::shared_ptr<const PreambleData> Preamble;
128  std::optional<ParsedAST> AST;
129  FileIndex Index;
130 
131 public:
132  // Number of non-fatal errors seen.
133  unsigned ErrCount = 0;
134 
135  Checker(llvm::StringRef File, const ClangdLSPServer::Options &Opts)
136  : File(File), Opts(Opts) {}
137 
138  // Read compilation database and choose a compile command for the file.
139  bool buildCommand(const ThreadsafeFS &TFS) {
140  log("Loading compilation database...");
141  DirectoryBasedGlobalCompilationDatabase::Options CDBOpts(TFS);
142  CDBOpts.CompileCommandsDir =
144  std::unique_ptr<GlobalCompilationDatabase> BaseCDB =
145  std::make_unique<DirectoryBasedGlobalCompilationDatabase>(CDBOpts);
146  auto Mangler = CommandMangler::detect();
147  Mangler.SystemIncludeExtractor =
148  getSystemIncludeExtractor(llvm::ArrayRef(Opts.QueryDriverGlobs));
149  if (Opts.ResourceDir)
150  Mangler.ResourceDir = *Opts.ResourceDir;
151  auto CDB = std::make_unique<OverlayCDB>(
152  BaseCDB.get(), std::vector<std::string>{}, std::move(Mangler));
153 
154  if (auto TrueCmd = CDB->getCompileCommand(File)) {
155  Cmd = std::move(*TrueCmd);
156  log("Compile command {0} is: {1}",
157  Cmd.Heuristic.empty() ? "from CDB" : Cmd.Heuristic,
158  printArgv(Cmd.CommandLine));
159  } else {
160  Cmd = CDB->getFallbackCommand(File);
161  log("Generic fallback command is: {0}", printArgv(Cmd.CommandLine));
162  }
163 
164  return true;
165  }
166 
167  // Prepare inputs and build CompilerInvocation (parsed compile command).
168  bool buildInvocation(const ThreadsafeFS &TFS,
169  std::optional<std::string> Contents) {
170  StoreDiags CaptureInvocationDiags;
171  std::vector<std::string> CC1Args;
172  Inputs.CompileCommand = Cmd;
173  Inputs.TFS = &TFS;
174  Inputs.ClangTidyProvider = Opts.ClangTidyProvider;
175  Inputs.Opts.PreambleParseForwardingFunctions =
176  Opts.PreambleParseForwardingFunctions;
177  if (Contents) {
178  Inputs.Contents = *Contents;
179  log("Imaginary source file contents:\n{0}", Inputs.Contents);
180  } else {
181  if (auto Contents = TFS.view(std::nullopt)->getBufferForFile(File)) {
182  Inputs.Contents = Contents->get()->getBuffer().str();
183  } else {
184  elog("Couldn't read {0}: {1}", File, Contents.getError().message());
185  return false;
186  }
187  }
188  log("Parsing command...");
189  Invocation =
190  buildCompilerInvocation(Inputs, CaptureInvocationDiags, &CC1Args);
191  auto InvocationDiags = CaptureInvocationDiags.take();
192  ErrCount += showErrors(InvocationDiags);
193  log("internal (cc1) args are: {0}", printArgv(CC1Args));
194  if (!Invocation) {
195  elog("Failed to parse command line");
196  return false;
197  }
198 
199  // FIXME: Check that resource-dir/built-in-headers exist?
200 
201  Style = getFormatStyleForFile(File, Inputs.Contents, TFS);
202 
203  return true;
204  }
205 
206  // Build preamble and AST, and index them.
207  bool buildAST() {
208  log("Building preamble...");
209  Preamble = buildPreamble(File, *Invocation, Inputs, /*StoreInMemory=*/true,
210  [&](ASTContext &Ctx, Preprocessor &PP,
211  const CanonicalIncludes &Includes) {
212  if (!Opts.BuildDynamicSymbolIndex)
213  return;
214  log("Indexing headers...");
215  Index.updatePreamble(File, /*Version=*/"null",
216  Ctx, PP, Includes);
217  });
218  if (!Preamble) {
219  elog("Failed to build preamble");
220  return false;
221  }
222  ErrCount += showErrors(Preamble->Diags);
223 
224  log("Building AST...");
225  AST = ParsedAST::build(File, Inputs, std::move(Invocation),
226  /*InvocationDiags=*/std::vector<Diag>{}, Preamble);
227  if (!AST) {
228  elog("Failed to build AST");
229  return false;
230  }
231  ErrCount += showErrors(llvm::ArrayRef(*AST->getDiagnostics())
232  .drop_front(Preamble->Diags.size()));
233 
234  if (Opts.BuildDynamicSymbolIndex) {
235  log("Indexing AST...");
236  Index.updateMain(File, *AST);
237  }
238 
239  if (!CheckTidyTime.empty()) {
240  if (!CLANGD_TIDY_CHECKS) {
241  elog("-{0} requires -DCLANGD_TIDY_CHECKS!", CheckTidyTime.ArgStr);
242  return false;
243  }
244  #ifndef NDEBUG
245  elog("Timing clang-tidy checks in asserts-mode is not representative!");
246  #endif
247  checkTidyTimes();
248  }
249 
250  return true;
251  }
252 
253  // For each check foo, we want to build with checks=-* and checks=-*,foo.
254  // (We do a full build rather than just AST matchers to meausre PPCallbacks).
255  //
256  // However, performance has both random noise and systematic changes, such as
257  // step-function slowdowns due to CPU scaling.
258  // We take the median of 5 measurements, and after every check discard the
259  // measurement if the baseline changed by >3%.
260  void checkTidyTimes() {
261  double Stability = 0.03;
262  log("Timing AST build with individual clang-tidy checks (target accuracy "
263  "{0:P0})",
264  Stability);
265 
266  using Duration = std::chrono::nanoseconds;
267  // Measure time elapsed by a block of code. Currently: user CPU time.
268  auto Time = [&](auto &&Run) -> Duration {
269  llvm::sys::TimePoint<> Elapsed;
270  std::chrono::nanoseconds UserBegin, UserEnd, System;
271  llvm::sys::Process::GetTimeUsage(Elapsed, UserBegin, System);
272  Run();
273  llvm::sys::Process::GetTimeUsage(Elapsed, UserEnd, System);
274  return UserEnd - UserBegin;
275  };
276  auto Change = [&](Duration Exp, Duration Base) -> double {
277  return (double)(Exp.count() - Base.count()) / Base.count();
278  };
279  // Build ParsedAST with a fixed check glob, and return the time taken.
280  auto Build = [&](llvm::StringRef Checks) -> Duration {
281  TidyProvider CTProvider = [&](tidy::ClangTidyOptions &Opts,
282  llvm::StringRef) {
283  Opts.Checks = Checks.str();
284  };
285  Inputs.ClangTidyProvider = CTProvider;
286  // Sigh, can't reuse the CompilerInvocation.
287  IgnoringDiagConsumer IgnoreDiags;
288  auto Invocation = buildCompilerInvocation(Inputs, IgnoreDiags);
289  Duration Val = Time([&] {
290  ParsedAST::build(File, Inputs, std::move(Invocation), {}, Preamble);
291  });
292  vlog(" Measured {0} ==> {1}", Checks, Val);
293  return Val;
294  };
295  // Measure several times, return the median.
296  auto MedianTime = [&](llvm::StringRef Checks) -> Duration {
297  std::array<Duration, 5> Measurements;
298  for (auto &M : Measurements)
299  M = Build(Checks);
300  llvm::sort(Measurements);
301  return Measurements[Measurements.size() / 2];
302  };
303  Duration Baseline = MedianTime("-*");
304  log(" Baseline = {0}", Baseline);
305  // Attempt to time a check, may update Baseline if it is unstable.
306  auto Measure = [&](llvm::StringRef Check) -> double {
307  for (;;) {
308  Duration Median = MedianTime(("-*," + Check).str());
309  Duration NewBase = MedianTime("-*");
310 
311  // Value only usable if baseline is fairly consistent before/after.
312  double DeltaFraction = Change(NewBase, Baseline);
313  Baseline = NewBase;
314  vlog(" Baseline = {0}", Baseline);
315  if (DeltaFraction < -Stability || DeltaFraction > Stability) {
316  elog(" Speed unstable, discarding measurement.");
317  continue;
318  }
319  return Change(Median, Baseline);
320  }
321  };
322 
323  for (const auto& Check : listTidyChecks(CheckTidyTime)) {
324  // vlog the check name in case we crash!
325  vlog(" Timing {0}", Check);
326  double Fraction = Measure(Check);
327  log(" {0} = {1:P0}", Check, Fraction);
328  }
329  log("Finished individual clang-tidy checks");
330 
331  // Restore old options.
332  Inputs.ClangTidyProvider = Opts.ClangTidyProvider;
333  }
334 
335  // Build Inlay Hints for the entire AST or the specified range
336  void buildInlayHints(std::optional<Range> LineRange) {
337  log("Building inlay hints");
338  auto Hints = inlayHints(*AST, LineRange);
339 
340  for (const auto &Hint : Hints) {
341  vlog(" {0} {1} {2}", Hint.kind, Hint.position, Hint.label);
342  }
343  }
344 
345  void buildSemanticHighlighting(std::optional<Range> LineRange) {
346  log("Building semantic highlighting");
347  auto Highlights = getSemanticHighlightings(*AST);
348  for (const auto HL : Highlights)
349  if (!LineRange || LineRange->contains(HL.R))
350  vlog(" {0} {1} {2}", HL.R, HL.Kind, HL.Modifiers);
351  }
352 
353  // Run AST-based features at each token in the file.
354  void testLocationFeatures(std::optional<Range> LineRange) {
355  trace::Span Trace("testLocationFeatures");
356  log("Testing features at each token (may be slow in large files)");
357  auto &SM = AST->getSourceManager();
358  auto SpelledTokens = AST->getTokens().spelledTokens(SM.getMainFileID());
359 
360  CodeCompleteOptions CCOpts = Opts.CodeComplete;
361  CCOpts.Index = &Index;
362 
363  for (const auto &Tok : SpelledTokens) {
364  unsigned Start = AST->getSourceManager().getFileOffset(Tok.location());
365  unsigned End = Start + Tok.length();
366  Position Pos = offsetToPosition(Inputs.Contents, Start);
367 
368  if (LineRange && !LineRange->contains(Pos))
369  continue;
370 
371  trace::Span Trace("Token");
372  SPAN_ATTACH(Trace, "pos", Pos);
373  SPAN_ATTACH(Trace, "text", Tok.text(AST->getSourceManager()));
374 
375  // FIXME: dumping the tokens may leak sensitive code into bug reports.
376  // Add an option to turn this off, once we decide how options work.
377  vlog(" {0} {1}", Pos, Tok.text(AST->getSourceManager()));
378  auto Tree = SelectionTree::createRight(AST->getASTContext(),
379  AST->getTokens(), Start, End);
380  Tweak::Selection Selection(&Index, *AST, Start, End, std::move(Tree),
381  nullptr);
382  // FS is only populated when applying a tweak, not during prepare as
383  // prepare should not do any I/O to be fast.
384  auto Tweaks =
385  prepareTweaks(Selection, Opts.TweakFilter, Opts.FeatureModules);
386  Selection.FS =
387  &AST->getSourceManager().getFileManager().getVirtualFileSystem();
388  for (const auto &T : Tweaks) {
389  auto Result = T->apply(Selection);
390  if (!Result) {
391  elog(" tweak: {0} ==> FAIL: {1}", T->id(), Result.takeError());
392  ++ErrCount;
393  } else {
394  vlog(" tweak: {0}", T->id());
395  }
396  }
397  unsigned Definitions = locateSymbolAt(*AST, Pos, &Index).size();
398  vlog(" definition: {0}", Definitions);
399 
400  auto Hover = getHover(*AST, Pos, Style, &Index);
401  vlog(" hover: {0}", Hover.has_value());
402 
403  unsigned DocHighlights = findDocumentHighlights(*AST, Pos).size();
404  vlog(" documentHighlight: {0}", DocHighlights);
405 
406  if (CheckCompletion) {
407  Position EndPos = offsetToPosition(Inputs.Contents, End);
408  auto CC = codeComplete(File, EndPos, Preamble.get(), Inputs, CCOpts);
409  vlog(" code completion: {0}",
410  CC.Completions.empty() ? "<empty>" : CC.Completions[0].Name);
411  }
412  }
413  }
414 };
415 
416 } // namespace
417 
418 bool check(llvm::StringRef File, const ThreadsafeFS &TFS,
419  const ClangdLSPServer::Options &Opts) {
420  std::optional<Range> LineRange;
421  if (!CheckFileLines.empty()) {
422  uint32_t Begin = 0, End = std::numeric_limits<uint32_t>::max();
423  StringRef RangeStr(CheckFileLines);
424  bool ParseError = RangeStr.consumeInteger(0, Begin);
425  if (RangeStr.empty()) {
426  End = Begin;
427  } else {
428  ParseError |= !RangeStr.consume_front("-");
429  ParseError |= RangeStr.consumeInteger(0, End);
430  }
431  if (ParseError || !RangeStr.empty() || Begin <= 0 || End < Begin) {
432  elog("Invalid --check-lines specified. Use Begin-End format, e.g. 3-17");
433  return false;
434  }
435  LineRange = Range{Position{static_cast<int>(Begin - 1), 0},
436  Position{static_cast<int>(End), 0}};
437  }
438 
439  llvm::SmallString<0> FakeFile;
440  std::optional<std::string> Contents;
441  if (File.empty()) {
442  llvm::sys::path::system_temp_directory(false, FakeFile);
443  llvm::sys::path::append(FakeFile, "test.cc");
444  File = FakeFile;
445  Contents = R"cpp(
446  #include <stddef.h>
447  #include <string>
448 
449  size_t N = 50;
450  auto xxx = std::string(N, 'x');
451  )cpp";
452  }
453  log("Testing on source file {0}", File);
454 
455  auto ContextProvider = ClangdServer::createConfiguredContextProvider(
456  Opts.ConfigProvider, nullptr);
457  WithContext Ctx(ContextProvider(
458  FakeFile.empty()
459  ? File
460  : /*Don't turn on local configs for an arbitrary temp path.*/ ""));
461  Checker C(File, Opts);
462  if (!C.buildCommand(TFS) || !C.buildInvocation(TFS, Contents) ||
463  !C.buildAST())
464  return false;
465  C.buildInlayHints(LineRange);
466  C.buildSemanticHighlighting(LineRange);
467  if (CheckLocations)
468  C.testLocationFeatures(LineRange);
469 
470  log("All checks completed, {0} errors", C.ErrCount);
471  return C.ErrCount == 0;
472 }
473 
474 } // namespace clangd
475 } // namespace clang
clang::clangd::buildPreamble
std::shared_ptr< const PreambleData > buildPreamble(PathRef FileName, CompilerInvocation CI, const ParseInputs &Inputs, bool StoreInMemory, PreambleParsedCallback PreambleCallback, PreambleBuildStats *Stats)
Build a preamble for the new inputs unless an old one can be reused.
Definition: Preamble.cpp:473
XRefs.h
Base
std::unique_ptr< GlobalCompilationDatabase > Base
Definition: GlobalCompilationDatabaseTests.cpp:85
clang::clangd::ErrorCode::ParseError
@ ParseError
Hints
std::vector< FixItHint > Hints
Definition: RedundantStrcatCallsCheck.cpp:44
E
const Expr * E
Definition: AvoidBindCheck.cpp:86
CodeComplete.h
clang::clangd::printArgv
std::string printArgv(llvm::ArrayRef< llvm::StringRef > Args)
Definition: CompileCommands.cpp:639
Checks
static cl::opt< std::string > Checks("checks", cl::desc(R"( Comma-separated list of globs with optional '-' prefix. Globs are processed in order of appearance in the list. Globs without '-' prefix add checks with matching names to the set, globs with the '-' prefix remove checks with matching names from the set of enabled checks. This option's value is appended to the value of the 'Checks' option in .clang-tidy file, if any. )"), cl::init(""), cl::cat(ClangTidyCategory))
FormatStyle
static cl::opt< std::string > FormatStyle("format-style", cl::desc(R"( Style for formatting code around applied fixes: - 'none' (default) turns off formatting - 'file' (literally 'file', not a placeholder) uses .clang-format file in the closest parent directory - '{ <json> }' specifies options inline, e.g. -format-style='{BasedOnStyle: llvm, IndentWidth: 8}' - 'llvm', 'google', 'webkit', 'mozilla' See clang-format documentation for the up-to-date information about formatting styles and options. This option overrides the 'FormatStyle` option in .clang-tidy file, if any. )"), cl::init("none"), cl::cat(ClangTidyCategory))
Preamble.h
Feature.h
Ctx
Context Ctx
Definition: TUScheduler.cpp:552
Trace.h
Preamble
const PreambleData & Preamble
Definition: CodeComplete.cpp:1241
Pos
size_t Pos
Definition: NoLintDirectiveHandler.cpp:96
InlayHints.h
clang::clangd::ClangdLSPServer::Options
Definition: ClangdLSPServer.h:39
Protocol.h
M
const google::protobuf::Message & M
Definition: Server.cpp:309
ThreadsafeFS.h
clang::clangd::getSystemIncludeExtractor
SystemIncludeExtractorFn getSystemIncludeExtractor(llvm::ArrayRef< std::string > QueryDriverGlobs)
Definition: SystemIncludeExtractor.cpp:370
Hover.h
Error
constexpr static llvm::SourceMgr::DiagKind Error
Definition: ConfigCompile.cpp:592
Inputs
ParseInputs Inputs
Definition: TUScheduler.cpp:549
clang::clangd::prepareTweaks
std::vector< std::unique_ptr< Tweak > > prepareTweaks(const Tweak::Selection &S, llvm::function_ref< bool(const Tweak &)> Filter, const FeatureModuleSet *Modules)
Calls prepare() on all tweaks that satisfy the filter, returning those that can run on the selection.
Definition: Tweak.cpp:72
clang::clangd::Position
Definition: Protocol.h:156
CanonicalIncludes.h
ns1::ns2::D
@ D
Definition: CategoricalFeature.h:3
ClangdLSPServer.h
clang::clangd::locateSymbolAt
std::vector< LocatedSymbol > locateSymbolAt(ParsedAST &AST, Position Pos, const SymbolIndex *Index)
Get definition of symbol at a specified Pos.
Definition: XRefs.cpp:747
clang::clangd::SelectionTree::createRight
static SelectionTree createRight(ASTContext &AST, const syntax::TokenBuffer &Tokens, unsigned Begin, unsigned End)
Definition: Selection.cpp:1060
Tweak.h
ErrCount
unsigned ErrCount
Definition: Check.cpp:133
GlobalCompilationDatabase.h
clang::clangd::CommandMangler::detect
static CommandMangler detect()
Definition: CompileCommands.cpp:188
CompileCommands.h
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::codeComplete
CodeCompleteResult codeComplete(PathRef FileName, Position Pos, const PreambleData *Preamble, const ParseInputs &ParseInput, CodeCompleteOptions Opts, SpeculativeFuzzyFind *SpecFuzzyFind)
Gets code completions at a specified Pos in FileName.
Definition: CodeComplete.cpp:2082
clang::clangd::getHover
std::optional< HoverInfo > getHover(ParsedAST &AST, Position Pos, const format::FormatStyle &Style, const SymbolIndex *Index)
Get the hover information when hovering at Pos.
Definition: Hover.cpp:1081
SPAN_ATTACH
#define SPAN_ATTACH(S, Name, Expr)
Attach a key-value pair to a Span event.
Definition: Trace.h:164
CC
CognitiveComplexity CC
Definition: FunctionCognitiveComplexityCheck.cpp:490
clang::clangd::vlog
void vlog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:72
clang::clangd::offsetToPosition
Position offsetToPosition(llvm::StringRef Code, size_t Offset)
Turn an offset in Code into a [line, column] pair.
Definition: SourceCode.cpp:201
FileIndex.h
clang::clangd::WithContext
WithContext replaces Context::current() with a provided scope.
Definition: Context.h:185
clang::clangd::getSemanticHighlightings
std::vector< HighlightingToken > getSemanticHighlightings(ParsedAST &AST)
Definition: SemanticHighlighting.cpp:962
clang::clangd::getFormatStyleForFile
format::FormatStyle getFormatStyleForFile(llvm::StringRef File, llvm::StringRef Content, const ThreadsafeFS &TFS)
Choose the clang-format style we should apply to a certain file.
Definition: SourceCode.cpp:581
clang::tidy::bugprone::PP
static Preprocessor * PP
Definition: BadSignalToKillThreadCheck.cpp:28
clang::clangd::log
void log(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:67
clang::clangd::buildCompilerInvocation
std::unique_ptr< CompilerInvocation > buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D, std::vector< std::string > *CC1Args)
Builds compiler invocation that could be used to build AST or preamble.
Definition: Compiler.cpp:95
SourceCode.h
Index
const SymbolIndex * Index
Definition: Dexp.cpp:99
Config.h
clang::clangd::ThreadsafeFS
Wrapper for vfs::FileSystem for use in multithreaded programs like clangd.
Definition: ThreadsafeFS.h:26
clang::clangd::Config::CDBSearchSpec::FixedCDBPath
std::optional< std::string > FixedCDBPath
Definition: Config.h:59
clang::clangd::Range
Definition: Protocol.h:185
C
const Criteria C
Definition: FunctionCognitiveComplexityCheck.cpp:91
SemanticHighlighting.h
clang::clangd::Config::CDBSearch
CDBSearchSpec CDBSearch
Where to search for compilation databases for this file's flags.
Definition: Config.h:68
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::check
bool check(llvm::StringRef File, const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts)
Definition: Check.cpp:418
clang::clangd::inlayHints
std::vector< InlayHint > inlayHints(ParsedAST &AST, std::optional< Range > RestrictRange)
Compute and return inlay hints for a file.
Definition: InlayHints.cpp:723
Diags
CapturedDiags Diags
Definition: ConfigCompileTests.cpp:38
clang::clangd::Config::current
static const Config & current()
Returns the Config of the current Context, or an empty configuration.
Definition: Config.cpp:17
clang::clangd::elog
void elog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:61
clang::clangd::ParsedAST::build
static std::optional< ParsedAST > build(llvm::StringRef Filename, const ParseInputs &Inputs, std::unique_ptr< clang::CompilerInvocation > CI, llvm::ArrayRef< Diag > CompilerInvocationDiags, std::shared_ptr< const PreambleData > Preamble)
Attempts to run Clang and store the parsed AST.
Definition: ParsedAST.cpp:345
clang::clangd::Config::CompileFlags
struct clang::clangd::Config::@2 CompileFlags
Controls how the compile command for the current file is determined.
IgnoreDiags
IgnoringDiagConsumer IgnoreDiags
Definition: HeadersTests.cpp:142
ParsedAST.h
clang::clangd::findDocumentHighlights
std::vector< DocumentHighlight > findDocumentHighlights(ParsedAST &AST, Position Pos)
Returns highlights for all usages of a symbol at Pos.
Definition: XRefs.cpp:1218
clang::clangd::ClangdServer::createConfiguredContextProvider
static std::function< Context(PathRef)> createConfiguredContextProvider(const config::Provider *Provider, ClangdServer::Callbacks *)
Creates a context provider that loads and installs config.
Definition: ClangdServer.cpp:301