clang-tools  9.0.0
XRefsTests.cpp
Go to the documentation of this file.
1 //===-- XRefsTests.cpp ---------------------------*- C++ -*--------------===//
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 #include "Annotations.h"
9 #include "ClangdUnit.h"
10 #include "Compiler.h"
11 #include "Matchers.h"
12 #include "Protocol.h"
13 #include "SyncAPI.h"
14 #include "TestFS.h"
15 #include "TestIndex.h"
16 #include "TestTU.h"
17 #include "XRefs.h"
18 #include "index/FileIndex.h"
19 #include "index/MemIndex.h"
20 #include "index/SymbolCollector.h"
21 #include "clang/Index/IndexingAction.h"
22 #include "llvm/ADT/None.h"
23 #include "llvm/Support/Path.h"
24 #include "llvm/Support/ScopedPrinter.h"
25 #include "gmock/gmock.h"
26 #include "gtest/gtest.h"
27 #include <string>
28 
29 namespace clang {
30 namespace clangd {
31 namespace {
32 
33 using ::testing::ElementsAre;
34 using ::testing::IsEmpty;
35 using ::testing::Matcher;
36 using ::testing::UnorderedElementsAreArray;
37 
38 class IgnoreDiagnostics : public DiagnosticsConsumer {
40  std::vector<Diag> Diagnostics) override {}
41 };
42 
43 MATCHER_P2(FileRange, File, Range, "") {
45 }
46 
47 // Extracts ranges from an annotated example, and constructs a matcher for a
48 // highlight set. Ranges should be named $read/$write as appropriate.
49 Matcher<const std::vector<DocumentHighlight> &>
50 HighlightsFrom(const Annotations &Test) {
51  std::vector<DocumentHighlight> Expected;
52  auto Add = [&](const Range &R, DocumentHighlightKind K) {
53  Expected.emplace_back();
54  Expected.back().range = R;
55  Expected.back().kind = K;
56  };
57  for (const auto &Range : Test.ranges())
59  for (const auto &Range : Test.ranges("read"))
61  for (const auto &Range : Test.ranges("write"))
63  return UnorderedElementsAreArray(Expected);
64 }
65 
66 TEST(HighlightsTest, All) {
67  const char *Tests[] = {
68  R"cpp(// Local variable
69  int main() {
70  int [[bonjour]];
71  $write[[^bonjour]] = 2;
72  int test1 = $read[[bonjour]];
73  }
74  )cpp",
75 
76  R"cpp(// Struct
77  namespace ns1 {
78  struct [[MyClass]] {
79  static void foo([[MyClass]]*) {}
80  };
81  } // namespace ns1
82  int main() {
83  ns1::[[My^Class]]* Params;
84  }
85  )cpp",
86 
87  R"cpp(// Function
88  int [[^foo]](int) {}
89  int main() {
90  [[foo]]([[foo]](42));
91  auto *X = &[[foo]];
92  }
93  )cpp",
94 
95  R"cpp(// Function parameter in decl
96  void foo(int [[^bar]]);
97  )cpp",
98  };
99  for (const char *Test : Tests) {
100  Annotations T(Test);
101  auto AST = TestTU::withCode(T.code()).build();
102  EXPECT_THAT(findDocumentHighlights(AST, T.point()), HighlightsFrom(T))
103  << Test;
104  }
105 }
106 
107 MATCHER_P3(Sym, Name, Decl, DefOrNone, "") {
108  llvm::Optional<Range> Def = DefOrNone;
109  if (Name != arg.Name) {
110  *result_listener << "Name is " << arg.Name;
111  return false;
112  }
113  if (Decl != arg.PreferredDeclaration.range) {
114  *result_listener << "Declaration is "
115  << llvm::to_string(arg.PreferredDeclaration);
116  return false;
117  }
118  if (Def && !arg.Definition) {
119  *result_listener << "Has no definition";
120  return false;
121  }
122  if (Def && arg.Definition->range != *Def) {
123  *result_listener << "Definition is " << llvm::to_string(arg.Definition);
124  return false;
125  }
126  return true;
127 }
128 ::testing::Matcher<LocatedSymbol> Sym(std::string Name, Range Decl) {
129  return Sym(Name, Decl, llvm::None);
130 }
131 MATCHER_P(Sym, Name, "") { return arg.Name == Name; }
132 
133 MATCHER_P(RangeIs, R, "") { return arg.range == R; }
134 
135 TEST(LocateSymbol, WithIndex) {
136  Annotations SymbolHeader(R"cpp(
137  class $forward[[Forward]];
138  class $foo[[Foo]] {};
139 
140  void $f1[[f1]]();
141 
142  inline void $f2[[f2]]() {}
143  )cpp");
144  Annotations SymbolCpp(R"cpp(
145  class $forward[[forward]] {};
146  void $f1[[f1]]() {}
147  )cpp");
148 
149  TestTU TU;
150  TU.Code = SymbolCpp.code();
151  TU.HeaderCode = SymbolHeader.code();
152  auto Index = TU.index();
153  auto LocateWithIndex = [&Index](const Annotations &Main) {
154  auto AST = TestTU::withCode(Main.code()).build();
155  return clangd::locateSymbolAt(AST, Main.point(), Index.get());
156  };
157 
158  Annotations Test(R"cpp(// only declaration in AST.
159  void [[f1]]();
160  int main() {
161  ^f1();
162  }
163  )cpp");
164  EXPECT_THAT(LocateWithIndex(Test),
165  ElementsAre(Sym("f1", Test.range(), SymbolCpp.range("f1"))));
166 
167  Test = Annotations(R"cpp(// definition in AST.
168  void [[f1]]() {}
169  int main() {
170  ^f1();
171  }
172  )cpp");
173  EXPECT_THAT(LocateWithIndex(Test),
174  ElementsAre(Sym("f1", SymbolHeader.range("f1"), Test.range())));
175 
176  Test = Annotations(R"cpp(// forward declaration in AST.
177  class [[Foo]];
178  F^oo* create();
179  )cpp");
180  EXPECT_THAT(LocateWithIndex(Test),
181  ElementsAre(Sym("Foo", Test.range(), SymbolHeader.range("foo"))));
182 
183  Test = Annotations(R"cpp(// defintion in AST.
184  class [[Forward]] {};
185  F^orward create();
186  )cpp");
187  EXPECT_THAT(
188  LocateWithIndex(Test),
189  ElementsAre(Sym("Forward", SymbolHeader.range("forward"), Test.range())));
190 }
191 
192 TEST(LocateSymbol, WithIndexPreferredLocation) {
193  Annotations SymbolHeader(R"cpp(
194  class $p[[Proto]] {};
195  void $f[[func]]() {};
196  )cpp");
197  TestTU TU;
198  TU.HeaderCode = SymbolHeader.code();
199  TU.HeaderFilename = "x.proto"; // Prefer locations in codegen files.
200  auto Index = TU.index();
201 
202  Annotations Test(R"cpp(// only declaration in AST.
203  // Shift to make range different.
204  class Proto;
205  void func() {}
206  P$p^roto* create() {
207  fu$f^nc();
208  return nullptr;
209  }
210  )cpp");
211 
212  auto AST = TestTU::withCode(Test.code()).build();
213  {
214  auto Locs = clangd::locateSymbolAt(AST, Test.point("p"), Index.get());
215  auto CodeGenLoc = SymbolHeader.range("p");
216  EXPECT_THAT(Locs, ElementsAre(Sym("Proto", CodeGenLoc, CodeGenLoc)));
217  }
218  {
219  auto Locs = clangd::locateSymbolAt(AST, Test.point("f"), Index.get());
220  auto CodeGenLoc = SymbolHeader.range("f");
221  EXPECT_THAT(Locs, ElementsAre(Sym("func", CodeGenLoc, CodeGenLoc)));
222  }
223 }
224 
225 TEST(LocateSymbol, All) {
226  // Ranges in tests:
227  // $decl is the declaration location (if absent, no symbol is located)
228  // $def is the definition location (if absent, symbol has no definition)
229  // unnamed range becomes both $decl and $def.
230  const char *Tests[] = {
231  R"cpp(// Local variable
232  int main() {
233  int [[bonjour]];
234  ^bonjour = 2;
235  int test1 = bonjour;
236  }
237  )cpp",
238 
239  R"cpp(// Struct
240  namespace ns1 {
241  struct [[MyClass]] {};
242  } // namespace ns1
243  int main() {
244  ns1::My^Class* Params;
245  }
246  )cpp",
247 
248  R"cpp(// Function definition via pointer
249  int [[foo]](int) {}
250  int main() {
251  auto *X = &^foo;
252  }
253  )cpp",
254 
255  R"cpp(// Function declaration via call
256  int $decl[[foo]](int);
257  int main() {
258  return ^foo(42);
259  }
260  )cpp",
261 
262  R"cpp(// Field
263  struct Foo { int [[x]]; };
264  int main() {
265  Foo bar;
266  bar.^x;
267  }
268  )cpp",
269 
270  R"cpp(// Field, member initializer
271  struct Foo {
272  int [[x]];
273  Foo() : ^x(0) {}
274  };
275  )cpp",
276 
277  R"cpp(// Field, GNU old-style field designator
278  struct Foo { int [[x]]; };
279  int main() {
280  Foo bar = { ^x : 1 };
281  }
282  )cpp",
283 
284  R"cpp(// Field, field designator
285  struct Foo { int [[x]]; };
286  int main() {
287  Foo bar = { .^x = 2 };
288  }
289  )cpp",
290 
291  R"cpp(// Method call
292  struct Foo { int $decl[[x]](); };
293  int main() {
294  Foo bar;
295  bar.^x();
296  }
297  )cpp",
298 
299  R"cpp(// Typedef
300  typedef int $decl[[Foo]];
301  int main() {
302  ^Foo bar;
303  }
304  )cpp",
305 
306  R"cpp(// Template type parameter
307  template <typename [[T]]>
308  void foo() { ^T t; }
309  )cpp",
310 
311  R"cpp(// Template template type parameter
312  template <template<typename> class [[T]]>
313  void foo() { ^T<int> t; }
314  )cpp",
315 
316  R"cpp(// Namespace
317  namespace $decl[[ns]] {
318  struct Foo { static void bar(); }
319  } // namespace ns
320  int main() { ^ns::Foo::bar(); }
321  )cpp",
322 
323  R"cpp(// Macro
324  #define MACRO 0
325  #define [[MACRO]] 1
326  int main() { return ^MACRO; }
327  #define MACRO 2
328  #undef macro
329  )cpp",
330 
331  R"cpp(// Macro
332  class TTT { public: int a; };
333  #define [[FF]](S) if (int b = S.a) {}
334  void f() {
335  TTT t;
336  F^F(t);
337  }
338  )cpp",
339 
340  R"cpp(// Macro argument
341  int [[i]];
342  #define ADDRESSOF(X) &X;
343  int *j = ADDRESSOF(^i);
344  )cpp",
345 
346  R"cpp(// Symbol concatenated inside macro (not supported)
347  int *pi;
348  #define POINTER(X) p # X;
349  int i = *POINTER(^i);
350  )cpp",
351 
352  R"cpp(// Forward class declaration
353  class Foo;
354  class [[Foo]] {};
355  F^oo* foo();
356  )cpp",
357 
358  R"cpp(// Function declaration
359  void foo();
360  void g() { f^oo(); }
361  void [[foo]]() {}
362  )cpp",
363 
364  R"cpp(
365  #define FF(name) class name##_Test {};
366  [[FF]](my);
367  void f() { my^_Test a; }
368  )cpp",
369 
370  R"cpp(
371  #define FF() class [[Test]] {};
372  FF();
373  void f() { T^est a; }
374  )cpp",
375 
376  R"cpp(// explicit template specialization
377  template <typename T>
378  struct Foo { void bar() {} };
379 
380  template <>
381  struct [[Foo]]<int> { void bar() {} };
382 
383  void foo() {
384  Foo<char> abc;
385  Fo^o<int> b;
386  }
387  )cpp",
388 
389  R"cpp(// implicit template specialization
390  template <typename T>
391  struct [[Foo]] { void bar() {} };
392  template <>
393  struct Foo<int> { void bar() {} };
394  void foo() {
395  Fo^o<char> abc;
396  Foo<int> b;
397  }
398  )cpp",
399 
400  R"cpp(// partial template specialization
401  template <typename T>
402  struct Foo { void bar() {} };
403  template <typename T>
404  struct [[Foo]]<T*> { void bar() {} };
405  ^Foo<int*> x;
406  )cpp",
407 
408  R"cpp(// function template specializations
409  template <class T>
410  void foo(T) {}
411  template <>
412  void [[foo]](int) {}
413  void bar() {
414  fo^o(10);
415  }
416  )cpp",
417 
418  R"cpp(// variable template decls
419  template <class T>
420  T var = T();
421 
422  template <>
423  double [[var]]<int> = 10;
424 
425  double y = va^r<int>;
426  )cpp",
427 
428  R"cpp(// No implicit constructors
429  class X {
430  X(X&& x) = default;
431  };
432  X [[makeX]]() {}
433  void foo() {
434  auto x = m^akeX();
435  }
436  )cpp",
437  };
438  for (const char *Test : Tests) {
439  Annotations T(Test);
440  llvm::Optional<Range> WantDecl;
441  llvm::Optional<Range> WantDef;
442  if (!T.ranges().empty())
443  WantDecl = WantDef = T.range();
444  if (!T.ranges("decl").empty())
445  WantDecl = T.range("decl");
446  if (!T.ranges("def").empty())
447  WantDef = T.range("def");
448 
449  auto AST = TestTU::withCode(T.code()).build();
450  auto Results = locateSymbolAt(AST, T.point());
451 
452  if (!WantDecl) {
453  EXPECT_THAT(Results, IsEmpty()) << Test;
454  } else {
455  ASSERT_THAT(Results, ::testing::SizeIs(1)) << Test;
456  EXPECT_EQ(Results[0].PreferredDeclaration.range, *WantDecl) << Test;
457  llvm::Optional<Range> GotDef;
458  if (Results[0].Definition)
459  GotDef = Results[0].Definition->range;
460  EXPECT_EQ(WantDef, GotDef) << Test;
461  }
462  }
463 }
464 
465 TEST(LocateSymbol, Ambiguous) {
466  auto T = Annotations(R"cpp(
467  struct Foo {
468  Foo();
469  Foo(Foo&&);
470  Foo(const char*);
471  };
472 
473  Foo f();
474 
475  void g(Foo foo);
476 
477  void call() {
478  const char* str = "123";
479  Foo a = $1^str;
480  Foo b = Foo($2^str);
481  Foo c = $3^f();
482  $4^g($5^f());
483  g($6^str);
484  Foo ab$7^c;
485  Foo ab$8^cd("asdf");
486  Foo foox = Fo$9^o("asdf");
487  }
488  )cpp");
489  auto AST = TestTU::withCode(T.code()).build();
490  // Ordered assertions are deliberate: we expect a predictable order.
491  EXPECT_THAT(locateSymbolAt(AST, T.point("1")), ElementsAre(Sym("str")));
492  EXPECT_THAT(locateSymbolAt(AST, T.point("2")), ElementsAre(Sym("str")));
493  EXPECT_THAT(locateSymbolAt(AST, T.point("3")), ElementsAre(Sym("f")));
494  EXPECT_THAT(locateSymbolAt(AST, T.point("4")), ElementsAre(Sym("g")));
495  EXPECT_THAT(locateSymbolAt(AST, T.point("5")), ElementsAre(Sym("f")));
496  EXPECT_THAT(locateSymbolAt(AST, T.point("6")), ElementsAre(Sym("str")));
497  EXPECT_THAT(locateSymbolAt(AST, T.point("7")), ElementsAre(Sym("abc")));
498  EXPECT_THAT(locateSymbolAt(AST, T.point("8")),
499  ElementsAre(Sym("Foo"), Sym("abcd")));
500  EXPECT_THAT(locateSymbolAt(AST, T.point("9")),
501  // First one is class definition, second is the constructor.
502  ElementsAre(Sym("Foo"), Sym("Foo")));
503 }
504 
505 TEST(LocateSymbol, TemplateTypedefs) {
506  auto T = Annotations(R"cpp(
507  template <class T> struct function {};
508  template <class T> using callback = function<T()>;
509 
510  c^allback<int> foo;
511  )cpp");
512  auto AST = TestTU::withCode(T.code()).build();
513  EXPECT_THAT(locateSymbolAt(AST, T.point()), ElementsAre(Sym("callback")));
514 }
515 
516 TEST(LocateSymbol, RelPathsInCompileCommand) {
517  // The source is in "/clangd-test/src".
518  // We build in "/clangd-test/build".
519 
520  Annotations SourceAnnotations(R"cpp(
521 #include "header_in_preamble.h"
522 int [[foo]];
523 #include "header_not_in_preamble.h"
524 int baz = f$p1^oo + bar_pre$p2^amble + bar_not_pre$p3^amble;
525 )cpp");
526 
527  Annotations HeaderInPreambleAnnotations(R"cpp(
528 int [[bar_preamble]];
529 )cpp");
530 
531  Annotations HeaderNotInPreambleAnnotations(R"cpp(
532 int [[bar_not_preamble]];
533 )cpp");
534 
535  // Make the compilation paths appear as ../src/foo.cpp in the compile
536  // commands.
537  SmallString<32> RelPathPrefix("..");
538  llvm::sys::path::append(RelPathPrefix, "src");
539  std::string BuildDir = testPath("build");
540  MockCompilationDatabase CDB(BuildDir, RelPathPrefix);
541 
542  IgnoreDiagnostics DiagConsumer;
543  MockFSProvider FS;
544  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
545 
546  // Fill the filesystem.
547  auto FooCpp = testPath("src/foo.cpp");
548  FS.Files[FooCpp] = "";
549  auto HeaderInPreambleH = testPath("src/header_in_preamble.h");
550  FS.Files[HeaderInPreambleH] = HeaderInPreambleAnnotations.code();
551  auto HeaderNotInPreambleH = testPath("src/header_not_in_preamble.h");
552  FS.Files[HeaderNotInPreambleH] = HeaderNotInPreambleAnnotations.code();
553 
554  runAddDocument(Server, FooCpp, SourceAnnotations.code());
555 
556  // Go to a definition in main source file.
557  auto Locations =
558  runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p1"));
559  EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
560  EXPECT_THAT(*Locations, ElementsAre(Sym("foo", SourceAnnotations.range())));
561 
562  // Go to a definition in header_in_preamble.h.
563  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p2"));
564  EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
565  EXPECT_THAT(
566  *Locations,
567  ElementsAre(Sym("bar_preamble", HeaderInPreambleAnnotations.range())));
568 
569  // Go to a definition in header_not_in_preamble.h.
570  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p3"));
571  EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error";
572  EXPECT_THAT(*Locations,
573  ElementsAre(Sym("bar_not_preamble",
574  HeaderNotInPreambleAnnotations.range())));
575 }
576 
577 TEST(Hover, Structured) {
578  struct {
579  const char *const Code;
580  const std::function<void(HoverInfo &)> ExpectedBuilder;
581  } Cases[] = {
582  // Global scope.
583  {R"cpp(
584  // Best foo ever.
585  void [[fo^o]]() {}
586  )cpp",
587  [](HoverInfo &HI) {
588  HI.NamespaceScope = "";
589  HI.Name = "foo";
590  HI.Kind = SymbolKind::Function;
591  HI.Documentation = "Best foo ever.";
592  HI.Definition = "void foo()";
593  HI.ReturnType = "void";
594  HI.Type = "void ()";
595  HI.Parameters.emplace();
596  }},
597  // Inside namespace
598  {R"cpp(
599  namespace ns1 { namespace ns2 {
600  /// Best foo ever.
601  void [[fo^o]]() {}
602  }}
603  )cpp",
604  [](HoverInfo &HI) {
605  HI.NamespaceScope = "ns1::ns2::";
606  HI.Name = "foo";
607  HI.Kind = SymbolKind::Function;
608  HI.Documentation = "Best foo ever.";
609  HI.Definition = "void foo()";
610  HI.ReturnType = "void";
611  HI.Type = "void ()";
612  HI.Parameters.emplace();
613  }},
614  // Field
615  {R"cpp(
616  namespace ns1 { namespace ns2 {
617  struct Foo {
618  int [[b^ar]];
619  };
620  }}
621  )cpp",
622  [](HoverInfo &HI) {
623  HI.NamespaceScope = "ns1::ns2::";
624  HI.LocalScope = "Foo::";
625  HI.Name = "bar";
626  HI.Kind = SymbolKind::Field;
627  HI.Definition = "int bar";
628  HI.Type = "int";
629  }},
630  // Local to class method.
631  {R"cpp(
632  namespace ns1 { namespace ns2 {
633  struct Foo {
634  void foo() {
635  int [[b^ar]];
636  }
637  };
638  }}
639  )cpp",
640  [](HoverInfo &HI) {
641  HI.NamespaceScope = "ns1::ns2::";
642  HI.LocalScope = "Foo::foo::";
643  HI.Name = "bar";
644  HI.Kind = SymbolKind::Variable;
645  HI.Definition = "int bar";
646  HI.Type = "int";
647  }},
648  // Anon namespace and local scope.
649  {R"cpp(
650  namespace ns1 { namespace {
651  struct {
652  int [[b^ar]];
653  } T;
654  }}
655  )cpp",
656  [](HoverInfo &HI) {
657  HI.NamespaceScope = "ns1::(anonymous)::";
658  HI.LocalScope = "(anonymous struct)::";
659  HI.Name = "bar";
660  HI.Kind = SymbolKind::Field;
661  HI.Definition = "int bar";
662  HI.Type = "int";
663  }},
664  // Variable with template type
665  {R"cpp(
666  template <typename T, class... Ts> class Foo { public: Foo(int); };
667  Foo<int, char, bool> [[fo^o]] = Foo<int, char, bool>(5);
668  )cpp",
669  [](HoverInfo &HI) {
670  HI.NamespaceScope = "";
671  HI.Name = "foo";
672  HI.Kind = SymbolKind::Variable;
673  HI.Definition = "Foo<int, char, bool> foo = Foo<int, char, bool>(5)";
674  HI.Type = "Foo<int, char, bool>";
675  }},
676  // Implicit template instantiation
677  {R"cpp(
678  template <typename T> class vector{};
679  [[vec^tor]]<int> foo;
680  )cpp",
681  [](HoverInfo &HI) {
682  HI.NamespaceScope = "";
683  HI.Name = "vector";
684  HI.Kind = SymbolKind::Class;
685  HI.Definition = "template <typename T> class vector {}";
686  HI.TemplateParameters = {
687  {std::string("typename"), std::string("T"), llvm::None},
688  };
689  }},
690  // Class template
691  {R"cpp(
692  template <template<typename, bool...> class C,
693  typename = char,
694  int = 0,
695  bool Q = false,
696  class... Ts> class Foo {};
697  template <template<typename, bool...> class T>
698  [[F^oo]]<T> foo;
699  )cpp",
700  [](HoverInfo &HI) {
701  HI.NamespaceScope = "";
702  HI.Name = "Foo";
703  HI.Kind = SymbolKind::Class;
704  HI.Definition =
705  R"cpp(template <template <typename, bool...> class C, typename = char, int = 0,
706  bool Q = false, class... Ts>
707 class Foo {})cpp";
708  HI.TemplateParameters = {
709  {std::string("template <typename, bool...> class"),
710  std::string("C"), llvm::None},
711  {std::string("typename"), llvm::None, std::string("char")},
712  {std::string("int"), llvm::None, std::string("0")},
713  {std::string("bool"), std::string("Q"), std::string("false")},
714  {std::string("class..."), std::string("Ts"), llvm::None},
715  };
716  }},
717  // Function template
718  {R"cpp(
719  template <template<typename, bool...> class C,
720  typename = char,
721  int = 0,
722  bool Q = false,
723  class... Ts> void foo();
724  template<typename, bool...> class Foo;
725 
726  void bar() {
727  [[fo^o]]<Foo>();
728  }
729  )cpp",
730  [](HoverInfo &HI) {
731  HI.NamespaceScope = "";
732  HI.Name = "foo";
733  HI.Kind = SymbolKind::Function;
734  HI.Definition =
735  R"cpp(template <template <typename, bool...> class C, typename = char, int = 0,
736  bool Q = false, class... Ts>
737 void foo())cpp";
738  HI.ReturnType = "void";
739  HI.Type = "void ()";
740  HI.Parameters.emplace();
741  HI.TemplateParameters = {
742  {std::string("template <typename, bool...> class"),
743  std::string("C"), llvm::None},
744  {std::string("typename"), llvm::None, std::string("char")},
745  {std::string("int"), llvm::None, std::string("0")},
746  {std::string("bool"), std::string("Q"), std::string("false")},
747  {std::string("class..."), std::string("Ts"), llvm::None},
748  };
749  }},
750  // Function decl
751  {R"cpp(
752  template<typename, bool...> class Foo {};
753  Foo<bool, true, false> foo(int, bool T = false);
754 
755  void bar() {
756  [[fo^o]](3);
757  }
758  )cpp",
759  [](HoverInfo &HI) {
760  HI.NamespaceScope = "";
761  HI.Name = "foo";
762  HI.Kind = SymbolKind::Function;
763  HI.Definition = "Foo<bool, true, false> foo(int, bool T = false)";
764  HI.ReturnType = "Foo<bool, true, false>";
765  HI.Type = "Foo<bool, true, false> (int, bool)";
766  HI.Parameters = {
767  {std::string("int"), llvm::None, llvm::None},
768  {std::string("bool"), std::string("T"), std::string("false")},
769  };
770  }},
771  // Pointers to lambdas
772  {R"cpp(
773  void foo() {
774  auto lamb = [](int T, bool B) -> bool { return T && B; };
775  auto *b = &lamb;
776  auto *[[^c]] = &b;
777  }
778  )cpp",
779  [](HoverInfo &HI) {
780  HI.NamespaceScope = "";
781  HI.LocalScope = "foo::";
782  HI.Name = "c";
783  HI.Kind = SymbolKind::Variable;
784  HI.Definition = "auto *c = &b";
785  HI.Type = "class (lambda) **";
786  HI.ReturnType = "bool";
787  HI.Parameters = {
788  {std::string("int"), std::string("T"), llvm::None},
789  {std::string("bool"), std::string("B"), llvm::None},
790  };
791  return HI;
792  }},
793  // Lambda parameter with decltype reference
794  {R"cpp(
795  auto lamb = [](int T, bool B) -> bool { return T && B; };
796  void foo(decltype(lamb)& bar) {
797  [[ba^r]](0, false);
798  }
799  )cpp",
800  [](HoverInfo &HI) {
801  HI.NamespaceScope = "";
802  HI.LocalScope = "foo::";
803  HI.Name = "bar";
804  HI.Kind = SymbolKind::Variable;
805  HI.Definition = "decltype(lamb) &bar";
806  HI.Type = "decltype(lamb) &";
807  HI.ReturnType = "bool";
808  HI.Parameters = {
809  {std::string("int"), std::string("T"), llvm::None},
810  {std::string("bool"), std::string("B"), llvm::None},
811  };
812  return HI;
813  }},
814  // Lambda parameter with decltype
815  {R"cpp(
816  auto lamb = [](int T, bool B) -> bool { return T && B; };
817  void foo(decltype(lamb) bar) {
818  [[ba^r]](0, false);
819  }
820  )cpp",
821  [](HoverInfo &HI) {
822  HI.NamespaceScope = "";
823  HI.LocalScope = "foo::";
824  HI.Name = "bar";
825  HI.Kind = SymbolKind::Variable;
826  HI.Definition = "decltype(lamb) bar";
827  HI.Type = "class (lambda)";
828  HI.ReturnType = "bool";
829  HI.Parameters = {
830  {std::string("int"), std::string("T"), llvm::None},
831  {std::string("bool"), std::string("B"), llvm::None},
832  };
833  return HI;
834  }},
835  // Lambda variable
836  {R"cpp(
837  void foo() {
838  int bar = 5;
839  auto lamb = [&bar](int T, bool B) -> bool { return T && B && bar; };
840  bool res = [[lam^b]](bar, false);
841  }
842  )cpp",
843  [](HoverInfo &HI) {
844  HI.NamespaceScope = "";
845  HI.LocalScope = "foo::";
846  HI.Name = "lamb";
847  HI.Kind = SymbolKind::Variable;
848  HI.Definition = "auto lamb = [&bar](int T, bool B) -> bool {}";
849  HI.Type = "class (lambda)";
850  HI.ReturnType = "bool";
851  HI.Parameters = {
852  {std::string("int"), std::string("T"), llvm::None},
853  {std::string("bool"), std::string("B"), llvm::None},
854  };
855  return HI;
856  }},
857  // Local variable in lambda
858  {R"cpp(
859  void foo() {
860  auto lamb = []{int [[te^st]];};
861  }
862  )cpp",
863  [](HoverInfo &HI) {
864  HI.NamespaceScope = "";
865  HI.LocalScope = "foo::(anonymous class)::operator()::";
866  HI.Name = "test";
867  HI.Kind = SymbolKind::Variable;
868  HI.Definition = "int test";
869  HI.Type = "int";
870  }},
871 
872  // auto on lambda
873  {R"cpp(
874  void foo() {
875  [[au^to]] lamb = []{};
876  }
877  )cpp",
878  [](HoverInfo &HI) {
879  HI.Name = "class (lambda)";
880  HI.Kind = SymbolKind::Variable;
881  }},
882  // auto on template instantiation
883  {R"cpp(
884  template<typename T> class Foo{};
885  void foo() {
886  [[au^to]] x = Foo<int>();
887  }
888  )cpp",
889  [](HoverInfo &HI) {
890  HI.Name = "class Foo<int>";
891  HI.Kind = SymbolKind::Variable;
892  }},
893  // auto on specialized template
894  {R"cpp(
895  template<typename T> class Foo{};
896  template<> class Foo<int>{};
897  void foo() {
898  [[au^to]] x = Foo<int>();
899  }
900  )cpp",
901  [](HoverInfo &HI) {
902  HI.Name = "class Foo<int>";
903  HI.Kind = SymbolKind::Variable;
904  }},
905 
906  // macro
907  {R"cpp(
908  // Best MACRO ever.
909  #define MACRO(x,y,z) void foo(x, y, z);
910  [[MAC^RO]](int, double d, bool z = false);
911  )cpp",
912  [](HoverInfo &HI) {
913  HI.Name = "MACRO", HI.Kind = SymbolKind::String,
914  HI.Definition = "#define MACRO(x, y, z) void foo(x, y, z);";
915  }},
916 
917  // constexprs
918  {R"cpp(
919  constexpr int add(int a, int b) { return a + b; }
920  int [[b^ar]] = add(1, 2);
921  )cpp",
922  [](HoverInfo &HI) {
923  HI.Name = "bar";
924  HI.Definition = "int bar = add(1, 2)";
925  HI.Kind = SymbolKind::Variable;
926  HI.Type = "int";
927  HI.NamespaceScope = "";
928  HI.Value = "3";
929  }},
930  {R"cpp(
931  int [[b^ar]] = sizeof(char);
932  )cpp",
933  [](HoverInfo &HI) {
934  HI.Name = "bar";
935  HI.Definition = "int bar = sizeof(char)";
936  HI.Kind = SymbolKind::Variable;
937  HI.Type = "int";
938  HI.NamespaceScope = "";
939  HI.Value = "1";
940  }},
941  {R"cpp(
942  template<int a, int b> struct Add {
943  static constexpr int result = a + b;
944  };
945  int [[ba^r]] = Add<1, 2>::result;
946  )cpp",
947  [](HoverInfo &HI) {
948  HI.Name = "bar";
949  HI.Definition = "int bar = Add<1, 2>::result";
950  HI.Kind = SymbolKind::Variable;
951  HI.Type = "int";
952  HI.NamespaceScope = "";
953  HI.Value = "3";
954  }},
955  // FIXME: We should use the Decl referenced, even if it comes from an
956  // implicit instantiation.
957  {R"cpp(
958  template<int a, int b> struct Add {
959  static constexpr int result = a + b;
960  };
961  int bar = Add<1, 2>::[[resu^lt]];
962  )cpp",
963  [](HoverInfo &HI) {
964  HI.Name = "result";
965  HI.Definition = "static constexpr int result = a + b";
966  HI.Kind = SymbolKind::Property;
967  HI.Type = "const int";
968  HI.NamespaceScope = "";
969  HI.LocalScope = "Add::";
970  }},
971  {R"cpp(
972  const char *[[ba^r]] = "1234";
973  )cpp",
974  [](HoverInfo &HI) {
975  HI.Name = "bar";
976  HI.Definition = "const char *bar = \"1234\"";
977  HI.Kind = SymbolKind::Variable;
978  HI.Type = "const char *";
979  HI.NamespaceScope = "";
980  HI.Value = "&\"1234\"[0]";
981  }},
982  };
983  for (const auto &Case : Cases) {
984  SCOPED_TRACE(Case.Code);
985 
986  Annotations T(Case.Code);
987  TestTU TU = TestTU::withCode(T.code());
988  TU.ExtraArgs.push_back("-std=c++17");
989  auto AST = TU.build();
990  ASSERT_TRUE(AST.getDiagnostics().empty());
991 
992  auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
993  ASSERT_TRUE(H);
994  HoverInfo Expected;
995  Expected.SymRange = T.range();
996  Case.ExpectedBuilder(Expected);
997 
998  EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
999  EXPECT_EQ(H->LocalScope, Expected.LocalScope);
1000  EXPECT_EQ(H->Name, Expected.Name);
1001  EXPECT_EQ(H->Kind, Expected.Kind);
1002  EXPECT_EQ(H->Documentation, Expected.Documentation);
1003  EXPECT_EQ(H->Definition, Expected.Definition);
1004  EXPECT_EQ(H->Type, Expected.Type);
1005  EXPECT_EQ(H->ReturnType, Expected.ReturnType);
1006  EXPECT_EQ(H->Parameters, Expected.Parameters);
1007  EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
1008  EXPECT_EQ(H->SymRange, Expected.SymRange);
1009  EXPECT_EQ(H->Value, Expected.Value);
1010  }
1011 } // namespace clang
1012 
1013 TEST(Hover, All) {
1014  struct OneTest {
1015  StringRef Input;
1016  StringRef ExpectedHover;
1017  };
1018 
1019  OneTest Tests[] = {
1020  {
1021  R"cpp(// No hover
1022  ^int main() {
1023  }
1024  )cpp",
1025  "",
1026  },
1027  {
1028  R"cpp(// Local variable
1029  int main() {
1030  int bonjour;
1031  ^bonjour = 2;
1032  int test1 = bonjour;
1033  }
1034  )cpp",
1035  "text[Declared in]code[main]\n"
1036  "codeblock(cpp) [\n"
1037  "int bonjour\n"
1038  "]",
1039  },
1040  {
1041  R"cpp(// Local variable in method
1042  struct s {
1043  void method() {
1044  int bonjour;
1045  ^bonjour = 2;
1046  }
1047  };
1048  )cpp",
1049  "text[Declared in]code[s::method]\n"
1050  "codeblock(cpp) [\n"
1051  "int bonjour\n"
1052  "]",
1053  },
1054  {
1055  R"cpp(// Struct
1056  namespace ns1 {
1057  struct MyClass {};
1058  } // namespace ns1
1059  int main() {
1060  ns1::My^Class* Params;
1061  }
1062  )cpp",
1063  "text[Declared in]code[ns1]\n"
1064  "codeblock(cpp) [\n"
1065  "struct MyClass {}\n"
1066  "]",
1067  },
1068  {
1069  R"cpp(// Class
1070  namespace ns1 {
1071  class MyClass {};
1072  } // namespace ns1
1073  int main() {
1074  ns1::My^Class* Params;
1075  }
1076  )cpp",
1077  "text[Declared in]code[ns1]\n"
1078  "codeblock(cpp) [\n"
1079  "class MyClass {}\n"
1080  "]",
1081  },
1082  {
1083  R"cpp(// Union
1084  namespace ns1 {
1085  union MyUnion { int x; int y; };
1086  } // namespace ns1
1087  int main() {
1088  ns1::My^Union Params;
1089  }
1090  )cpp",
1091  "text[Declared in]code[ns1]\n"
1092  "codeblock(cpp) [\n"
1093  "union MyUnion {}\n"
1094  "]",
1095  },
1096  {
1097  R"cpp(// Function definition via pointer
1098  int foo(int) {}
1099  int main() {
1100  auto *X = &^foo;
1101  }
1102  )cpp",
1103  "text[Declared in]code[global namespace]\n"
1104  "codeblock(cpp) [\n"
1105  "int foo(int)\n"
1106  "]\n"
1107  "text[Function definition via pointer]",
1108  },
1109  {
1110  R"cpp(// Function declaration via call
1111  int foo(int);
1112  int main() {
1113  return ^foo(42);
1114  }
1115  )cpp",
1116  "text[Declared in]code[global namespace]\n"
1117  "codeblock(cpp) [\n"
1118  "int foo(int)\n"
1119  "]\n"
1120  "text[Function declaration via call]",
1121  },
1122  {
1123  R"cpp(// Field
1124  struct Foo { int x; };
1125  int main() {
1126  Foo bar;
1127  bar.^x;
1128  }
1129  )cpp",
1130  "text[Declared in]code[Foo]\n"
1131  "codeblock(cpp) [\n"
1132  "int x\n"
1133  "]",
1134  },
1135  {
1136  R"cpp(// Field with initialization
1137  struct Foo { int x = 5; };
1138  int main() {
1139  Foo bar;
1140  bar.^x;
1141  }
1142  )cpp",
1143  "text[Declared in]code[Foo]\n"
1144  "codeblock(cpp) [\n"
1145  "int x = 5\n"
1146  "]",
1147  },
1148  {
1149  R"cpp(// Static field
1150  struct Foo { static int x; };
1151  int main() {
1152  Foo::^x;
1153  }
1154  )cpp",
1155  "text[Declared in]code[Foo]\n"
1156  "codeblock(cpp) [\n"
1157  "static int x\n"
1158  "]",
1159  },
1160  {
1161  R"cpp(// Field, member initializer
1162  struct Foo {
1163  int x;
1164  Foo() : ^x(0) {}
1165  };
1166  )cpp",
1167  "text[Declared in]code[Foo]\n"
1168  "codeblock(cpp) [\n"
1169  "int x\n"
1170  "]",
1171  },
1172  {
1173  R"cpp(// Field, GNU old-style field designator
1174  struct Foo { int x; };
1175  int main() {
1176  Foo bar = { ^x : 1 };
1177  }
1178  )cpp",
1179  "text[Declared in]code[Foo]\n"
1180  "codeblock(cpp) [\n"
1181  "int x\n"
1182  "]",
1183  },
1184  {
1185  R"cpp(// Field, field designator
1186  struct Foo { int x; };
1187  int main() {
1188  Foo bar = { .^x = 2 };
1189  }
1190  )cpp",
1191  "text[Declared in]code[Foo]\n"
1192  "codeblock(cpp) [\n"
1193  "int x\n"
1194  "]",
1195  },
1196  {
1197  R"cpp(// Method call
1198  struct Foo { int x(); };
1199  int main() {
1200  Foo bar;
1201  bar.^x();
1202  }
1203  )cpp",
1204  "text[Declared in]code[Foo]\n"
1205  "codeblock(cpp) [\n"
1206  "int x()\n"
1207  "]",
1208  },
1209  {
1210  R"cpp(// Static method call
1211  struct Foo { static int x(); };
1212  int main() {
1213  Foo::^x();
1214  }
1215  )cpp",
1216  "text[Declared in]code[Foo]\n"
1217  "codeblock(cpp) [\n"
1218  "static int x()\n"
1219  "]",
1220  },
1221  {
1222  R"cpp(// Typedef
1223  typedef int Foo;
1224  int main() {
1225  ^Foo bar;
1226  }
1227  )cpp",
1228  "text[Declared in]code[global namespace]\n"
1229  "codeblock(cpp) [\n"
1230  "typedef int Foo\n"
1231  "]\n"
1232  "text[Typedef]",
1233  },
1234  {
1235  R"cpp(// Namespace
1236  namespace ns {
1237  struct Foo { static void bar(); }
1238  } // namespace ns
1239  int main() { ^ns::Foo::bar(); }
1240  )cpp",
1241  "text[Declared in]code[global namespace]\n"
1242  "codeblock(cpp) [\n"
1243  "namespace ns {}\n"
1244  "]",
1245  },
1246  {
1247  R"cpp(// Anonymous namespace
1248  namespace ns {
1249  namespace {
1250  int foo;
1251  } // anonymous namespace
1252  } // namespace ns
1253  int main() { ns::f^oo++; }
1254  )cpp",
1255  "text[Declared in]code[ns::(anonymous)]\n"
1256  "codeblock(cpp) [\n"
1257  "int foo\n"
1258  "]",
1259  },
1260  {
1261  R"cpp(// Macro
1262  #define MACRO 0
1263  #define MACRO 1
1264  int main() { return ^MACRO; }
1265  #define MACRO 2
1266  #undef macro
1267  )cpp",
1268  "codeblock(cpp) [\n"
1269  "#define MACRO 1\n"
1270  "]",
1271  },
1272  {
1273  R"cpp(// Macro
1274  #define MACRO 0
1275  #define MACRO2 ^MACRO
1276  )cpp",
1277  "codeblock(cpp) [\n"
1278  "#define MACRO 0\n"
1279  "]",
1280  },
1281  {
1282  R"cpp(// Macro
1283  #define MACRO {\
1284  return 0;\
1285  }
1286  int main() ^MACRO
1287  )cpp",
1288  R"cpp(codeblock(cpp) [
1289 #define MACRO \
1290  { return 0; }
1291 ])cpp",
1292  },
1293  {
1294  R"cpp(// Forward class declaration
1295  class Foo;
1296  class Foo {};
1297  F^oo* foo();
1298  )cpp",
1299  "text[Declared in]code[global namespace]\n"
1300  "codeblock(cpp) [\n"
1301  "class Foo {}\n"
1302  "]\n"
1303  "text[Forward class declaration]",
1304  },
1305  {
1306  R"cpp(// Function declaration
1307  void foo();
1308  void g() { f^oo(); }
1309  void foo() {}
1310  )cpp",
1311  "text[Declared in]code[global namespace]\n"
1312  "codeblock(cpp) [\n"
1313  "void foo()\n"
1314  "]\n"
1315  "text[Function declaration]",
1316  },
1317  {
1318  R"cpp(// Enum declaration
1319  enum Hello {
1320  ONE, TWO, THREE,
1321  };
1322  void foo() {
1323  Hel^lo hello = ONE;
1324  }
1325  )cpp",
1326  "text[Declared in]code[global namespace]\n"
1327  "codeblock(cpp) [\n"
1328  "enum Hello {}\n"
1329  "]\n"
1330  "text[Enum declaration]",
1331  },
1332  {
1333  R"cpp(// Enumerator
1334  enum Hello {
1335  ONE, TWO, THREE,
1336  };
1337  void foo() {
1338  Hello hello = O^NE;
1339  }
1340  )cpp",
1341  "text[Declared in]code[Hello]\n"
1342  "codeblock(cpp) [\n"
1343  "ONE\n"
1344  "]",
1345  },
1346  {
1347  R"cpp(// Enumerator in anonymous enum
1348  enum {
1349  ONE, TWO, THREE,
1350  };
1351  void foo() {
1352  int hello = O^NE;
1353  }
1354  )cpp",
1355  "text[Declared in]code[global namespace]\n"
1356  "codeblock(cpp) [\n"
1357  "ONE\n"
1358  "]",
1359  },
1360  {
1361  R"cpp(// Global variable
1362  static int hey = 10;
1363  void foo() {
1364  he^y++;
1365  }
1366  )cpp",
1367  "text[Declared in]code[global namespace]\n"
1368  "codeblock(cpp) [\n"
1369  "static int hey = 10\n"
1370  "]\n"
1371  "text[Global variable]",
1372  },
1373  {
1374  R"cpp(// Global variable in namespace
1375  namespace ns1 {
1376  static int hey = 10;
1377  }
1378  void foo() {
1379  ns1::he^y++;
1380  }
1381  )cpp",
1382  "text[Declared in]code[ns1]\n"
1383  "codeblock(cpp) [\n"
1384  "static int hey = 10\n"
1385  "]",
1386  },
1387  {
1388  R"cpp(// Field in anonymous struct
1389  static struct {
1390  int hello;
1391  } s;
1392  void foo() {
1393  s.he^llo++;
1394  }
1395  )cpp",
1396  "text[Declared in]code[(anonymous struct)]\n"
1397  "codeblock(cpp) [\n"
1398  "int hello\n"
1399  "]",
1400  },
1401  {
1402  R"cpp(// Templated function
1403  template <typename T>
1404  T foo() {
1405  return 17;
1406  }
1407  void g() { auto x = f^oo<int>(); }
1408  )cpp",
1409  "text[Declared in]code[global namespace]\n"
1410  "codeblock(cpp) [\n"
1411  "template <typename T> T foo()\n"
1412  "]\n"
1413  "text[Templated function]",
1414  },
1415  {
1416  R"cpp(// Anonymous union
1417  struct outer {
1418  union {
1419  int abc, def;
1420  } v;
1421  };
1422  void g() { struct outer o; o.v.d^ef++; }
1423  )cpp",
1424  "text[Declared in]code[outer::(anonymous union)]\n"
1425  "codeblock(cpp) [\n"
1426  "int def\n"
1427  "]",
1428  },
1429  {
1430  R"cpp(// documentation from index
1431  int nextSymbolIsAForwardDeclFromIndexWithNoLocalDocs;
1432  void indexSymbol();
1433  void g() { ind^exSymbol(); }
1434  )cpp",
1435  "text[Declared in]code[global namespace]\n"
1436  "codeblock(cpp) [\n"
1437  "void indexSymbol()\n"
1438  "]\n"
1439  "text[comment from index]",
1440  },
1441  {
1442  R"cpp(// Nothing
1443  void foo() {
1444  ^
1445  }
1446  )cpp",
1447  "",
1448  },
1449  {
1450  R"cpp(// Simple initialization with auto
1451  void foo() {
1452  ^auto i = 1;
1453  }
1454  )cpp",
1455  "codeblock(cpp) [\n"
1456  "int\n"
1457  "]",
1458  },
1459  {
1460  R"cpp(// Simple initialization with const auto
1461  void foo() {
1462  const ^auto i = 1;
1463  }
1464  )cpp",
1465  "codeblock(cpp) [\n"
1466  "int\n"
1467  "]",
1468  },
1469  {
1470  R"cpp(// Simple initialization with const auto&
1471  void foo() {
1472  const ^auto& i = 1;
1473  }
1474  )cpp",
1475  "codeblock(cpp) [\n"
1476  "int\n"
1477  "]",
1478  },
1479  {
1480  R"cpp(// Simple initialization with auto&
1481  void foo() {
1482  ^auto& i = 1;
1483  }
1484  )cpp",
1485  "codeblock(cpp) [\n"
1486  "int\n"
1487  "]",
1488  },
1489  {
1490  R"cpp(// Simple initialization with auto*
1491  void foo() {
1492  int a = 1;
1493  ^auto* i = &a;
1494  }
1495  )cpp",
1496  "codeblock(cpp) [\n"
1497  "int\n"
1498  "]",
1499  },
1500  {
1501  R"cpp(// Auto with initializer list.
1502  namespace std
1503  {
1504  template<class _E>
1505  class initializer_list {};
1506  }
1507  void foo() {
1508  ^auto i = {1,2};
1509  }
1510  )cpp",
1511  "codeblock(cpp) [\n"
1512  "class std::initializer_list<int>\n"
1513  "]",
1514  },
1515  {
1516  R"cpp(// User defined conversion to auto
1517  struct Bar {
1518  operator ^auto() const { return 10; }
1519  };
1520  )cpp",
1521  "codeblock(cpp) [\n"
1522  "int\n"
1523  "]",
1524  },
1525  {
1526  R"cpp(// Simple initialization with decltype(auto)
1527  void foo() {
1528  ^decltype(auto) i = 1;
1529  }
1530  )cpp",
1531  "codeblock(cpp) [\n"
1532  "int\n"
1533  "]",
1534  },
1535  {
1536  R"cpp(// Simple initialization with const decltype(auto)
1537  void foo() {
1538  const int j = 0;
1539  ^decltype(auto) i = j;
1540  }
1541  )cpp",
1542  "codeblock(cpp) [\n"
1543  "const int\n"
1544  "]",
1545  },
1546  {
1547  R"cpp(// Simple initialization with const& decltype(auto)
1548  void foo() {
1549  int k = 0;
1550  const int& j = k;
1551  ^decltype(auto) i = j;
1552  }
1553  )cpp",
1554  "codeblock(cpp) [\n"
1555  "const int &\n"
1556  "]",
1557  },
1558  {
1559  R"cpp(// Simple initialization with & decltype(auto)
1560  void foo() {
1561  int k = 0;
1562  int& j = k;
1563  ^decltype(auto) i = j;
1564  }
1565  )cpp",
1566  "codeblock(cpp) [\n"
1567  "int &\n"
1568  "]",
1569  },
1570  {
1571  R"cpp(// decltype with initializer list: nothing
1572  namespace std
1573  {
1574  template<class _E>
1575  class initializer_list {};
1576  }
1577  void foo() {
1578  ^decltype(auto) i = {1,2};
1579  }
1580  )cpp",
1581  "",
1582  },
1583  {
1584  R"cpp(// simple trailing return type
1585  ^auto main() -> int {
1586  return 0;
1587  }
1588  )cpp",
1589  "codeblock(cpp) [\n"
1590  "int\n"
1591  "]",
1592  },
1593  {
1594  R"cpp(// auto function return with trailing type
1595  struct Bar {};
1596  ^auto test() -> decltype(Bar()) {
1597  return Bar();
1598  }
1599  )cpp",
1600  "codeblock(cpp) [\n"
1601  "struct Bar\n"
1602  "]",
1603  },
1604  {
1605  R"cpp(// trailing return type
1606  struct Bar {};
1607  auto test() -> ^decltype(Bar()) {
1608  return Bar();
1609  }
1610  )cpp",
1611  "codeblock(cpp) [\n"
1612  "struct Bar\n"
1613  "]",
1614  },
1615  {
1616  R"cpp(// auto in function return
1617  struct Bar {};
1618  ^auto test() {
1619  return Bar();
1620  }
1621  )cpp",
1622  "codeblock(cpp) [\n"
1623  "struct Bar\n"
1624  "]",
1625  },
1626  {
1627  R"cpp(// auto& in function return
1628  struct Bar {};
1629  ^auto& test() {
1630  return Bar();
1631  }
1632  )cpp",
1633  "codeblock(cpp) [\n"
1634  "struct Bar\n"
1635  "]",
1636  },
1637  {
1638  R"cpp(// auto* in function return
1639  struct Bar {};
1640  ^auto* test() {
1641  Bar* bar;
1642  return bar;
1643  }
1644  )cpp",
1645  "codeblock(cpp) [\n"
1646  "struct Bar\n"
1647  "]",
1648  },
1649  {
1650  R"cpp(// const auto& in function return
1651  struct Bar {};
1652  const ^auto& test() {
1653  return Bar();
1654  }
1655  )cpp",
1656  "codeblock(cpp) [\n"
1657  "struct Bar\n"
1658  "]",
1659  },
1660  {
1661  R"cpp(// decltype(auto) in function return
1662  struct Bar {};
1663  ^decltype(auto) test() {
1664  return Bar();
1665  }
1666  )cpp",
1667  "codeblock(cpp) [\n"
1668  "struct Bar\n"
1669  "]",
1670  },
1671  {
1672  R"cpp(// decltype(auto) reference in function return
1673  struct Bar {};
1674  ^decltype(auto) test() {
1675  int a;
1676  return (a);
1677  }
1678  )cpp",
1679  "codeblock(cpp) [\n"
1680  "int &\n"
1681  "]",
1682  },
1683  {
1684  R"cpp(// decltype lvalue reference
1685  void foo() {
1686  int I = 0;
1687  ^decltype(I) J = I;
1688  }
1689  )cpp",
1690  "codeblock(cpp) [\n"
1691  "int\n"
1692  "]",
1693  },
1694  {
1695  R"cpp(// decltype lvalue reference
1696  void foo() {
1697  int I= 0;
1698  int &K = I;
1699  ^decltype(K) J = I;
1700  }
1701  )cpp",
1702  "codeblock(cpp) [\n"
1703  "int &\n"
1704  "]",
1705  },
1706  {
1707  R"cpp(// decltype lvalue reference parenthesis
1708  void foo() {
1709  int I = 0;
1710  ^decltype((I)) J = I;
1711  }
1712  )cpp",
1713  "codeblock(cpp) [\n"
1714  "int &\n"
1715  "]",
1716  },
1717  {
1718  R"cpp(// decltype rvalue reference
1719  void foo() {
1720  int I = 0;
1721  ^decltype(static_cast<int&&>(I)) J = static_cast<int&&>(I);
1722  }
1723  )cpp",
1724  "codeblock(cpp) [\n"
1725  "int &&\n"
1726  "]",
1727  },
1728  {
1729  R"cpp(// decltype rvalue reference function call
1730  int && bar();
1731  void foo() {
1732  int I = 0;
1733  ^decltype(bar()) J = bar();
1734  }
1735  )cpp",
1736  "codeblock(cpp) [\n"
1737  "int &&\n"
1738  "]",
1739  },
1740  {
1741  R"cpp(// decltype of function with trailing return type.
1742  struct Bar {};
1743  auto test() -> decltype(Bar()) {
1744  return Bar();
1745  }
1746  void foo() {
1747  ^decltype(test()) i = test();
1748  }
1749  )cpp",
1750  "codeblock(cpp) [\n"
1751  "struct Bar\n"
1752  "]",
1753  },
1754  {
1755  R"cpp(// decltype of var with decltype.
1756  void foo() {
1757  int I = 0;
1758  decltype(I) J = I;
1759  ^decltype(J) K = J;
1760  }
1761  )cpp",
1762  "codeblock(cpp) [\n"
1763  "int\n"
1764  "]",
1765  },
1766  {
1767  R"cpp(// structured binding. Not supported yet
1768  struct Bar {};
1769  void foo() {
1770  Bar a[2];
1771  ^auto [x,y] = a;
1772  }
1773  )cpp",
1774  "",
1775  },
1776  {
1777  R"cpp(// Template auto parameter. Nothing (Not useful).
1778  template<^auto T>
1779  void func() {
1780  }
1781  void foo() {
1782  func<1>();
1783  }
1784  )cpp",
1785  "",
1786  },
1787  {
1788  R"cpp(// More compilcated structured types.
1789  int bar();
1790  ^auto (*foo)() = bar;
1791  )cpp",
1792  "codeblock(cpp) [\n"
1793  "int\n"
1794  "]",
1795  },
1796  };
1797 
1798  // Create a tiny index, so tests above can verify documentation is fetched.
1799  Symbol IndexSym = func("indexSymbol");
1800  IndexSym.Documentation = "comment from index";
1802  Symbols.insert(IndexSym);
1803  auto Index =
1804  MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab());
1805 
1806  for (const OneTest &Test : Tests) {
1807  Annotations T(Test.Input);
1808  TestTU TU = TestTU::withCode(T.code());
1809  TU.ExtraArgs.push_back("-std=c++17");
1810  auto AST = TU.build();
1811  if (auto H =
1812  getHover(AST, T.point(), format::getLLVMStyle(), Index.get())) {
1813  EXPECT_NE("", Test.ExpectedHover) << Test.Input;
1814  EXPECT_EQ(H->present().renderForTests(), Test.ExpectedHover.str())
1815  << Test.Input;
1816  } else
1817  EXPECT_EQ("", Test.ExpectedHover.str()) << Test.Input;
1818  }
1819 }
1820 
1821 TEST(GoToInclude, All) {
1822  MockFSProvider FS;
1823  IgnoreDiagnostics DiagConsumer;
1824  MockCompilationDatabase CDB;
1825  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
1826 
1827  auto FooCpp = testPath("foo.cpp");
1828  const char *SourceContents = R"cpp(
1829  #include ^"$2^foo.h$3^"
1830  #include "$4^invalid.h"
1831  int b = a;
1832  // test
1833  int foo;
1834  #in$5^clude "$6^foo.h"$7^
1835  )cpp";
1836  Annotations SourceAnnotations(SourceContents);
1837  FS.Files[FooCpp] = SourceAnnotations.code();
1838  auto FooH = testPath("foo.h");
1839 
1840  const char *HeaderContents = R"cpp([[]]#pragma once
1841  int a;
1842  )cpp";
1843  Annotations HeaderAnnotations(HeaderContents);
1844  FS.Files[FooH] = HeaderAnnotations.code();
1845 
1846  Server.addDocument(FooH, HeaderAnnotations.code());
1847  Server.addDocument(FooCpp, SourceAnnotations.code());
1848 
1849  // Test include in preamble.
1850  auto Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point());
1851  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1852  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1853 
1854  // Test include in preamble, last char.
1855  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("2"));
1856  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1857  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1858 
1859  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("3"));
1860  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1861  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1862 
1863  // Test include outside of preamble.
1864  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("6"));
1865  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1866  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1867 
1868  // Test a few positions that do not result in Locations.
1869  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("4"));
1870  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1871  EXPECT_THAT(*Locations, IsEmpty());
1872 
1873  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("5"));
1874  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1875  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1876 
1877  Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("7"));
1878  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1879  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1880 
1881  // Objective C #import directive.
1882  Annotations ObjC(R"objc(
1883  #import "^foo.h"
1884  )objc");
1885  auto FooM = testPath("foo.m");
1886  FS.Files[FooM] = ObjC.code();
1887 
1888  Server.addDocument(FooM, ObjC.code());
1889  Locations = runLocateSymbolAt(Server, FooM, ObjC.point());
1890  ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error";
1891  EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range())));
1892 }
1893 
1894 TEST(LocateSymbol, WithPreamble) {
1895  // Test stragety: AST should always use the latest preamble instead of last
1896  // good preamble.
1897  MockFSProvider FS;
1898  IgnoreDiagnostics DiagConsumer;
1899  MockCompilationDatabase CDB;
1900  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
1901 
1902  auto FooCpp = testPath("foo.cpp");
1903  // The trigger locations must be the same.
1904  Annotations FooWithHeader(R"cpp(#include "fo^o.h")cpp");
1905  Annotations FooWithoutHeader(R"cpp(double [[fo^o]]();)cpp");
1906 
1907  FS.Files[FooCpp] = FooWithHeader.code();
1908 
1909  auto FooH = testPath("foo.h");
1910  Annotations FooHeader(R"cpp([[]])cpp");
1911  FS.Files[FooH] = FooHeader.code();
1912 
1913  runAddDocument(Server, FooCpp, FooWithHeader.code());
1914  // LocateSymbol goes to a #include file: the result comes from the preamble.
1915  EXPECT_THAT(
1916  cantFail(runLocateSymbolAt(Server, FooCpp, FooWithHeader.point())),
1917  ElementsAre(Sym("foo.h", FooHeader.range())));
1918 
1919  // Only preamble is built, and no AST is built in this request.
1920  Server.addDocument(FooCpp, FooWithoutHeader.code(), WantDiagnostics::No);
1921  // We build AST here, and it should use the latest preamble rather than the
1922  // stale one.
1923  EXPECT_THAT(
1924  cantFail(runLocateSymbolAt(Server, FooCpp, FooWithoutHeader.point())),
1925  ElementsAre(Sym("foo", FooWithoutHeader.range())));
1926 
1927  // Reset test environment.
1928  runAddDocument(Server, FooCpp, FooWithHeader.code());
1929  // Both preamble and AST are built in this request.
1930  Server.addDocument(FooCpp, FooWithoutHeader.code(), WantDiagnostics::Yes);
1931  // Use the AST being built in above request.
1932  EXPECT_THAT(
1933  cantFail(runLocateSymbolAt(Server, FooCpp, FooWithoutHeader.point())),
1934  ElementsAre(Sym("foo", FooWithoutHeader.range())));
1935 }
1936 
1937 TEST(FindReferences, WithinAST) {
1938  const char *Tests[] = {
1939  R"cpp(// Local variable
1940  int main() {
1941  int [[foo]];
1942  [[^foo]] = 2;
1943  int test1 = [[foo]];
1944  }
1945  )cpp",
1946 
1947  R"cpp(// Struct
1948  namespace ns1 {
1949  struct [[Foo]] {};
1950  } // namespace ns1
1951  int main() {
1952  ns1::[[Fo^o]]* Params;
1953  }
1954  )cpp",
1955 
1956  R"cpp(// Forward declaration
1957  class [[Foo]];
1958  class [[Foo]] {}
1959  int main() {
1960  [[Fo^o]] foo;
1961  }
1962  )cpp",
1963 
1964  R"cpp(// Function
1965  int [[foo]](int) {}
1966  int main() {
1967  auto *X = &[[^foo]];
1968  [[foo]](42)
1969  }
1970  )cpp",
1971 
1972  R"cpp(// Field
1973  struct Foo {
1974  int [[foo]];
1975  Foo() : [[foo]](0) {}
1976  };
1977  int main() {
1978  Foo f;
1979  f.[[f^oo]] = 1;
1980  }
1981  )cpp",
1982 
1983  R"cpp(// Method call
1984  struct Foo { int [[foo]](); };
1985  int Foo::[[foo]]() {}
1986  int main() {
1987  Foo f;
1988  f.[[^foo]]();
1989  }
1990  )cpp",
1991 
1992  R"cpp(// Constructor
1993  struct Foo {
1994  [[F^oo]](int);
1995  };
1996  void foo() {
1997  Foo f = [[Foo]](42);
1998  }
1999  )cpp",
2000 
2001  R"cpp(// Typedef
2002  typedef int [[Foo]];
2003  int main() {
2004  [[^Foo]] bar;
2005  }
2006  )cpp",
2007 
2008  R"cpp(// Namespace
2009  namespace [[ns]] {
2010  struct Foo {};
2011  } // namespace ns
2012  int main() { [[^ns]]::Foo foo; }
2013  )cpp",
2014  };
2015  for (const char *Test : Tests) {
2016  Annotations T(Test);
2017  auto AST = TestTU::withCode(T.code()).build();
2018  std::vector<Matcher<Location>> ExpectedLocations;
2019  for (const auto &R : T.ranges())
2020  ExpectedLocations.push_back(RangeIs(R));
2021  EXPECT_THAT(findReferences(AST, T.point(), 0),
2022  ElementsAreArray(ExpectedLocations))
2023  << Test;
2024  }
2025 }
2026 
2027 TEST(FindReferences, ExplicitSymbols) {
2028  const char *Tests[] = {
2029  R"cpp(
2030  struct Foo { Foo* [self]() const; };
2031  void f() {
2032  if (Foo* T = foo.[^self]()) {} // Foo member call expr.
2033  }
2034  )cpp",
2035 
2036  R"cpp(
2037  struct Foo { Foo(int); };
2038  Foo f() {
2039  int [b];
2040  return [^b]; // Foo constructor expr.
2041  }
2042  )cpp",
2043 
2044  R"cpp(
2045  struct Foo {};
2046  void g(Foo);
2047  Foo [f]();
2048  void call() {
2049  g([^f]()); // Foo constructor expr.
2050  }
2051  )cpp",
2052 
2053  R"cpp(
2054  void [foo](int);
2055  void [foo](double);
2056 
2057  namespace ns {
2058  using ::[fo^o];
2059  }
2060  )cpp",
2061  };
2062  for (const char *Test : Tests) {
2063  Annotations T(Test);
2064  auto AST = TestTU::withCode(T.code()).build();
2065  std::vector<Matcher<Location>> ExpectedLocations;
2066  for (const auto &R : T.ranges())
2067  ExpectedLocations.push_back(RangeIs(R));
2068  EXPECT_THAT(findReferences(AST, T.point(), 0),
2069  ElementsAreArray(ExpectedLocations))
2070  << Test;
2071  }
2072 }
2073 
2074 TEST(FindReferences, NeedsIndex) {
2075  const char *Header = "int foo();";
2076  Annotations Main("int main() { [[f^oo]](); }");
2077  TestTU TU;
2078  TU.Code = Main.code();
2079  TU.HeaderCode = Header;
2080  auto AST = TU.build();
2081 
2082  // References in main file are returned without index.
2083  EXPECT_THAT(findReferences(AST, Main.point(), 0, /*Index=*/nullptr),
2084  ElementsAre(RangeIs(Main.range())));
2085  Annotations IndexedMain(R"cpp(
2086  int main() { [[f^oo]](); }
2087  )cpp");
2088 
2089  // References from indexed files are included.
2090  TestTU IndexedTU;
2091  IndexedTU.Code = IndexedMain.code();
2092  IndexedTU.Filename = "Indexed.cpp";
2093  IndexedTU.HeaderCode = Header;
2094  EXPECT_THAT(findReferences(AST, Main.point(), 0, IndexedTU.index().get()),
2095  ElementsAre(RangeIs(Main.range()), RangeIs(IndexedMain.range())));
2096 
2097  EXPECT_EQ(1u, findReferences(AST, Main.point(), /*Limit*/ 1,
2098  IndexedTU.index().get())
2099  .size());
2100 
2101  // If the main file is in the index, we don't return duplicates.
2102  // (even if the references are in a different location)
2103  TU.Code = ("\n\n" + Main.code()).str();
2104  EXPECT_THAT(findReferences(AST, Main.point(), 0, TU.index().get()),
2105  ElementsAre(RangeIs(Main.range())));
2106 }
2107 
2108 TEST(FindReferences, NoQueryForLocalSymbols) {
2109  struct RecordingIndex : public MemIndex {
2110  mutable Optional<llvm::DenseSet<SymbolID>> RefIDs;
2111  void refs(const RefsRequest &Req,
2112  llvm::function_ref<void(const Ref &)>) const override {
2113  RefIDs = Req.IDs;
2114  }
2115  };
2116 
2117  struct Test {
2118  StringRef AnnotatedCode;
2119  bool WantQuery;
2120  } Tests[] = {
2121  {"int ^x;", true},
2122  // For now we don't assume header structure which would allow skipping.
2123  {"namespace { int ^x; }", true},
2124  {"static int ^x;", true},
2125  // Anything in a function certainly can't be referenced though.
2126  {"void foo() { int ^x; }", false},
2127  {"void foo() { struct ^x{}; }", false},
2128  {"auto lambda = []{ int ^x; };", false},
2129  };
2130  for (Test T : Tests) {
2131  Annotations File(T.AnnotatedCode);
2132  RecordingIndex Rec;
2133  auto AST = TestTU::withCode(File.code()).build();
2134  findReferences(AST, File.point(), 0, &Rec);
2135  if (T.WantQuery)
2136  EXPECT_NE(Rec.RefIDs, None) << T.AnnotatedCode;
2137  else
2138  EXPECT_EQ(Rec.RefIDs, None) << T.AnnotatedCode;
2139  }
2140 }
2141 
2142 TEST(GetDeducedType, KwAutoExpansion) {
2143  struct Test {
2144  StringRef AnnotatedCode;
2145  const char *DeducedType;
2146  } Tests[] = {
2147  {"^auto i = 0;", "int"},
2148  {"^auto f(){ return 1;};", "int"}
2149  };
2150  for (Test T : Tests) {
2151  Annotations File(T.AnnotatedCode);
2152  auto AST = TestTU::withCode(File.code()).build();
2153  ASSERT_TRUE(AST.getDiagnostics().empty())
2154  << AST.getDiagnostics().begin()->Message;
2155  SourceManagerForFile SM("foo.cpp", File.code());
2156 
2157  for (Position Pos : File.points()) {
2158  auto Location = sourceLocationInMainFile(SM.get(), Pos);
2159  ASSERT_TRUE(!!Location) << llvm::toString(Location.takeError());
2161  EXPECT_EQ(DeducedType->getAsString(), T.DeducedType);
2162  }
2163  }
2164 }
2165 
2166 } // namespace
2167 } // namespace clangd
2168 } // namespace clang
llvm::Optional< QualType > getDeducedType(ParsedAST &AST, SourceLocation SourceLocationBeg)
Retrieves the deduced type at a given location (auto, decltype).
Definition: XRefs.cpp:874
MATCHER_P(Named, N, "")
const char * AnnotatedCode
Diagnostics must be generated for this snapshot.
llvm::Expected< std::vector< LocatedSymbol > > runLocateSymbolAt(ClangdServer &Server, PathRef File, Position Pos)
Definition: SyncAPI.cpp:88
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:23
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
std::vector< CodeCompletionResult > Results
MockFSProvider FS
static Options optsForTest()
Documents should not be synced at all.
llvm::Expected< SourceLocation > sourceLocationInMainFile(const SourceManager &SM, Position P)
Return the file location, corresponding to P.
Definition: SourceCode.cpp:363
std::vector< const char * > ExtraArgs
Definition: TestTU.h:57
static std::unique_ptr< SymbolIndex > build(SymbolSlab Symbols, RefSlab Refs, RelationSlab Relations)
Builds an index from slabs. The index takes ownership of the data.
Definition: MemIndex.cpp:19
llvm::Optional< HoverInfo > getHover(ParsedAST &AST, Position Pos, format::FormatStyle Style, const SymbolIndex *Index)
Get the hover information when hovering at Pos.
Definition: XRefs.cpp:899
TEST(BackgroundQueueTest, Priority)
std::string testPath(PathRef File)
Definition: TestFS.cpp:82
virtual void onDiagnosticsReady(PathRef File, std::vector< Diag > Diagnostics)=0
Called by ClangdServer when Diagnostics for File are ready.
static URIForFile canonicalize(llvm::StringRef AbsPath, llvm::StringRef TUPath)
Canonicalizes AbsPath via URI.
Definition: Protocol.cpp:32
static constexpr llvm::StringLiteral Name
const char * testRoot()
Definition: TestFS.cpp:74
SymbolSlab Symbols
std::vector< DocumentHighlight > findDocumentHighlights(ParsedAST &AST, Position Pos)
Returns highlights for all usages of a symbol at Pos.
Definition: XRefs.cpp:436
static TestTU withCode(llvm::StringRef Code)
Definition: TestTU.h:33
CodeCompletionBuilder Builder
std::vector< Location > findReferences(ParsedAST &AST, Position Pos, uint32_t Limit, const SymbolIndex *Index)
Returns reference locations of the symbol at a specified Pos.
Definition: XRefs.cpp:935
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
ClangdServer Server
CharSourceRange Range
SourceRange for the file name.
std::vector< const char * > Expected
IgnoreDiagnostics DiagConsumer
std::vector< LocatedSymbol > locateSymbolAt(ParsedAST &AST, Position Pos, const SymbolIndex *Index)
Get definition of symbol at a specified Pos.
Definition: XRefs.cpp:261
std::vector< HeaderEntry > HeaderContents
Definition: Modularize.cpp:483
QualType DeducedType
Definition: XRefs.cpp:867
void runAddDocument(ClangdServer &Server, PathRef File, llvm::StringRef Contents, WantDiagnostics WantDiags)
Definition: SyncAPI.cpp:15
const SymbolIndex * Index
Definition: Dexp.cpp:84
Symbol func(llvm::StringRef Name)
Definition: TestIndex.cpp:60