1 //===-- HoverTests.cpp ----------------------------------------------------===//
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 "AST.h"
10 #include "Annotations.h"
11 #include "Hover.h"
12 #include "TestIndex.h"
13 #include "TestTU.h"
14 #include "index/MemIndex.h"
15 #include "clang/Index/IndexSymbol.h"
16 #include "llvm/ADT/None.h"
17 #include "llvm/ADT/StringRef.h"
18 
19 #include "gmock/gmock.h"
20 #include "gtest/gtest.h"
21 #include <string>
22 #include <vector>
23 
24 namespace clang {
25 namespace clangd {
26 namespace {
27 
TEST(Hover,Structured)28 TEST(Hover, Structured) {
29   struct {
30     const char *const Code;
31     const std::function<void(HoverInfo &)> ExpectedBuilder;
32   } Cases[] = {
33       // Global scope.
34       {R"cpp(
35           // Best foo ever.
36           void [[fo^o]]() {}
37           )cpp",
38        [](HoverInfo &HI) {
39          HI.NamespaceScope = "";
40          HI.Name = "foo";
41          HI.Kind = index::SymbolKind::Function;
42          HI.Documentation = "Best foo ever.";
43          HI.Definition = "void foo()";
44          HI.ReturnType = "void";
45          HI.Type = "void ()";
46          HI.Parameters.emplace();
47        }},
48       // Inside namespace
49       {R"cpp(
50           namespace ns1 { namespace ns2 {
51             /// Best foo ever.
52             void [[fo^o]]() {}
53           }}
54           )cpp",
55        [](HoverInfo &HI) {
56          HI.NamespaceScope = "ns1::ns2::";
57          HI.Name = "foo";
58          HI.Kind = index::SymbolKind::Function;
59          HI.Documentation = "Best foo ever.";
60          HI.Definition = "void foo()";
61          HI.ReturnType = "void";
62          HI.Type = "void ()";
63          HI.Parameters.emplace();
64        }},
65       // Field
66       {R"cpp(
67           namespace ns1 { namespace ns2 {
68             struct Foo {
69               int [[b^ar]];
70             };
71           }}
72           )cpp",
73        [](HoverInfo &HI) {
74          HI.NamespaceScope = "ns1::ns2::";
75          HI.LocalScope = "Foo::";
76          HI.Name = "bar";
77          HI.Kind = index::SymbolKind::Field;
78          HI.Definition = "int bar";
79          HI.Type = "int";
80        }},
81       // Local to class method.
82       {R"cpp(
83           namespace ns1 { namespace ns2 {
84             struct Foo {
85               void foo() {
86                 int [[b^ar]];
87               }
88             };
89           }}
90           )cpp",
91        [](HoverInfo &HI) {
92          HI.NamespaceScope = "ns1::ns2::";
93          HI.LocalScope = "Foo::foo::";
94          HI.Name = "bar";
95          HI.Kind = index::SymbolKind::Variable;
96          HI.Definition = "int bar";
97          HI.Type = "int";
98        }},
99       // Anon namespace and local scope.
100       {R"cpp(
101           namespace ns1 { namespace {
102             struct {
103               int [[b^ar]];
104             } T;
105           }}
106           )cpp",
107        [](HoverInfo &HI) {
108          HI.NamespaceScope = "ns1::";
109          HI.LocalScope = "(anonymous struct)::";
110          HI.Name = "bar";
111          HI.Kind = index::SymbolKind::Field;
112          HI.Definition = "int bar";
113          HI.Type = "int";
114        }},
115       // Variable with template type
116       {R"cpp(
117           template <typename T, class... Ts> class Foo { public: Foo(int); };
118           Foo<int, char, bool> [[fo^o]] = Foo<int, char, bool>(5);
119           )cpp",
120        [](HoverInfo &HI) {
121          HI.NamespaceScope = "";
122          HI.Name = "foo";
123          HI.Kind = index::SymbolKind::Variable;
124          HI.Definition = "Foo<int, char, bool> foo = Foo<int, char, bool>(5)";
125          HI.Type = "Foo<int, char, bool>";
126        }},
127       // Implicit template instantiation
128       {R"cpp(
129           template <typename T> class vector{};
130           [[vec^tor]]<int> foo;
131           )cpp",
132        [](HoverInfo &HI) {
133          HI.NamespaceScope = "";
134          HI.Name = "vector<int>";
135          HI.Kind = index::SymbolKind::Class;
136          HI.Definition = "template <> class vector<int> {}";
137        }},
138       // Class template
139       {R"cpp(
140           template <template<typename, bool...> class C,
141                     typename = char,
142                     int = 0,
143                     bool Q = false,
144                     class... Ts> class Foo {};
145           template <template<typename, bool...> class T>
146           [[F^oo]]<T> foo;
147           )cpp",
148        [](HoverInfo &HI) {
149          HI.NamespaceScope = "";
150          HI.Name = "Foo";
151          HI.Kind = index::SymbolKind::Class;
152          HI.Definition =
153              R"cpp(template <template <typename, bool...> class C, typename = char, int = 0,
154           bool Q = false, class... Ts>
155 class Foo {})cpp";
156          HI.TemplateParameters = {
157              {std::string("template <typename, bool...> class"),
158               std::string("C"), llvm::None},
159              {std::string("typename"), llvm::None, std::string("char")},
160              {std::string("int"), llvm::None, std::string("0")},
161              {std::string("bool"), std::string("Q"), std::string("false")},
162              {std::string("class..."), std::string("Ts"), llvm::None},
163          };
164        }},
165       // Function template
166       {R"cpp(
167           template <template<typename, bool...> class C,
168                     typename = char,
169                     int = 0,
170                     bool Q = false,
171                     class... Ts> void foo();
172           template<typename, bool...> class Foo;
173 
174           void bar() {
175             [[fo^o]]<Foo>();
176           }
177           )cpp",
178        [](HoverInfo &HI) {
179          HI.NamespaceScope = "";
180          HI.Name = "foo";
181          HI.Kind = index::SymbolKind::Function;
182          HI.Definition = "template <> void foo<Foo, char, 0, false, <>>()";
183          HI.ReturnType = "void";
184          HI.Type = "void ()";
185          HI.Parameters.emplace();
186        }},
187       // Function decl
188       {R"cpp(
189           template<typename, bool...> class Foo {};
190           Foo<bool, true, false> foo(int, bool T = false);
191 
192           void bar() {
193             [[fo^o]](3);
194           }
195           )cpp",
196        [](HoverInfo &HI) {
197          HI.NamespaceScope = "";
198          HI.Name = "foo";
199          HI.Kind = index::SymbolKind::Function;
200          HI.Definition = "Foo<bool, true, false> foo(int, bool T = false)";
201          HI.ReturnType = "Foo<bool, true, false>";
202          HI.Type = "Foo<bool, true, false> (int, bool)";
203          HI.Parameters = {
204              {std::string("int"), llvm::None, llvm::None},
205              {std::string("bool"), std::string("T"), std::string("false")},
206          };
207        }},
208       // Pointers to lambdas
209       {R"cpp(
210         void foo() {
211           auto lamb = [](int T, bool B) -> bool { return T && B; };
212           auto *b = &lamb;
213           auto *[[^c]] = &b;
214         }
215         )cpp",
216        [](HoverInfo &HI) {
217          HI.NamespaceScope = "";
218          HI.LocalScope = "foo::";
219          HI.Name = "c";
220          HI.Kind = index::SymbolKind::Variable;
221          HI.Definition = "auto *c = &b";
222          HI.Type = "class (lambda) **";
223          HI.ReturnType = "bool";
224          HI.Parameters = {
225              {std::string("int"), std::string("T"), llvm::None},
226              {std::string("bool"), std::string("B"), llvm::None},
227          };
228          return HI;
229        }},
230       // Lambda parameter with decltype reference
231       {R"cpp(
232         auto lamb = [](int T, bool B) -> bool { return T && B; };
233         void foo(decltype(lamb)& bar) {
234           [[ba^r]](0, false);
235         }
236         )cpp",
237        [](HoverInfo &HI) {
238          HI.NamespaceScope = "";
239          HI.LocalScope = "foo::";
240          HI.Name = "bar";
241          HI.Kind = index::SymbolKind::Parameter;
242          HI.Definition = "decltype(lamb) &bar";
243          HI.Type = "decltype(lamb) &";
244          HI.ReturnType = "bool";
245          HI.Parameters = {
246              {std::string("int"), std::string("T"), llvm::None},
247              {std::string("bool"), std::string("B"), llvm::None},
248          };
249          return HI;
250        }},
251       // Lambda parameter with decltype
252       {R"cpp(
253         auto lamb = [](int T, bool B) -> bool { return T && B; };
254         void foo(decltype(lamb) bar) {
255           [[ba^r]](0, false);
256         }
257         )cpp",
258        [](HoverInfo &HI) {
259          HI.NamespaceScope = "";
260          HI.LocalScope = "foo::";
261          HI.Name = "bar";
262          HI.Kind = index::SymbolKind::Parameter;
263          HI.Definition = "decltype(lamb) bar";
264          HI.Type = "class (lambda)";
265          HI.ReturnType = "bool";
266          HI.Parameters = {
267              {std::string("int"), std::string("T"), llvm::None},
268              {std::string("bool"), std::string("B"), llvm::None},
269          };
270          HI.Value = "false";
271          return HI;
272        }},
273       // Lambda variable
274       {R"cpp(
275         void foo() {
276           int bar = 5;
277           auto lamb = [&bar](int T, bool B) -> bool { return T && B && bar; };
278           bool res = [[lam^b]](bar, false);
279         }
280         )cpp",
281        [](HoverInfo &HI) {
282          HI.NamespaceScope = "";
283          HI.LocalScope = "foo::";
284          HI.Name = "lamb";
285          HI.Kind = index::SymbolKind::Variable;
286          HI.Definition = "auto lamb = [&bar](int T, bool B) -> bool {}";
287          HI.Type = "class (lambda)";
288          HI.ReturnType = "bool";
289          HI.Parameters = {
290              {std::string("int"), std::string("T"), llvm::None},
291              {std::string("bool"), std::string("B"), llvm::None},
292          };
293          return HI;
294        }},
295       // Local variable in lambda
296       {R"cpp(
297         void foo() {
298           auto lamb = []{int [[te^st]];};
299         }
300         )cpp",
301        [](HoverInfo &HI) {
302          HI.NamespaceScope = "";
303          HI.LocalScope = "foo::(anonymous class)::operator()::";
304          HI.Name = "test";
305          HI.Kind = index::SymbolKind::Variable;
306          HI.Definition = "int test";
307          HI.Type = "int";
308        }},
309       // Partially-specialized class template. (formerly type-parameter-0-0)
310       {R"cpp(
311         template <typename T> class X;
312         template <typename T> class [[^X]]<T*> {};
313         )cpp",
314        [](HoverInfo &HI) {
315          HI.Name = "X<T *>";
316          HI.NamespaceScope = "";
317          HI.Kind = index::SymbolKind::Class;
318          HI.Definition = "template <typename T> class X<T *> {}";
319        }},
320       // Constructor of partially-specialized class template
321       {R"cpp(
322           template<typename, typename=void> struct X;
323           template<typename T> struct X<T*>{ [[^X]](); };
324           )cpp",
325        [](HoverInfo &HI) {
326          HI.NamespaceScope = "";
327          HI.Name = "X";
328          HI.LocalScope = "X<T *>::"; // FIXME: X<T *, void>::
329          HI.Kind = index::SymbolKind::Constructor;
330          HI.Definition = "X()";
331          HI.Parameters.emplace();
332        }},
333       {"class X { [[^~]]X(); };", // FIXME: Should be [[~X]]()
334        [](HoverInfo &HI) {
335          HI.NamespaceScope = "";
336          HI.Name = "~X";
337          HI.LocalScope = "X::";
338          HI.Kind = index::SymbolKind::Destructor;
339          HI.Definition = "~X()";
340          HI.Parameters.emplace();
341        }},
342       {"class X { [[op^erator]] int(); };",
343        [](HoverInfo &HI) {
344          HI.NamespaceScope = "";
345          HI.Name = "operator int";
346          HI.LocalScope = "X::";
347          HI.Kind = index::SymbolKind::ConversionFunction;
348          HI.Definition = "operator int()";
349          HI.Parameters.emplace();
350        }},
351       {"class X { operator [[^X]]*(); };",
352        [](HoverInfo &HI) {
353          HI.NamespaceScope = "";
354          HI.Name = "X";
355          HI.Kind = index::SymbolKind::Class;
356          HI.Definition = "class X {}";
357        }},
358 
359       // auto on lambda
360       {R"cpp(
361         void foo() {
362           [[au^to]] lamb = []{};
363         }
364         )cpp",
365        [](HoverInfo &HI) {
366          HI.Name = "(lambda)";
367          HI.Kind = index::SymbolKind::Class;
368        }},
369       // auto on template instantiation
370       {R"cpp(
371         template<typename T> class Foo{};
372         void foo() {
373           [[au^to]] x = Foo<int>();
374         }
375         )cpp",
376        [](HoverInfo &HI) {
377          HI.Name = "Foo<int>";
378          HI.Kind = index::SymbolKind::Class;
379        }},
380       // auto on specialized template
381       {R"cpp(
382         template<typename T> class Foo{};
383         template<> class Foo<int>{};
384         void foo() {
385           [[au^to]] x = Foo<int>();
386         }
387         )cpp",
388        [](HoverInfo &HI) {
389          HI.Name = "Foo<int>";
390          HI.Kind = index::SymbolKind::Class;
391        }},
392 
393       // macro
394       {R"cpp(
395         // Best MACRO ever.
396         #define MACRO(x,y,z) void foo(x, y, z);
397         [[MAC^RO]](int, double d, bool z = false);
398         )cpp",
399        [](HoverInfo &HI) {
400          HI.Name = "MACRO", HI.Kind = index::SymbolKind::Macro,
401          HI.Definition = "#define MACRO(x, y, z) void foo(x, y, z);";
402        }},
403 
404       // constexprs
405       {R"cpp(
406         constexpr int add(int a, int b) { return a + b; }
407         int [[b^ar]] = add(1, 2);
408         )cpp",
409        [](HoverInfo &HI) {
410          HI.Name = "bar";
411          HI.Definition = "int bar = add(1, 2)";
412          HI.Kind = index::SymbolKind::Variable;
413          HI.Type = "int";
414          HI.NamespaceScope = "";
415          HI.Value = "3";
416        }},
417       {R"cpp(
418         int [[b^ar]] = sizeof(char);
419         )cpp",
420        [](HoverInfo &HI) {
421          HI.Name = "bar";
422          HI.Definition = "int bar = sizeof(char)";
423          HI.Kind = index::SymbolKind::Variable;
424          HI.Type = "int";
425          HI.NamespaceScope = "";
426          HI.Value = "1";
427        }},
428       {R"cpp(
429         template<int a, int b> struct Add {
430           static constexpr int result = a + b;
431         };
432         int [[ba^r]] = Add<1, 2>::result;
433         )cpp",
434        [](HoverInfo &HI) {
435          HI.Name = "bar";
436          HI.Definition = "int bar = Add<1, 2>::result";
437          HI.Kind = index::SymbolKind::Variable;
438          HI.Type = "int";
439          HI.NamespaceScope = "";
440          HI.Value = "3";
441        }},
442       {R"cpp(
443         enum Color { RED, GREEN, };
444         Color x = [[GR^EEN]];
445        )cpp",
446        [](HoverInfo &HI) {
447          HI.Name = "GREEN";
448          HI.NamespaceScope = "";
449          HI.LocalScope = "Color::";
450          HI.Definition = "GREEN";
451          HI.Kind = index::SymbolKind::EnumConstant;
452          HI.Type = "enum Color";
453          HI.Value = "1"; // Numeric when hovering on the enumerator name.
454        }},
455       {R"cpp(
456         enum Color { RED, GREEN, };
457         Color x = GREEN;
458         Color y = [[^x]];
459        )cpp",
460        [](HoverInfo &HI) {
461          HI.Name = "x";
462          HI.NamespaceScope = "";
463          HI.Definition = "Color x = GREEN";
464          HI.Kind = index::SymbolKind::Variable;
465          HI.Type = "enum Color";
466          HI.Value = "GREEN (1)"; // Symbolic when hovering on an expression.
467        }},
468       {R"cpp(
469         template<int a, int b> struct Add {
470           static constexpr int result = a + b;
471         };
472         int bar = Add<1, 2>::[[resu^lt]];
473         )cpp",
474        [](HoverInfo &HI) {
475          HI.Name = "result";
476          HI.Definition = "static constexpr int result = 1 + 2";
477          HI.Kind = index::SymbolKind::StaticProperty;
478          HI.Type = "const int";
479          HI.NamespaceScope = "";
480          HI.LocalScope = "Add<1, 2>::";
481          HI.Value = "3";
482        }},
483       {R"cpp(
484         constexpr int answer() { return 40 + 2; }
485         int x = [[ans^wer]]();
486         )cpp",
487        [](HoverInfo &HI) {
488          HI.Name = "answer";
489          HI.Definition = "constexpr int answer()";
490          HI.Kind = index::SymbolKind::Function;
491          HI.Type = "int ()";
492          HI.ReturnType = "int";
493          HI.Parameters.emplace();
494          HI.NamespaceScope = "";
495          HI.Value = "42";
496        }},
497       {R"cpp(
498         const char *[[ba^r]] = "1234";
499         )cpp",
500        [](HoverInfo &HI) {
501          HI.Name = "bar";
502          HI.Definition = "const char *bar = \"1234\"";
503          HI.Kind = index::SymbolKind::Variable;
504          HI.Type = "const char *";
505          HI.NamespaceScope = "";
506          HI.Value = "&\"1234\"[0]";
507        }},
508       {R"cpp(// Should not crash
509         template <typename T>
510         struct Tmpl {
511           Tmpl(int name);
512         };
513 
514         template <typename A>
515         void boom(int name) {
516           new Tmpl<A>([[na^me]]);
517         })cpp",
518        [](HoverInfo &HI) {
519          HI.Name = "name";
520          HI.Definition = "int name";
521          HI.Kind = index::SymbolKind::Parameter;
522          HI.Type = "int";
523          HI.NamespaceScope = "";
524          HI.LocalScope = "boom::";
525        }},
526       {
527           R"cpp(// Should not print inline or anon namespaces.
528           namespace ns {
529             inline namespace in_ns {
530               namespace a {
531                 namespace {
532                   namespace b {
533                     inline namespace in_ns2 {
534                       class Foo {};
535                     } // in_ns2
536                   } // b
537                 } // anon
538               } // a
539             } // in_ns
540           } // ns
541           void foo() {
542             ns::a::b::[[F^oo]] x;
543             (void)x;
544           }
545           )cpp",
546           [](HoverInfo &HI) {
547             HI.Name = "Foo";
548             HI.Kind = index::SymbolKind::Class;
549             HI.NamespaceScope = "ns::a::b::";
550             HI.Definition = "class Foo {}";
551           }},
552       {
553           R"cpp(
554           template <typename T> class Foo {};
555           class X;
556           void foo() {
557             [[^auto]] x = Foo<X>();
558           }
559           )cpp",
560           [](HoverInfo &HI) {
561             HI.Name = "Foo<X>";
562             HI.Kind = index::SymbolKind::Class;
563           }},
564       {// Falls back to primary template, when the type is not instantiated.
565        R"cpp(
566           // comment from primary
567           template <typename T> class Foo {};
568           // comment from specialization
569           template <typename T> class Foo<T*> {};
570           void foo() {
571             [[Fo^o]]<int*> *x = nullptr;
572           }
573           )cpp",
574        [](HoverInfo &HI) {
575          HI.Name = "Foo<int *>";
576          HI.Kind = index::SymbolKind::Class;
577          HI.NamespaceScope = "";
578          HI.Definition = "template <> class Foo<int *>";
579          // FIXME: Maybe force instantiation to make use of real template
580          // pattern.
581          HI.Documentation = "comment from primary";
582        }},
583   };
584   for (const auto &Case : Cases) {
585     SCOPED_TRACE(Case.Code);
586 
587     Annotations T(Case.Code);
588     TestTU TU = TestTU::withCode(T.code());
589     TU.ExtraArgs.push_back("-std=c++17");
590     // FIXME: This is no longer necessary, as the default behavior is no delayed
591     // parsing in the triplet below.
592     TU.ExtraArgs.push_back("-fno-delayed-template-parsing");
593     // Types might be different depending on the target triplet, we chose a
594     // fixed one to make sure tests passes on different platform.
595     TU.ExtraArgs.push_back("--target=x86_64-pc-linux-gnu");
596     auto AST = TU.build();
597     ASSERT_TRUE(AST.getDiagnostics().empty());
598 
599     auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
600     ASSERT_TRUE(H);
601     HoverInfo Expected;
602     Expected.SymRange = T.range();
603     Case.ExpectedBuilder(Expected);
604 
605     EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
606     EXPECT_EQ(H->LocalScope, Expected.LocalScope);
607     EXPECT_EQ(H->Name, Expected.Name);
608     EXPECT_EQ(H->Kind, Expected.Kind);
609     EXPECT_EQ(H->Documentation, Expected.Documentation);
610     EXPECT_EQ(H->Definition, Expected.Definition);
611     EXPECT_EQ(H->Type, Expected.Type);
612     EXPECT_EQ(H->ReturnType, Expected.ReturnType);
613     EXPECT_EQ(H->Parameters, Expected.Parameters);
614     EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
615     EXPECT_EQ(H->SymRange, Expected.SymRange);
616     EXPECT_EQ(H->Value, Expected.Value);
617   }
618 }
619 
TEST(Hover,NoHover)620 TEST(Hover, NoHover) {
621   llvm::StringRef Tests[] = {
622       "^int main() {}",
623       "void foo() {^}",
624       R"cpp(// structured binding. Not supported yet
625             struct Bar {};
626             void foo() {
627               Bar a[2];
628               ^auto [x,y] = a;
629             }
630           )cpp",
631       R"cpp(// Template auto parameter. Nothing (Not useful).
632             template<^auto T>
633             void func() {
634             }
635             void foo() {
636                func<1>();
637             }
638           )cpp",
639       R"cpp(// non-named decls don't get hover. Don't crash!
640             ^static_assert(1, "");
641           )cpp",
642       R"cpp(// non-evaluatable expr
643           template <typename T> void foo() {
644             (void)[[size^of]](T);
645           })cpp",
646       // literals
647       "auto x = t^rue;",
648       "auto x = '^A';",
649       "auto x = ^(int){42};",
650       "auto x = ^42.;",
651       "auto x = ^42.0i;",
652       "auto x = ^42;",
653       "auto x = ^nullptr;",
654       "auto x = ^\"asdf\";",
655   };
656 
657   for (const auto &Test : Tests) {
658     SCOPED_TRACE(Test);
659 
660     Annotations T(Test);
661     TestTU TU = TestTU::withCode(T.code());
662     TU.ExtraArgs.push_back("-std=c++17");
663     auto AST = TU.build();
664     ASSERT_TRUE(AST.getDiagnostics().empty());
665 
666     auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
667     ASSERT_FALSE(H);
668   }
669 }
670 
TEST(Hover,All)671 TEST(Hover, All) {
672   struct {
673     const char *const Code;
674     const std::function<void(HoverInfo &)> ExpectedBuilder;
675   } Cases[] = {
676       {
677           R"cpp(// Local variable
678             int main() {
679               int bonjour;
680               ^[[bonjour]] = 2;
681               int test1 = bonjour;
682             }
683           )cpp",
684           [](HoverInfo &HI) {
685             HI.Name = "bonjour";
686             HI.Kind = index::SymbolKind::Variable;
687             HI.NamespaceScope = "";
688             HI.LocalScope = "main::";
689             HI.Type = "int";
690             HI.Definition = "int bonjour";
691           }},
692       {
693           R"cpp(// Local variable in method
694             struct s {
695               void method() {
696                 int bonjour;
697                 ^[[bonjour]] = 2;
698               }
699             };
700           )cpp",
701           [](HoverInfo &HI) {
702             HI.Name = "bonjour";
703             HI.Kind = index::SymbolKind::Variable;
704             HI.NamespaceScope = "";
705             HI.LocalScope = "s::method::";
706             HI.Type = "int";
707             HI.Definition = "int bonjour";
708           }},
709       {
710           R"cpp(// Struct
711             namespace ns1 {
712               struct MyClass {};
713             } // namespace ns1
714             int main() {
715               ns1::[[My^Class]]* Params;
716             }
717           )cpp",
718           [](HoverInfo &HI) {
719             HI.Name = "MyClass";
720             HI.Kind = index::SymbolKind::Struct;
721             HI.NamespaceScope = "ns1::";
722             HI.Definition = "struct MyClass {}";
723           }},
724       {
725           R"cpp(// Class
726             namespace ns1 {
727               class MyClass {};
728             } // namespace ns1
729             int main() {
730               ns1::[[My^Class]]* Params;
731             }
732           )cpp",
733           [](HoverInfo &HI) {
734             HI.Name = "MyClass";
735             HI.Kind = index::SymbolKind::Class;
736             HI.NamespaceScope = "ns1::";
737             HI.Definition = "class MyClass {}";
738           }},
739       {
740           R"cpp(// Union
741             namespace ns1 {
742               union MyUnion { int x; int y; };
743             } // namespace ns1
744             int main() {
745               ns1::[[My^Union]] Params;
746             }
747           )cpp",
748           [](HoverInfo &HI) {
749             HI.Name = "MyUnion";
750             HI.Kind = index::SymbolKind::Union;
751             HI.NamespaceScope = "ns1::";
752             HI.Definition = "union MyUnion {}";
753           }},
754       {
755           R"cpp(// Function definition via pointer
756             void foo(int) {}
757             int main() {
758               auto *X = &^[[foo]];
759             }
760           )cpp",
761           [](HoverInfo &HI) {
762             HI.Name = "foo";
763             HI.Kind = index::SymbolKind::Function;
764             HI.NamespaceScope = "";
765             HI.Type = "void (int)";
766             HI.Definition = "void foo(int)";
767             HI.Documentation = "Function definition via pointer";
768             HI.ReturnType = "void";
769             HI.Parameters = {
770                 {std::string("int"), llvm::None, llvm::None},
771             };
772           }},
773       {
774           R"cpp(// Function declaration via call
775             int foo(int);
776             int main() {
777               return ^[[foo]](42);
778             }
779           )cpp",
780           [](HoverInfo &HI) {
781             HI.Name = "foo";
782             HI.Kind = index::SymbolKind::Function;
783             HI.NamespaceScope = "";
784             HI.Type = "int (int)";
785             HI.Definition = "int foo(int)";
786             HI.Documentation = "Function declaration via call";
787             HI.ReturnType = "int";
788             HI.Parameters = {
789                 {std::string("int"), llvm::None, llvm::None},
790             };
791           }},
792       {
793           R"cpp(// Field
794             struct Foo { int x; };
795             int main() {
796               Foo bar;
797               (void)bar.^[[x]];
798             }
799           )cpp",
800           [](HoverInfo &HI) {
801             HI.Name = "x";
802             HI.Kind = index::SymbolKind::Field;
803             HI.NamespaceScope = "";
804             HI.LocalScope = "Foo::";
805             HI.Type = "int";
806             HI.Definition = "int x";
807           }},
808       {
809           R"cpp(// Field with initialization
810             struct Foo { int x = 5; };
811             int main() {
812               Foo bar;
813               (void)bar.^[[x]];
814             }
815           )cpp",
816           [](HoverInfo &HI) {
817             HI.Name = "x";
818             HI.Kind = index::SymbolKind::Field;
819             HI.NamespaceScope = "";
820             HI.LocalScope = "Foo::";
821             HI.Type = "int";
822             HI.Definition = "int x = 5";
823           }},
824       {
825           R"cpp(// Static field
826             struct Foo { static int x; };
827             int main() {
828               (void)Foo::^[[x]];
829             }
830           )cpp",
831           [](HoverInfo &HI) {
832             HI.Name = "x";
833             HI.Kind = index::SymbolKind::StaticProperty;
834             HI.NamespaceScope = "";
835             HI.LocalScope = "Foo::";
836             HI.Type = "int";
837             HI.Definition = "static int x";
838           }},
839       {
840           R"cpp(// Field, member initializer
841             struct Foo {
842               int x;
843               Foo() : ^[[x]](0) {}
844             };
845           )cpp",
846           [](HoverInfo &HI) {
847             HI.Name = "x";
848             HI.Kind = index::SymbolKind::Field;
849             HI.NamespaceScope = "";
850             HI.LocalScope = "Foo::";
851             HI.Type = "int";
852             HI.Definition = "int x";
853           }},
854       {
855           R"cpp(// Field, GNU old-style field designator
856             struct Foo { int x; };
857             int main() {
858               Foo bar = { ^[[x]] : 1 };
859             }
860           )cpp",
861           [](HoverInfo &HI) {
862             HI.Name = "x";
863             HI.Kind = index::SymbolKind::Field;
864             HI.NamespaceScope = "";
865             HI.LocalScope = "Foo::";
866             HI.Type = "int";
867             HI.Definition = "int x";
868             HI.Value = "{1}";
869           }},
870       {
871           R"cpp(// Field, field designator
872             struct Foo { int x; };
873             int main() {
874               Foo bar = { .^[[x]] = 2 };
875             }
876           )cpp",
877           [](HoverInfo &HI) {
878             HI.Name = "x";
879             HI.Kind = index::SymbolKind::Field;
880             HI.NamespaceScope = "";
881             HI.LocalScope = "Foo::";
882             HI.Type = "int";
883             HI.Definition = "int x";
884             HI.Value = "{2}";
885           }},
886       {
887           R"cpp(// Method call
888             struct Foo { int x(); };
889             int main() {
890               Foo bar;
891               bar.^[[x]]();
892             }
893           )cpp",
894           [](HoverInfo &HI) {
895             HI.Name = "x";
896             HI.Kind = index::SymbolKind::InstanceMethod;
897             HI.NamespaceScope = "";
898             HI.LocalScope = "Foo::";
899             HI.Type = "int ()";
900             HI.Definition = "int x()";
901             HI.ReturnType = "int";
902             HI.Parameters = std::vector<HoverInfo::Param>{};
903           }},
904       {
905           R"cpp(// Static method call
906             struct Foo { static int x(); };
907             int main() {
908               Foo::^[[x]]();
909             }
910           )cpp",
911           [](HoverInfo &HI) {
912             HI.Name = "x";
913             HI.Kind = index::SymbolKind::StaticMethod;
914             HI.NamespaceScope = "";
915             HI.LocalScope = "Foo::";
916             HI.Type = "int ()";
917             HI.Definition = "static int x()";
918             HI.ReturnType = "int";
919             HI.Parameters = std::vector<HoverInfo::Param>{};
920           }},
921       {
922           R"cpp(// Typedef
923             typedef int Foo;
924             int main() {
925               ^[[Foo]] bar;
926             }
927           )cpp",
928           [](HoverInfo &HI) {
929             HI.Name = "Foo";
930             HI.Kind = index::SymbolKind::TypeAlias;
931             HI.NamespaceScope = "";
932             HI.Definition = "typedef int Foo";
933             HI.Documentation = "Typedef";
934             // FIXME: Maybe put underlying type into HI.Type for aliases?
935           }},
936       {
937           R"cpp(// Typedef with embedded definition
938             typedef struct Bar {} Foo;
939             int main() {
940               ^[[Foo]] bar;
941             }
942           )cpp",
943           [](HoverInfo &HI) {
944             HI.Name = "Foo";
945             HI.Kind = index::SymbolKind::TypeAlias;
946             HI.NamespaceScope = "";
947             HI.Definition = "typedef struct Bar Foo";
948             HI.Documentation = "Typedef with embedded definition";
949           }},
950       {
951           R"cpp(// Namespace
952             namespace ns {
953             struct Foo { static void bar(); };
954             } // namespace ns
955             int main() { ^[[ns]]::Foo::bar(); }
956           )cpp",
957           [](HoverInfo &HI) {
958             HI.Name = "ns";
959             HI.Kind = index::SymbolKind::Namespace;
960             HI.NamespaceScope = "";
961             HI.Definition = "namespace ns {}";
962           }},
963       {
964           R"cpp(// Anonymous namespace
965             namespace ns {
966               namespace {
967                 int foo;
968               } // anonymous namespace
969             } // namespace ns
970             int main() { ns::[[f^oo]]++; }
971           )cpp",
972           [](HoverInfo &HI) {
973             HI.Name = "foo";
974             HI.Kind = index::SymbolKind::Variable;
975             HI.NamespaceScope = "ns::";
976             HI.Type = "int";
977             HI.Definition = "int foo";
978           }},
979       {
980           R"cpp(// Macro
981             #define MACRO 0
982             int main() { return ^[[MACRO]]; }
983           )cpp",
984           [](HoverInfo &HI) {
985             HI.Name = "MACRO";
986             HI.Kind = index::SymbolKind::Macro;
987             HI.Definition = "#define MACRO 0";
988           }},
989       {
990           R"cpp(// Macro
991             #define MACRO 0
992             #define MACRO2 ^[[MACRO]]
993           )cpp",
994           [](HoverInfo &HI) {
995             HI.Name = "MACRO";
996             HI.Kind = index::SymbolKind::Macro;
997             HI.Definition = "#define MACRO 0";
998           }},
999       {
1000           R"cpp(// Macro
1001             #define MACRO {\
1002               return 0;\
1003             }
1004             int main() ^[[MACRO]]
1005           )cpp",
1006           [](HoverInfo &HI) {
1007             HI.Name = "MACRO";
1008             HI.Kind = index::SymbolKind::Macro;
1009             HI.Definition =
1010                 R"cpp(#define MACRO                                                                  \
1011   { return 0; })cpp";
1012           }},
1013       {
1014           R"cpp(// Forward class declaration
1015             class Foo;
1016             class Foo {};
1017             [[F^oo]]* foo();
1018           )cpp",
1019           [](HoverInfo &HI) {
1020             HI.Name = "Foo";
1021             HI.Kind = index::SymbolKind::Class;
1022             HI.NamespaceScope = "";
1023             HI.Definition = "class Foo {}";
1024             HI.Documentation = "Forward class declaration";
1025           }},
1026       {
1027           R"cpp(// Function declaration
1028             void foo();
1029             void g() { [[f^oo]](); }
1030             void foo() {}
1031           )cpp",
1032           [](HoverInfo &HI) {
1033             HI.Name = "foo";
1034             HI.Kind = index::SymbolKind::Function;
1035             HI.NamespaceScope = "";
1036             HI.Type = "void ()";
1037             HI.Definition = "void foo()";
1038             HI.Documentation = "Function declaration";
1039             HI.ReturnType = "void";
1040             HI.Parameters = std::vector<HoverInfo::Param>{};
1041           }},
1042       {
1043           R"cpp(// Enum declaration
1044             enum Hello {
1045               ONE, TWO, THREE,
1046             };
1047             void foo() {
1048               [[Hel^lo]] hello = ONE;
1049             }
1050           )cpp",
1051           [](HoverInfo &HI) {
1052             HI.Name = "Hello";
1053             HI.Kind = index::SymbolKind::Enum;
1054             HI.NamespaceScope = "";
1055             HI.Definition = "enum Hello {}";
1056             HI.Documentation = "Enum declaration";
1057           }},
1058       {
1059           R"cpp(// Enumerator
1060             enum Hello {
1061               ONE, TWO, THREE,
1062             };
1063             void foo() {
1064               Hello hello = [[O^NE]];
1065             }
1066           )cpp",
1067           [](HoverInfo &HI) {
1068             HI.Name = "ONE";
1069             HI.Kind = index::SymbolKind::EnumConstant;
1070             HI.NamespaceScope = "";
1071             HI.LocalScope = "Hello::";
1072             HI.Type = "enum Hello";
1073             HI.Definition = "ONE";
1074             HI.Value = "0";
1075           }},
1076       {
1077           R"cpp(// Enumerator in anonymous enum
1078             enum {
1079               ONE, TWO, THREE,
1080             };
1081             void foo() {
1082               int hello = [[O^NE]];
1083             }
1084           )cpp",
1085           [](HoverInfo &HI) {
1086             HI.Name = "ONE";
1087             HI.Kind = index::SymbolKind::EnumConstant;
1088             HI.NamespaceScope = "";
1089             // FIXME: This should be `(anon enum)::`
1090             HI.LocalScope = "";
1091             HI.Type = "enum (anonymous)";
1092             HI.Definition = "ONE";
1093             HI.Value = "0";
1094           }},
1095       {
1096           R"cpp(// Global variable
1097             static int hey = 10;
1098             void foo() {
1099               [[he^y]]++;
1100             }
1101           )cpp",
1102           [](HoverInfo &HI) {
1103             HI.Name = "hey";
1104             HI.Kind = index::SymbolKind::Variable;
1105             HI.NamespaceScope = "";
1106             HI.Type = "int";
1107             HI.Definition = "static int hey = 10";
1108             HI.Documentation = "Global variable";
1109             // FIXME: Value shouldn't be set in this case
1110             HI.Value = "10";
1111           }},
1112       {
1113           R"cpp(// Global variable in namespace
1114             namespace ns1 {
1115               static int hey = 10;
1116             }
1117             void foo() {
1118               ns1::[[he^y]]++;
1119             }
1120           )cpp",
1121           [](HoverInfo &HI) {
1122             HI.Name = "hey";
1123             HI.Kind = index::SymbolKind::Variable;
1124             HI.NamespaceScope = "ns1::";
1125             HI.Type = "int";
1126             HI.Definition = "static int hey = 10";
1127             HI.Value = "10";
1128           }},
1129       {
1130           R"cpp(// Field in anonymous struct
1131             static struct {
1132               int hello;
1133             } s;
1134             void foo() {
1135               s.[[he^llo]]++;
1136             }
1137           )cpp",
1138           [](HoverInfo &HI) {
1139             HI.Name = "hello";
1140             HI.Kind = index::SymbolKind::Field;
1141             HI.NamespaceScope = "";
1142             HI.LocalScope = "(anonymous struct)::";
1143             HI.Type = "int";
1144             HI.Definition = "int hello";
1145           }},
1146       {
1147           R"cpp(// Templated function
1148             template <typename T>
1149             T foo() {
1150               return 17;
1151             }
1152             void g() { auto x = [[f^oo]]<int>(); }
1153           )cpp",
1154           [](HoverInfo &HI) {
1155             HI.Name = "foo";
1156             HI.Kind = index::SymbolKind::Function;
1157             HI.NamespaceScope = "";
1158             HI.Type = "int ()";
1159             HI.Definition = "template <> int foo<int>()";
1160             HI.Documentation = "Templated function";
1161             HI.ReturnType = "int";
1162             HI.Parameters = std::vector<HoverInfo::Param>{};
1163             // FIXME: We should populate template parameters with arguments in
1164             // case of instantiations.
1165           }},
1166       {
1167           R"cpp(// Anonymous union
1168             struct outer {
1169               union {
1170                 int abc, def;
1171               } v;
1172             };
1173             void g() { struct outer o; o.v.[[d^ef]]++; }
1174           )cpp",
1175           [](HoverInfo &HI) {
1176             HI.Name = "def";
1177             HI.Kind = index::SymbolKind::Field;
1178             HI.NamespaceScope = "";
1179             HI.LocalScope = "outer::(anonymous union)::";
1180             HI.Type = "int";
1181             HI.Definition = "int def";
1182           }},
1183       {
1184           R"cpp(// documentation from index
1185             int nextSymbolIsAForwardDeclFromIndexWithNoLocalDocs;
1186             void indexSymbol();
1187             void g() { [[ind^exSymbol]](); }
1188           )cpp",
1189           [](HoverInfo &HI) {
1190             HI.Name = "indexSymbol";
1191             HI.Kind = index::SymbolKind::Function;
1192             HI.NamespaceScope = "";
1193             HI.Type = "void ()";
1194             HI.Definition = "void indexSymbol()";
1195             HI.ReturnType = "void";
1196             HI.Parameters = std::vector<HoverInfo::Param>{};
1197             HI.Documentation = "comment from index";
1198           }},
1199       {
1200           R"cpp(// Simple initialization with auto
1201             void foo() {
1202               ^[[auto]] i = 1;
1203             }
1204           )cpp",
1205           [](HoverInfo &HI) {
1206             HI.Name = "int";
1207             // FIXME: Should be Builtin/Integral.
1208             HI.Kind = index::SymbolKind::Unknown;
1209           }},
1210       {
1211           R"cpp(// Simple initialization with const auto
1212             void foo() {
1213               const ^[[auto]] i = 1;
1214             }
1215           )cpp",
1216           [](HoverInfo &HI) { HI.Name = "int"; }},
1217       {
1218           R"cpp(// Simple initialization with const auto&
1219             void foo() {
1220               const ^[[auto]]& i = 1;
1221             }
1222           )cpp",
1223           [](HoverInfo &HI) { HI.Name = "int"; }},
1224       {
1225           R"cpp(// Simple initialization with auto&
1226             void foo() {
1227               int x;
1228               ^[[auto]]& i = x;
1229             }
1230           )cpp",
1231           [](HoverInfo &HI) { HI.Name = "int"; }},
1232       {
1233           R"cpp(// Simple initialization with auto*
1234             void foo() {
1235               int a = 1;
1236               ^[[auto]]* i = &a;
1237             }
1238           )cpp",
1239           [](HoverInfo &HI) { HI.Name = "int"; }},
1240       {
1241           R"cpp(// Auto with initializer list.
1242             namespace std
1243             {
1244               template<class _E>
1245               class initializer_list {};
1246             }
1247             void foo() {
1248               ^[[auto]] i = {1,2};
1249             }
1250           )cpp",
1251           [](HoverInfo &HI) {
1252             HI.Name = "initializer_list<int>";
1253             HI.Kind = index::SymbolKind::Class;
1254           }},
1255       {
1256           R"cpp(// User defined conversion to auto
1257             struct Bar {
1258               operator ^[[auto]]() const { return 10; }
1259             };
1260           )cpp",
1261           [](HoverInfo &HI) { HI.Name = "int"; }},
1262       {
1263           R"cpp(// Simple initialization with decltype(auto)
1264             void foo() {
1265               ^[[decltype]](auto) i = 1;
1266             }
1267           )cpp",
1268           [](HoverInfo &HI) { HI.Name = "int"; }},
1269       {
1270           R"cpp(// Simple initialization with const decltype(auto)
1271             void foo() {
1272               const int j = 0;
1273               ^[[decltype]](auto) i = j;
1274             }
1275           )cpp",
1276           [](HoverInfo &HI) { HI.Name = "const int"; }},
1277       {
1278           R"cpp(// Simple initialization with const& decltype(auto)
1279             void foo() {
1280               int k = 0;
1281               const int& j = k;
1282               ^[[decltype]](auto) i = j;
1283             }
1284           )cpp",
1285           [](HoverInfo &HI) { HI.Name = "const int &"; }},
1286       {
1287           R"cpp(// Simple initialization with & decltype(auto)
1288             void foo() {
1289               int k = 0;
1290               int& j = k;
1291               ^[[decltype]](auto) i = j;
1292             }
1293           )cpp",
1294           [](HoverInfo &HI) { HI.Name = "int &"; }},
1295       {
1296           R"cpp(// simple trailing return type
1297             ^[[auto]] main() -> int {
1298               return 0;
1299             }
1300           )cpp",
1301           [](HoverInfo &HI) { HI.Name = "int"; }},
1302       {
1303           R"cpp(// auto function return with trailing type
1304             struct Bar {};
1305             ^[[auto]] test() -> decltype(Bar()) {
1306               return Bar();
1307             }
1308           )cpp",
1309           [](HoverInfo &HI) {
1310             HI.Name = "Bar";
1311             HI.Kind = index::SymbolKind::Struct;
1312             HI.Documentation = "auto function return with trailing type";
1313           }},
1314       {
1315           R"cpp(// trailing return type
1316             struct Bar {};
1317             auto test() -> ^[[decltype]](Bar()) {
1318               return Bar();
1319             }
1320           )cpp",
1321           [](HoverInfo &HI) {
1322             HI.Name = "Bar";
1323             HI.Kind = index::SymbolKind::Struct;
1324             HI.Documentation = "trailing return type";
1325           }},
1326       {
1327           R"cpp(// auto in function return
1328             struct Bar {};
1329             ^[[auto]] test() {
1330               return Bar();
1331             }
1332           )cpp",
1333           [](HoverInfo &HI) {
1334             HI.Name = "Bar";
1335             HI.Kind = index::SymbolKind::Struct;
1336             HI.Documentation = "auto in function return";
1337           }},
1338       {
1339           R"cpp(// auto& in function return
1340             struct Bar {};
1341             ^[[auto]]& test() {
1342               static Bar x;
1343               return x;
1344             }
1345           )cpp",
1346           [](HoverInfo &HI) {
1347             HI.Name = "Bar";
1348             HI.Kind = index::SymbolKind::Struct;
1349             HI.Documentation = "auto& in function return";
1350           }},
1351       {
1352           R"cpp(// auto* in function return
1353             struct Bar {};
1354             ^[[auto]]* test() {
1355               Bar* bar;
1356               return bar;
1357             }
1358           )cpp",
1359           [](HoverInfo &HI) {
1360             HI.Name = "Bar";
1361             HI.Kind = index::SymbolKind::Struct;
1362             HI.Documentation = "auto* in function return";
1363           }},
1364       {
1365           R"cpp(// const auto& in function return
1366             struct Bar {};
1367             const ^[[auto]]& test() {
1368               static Bar x;
1369               return x;
1370             }
1371           )cpp",
1372           [](HoverInfo &HI) {
1373             HI.Name = "Bar";
1374             HI.Kind = index::SymbolKind::Struct;
1375             HI.Documentation = "const auto& in function return";
1376           }},
1377       {
1378           R"cpp(// decltype(auto) in function return
1379             struct Bar {};
1380             ^[[decltype]](auto) test() {
1381               return Bar();
1382             }
1383           )cpp",
1384           [](HoverInfo &HI) {
1385             HI.Name = "Bar";
1386             HI.Kind = index::SymbolKind::Struct;
1387             HI.Documentation = "decltype(auto) in function return";
1388           }},
1389       {
1390           R"cpp(// decltype(auto) reference in function return
1391             ^[[decltype]](auto) test() {
1392               static int a;
1393               return (a);
1394             }
1395           )cpp",
1396           [](HoverInfo &HI) { HI.Name = "int &"; }},
1397       {
1398           R"cpp(// decltype lvalue reference
1399             void foo() {
1400               int I = 0;
1401               ^[[decltype]](I) J = I;
1402             }
1403           )cpp",
1404           [](HoverInfo &HI) { HI.Name = "int"; }},
1405       {
1406           R"cpp(// decltype lvalue reference
1407             void foo() {
1408               int I= 0;
1409               int &K = I;
1410               ^[[decltype]](K) J = I;
1411             }
1412           )cpp",
1413           [](HoverInfo &HI) { HI.Name = "int &"; }},
1414       {
1415           R"cpp(// decltype lvalue reference parenthesis
1416             void foo() {
1417               int I = 0;
1418               ^[[decltype]]((I)) J = I;
1419             }
1420           )cpp",
1421           [](HoverInfo &HI) { HI.Name = "int &"; }},
1422       {
1423           R"cpp(// decltype rvalue reference
1424             void foo() {
1425               int I = 0;
1426               ^[[decltype]](static_cast<int&&>(I)) J = static_cast<int&&>(I);
1427             }
1428           )cpp",
1429           [](HoverInfo &HI) { HI.Name = "int &&"; }},
1430       {
1431           R"cpp(// decltype rvalue reference function call
1432             int && bar();
1433             void foo() {
1434               int I = 0;
1435               ^[[decltype]](bar()) J = bar();
1436             }
1437           )cpp",
1438           [](HoverInfo &HI) { HI.Name = "int &&"; }},
1439       {
1440           R"cpp(// decltype of function with trailing return type.
1441             struct Bar {};
1442             auto test() -> decltype(Bar()) {
1443               return Bar();
1444             }
1445             void foo() {
1446               ^[[decltype]](test()) i = test();
1447             }
1448           )cpp",
1449           [](HoverInfo &HI) {
1450             HI.Name = "Bar";
1451             HI.Kind = index::SymbolKind::Struct;
1452             HI.Documentation =
1453                 "decltype of function with trailing return type.";
1454           }},
1455       {
1456           R"cpp(// decltype of var with decltype.
1457             void foo() {
1458               int I = 0;
1459               decltype(I) J = I;
1460               ^[[decltype]](J) K = J;
1461             }
1462           )cpp",
1463           [](HoverInfo &HI) { HI.Name = "int"; }},
1464       {
1465           R"cpp(// More complicated structured types.
1466             int bar();
1467             ^[[auto]] (*foo)() = bar;
1468           )cpp",
1469           [](HoverInfo &HI) { HI.Name = "int"; }},
1470       {
1471           R"cpp(// Should not crash when evaluating the initializer.
1472             struct Test {};
1473             void test() { Test && [[te^st]] = {}; }
1474           )cpp",
1475           [](HoverInfo &HI) {
1476             HI.Name = "test";
1477             HI.Kind = index::SymbolKind::Variable;
1478             HI.NamespaceScope = "";
1479             HI.LocalScope = "test::";
1480             HI.Type = "struct Test &&";
1481             HI.Definition = "Test &&test = {}";
1482             HI.Value = "{}";
1483           }},
1484       {
1485           R"cpp(// auto on alias
1486           typedef int int_type;
1487           ^[[auto]] x = int_type();
1488           )cpp",
1489           [](HoverInfo &HI) { HI.Name = "int"; }},
1490       {
1491           R"cpp(// auto on alias
1492           struct cls {};
1493           typedef cls cls_type;
1494           ^[[auto]] y = cls_type();
1495           )cpp",
1496           [](HoverInfo &HI) {
1497             HI.Name = "cls";
1498             HI.Kind = index::SymbolKind::Struct;
1499             HI.Documentation = "auto on alias";
1500           }},
1501       {
1502           R"cpp(// auto on alias
1503           template <class>
1504           struct templ {};
1505           ^[[auto]] z = templ<int>();
1506           )cpp",
1507           [](HoverInfo &HI) {
1508             HI.Name = "templ<int>";
1509             HI.Kind = index::SymbolKind::Struct;
1510             HI.Documentation = "auto on alias";
1511           }},
1512       {
1513           R"cpp(// should not crash.
1514           template <class T> struct cls {
1515             int method();
1516           };
1517 
1518           auto test = cls<int>().[[m^ethod]]();
1519           )cpp",
1520           [](HoverInfo &HI) {
1521             HI.Definition = "int method()";
1522             HI.Kind = index::SymbolKind::InstanceMethod;
1523             HI.NamespaceScope = "";
1524             HI.LocalScope = "cls<int>::";
1525             HI.Name = "method";
1526             HI.Parameters.emplace();
1527             HI.ReturnType = "int";
1528             HI.Type = "int ()";
1529           }},
1530       {
1531           R"cpp(// type of nested templates.
1532           template <class T> struct cls {};
1533           cls<cls<cls<int>>> [[fo^o]];
1534           )cpp",
1535           [](HoverInfo &HI) {
1536             HI.Definition = "cls<cls<cls<int>>> foo";
1537             HI.Kind = index::SymbolKind::Variable;
1538             HI.NamespaceScope = "";
1539             HI.Name = "foo";
1540             HI.Type = "cls<cls<cls<int> > >";
1541             HI.Value = "{}";
1542           }},
1543       {
1544           R"cpp(// type of nested templates.
1545           template <class T> struct cls {};
1546           [[cl^s]]<cls<cls<int>>> foo;
1547           )cpp",
1548           [](HoverInfo &HI) {
1549             HI.Definition = "template <> struct cls<cls<cls<int>>> {}";
1550             HI.Kind = index::SymbolKind::Struct;
1551             HI.NamespaceScope = "";
1552             HI.Name = "cls<cls<cls<int> > >";
1553             HI.Documentation = "type of nested templates.";
1554           }},
1555       {
1556           R"cpp(// type with decltype
1557           int a;
1558           decltype(a) [[b^]] = a;)cpp",
1559           [](HoverInfo &HI) {
1560             HI.Definition = "decltype(a) b = a";
1561             HI.Kind = index::SymbolKind::Variable;
1562             HI.NamespaceScope = "";
1563             HI.Name = "b";
1564             HI.Type = "int";
1565           }},
1566       {
1567           R"cpp(// type with decltype
1568           int a;
1569           decltype(a) c;
1570           decltype(c) [[b^]] = a;)cpp",
1571           [](HoverInfo &HI) {
1572             HI.Definition = "decltype(c) b = a";
1573             HI.Kind = index::SymbolKind::Variable;
1574             HI.NamespaceScope = "";
1575             HI.Name = "b";
1576             HI.Type = "int";
1577           }},
1578       {
1579           R"cpp(// type with decltype
1580           int a;
1581           const decltype(a) [[b^]] = a;)cpp",
1582           [](HoverInfo &HI) {
1583             HI.Definition = "const decltype(a) b = a";
1584             HI.Kind = index::SymbolKind::Variable;
1585             HI.NamespaceScope = "";
1586             HI.Name = "b";
1587             HI.Type = "int";
1588           }},
1589       {
1590           R"cpp(// type with decltype
1591           int a;
1592           auto [[f^oo]](decltype(a) x) -> decltype(a) { return 0; })cpp",
1593           [](HoverInfo &HI) {
1594             HI.Definition = "auto foo(decltype(a) x) -> decltype(a)";
1595             HI.Kind = index::SymbolKind::Function;
1596             HI.NamespaceScope = "";
1597             HI.Name = "foo";
1598             // FIXME: Handle composite types with decltype with a printing
1599             // policy.
1600             HI.Type = "auto (decltype(a)) -> decltype(a)";
1601             HI.ReturnType = "int";
1602             HI.Parameters = {
1603                 {std::string("int"), std::string("x"), llvm::None}};
1604           }},
1605       {
1606           R"cpp(// sizeof expr
1607           void foo() {
1608             (void)[[size^of]](char);
1609           })cpp",
1610           [](HoverInfo &HI) {
1611             HI.Name = "expression";
1612             HI.Type = "unsigned long";
1613             HI.Value = "1";
1614           }},
1615       {
1616           R"cpp(// alignof expr
1617           void foo() {
1618             (void)[[align^of]](char);
1619           })cpp",
1620           [](HoverInfo &HI) {
1621             HI.Name = "expression";
1622             HI.Type = "unsigned long";
1623             HI.Value = "1";
1624           }},
1625       {
1626           R"cpp(
1627           template <typename T = int>
1628           void foo(const T& = T()) {
1629             [[f^oo]]<>(3);
1630           })cpp",
1631           [](HoverInfo &HI) {
1632             HI.Name = "foo";
1633             HI.Kind = index::SymbolKind::Function;
1634             HI.Type = "void (const int &)";
1635             HI.ReturnType = "void";
1636             HI.Parameters = {
1637                 {std::string("const int &"), llvm::None, std::string("T()")}};
1638             HI.Definition = "template <> void foo<int>(const int &)";
1639             HI.NamespaceScope = "";
1640           }},
1641   };
1642 
1643   // Create a tiny index, so tests above can verify documentation is fetched.
1644   Symbol IndexSym = func("indexSymbol");
1645   IndexSym.Documentation = "comment from index";
1646   SymbolSlab::Builder Symbols;
1647   Symbols.insert(IndexSym);
1648   auto Index =
1649       MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab());
1650 
1651   for (const auto &Case : Cases) {
1652     SCOPED_TRACE(Case.Code);
1653 
1654     Annotations T(Case.Code);
1655     TestTU TU = TestTU::withCode(T.code());
1656     TU.ExtraArgs.push_back("-std=c++17");
1657     TU.ExtraArgs.push_back("-Wno-gnu-designator");
1658     // Types might be different depending on the target triplet, we chose a
1659     // fixed one to make sure tests passes on different platform.
1660     TU.ExtraArgs.push_back("--target=x86_64-pc-linux-gnu");
1661     auto AST = TU.build();
1662     for (const auto &D : AST.getDiagnostics())
1663       ADD_FAILURE() << D;
1664     ASSERT_TRUE(AST.getDiagnostics().empty());
1665 
1666     auto H = getHover(AST, T.point(), format::getLLVMStyle(), Index.get());
1667     ASSERT_TRUE(H);
1668     HoverInfo Expected;
1669     Expected.SymRange = T.range();
1670     Case.ExpectedBuilder(Expected);
1671 
1672     SCOPED_TRACE(H->present().asPlainText());
1673     EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
1674     EXPECT_EQ(H->LocalScope, Expected.LocalScope);
1675     EXPECT_EQ(H->Name, Expected.Name);
1676     EXPECT_EQ(H->Kind, Expected.Kind);
1677     EXPECT_EQ(H->Documentation, Expected.Documentation);
1678     EXPECT_EQ(H->Definition, Expected.Definition);
1679     EXPECT_EQ(H->Type, Expected.Type);
1680     EXPECT_EQ(H->ReturnType, Expected.ReturnType);
1681     EXPECT_EQ(H->Parameters, Expected.Parameters);
1682     EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
1683     EXPECT_EQ(H->SymRange, Expected.SymRange);
1684     EXPECT_EQ(H->Value, Expected.Value);
1685   }
1686 }
1687 
TEST(Hover,DocsFromIndex)1688 TEST(Hover, DocsFromIndex) {
1689   Annotations T(R"cpp(
1690   template <typename T> class X {};
1691   void foo() {
1692     au^to t = X<int>();
1693     X^<int> w;
1694     (void)w;
1695   })cpp");
1696 
1697   TestTU TU = TestTU::withCode(T.code());
1698   auto AST = TU.build();
1699   for (const auto &D : AST.getDiagnostics())
1700     ADD_FAILURE() << D;
1701   ASSERT_TRUE(AST.getDiagnostics().empty());
1702 
1703   Symbol IndexSym;
1704   IndexSym.ID = *getSymbolID(&findDecl(AST, "X"));
1705   IndexSym.Documentation = "comment from index";
1706   SymbolSlab::Builder Symbols;
1707   Symbols.insert(IndexSym);
1708   auto Index =
1709       MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab());
1710 
1711   for (const auto &P : T.points()) {
1712     auto H = getHover(AST, P, format::getLLVMStyle(), Index.get());
1713     ASSERT_TRUE(H);
1714     EXPECT_EQ(H->Documentation, IndexSym.Documentation);
1715   }
1716 }
1717 
TEST(Hover,DocsFromAST)1718 TEST(Hover, DocsFromAST) {
1719   Annotations T(R"cpp(
1720   // doc
1721   template <typename T> class X {};
1722   // doc
1723   template <typename T> void bar() {}
1724   // doc
1725   template <typename T> T baz;
1726   void foo() {
1727     au^to t = X<int>();
1728     X^<int>();
1729     b^ar<int>();
1730     au^to T = ba^z<X<int>>;
1731     ba^z<int> = 0;
1732   })cpp");
1733 
1734   TestTU TU = TestTU::withCode(T.code());
1735   auto AST = TU.build();
1736   for (const auto &D : AST.getDiagnostics())
1737     ADD_FAILURE() << D;
1738   ASSERT_TRUE(AST.getDiagnostics().empty());
1739 
1740   for (const auto &P : T.points()) {
1741     auto H = getHover(AST, P, format::getLLVMStyle(), nullptr);
1742     ASSERT_TRUE(H);
1743     EXPECT_EQ(H->Documentation, "doc");
1744   }
1745 }
1746 
TEST(Hover,DocsFromMostSpecial)1747 TEST(Hover, DocsFromMostSpecial) {
1748   Annotations T(R"cpp(
1749   // doc1
1750   template <typename T> class $doc1^X {};
1751   // doc2
1752   template <> class $doc2^X<int> {};
1753   // doc3
1754   template <typename T> class $doc3^X<T*> {};
1755   void foo() {
1756     X$doc1^<char>();
1757     X$doc2^<int>();
1758     X$doc3^<int*>();
1759   })cpp");
1760 
1761   TestTU TU = TestTU::withCode(T.code());
1762   auto AST = TU.build();
1763   for (const auto &D : AST.getDiagnostics())
1764     ADD_FAILURE() << D;
1765   ASSERT_TRUE(AST.getDiagnostics().empty());
1766 
1767   for (auto Comment : {"doc1", "doc2", "doc3"}) {
1768     for (const auto &P : T.points(Comment)) {
1769       auto H = getHover(AST, P, format::getLLVMStyle(), nullptr);
1770       ASSERT_TRUE(H);
1771       EXPECT_EQ(H->Documentation, Comment);
1772     }
1773   }
1774 }
1775 
TEST(Hover,Present)1776 TEST(Hover, Present) {
1777   struct {
1778     const std::function<void(HoverInfo &)> Builder;
1779     llvm::StringRef ExpectedRender;
1780   } Cases[] = {
1781       {
1782           [](HoverInfo &HI) {
1783             HI.Kind = index::SymbolKind::Unknown;
1784             HI.Name = "X";
1785           },
1786           R"(X)",
1787       },
1788       {
1789           [](HoverInfo &HI) {
1790             HI.Kind = index::SymbolKind::NamespaceAlias;
1791             HI.Name = "foo";
1792           },
1793           R"(namespace-alias foo)",
1794       },
1795       {
1796           [](HoverInfo &HI) {
1797             HI.Kind = index::SymbolKind::Class;
1798             HI.TemplateParameters = {
1799                 {std::string("typename"), std::string("T"), llvm::None},
1800                 {std::string("typename"), std::string("C"),
1801                  std::string("bool")},
1802             };
1803             HI.Documentation = "documentation";
1804             HI.Definition =
1805                 "template <typename T, typename C = bool> class Foo {}";
1806             HI.Name = "foo";
1807             HI.NamespaceScope.emplace();
1808           },
1809           R"(class foo
1810 
1811 documentation
1812 
1813 template <typename T, typename C = bool> class Foo {})",
1814       },
1815       {
1816           [](HoverInfo &HI) {
1817             HI.Kind = index::SymbolKind::Function;
1818             HI.Name = "foo";
1819             HI.Type = "type";
1820             HI.ReturnType = "ret_type";
1821             HI.Parameters.emplace();
1822             HoverInfo::Param P;
1823             HI.Parameters->push_back(P);
1824             P.Type = "type";
1825             HI.Parameters->push_back(P);
1826             P.Name = "foo";
1827             HI.Parameters->push_back(P);
1828             P.Default = "default";
1829             HI.Parameters->push_back(P);
1830             HI.NamespaceScope = "ns::";
1831             HI.Definition = "ret_type foo(params) {}";
1832           },
1833           R"(function foo
1834 
1835 → ret_type
1836 Parameters:
1837 -
1838 - type
1839 - type foo
1840 - type foo = default
1841 
1842 // In namespace ns
1843 ret_type foo(params) {})",
1844       },
1845       {
1846           [](HoverInfo &HI) {
1847             HI.Kind = index::SymbolKind::Variable;
1848             HI.LocalScope = "test::bar::";
1849             HI.Value = "value";
1850             HI.Name = "foo";
1851             HI.Type = "type";
1852             HI.Definition = "def";
1853           },
1854           R"(variable foo
1855 
1856 Type: type
1857 Value = value
1858 
1859 // In test::bar
1860 def)",
1861       },
1862   };
1863 
1864   for (const auto &C : Cases) {
1865     HoverInfo HI;
1866     C.Builder(HI);
1867     EXPECT_EQ(HI.present().asPlainText(), C.ExpectedRender);
1868   }
1869 }
1870 
1871 // This is a separate test as headings don't create any differences in plaintext
1872 // mode.
TEST(Hover,PresentHeadings)1873 TEST(Hover, PresentHeadings) {
1874   HoverInfo HI;
1875   HI.Kind = index::SymbolKind::Variable;
1876   HI.Name = "foo";
1877 
1878   EXPECT_EQ(HI.present().asMarkdown(), "### variable `foo`");
1879 }
1880 
1881 // This is a separate test as rulers behave differently in markdown vs
1882 // plaintext.
TEST(Hover,PresentRulers)1883 TEST(Hover, PresentRulers) {
1884   HoverInfo HI;
1885   HI.Kind = index::SymbolKind::Variable;
1886   HI.Name = "foo";
1887   HI.Value = "val";
1888   HI.Definition = "def";
1889 
1890   llvm::StringRef ExpectedMarkdown = R"md(### variable `foo`
1891 
1892 ---
1893 Value \= `val`
1894 
1895 ---
1896 ```cpp
1897 def
1898 ```)md";
1899   EXPECT_EQ(HI.present().asMarkdown(), ExpectedMarkdown);
1900 
1901   llvm::StringRef ExpectedPlaintext = R"pt(variable foo
1902 
1903 Value = val
1904 
1905 def)pt";
1906   EXPECT_EQ(HI.present().asPlainText(), ExpectedPlaintext);
1907 }
1908 } // namespace
1909 } // namespace clangd
1910 } // namespace clang
1911