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/Basic/Specifiers.h"
16 #include "clang/Index/IndexSymbol.h"
17 #include "llvm/ADT/None.h"
18 #include "llvm/ADT/StringRef.h"
19 
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22 #include <string>
23 #include <vector>
24 
25 namespace clang {
26 namespace clangd {
27 namespace {
28 
29 using PassMode = HoverInfo::PassType::PassMode;
30 
TEST(Hover,Structured)31 TEST(Hover, Structured) {
32   struct {
33     const char *const Code;
34     const std::function<void(HoverInfo &)> ExpectedBuilder;
35   } Cases[] = {
36       // Global scope.
37       {R"cpp(
38           // Best foo ever.
39           void [[fo^o]]() {}
40           )cpp",
41        [](HoverInfo &HI) {
42          HI.NamespaceScope = "";
43          HI.Name = "foo";
44          HI.Kind = index::SymbolKind::Function;
45          HI.Documentation = "Best foo ever.";
46          HI.Definition = "void foo()";
47          HI.ReturnType = "void";
48          HI.Type = "void ()";
49          HI.Parameters.emplace();
50        }},
51       // Inside namespace
52       {R"cpp(
53           namespace ns1 { namespace ns2 {
54             /// Best foo ever.
55             void [[fo^o]]() {}
56           }}
57           )cpp",
58        [](HoverInfo &HI) {
59          HI.NamespaceScope = "ns1::ns2::";
60          HI.Name = "foo";
61          HI.Kind = index::SymbolKind::Function;
62          HI.Documentation = "Best foo ever.";
63          HI.Definition = "void foo()";
64          HI.ReturnType = "void";
65          HI.Type = "void ()";
66          HI.Parameters.emplace();
67        }},
68       // Field
69       {R"cpp(
70           namespace ns1 { namespace ns2 {
71             struct Foo {
72               char [[b^ar]];
73             };
74           }}
75           )cpp",
76        [](HoverInfo &HI) {
77          HI.NamespaceScope = "ns1::ns2::";
78          HI.LocalScope = "Foo::";
79          HI.Name = "bar";
80          HI.Kind = index::SymbolKind::Field;
81          HI.Definition = "char bar";
82          HI.Type = "char";
83          HI.Offset = 0;
84          HI.Size = 1;
85          HI.AccessSpecifier = "public";
86        }},
87       // Local to class method.
88       {R"cpp(
89           namespace ns1 { namespace ns2 {
90             struct Foo {
91               void foo() {
92                 int [[b^ar]];
93               }
94             };
95           }}
96           )cpp",
97        [](HoverInfo &HI) {
98          HI.NamespaceScope = "ns1::ns2::";
99          HI.LocalScope = "Foo::foo::";
100          HI.Name = "bar";
101          HI.Kind = index::SymbolKind::Variable;
102          HI.Definition = "int bar";
103          HI.Type = "int";
104        }},
105       // Anon namespace and local scope.
106       {R"cpp(
107           namespace ns1 { namespace {
108             struct {
109               char [[b^ar]];
110             } T;
111           }}
112           )cpp",
113        [](HoverInfo &HI) {
114          HI.NamespaceScope = "ns1::";
115          HI.LocalScope = "(anonymous struct)::";
116          HI.Name = "bar";
117          HI.Kind = index::SymbolKind::Field;
118          HI.Definition = "char bar";
119          HI.Type = "char";
120          HI.Offset = 0;
121          HI.Size = 1;
122          HI.AccessSpecifier = "public";
123        }},
124       // Struct definition shows size.
125       {R"cpp(
126           struct [[^X]]{};
127           )cpp",
128        [](HoverInfo &HI) {
129          HI.NamespaceScope = "";
130          HI.Name = "X";
131          HI.Kind = index::SymbolKind::Struct;
132          HI.Definition = "struct X {}";
133          HI.Size = 1;
134        }},
135       // Variable with template type
136       {R"cpp(
137           template <typename T, class... Ts> class Foo { public: Foo(int); };
138           Foo<int, char, bool> [[fo^o]] = Foo<int, char, bool>(5);
139           )cpp",
140        [](HoverInfo &HI) {
141          HI.NamespaceScope = "";
142          HI.Name = "foo";
143          HI.Kind = index::SymbolKind::Variable;
144          HI.Definition = "Foo<int, char, bool> foo = Foo<int, char, bool>(5)";
145          HI.Type = "Foo<int, char, bool>";
146        }},
147       // Implicit template instantiation
148       {R"cpp(
149           template <typename T> class vector{};
150           [[vec^tor]]<int> foo;
151           )cpp",
152        [](HoverInfo &HI) {
153          HI.NamespaceScope = "";
154          HI.Name = "vector<int>";
155          HI.Kind = index::SymbolKind::Class;
156          HI.Definition = "template <> class vector<int> {}";
157        }},
158       // Class template
159       {R"cpp(
160           template <template<typename, bool...> class C,
161                     typename = char,
162                     int = 0,
163                     bool Q = false,
164                     class... Ts> class Foo {};
165           template <template<typename, bool...> class T>
166           [[F^oo]]<T> foo;
167           )cpp",
168        [](HoverInfo &HI) {
169          HI.NamespaceScope = "";
170          HI.Name = "Foo";
171          HI.Kind = index::SymbolKind::Class;
172          HI.Definition =
173              R"cpp(template <template <typename, bool...> class C, typename = char, int = 0,
174           bool Q = false, class... Ts>
175 class Foo {})cpp";
176          HI.TemplateParameters = {
177              {std::string("template <typename, bool...> class"),
178               std::string("C"), llvm::None},
179              {std::string("typename"), llvm::None, std::string("char")},
180              {std::string("int"), llvm::None, std::string("0")},
181              {std::string("bool"), std::string("Q"), std::string("false")},
182              {std::string("class..."), std::string("Ts"), llvm::None},
183          };
184        }},
185       // Function template
186       {R"cpp(
187           template <template<typename, bool...> class C,
188                     typename = char,
189                     int = 0,
190                     bool Q = false,
191                     class... Ts> void foo();
192           template<typename, bool...> class Foo;
193 
194           void bar() {
195             [[fo^o]]<Foo>();
196           }
197           )cpp",
198        [](HoverInfo &HI) {
199          HI.NamespaceScope = "";
200          HI.Name = "foo";
201          HI.Kind = index::SymbolKind::Function;
202          HI.Definition = "template <> void foo<Foo, char, 0, false, <>>()";
203          HI.ReturnType = "void";
204          HI.Type = "void ()";
205          HI.Parameters.emplace();
206        }},
207       // Function decl
208       {R"cpp(
209           template<typename, bool...> class Foo {};
210           Foo<bool, true, false> foo(int, bool T = false);
211 
212           void bar() {
213             [[fo^o]](3);
214           }
215           )cpp",
216        [](HoverInfo &HI) {
217          HI.NamespaceScope = "";
218          HI.Name = "foo";
219          HI.Kind = index::SymbolKind::Function;
220          HI.Definition = "Foo<bool, true, false> foo(int, bool T = false)";
221          HI.ReturnType = "Foo<bool, true, false>";
222          HI.Type = "Foo<bool, true, false> (int, bool)";
223          HI.Parameters = {
224              {std::string("int"), llvm::None, llvm::None},
225              {std::string("bool"), std::string("T"), std::string("false")},
226          };
227        }},
228       // Pointers to lambdas
229       {R"cpp(
230         void foo() {
231           auto lamb = [](int T, bool B) -> bool { return T && B; };
232           auto *b = &lamb;
233           auto *[[^c]] = &b;
234         }
235         )cpp",
236        [](HoverInfo &HI) {
237          HI.NamespaceScope = "";
238          HI.LocalScope = "foo::";
239          HI.Name = "c";
240          HI.Kind = index::SymbolKind::Variable;
241          HI.Definition = "auto *c = &b";
242          HI.Type = "(lambda) **";
243          HI.ReturnType = "bool";
244          HI.Parameters = {
245              {std::string("int"), std::string("T"), llvm::None},
246              {std::string("bool"), std::string("B"), llvm::None},
247          };
248          return HI;
249        }},
250       // Lambda parameter with decltype reference
251       {R"cpp(
252         auto lamb = [](int T, bool B) -> bool { return T && B; };
253         void foo(decltype(lamb)& bar) {
254           [[ba^r]](0, false);
255         }
256         )cpp",
257        [](HoverInfo &HI) {
258          HI.NamespaceScope = "";
259          HI.LocalScope = "foo::";
260          HI.Name = "bar";
261          HI.Kind = index::SymbolKind::Parameter;
262          HI.Definition = "decltype(lamb) &bar";
263          HI.Type = "decltype(lamb) &";
264          HI.ReturnType = "bool";
265          HI.Parameters = {
266              {std::string("int"), std::string("T"), llvm::None},
267              {std::string("bool"), std::string("B"), llvm::None},
268          };
269          return HI;
270        }},
271       // Lambda parameter with decltype
272       {R"cpp(
273         auto lamb = [](int T, bool B) -> bool { return T && B; };
274         void foo(decltype(lamb) bar) {
275           [[ba^r]](0, false);
276         }
277         )cpp",
278        [](HoverInfo &HI) {
279          HI.NamespaceScope = "";
280          HI.LocalScope = "foo::";
281          HI.Name = "bar";
282          HI.Kind = index::SymbolKind::Parameter;
283          HI.Definition = "decltype(lamb) bar";
284          HI.Type = "class (lambda)";
285          HI.ReturnType = "bool";
286          HI.Parameters = {
287              {std::string("int"), std::string("T"), llvm::None},
288              {std::string("bool"), std::string("B"), llvm::None},
289          };
290          HI.Value = "false";
291          return HI;
292        }},
293       // Lambda variable
294       {R"cpp(
295         void foo() {
296           int bar = 5;
297           auto lamb = [&bar](int T, bool B) -> bool { return T && B && bar; };
298           bool res = [[lam^b]](bar, false);
299         }
300         )cpp",
301        [](HoverInfo &HI) {
302          HI.NamespaceScope = "";
303          HI.LocalScope = "foo::";
304          HI.Name = "lamb";
305          HI.Kind = index::SymbolKind::Variable;
306          HI.Definition = "auto lamb = [&bar](int T, bool B) -> bool {}";
307          HI.Type = "class (lambda)";
308          HI.ReturnType = "bool";
309          HI.Parameters = {
310              {std::string("int"), std::string("T"), llvm::None},
311              {std::string("bool"), std::string("B"), llvm::None},
312          };
313          return HI;
314        }},
315       // Local variable in lambda
316       {R"cpp(
317         void foo() {
318           auto lamb = []{int [[te^st]];};
319         }
320         )cpp",
321        [](HoverInfo &HI) {
322          HI.NamespaceScope = "";
323          HI.LocalScope = "foo::(anonymous class)::operator()::";
324          HI.Name = "test";
325          HI.Kind = index::SymbolKind::Variable;
326          HI.Definition = "int test";
327          HI.Type = "int";
328        }},
329       // Partially-specialized class template. (formerly type-parameter-0-0)
330       {R"cpp(
331         template <typename T> class X;
332         template <typename T> class [[^X]]<T*> {};
333         )cpp",
334        [](HoverInfo &HI) {
335          HI.Name = "X<T *>";
336          HI.NamespaceScope = "";
337          HI.Kind = index::SymbolKind::Class;
338          HI.Definition = "template <typename T> class X<T *> {}";
339        }},
340       // Constructor of partially-specialized class template
341       {R"cpp(
342           template<typename, typename=void> struct X;
343           template<typename T> struct X<T*>{ [[^X]](); };
344           )cpp",
345        [](HoverInfo &HI) {
346          HI.NamespaceScope = "";
347          HI.Name = "X";
348          HI.LocalScope = "X<T *>::"; // FIXME: X<T *, void>::
349          HI.Kind = index::SymbolKind::Constructor;
350          HI.Definition = "X()";
351          HI.Parameters.emplace();
352          HI.AccessSpecifier = "public";
353        }},
354       {"class X { [[^~]]X(); };", // FIXME: Should be [[~X]]()
355        [](HoverInfo &HI) {
356          HI.NamespaceScope = "";
357          HI.Name = "~X";
358          HI.LocalScope = "X::";
359          HI.Kind = index::SymbolKind::Destructor;
360          HI.Definition = "~X()";
361          HI.Parameters.emplace();
362          HI.AccessSpecifier = "private";
363        }},
364       {"class X { [[op^erator]] int(); };",
365        [](HoverInfo &HI) {
366          HI.NamespaceScope = "";
367          HI.Name = "operator int";
368          HI.LocalScope = "X::";
369          HI.Kind = index::SymbolKind::ConversionFunction;
370          HI.Definition = "operator int()";
371          HI.Parameters.emplace();
372          HI.AccessSpecifier = "private";
373        }},
374       {"class X { operator [[^X]](); };",
375        [](HoverInfo &HI) {
376          HI.NamespaceScope = "";
377          HI.Name = "X";
378          HI.Kind = index::SymbolKind::Class;
379          HI.Definition = "class X {}";
380        }},
381 
382       // auto on structured bindings
383       {R"cpp(
384         void foo() {
385           struct S { int x; float y; };
386           [[au^to]] [x, y] = S();
387         }
388         )cpp",
389        [](HoverInfo &HI) {
390          HI.Name = "auto";
391          HI.Kind = index::SymbolKind::TypeAlias;
392          HI.Definition = "struct S";
393        }},
394       // undeduced auto
395       {R"cpp(
396         template<typename T>
397         void foo() {
398           [[au^to]] x = T{};
399         }
400         )cpp",
401        [](HoverInfo &HI) {
402          HI.Name = "auto";
403          HI.Kind = index::SymbolKind::TypeAlias;
404          HI.Definition = "/* not deduced */";
405        }},
406       // auto on lambda
407       {R"cpp(
408         void foo() {
409           [[au^to]] lamb = []{};
410         }
411         )cpp",
412        [](HoverInfo &HI) {
413          HI.Name = "auto";
414          HI.Kind = index::SymbolKind::TypeAlias;
415          HI.Definition = "class(lambda)";
416        }},
417       // auto on template instantiation
418       {R"cpp(
419         template<typename T> class Foo{};
420         void foo() {
421           [[au^to]] x = Foo<int>();
422         }
423         )cpp",
424        [](HoverInfo &HI) {
425          HI.Name = "auto";
426          HI.Kind = index::SymbolKind::TypeAlias;
427          HI.Definition = "class Foo<int>";
428        }},
429       // auto on specialized template
430       {R"cpp(
431         template<typename T> class Foo{};
432         template<> class Foo<int>{};
433         void foo() {
434           [[au^to]] x = Foo<int>();
435         }
436         )cpp",
437        [](HoverInfo &HI) {
438          HI.Name = "auto";
439          HI.Kind = index::SymbolKind::TypeAlias;
440          HI.Definition = "class Foo<int>";
441        }},
442 
443       // macro
444       {R"cpp(
445         // Best MACRO ever.
446         #define MACRO(x,y,z) void foo(x, y, z);
447         [[MAC^RO]](int, double d, bool z = false);
448         )cpp",
449        [](HoverInfo &HI) {
450          HI.Name = "MACRO", HI.Kind = index::SymbolKind::Macro,
451          HI.Definition = "#define MACRO(x, y, z) void foo(x, y, z);";
452        }},
453 
454       // constexprs
455       {R"cpp(
456         constexpr int add(int a, int b) { return a + b; }
457         int [[b^ar]] = add(1, 2);
458         )cpp",
459        [](HoverInfo &HI) {
460          HI.Name = "bar";
461          HI.Definition = "int bar = add(1, 2)";
462          HI.Kind = index::SymbolKind::Variable;
463          HI.Type = "int";
464          HI.NamespaceScope = "";
465          HI.Value = "3";
466        }},
467       {R"cpp(
468         int [[b^ar]] = sizeof(char);
469         )cpp",
470        [](HoverInfo &HI) {
471          HI.Name = "bar";
472          HI.Definition = "int bar = sizeof(char)";
473          HI.Kind = index::SymbolKind::Variable;
474          HI.Type = "int";
475          HI.NamespaceScope = "";
476          HI.Value = "1";
477        }},
478       {R"cpp(
479         template<int a, int b> struct Add {
480           static constexpr int result = a + b;
481         };
482         int [[ba^r]] = Add<1, 2>::result;
483         )cpp",
484        [](HoverInfo &HI) {
485          HI.Name = "bar";
486          HI.Definition = "int bar = Add<1, 2>::result";
487          HI.Kind = index::SymbolKind::Variable;
488          HI.Type = "int";
489          HI.NamespaceScope = "";
490          HI.Value = "3";
491        }},
492       {R"cpp(
493         enum Color { RED, GREEN, };
494         Color x = [[GR^EEN]];
495        )cpp",
496        [](HoverInfo &HI) {
497          HI.Name = "GREEN";
498          HI.NamespaceScope = "";
499          HI.LocalScope = "Color::";
500          HI.Definition = "GREEN";
501          HI.Kind = index::SymbolKind::EnumConstant;
502          HI.Type = "enum Color";
503          HI.Value = "1"; // Numeric when hovering on the enumerator name.
504        }},
505       {R"cpp(
506         enum Color { RED, GREEN, };
507         Color x = GREEN;
508         Color y = [[^x]];
509        )cpp",
510        [](HoverInfo &HI) {
511          HI.Name = "x";
512          HI.NamespaceScope = "";
513          HI.Definition = "Color x = GREEN";
514          HI.Kind = index::SymbolKind::Variable;
515          HI.Type = "enum Color";
516          HI.Value = "GREEN (1)"; // Symbolic when hovering on an expression.
517        }},
518       {R"cpp(
519         template<int a, int b> struct Add {
520           static constexpr int result = a + b;
521         };
522         int bar = Add<1, 2>::[[resu^lt]];
523         )cpp",
524        [](HoverInfo &HI) {
525          HI.Name = "result";
526          HI.Definition = "static constexpr int result = 1 + 2";
527          HI.Kind = index::SymbolKind::StaticProperty;
528          HI.Type = "const int";
529          HI.NamespaceScope = "";
530          HI.LocalScope = "Add<1, 2>::";
531          HI.Value = "3";
532          HI.AccessSpecifier = "public";
533        }},
534       {R"cpp(
535         constexpr int answer() { return 40 + 2; }
536         int x = [[ans^wer]]();
537         )cpp",
538        [](HoverInfo &HI) {
539          HI.Name = "answer";
540          HI.Definition = "constexpr int answer()";
541          HI.Kind = index::SymbolKind::Function;
542          HI.Type = "int ()";
543          HI.ReturnType = "int";
544          HI.Parameters.emplace();
545          HI.NamespaceScope = "";
546          HI.Value = "42";
547        }},
548       {R"cpp(
549         const char *[[ba^r]] = "1234";
550         )cpp",
551        [](HoverInfo &HI) {
552          HI.Name = "bar";
553          HI.Definition = "const char *bar = \"1234\"";
554          HI.Kind = index::SymbolKind::Variable;
555          HI.Type = "const char *";
556          HI.NamespaceScope = "";
557          HI.Value = "&\"1234\"[0]";
558        }},
559       {R"cpp(// Should not crash
560         template <typename T>
561         struct Tmpl {
562           Tmpl(int name);
563         };
564 
565         template <typename A>
566         void boom(int name) {
567           new Tmpl<A>([[na^me]]);
568         })cpp",
569        [](HoverInfo &HI) {
570          HI.Name = "name";
571          HI.Definition = "int name";
572          HI.Kind = index::SymbolKind::Parameter;
573          HI.Type = "int";
574          HI.NamespaceScope = "";
575          HI.LocalScope = "boom::";
576        }},
577       {
578           R"cpp(// Should not print inline or anon namespaces.
579           namespace ns {
580             inline namespace in_ns {
581               namespace a {
582                 namespace {
583                   namespace b {
584                     inline namespace in_ns2 {
585                       class Foo {};
586                     } // in_ns2
587                   } // b
588                 } // anon
589               } // a
590             } // in_ns
591           } // ns
592           void foo() {
593             ns::a::b::[[F^oo]] x;
594             (void)x;
595           }
596           )cpp",
597           [](HoverInfo &HI) {
598             HI.Name = "Foo";
599             HI.Kind = index::SymbolKind::Class;
600             HI.NamespaceScope = "ns::a::b::";
601             HI.Definition = "class Foo {}";
602           }},
603       {
604           R"cpp(
605           template <typename T> class Foo {};
606           class X;
607           void foo() {
608             [[^auto]] x = Foo<X>();
609           }
610           )cpp",
611           [](HoverInfo &HI) {
612             HI.Name = "auto";
613             HI.Kind = index::SymbolKind::TypeAlias;
614             HI.Definition = "class Foo<X>";
615           }},
616       {// Falls back to primary template, when the type is not instantiated.
617        R"cpp(
618           // comment from primary
619           template <typename T> class Foo {};
620           // comment from specialization
621           template <typename T> class Foo<T*> {};
622           void foo() {
623             [[Fo^o]]<int*> *x = nullptr;
624           }
625           )cpp",
626        [](HoverInfo &HI) {
627          HI.Name = "Foo<int *>";
628          HI.Kind = index::SymbolKind::Class;
629          HI.NamespaceScope = "";
630          HI.Definition = "template <> class Foo<int *>";
631          // FIXME: Maybe force instantiation to make use of real template
632          // pattern.
633          HI.Documentation = "comment from primary";
634        }},
635       {// Template Type Parameter
636        R"cpp(
637           template <typename [[^T]] = int> void foo();
638           )cpp",
639        [](HoverInfo &HI) {
640          HI.Name = "T";
641          HI.Kind = index::SymbolKind::TemplateTypeParm;
642          HI.NamespaceScope = "";
643          HI.Definition = "typename T = int";
644          HI.LocalScope = "foo::";
645          HI.Type = "typename";
646          HI.AccessSpecifier = "public";
647        }},
648       {// TemplateTemplate Type Parameter
649        R"cpp(
650           template <template<typename> class [[^T]]> void foo();
651           )cpp",
652        [](HoverInfo &HI) {
653          HI.Name = "T";
654          HI.Kind = index::SymbolKind::TemplateTemplateParm;
655          HI.NamespaceScope = "";
656          HI.Definition = "template <typename> class T";
657          HI.LocalScope = "foo::";
658          HI.Type = "template <typename> class";
659          HI.AccessSpecifier = "public";
660        }},
661       {// NonType Template Parameter
662        R"cpp(
663           template <int [[^T]] = 5> void foo();
664           )cpp",
665        [](HoverInfo &HI) {
666          HI.Name = "T";
667          HI.Kind = index::SymbolKind::NonTypeTemplateParm;
668          HI.NamespaceScope = "";
669          HI.Definition = "int T = 5";
670          HI.LocalScope = "foo::";
671          HI.Type = "int";
672          HI.AccessSpecifier = "public";
673        }},
674 
675       {// Getter
676        R"cpp(
677           struct X { int Y; float [[^y]]() { return Y; } };
678           )cpp",
679        [](HoverInfo &HI) {
680          HI.Name = "y";
681          HI.Kind = index::SymbolKind::InstanceMethod;
682          HI.NamespaceScope = "";
683          HI.Definition = "float y()";
684          HI.LocalScope = "X::";
685          HI.Documentation = "Trivial accessor for `Y`.";
686          HI.Type = "float ()";
687          HI.ReturnType = "float";
688          HI.Parameters.emplace();
689          HI.AccessSpecifier = "public";
690        }},
691       {// Setter
692        R"cpp(
693           struct X { int Y; void [[^setY]](float v) { Y = v; } };
694           )cpp",
695        [](HoverInfo &HI) {
696          HI.Name = "setY";
697          HI.Kind = index::SymbolKind::InstanceMethod;
698          HI.NamespaceScope = "";
699          HI.Definition = "void setY(float v)";
700          HI.LocalScope = "X::";
701          HI.Documentation = "Trivial setter for `Y`.";
702          HI.Type = "void (float)";
703          HI.ReturnType = "void";
704          HI.Parameters.emplace();
705          HI.Parameters->emplace_back();
706          HI.Parameters->back().Type = "float";
707          HI.Parameters->back().Name = "v";
708          HI.AccessSpecifier = "public";
709        }},
710       {// Setter (builder)
711        R"cpp(
712           struct X { int Y; X& [[^setY]](float v) { Y = v; return *this; } };
713           )cpp",
714        [](HoverInfo &HI) {
715          HI.Name = "setY";
716          HI.Kind = index::SymbolKind::InstanceMethod;
717          HI.NamespaceScope = "";
718          HI.Definition = "X &setY(float v)";
719          HI.LocalScope = "X::";
720          HI.Documentation = "Trivial setter for `Y`.";
721          HI.Type = "X &(float)";
722          HI.ReturnType = "X &";
723          HI.Parameters.emplace();
724          HI.Parameters->emplace_back();
725          HI.Parameters->back().Type = "float";
726          HI.Parameters->back().Name = "v";
727          HI.AccessSpecifier = "public";
728        }},
729       {// Setter (move)
730        R"cpp(
731           namespace std { template<typename T> T&& move(T&& t); }
732           struct X { int Y; void [[^setY]](float v) { Y = std::move(v); } };
733           )cpp",
734        [](HoverInfo &HI) {
735          HI.Name = "setY";
736          HI.Kind = index::SymbolKind::InstanceMethod;
737          HI.NamespaceScope = "";
738          HI.Definition = "void setY(float v)";
739          HI.LocalScope = "X::";
740          HI.Documentation = "Trivial setter for `Y`.";
741          HI.Type = "void (float)";
742          HI.ReturnType = "void";
743          HI.Parameters.emplace();
744          HI.Parameters->emplace_back();
745          HI.Parameters->back().Type = "float";
746          HI.Parameters->back().Name = "v";
747          HI.AccessSpecifier = "public";
748        }},
749       {// Field type initializer.
750        R"cpp(
751           struct X { int x = 2; };
752           X ^[[x]];
753           )cpp",
754        [](HoverInfo &HI) {
755          HI.Name = "x";
756          HI.Kind = index::SymbolKind::Variable;
757          HI.NamespaceScope = "";
758          HI.Definition = "X x";
759          HI.Type = "struct X";
760        }},
761       {// Don't crash on null types.
762        R"cpp(auto [^[[x]]] = 1; /*error-ok*/)cpp",
763        [](HoverInfo &HI) {
764          HI.Name = "x";
765          HI.Kind = index::SymbolKind::Variable;
766          HI.NamespaceScope = "";
767          HI.Definition = "";
768          HI.Type = "NULL TYPE";
769          // Bindings are in theory public members of an anonymous struct.
770          HI.AccessSpecifier = "public";
771        }},
772       {// Extra info for function call.
773        R"cpp(
774           void fun(int arg_a, int &arg_b) {};
775           void code() {
776             int a = 1, b = 2;
777             fun(a, [[^b]]);
778           }
779           )cpp",
780        [](HoverInfo &HI) {
781          HI.Name = "b";
782          HI.Kind = index::SymbolKind::Variable;
783          HI.NamespaceScope = "";
784          HI.Definition = "int b = 2";
785          HI.LocalScope = "code::";
786          HI.Value = "2";
787          HI.Type = "int";
788          HI.CalleeArgInfo.emplace();
789          HI.CalleeArgInfo->Name = "arg_b";
790          HI.CalleeArgInfo->Type = "int &";
791          HI.CallPassType.emplace();
792          HI.CallPassType->PassBy = PassMode::Ref;
793          HI.CallPassType->Converted = false;
794        }},
795       {// Extra info for method call.
796        R"cpp(
797           class C {
798            public:
799             void fun(int arg_a = 3, int arg_b = 4) {}
800           };
801           void code() {
802             int a = 1, b = 2;
803             C c;
804             c.fun([[^a]], b);
805           }
806           )cpp",
807        [](HoverInfo &HI) {
808          HI.Name = "a";
809          HI.Kind = index::SymbolKind::Variable;
810          HI.NamespaceScope = "";
811          HI.Definition = "int a = 1";
812          HI.LocalScope = "code::";
813          HI.Value = "1";
814          HI.Type = "int";
815          HI.CalleeArgInfo.emplace();
816          HI.CalleeArgInfo->Name = "arg_a";
817          HI.CalleeArgInfo->Type = "int";
818          HI.CalleeArgInfo->Default = "3";
819          HI.CallPassType.emplace();
820          HI.CallPassType->PassBy = PassMode::Value;
821          HI.CallPassType->Converted = false;
822        }},
823       {// Dont crash on invalid decl
824        R"cpp(
825         // error-ok
826         struct Foo {
827           Bar [[x^x]];
828         };)cpp",
829        [](HoverInfo &HI) {
830          HI.Name = "xx";
831          HI.Kind = index::SymbolKind::Field;
832          HI.NamespaceScope = "";
833          HI.Definition = "int xx";
834          HI.LocalScope = "Foo::";
835          HI.Type = "int";
836          HI.AccessSpecifier = "public";
837        }},
838       {R"cpp(
839         // error-ok
840         struct Foo {
841           Bar xx;
842           int [[y^y]];
843         };)cpp",
844        [](HoverInfo &HI) {
845          HI.Name = "yy";
846          HI.Kind = index::SymbolKind::Field;
847          HI.NamespaceScope = "";
848          HI.Definition = "int yy";
849          HI.LocalScope = "Foo::";
850          HI.Type = "int";
851          HI.AccessSpecifier = "public";
852        }},
853       {// No crash on InitListExpr.
854        R"cpp(
855           struct Foo {
856             int a[10];
857           };
858           constexpr Foo k2 = {
859             ^[[{]]1} // FIXME: why the hover range is 1 character?
860           };
861          )cpp",
862        [](HoverInfo &HI) {
863          HI.Name = "expression";
864          HI.Kind = index::SymbolKind::Unknown;
865          HI.Type = "int [10]";
866          HI.Value = "{1}";
867        }}};
868   for (const auto &Case : Cases) {
869     SCOPED_TRACE(Case.Code);
870 
871     Annotations T(Case.Code);
872     TestTU TU = TestTU::withCode(T.code());
873     TU.ExtraArgs.push_back("-std=c++17");
874     // Types might be different depending on the target triplet, we chose a
875     // fixed one to make sure tests passes on different platform.
876     TU.ExtraArgs.push_back("--target=x86_64-pc-linux-gnu");
877     auto AST = TU.build();
878 
879     auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
880     ASSERT_TRUE(H);
881     HoverInfo Expected;
882     Expected.SymRange = T.range();
883     Case.ExpectedBuilder(Expected);
884 
885     EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
886     EXPECT_EQ(H->LocalScope, Expected.LocalScope);
887     EXPECT_EQ(H->Name, Expected.Name);
888     EXPECT_EQ(H->Kind, Expected.Kind);
889     EXPECT_EQ(H->Documentation, Expected.Documentation);
890     EXPECT_EQ(H->Definition, Expected.Definition);
891     EXPECT_EQ(H->Type, Expected.Type);
892     EXPECT_EQ(H->ReturnType, Expected.ReturnType);
893     EXPECT_EQ(H->Parameters, Expected.Parameters);
894     EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
895     EXPECT_EQ(H->SymRange, Expected.SymRange);
896     EXPECT_EQ(H->Value, Expected.Value);
897     EXPECT_EQ(H->Size, Expected.Size);
898     EXPECT_EQ(H->Offset, Expected.Offset);
899     EXPECT_EQ(H->AccessSpecifier, Expected.AccessSpecifier);
900     EXPECT_EQ(H->CalleeArgInfo, Expected.CalleeArgInfo);
901     EXPECT_EQ(H->CallPassType, Expected.CallPassType);
902   }
903 }
904 
TEST(Hover,CallPassType)905 TEST(Hover, CallPassType) {
906   const llvm::StringRef CodePrefix = R"cpp(
907 class Base {};
908 class Derived : public Base {};
909 class CustomClass {
910  public:
911   CustomClass() {}
912   CustomClass(const Base &x) {}
913   CustomClass(int &x) {}
914   CustomClass(float x) {}
915 };
916 
917 void int_by_ref(int &x) {}
918 void int_by_const_ref(const int &x) {}
919 void int_by_value(int x) {}
920 void base_by_ref(Base &x) {}
921 void base_by_const_ref(const Base &x) {}
922 void base_by_value(Base x) {}
923 void float_by_value(float x) {}
924 void custom_by_value(CustomClass x) {}
925 
926 void fun() {
927   int int_x;
928   int &int_ref = int_x;
929   const int &int_const_ref = int_x;
930   Base base;
931   const Base &base_const_ref = base;
932   Derived derived;
933   float float_x;
934 )cpp";
935   const llvm::StringRef CodeSuffix = "}";
936 
937   struct {
938     const char *const Code;
939     HoverInfo::PassType::PassMode PassBy;
940     bool Converted;
941   } Tests[] = {
942       // Integer tests
943       {"int_by_value([[^int_x]]);", PassMode::Value, false},
944       {"int_by_ref([[^int_x]]);", PassMode::Ref, false},
945       {"int_by_const_ref([[^int_x]]);", PassMode::ConstRef, false},
946       {"int_by_value([[^int_ref]]);", PassMode::Value, false},
947       {"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef, false},
948       {"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef, false},
949       {"int_by_const_ref([[^int_const_ref]]);", PassMode::ConstRef, false},
950       // Custom class tests
951       {"base_by_ref([[^base]]);", PassMode::Ref, false},
952       {"base_by_const_ref([[^base]]);", PassMode::ConstRef, false},
953       {"base_by_const_ref([[^base_const_ref]]);", PassMode::ConstRef, false},
954       {"base_by_value([[^base]]);", PassMode::Value, false},
955       {"base_by_value([[^base_const_ref]]);", PassMode::Value, false},
956       {"base_by_ref([[^derived]]);", PassMode::Ref, false},
957       {"base_by_const_ref([[^derived]]);", PassMode::ConstRef, false},
958       {"base_by_value([[^derived]]);", PassMode::Value, false},
959       // Converted tests
960       {"float_by_value([[^int_x]]);", PassMode::Value, true},
961       {"float_by_value([[^int_ref]]);", PassMode::Value, true},
962       {"float_by_value([[^int_const_ref]]);", PassMode::Value, true},
963       {"custom_by_value([[^int_x]]);", PassMode::Ref, true},
964       {"custom_by_value([[^float_x]]);", PassMode::Value, true},
965       {"custom_by_value([[^base]]);", PassMode::ConstRef, true},
966   };
967   for (const auto &Test : Tests) {
968     SCOPED_TRACE(Test.Code);
969 
970     const auto Code = (CodePrefix + Test.Code + CodeSuffix).str();
971     Annotations T(Code);
972     TestTU TU = TestTU::withCode(T.code());
973     TU.ExtraArgs.push_back("-std=c++17");
974     auto AST = TU.build();
975     auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
976     ASSERT_TRUE(H);
977     EXPECT_EQ(H->CallPassType->PassBy, Test.PassBy);
978     EXPECT_EQ(H->CallPassType->Converted, Test.Converted);
979   }
980 }
981 
TEST(Hover,NoHover)982 TEST(Hover, NoHover) {
983   llvm::StringRef Tests[] = {
984       "^int main() {}",
985       "void foo() {^}",
986       // FIXME: "decltype(auto)" should be a single hover
987       "decltype(au^to) x = 0;",
988       // FIXME: not supported yet
989       R"cpp(// Lambda auto parameter
990             auto lamb = [](a^uto){};
991           )cpp",
992       R"cpp(// non-named decls don't get hover. Don't crash!
993             ^static_assert(1, "");
994           )cpp",
995       R"cpp(// non-evaluatable expr
996           template <typename T> void foo() {
997             (void)[[size^of]](T);
998           })cpp",
999       R"cpp(// should not crash on invalid semantic form of init-list-expr.
1000             /*error-ok*/
1001             struct Foo {
1002               int xyz = 0;
1003             };
1004             class Bar {};
1005             constexpr Foo s = ^{
1006               .xyz = Bar(),
1007             };
1008           )cpp",
1009       // literals
1010       "auto x = t^rue;",
1011       "auto x = '^A';",
1012       "auto x = ^(int){42};",
1013       "auto x = ^42.;",
1014       "auto x = ^42.0i;",
1015       "auto x = ^42;",
1016       "auto x = ^nullptr;",
1017       "auto x = ^\"asdf\";",
1018   };
1019 
1020   for (const auto &Test : Tests) {
1021     SCOPED_TRACE(Test);
1022 
1023     Annotations T(Test);
1024     TestTU TU = TestTU::withCode(T.code());
1025     TU.ExtraArgs.push_back("-std=c++17");
1026     auto AST = TU.build();
1027     auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
1028     ASSERT_FALSE(H);
1029   }
1030 }
1031 
TEST(Hover,All)1032 TEST(Hover, All) {
1033   struct {
1034     const char *const Code;
1035     const std::function<void(HoverInfo &)> ExpectedBuilder;
1036   } Cases[] = {
1037       {
1038           R"cpp(// Local variable
1039             int main() {
1040               int bonjour;
1041               ^[[bonjour]] = 2;
1042               int test1 = bonjour;
1043             }
1044           )cpp",
1045           [](HoverInfo &HI) {
1046             HI.Name = "bonjour";
1047             HI.Kind = index::SymbolKind::Variable;
1048             HI.NamespaceScope = "";
1049             HI.LocalScope = "main::";
1050             HI.Type = "int";
1051             HI.Definition = "int bonjour";
1052           }},
1053       {
1054           R"cpp(// Local variable in method
1055             struct s {
1056               void method() {
1057                 int bonjour;
1058                 ^[[bonjour]] = 2;
1059               }
1060             };
1061           )cpp",
1062           [](HoverInfo &HI) {
1063             HI.Name = "bonjour";
1064             HI.Kind = index::SymbolKind::Variable;
1065             HI.NamespaceScope = "";
1066             HI.LocalScope = "s::method::";
1067             HI.Type = "int";
1068             HI.Definition = "int bonjour";
1069           }},
1070       {
1071           R"cpp(// Struct
1072             namespace ns1 {
1073               struct MyClass {};
1074             } // namespace ns1
1075             int main() {
1076               ns1::[[My^Class]]* Params;
1077             }
1078           )cpp",
1079           [](HoverInfo &HI) {
1080             HI.Name = "MyClass";
1081             HI.Kind = index::SymbolKind::Struct;
1082             HI.NamespaceScope = "ns1::";
1083             HI.Definition = "struct MyClass {}";
1084           }},
1085       {
1086           R"cpp(// Class
1087             namespace ns1 {
1088               class MyClass {};
1089             } // namespace ns1
1090             int main() {
1091               ns1::[[My^Class]]* Params;
1092             }
1093           )cpp",
1094           [](HoverInfo &HI) {
1095             HI.Name = "MyClass";
1096             HI.Kind = index::SymbolKind::Class;
1097             HI.NamespaceScope = "ns1::";
1098             HI.Definition = "class MyClass {}";
1099           }},
1100       {
1101           R"cpp(// Union
1102             namespace ns1 {
1103               union MyUnion { int x; int y; };
1104             } // namespace ns1
1105             int main() {
1106               ns1::[[My^Union]] Params;
1107             }
1108           )cpp",
1109           [](HoverInfo &HI) {
1110             HI.Name = "MyUnion";
1111             HI.Kind = index::SymbolKind::Union;
1112             HI.NamespaceScope = "ns1::";
1113             HI.Definition = "union MyUnion {}";
1114           }},
1115       {
1116           R"cpp(// Function definition via pointer
1117             void foo(int) {}
1118             int main() {
1119               auto *X = &^[[foo]];
1120             }
1121           )cpp",
1122           [](HoverInfo &HI) {
1123             HI.Name = "foo";
1124             HI.Kind = index::SymbolKind::Function;
1125             HI.NamespaceScope = "";
1126             HI.Type = "void (int)";
1127             HI.Definition = "void foo(int)";
1128             HI.Documentation = "Function definition via pointer";
1129             HI.ReturnType = "void";
1130             HI.Parameters = {
1131                 {std::string("int"), llvm::None, llvm::None},
1132             };
1133           }},
1134       {
1135           R"cpp(// Function declaration via call
1136             int foo(int);
1137             int main() {
1138               return ^[[foo]](42);
1139             }
1140           )cpp",
1141           [](HoverInfo &HI) {
1142             HI.Name = "foo";
1143             HI.Kind = index::SymbolKind::Function;
1144             HI.NamespaceScope = "";
1145             HI.Type = "int (int)";
1146             HI.Definition = "int foo(int)";
1147             HI.Documentation = "Function declaration via call";
1148             HI.ReturnType = "int";
1149             HI.Parameters = {
1150                 {std::string("int"), llvm::None, llvm::None},
1151             };
1152           }},
1153       {
1154           R"cpp(// Field
1155             struct Foo { int x; };
1156             int main() {
1157               Foo bar;
1158               (void)bar.^[[x]];
1159             }
1160           )cpp",
1161           [](HoverInfo &HI) {
1162             HI.Name = "x";
1163             HI.Kind = index::SymbolKind::Field;
1164             HI.NamespaceScope = "";
1165             HI.LocalScope = "Foo::";
1166             HI.Type = "int";
1167             HI.Definition = "int x";
1168           }},
1169       {
1170           R"cpp(// Field with initialization
1171             struct Foo { int x = 5; };
1172             int main() {
1173               Foo bar;
1174               (void)bar.^[[x]];
1175             }
1176           )cpp",
1177           [](HoverInfo &HI) {
1178             HI.Name = "x";
1179             HI.Kind = index::SymbolKind::Field;
1180             HI.NamespaceScope = "";
1181             HI.LocalScope = "Foo::";
1182             HI.Type = "int";
1183             HI.Definition = "int x = 5";
1184           }},
1185       {
1186           R"cpp(// Static field
1187             struct Foo { static int x; };
1188             int main() {
1189               (void)Foo::^[[x]];
1190             }
1191           )cpp",
1192           [](HoverInfo &HI) {
1193             HI.Name = "x";
1194             HI.Kind = index::SymbolKind::StaticProperty;
1195             HI.NamespaceScope = "";
1196             HI.LocalScope = "Foo::";
1197             HI.Type = "int";
1198             HI.Definition = "static int x";
1199           }},
1200       {
1201           R"cpp(// Field, member initializer
1202             struct Foo {
1203               int x;
1204               Foo() : ^[[x]](0) {}
1205             };
1206           )cpp",
1207           [](HoverInfo &HI) {
1208             HI.Name = "x";
1209             HI.Kind = index::SymbolKind::Field;
1210             HI.NamespaceScope = "";
1211             HI.LocalScope = "Foo::";
1212             HI.Type = "int";
1213             HI.Definition = "int x";
1214           }},
1215       {
1216           R"cpp(// Field, GNU old-style field designator
1217             struct Foo { int x; };
1218             int main() {
1219               Foo bar = { ^[[x]] : 1 };
1220             }
1221           )cpp",
1222           [](HoverInfo &HI) {
1223             HI.Name = "x";
1224             HI.Kind = index::SymbolKind::Field;
1225             HI.NamespaceScope = "";
1226             HI.LocalScope = "Foo::";
1227             HI.Type = "int";
1228             HI.Definition = "int x";
1229             // FIXME: Initializer for x is a DesignatedInitListExpr, hence it is
1230             // of struct type and omitted.
1231           }},
1232       {
1233           R"cpp(// Field, field designator
1234             struct Foo { int x; int y; };
1235             int main() {
1236               Foo bar = { .^[[x]] = 2, .y = 2 };
1237             }
1238           )cpp",
1239           [](HoverInfo &HI) {
1240             HI.Name = "x";
1241             HI.Kind = index::SymbolKind::Field;
1242             HI.NamespaceScope = "";
1243             HI.LocalScope = "Foo::";
1244             HI.Type = "int";
1245             HI.Definition = "int x";
1246           }},
1247       {
1248           R"cpp(// Method call
1249             struct Foo { int x(); };
1250             int main() {
1251               Foo bar;
1252               bar.^[[x]]();
1253             }
1254           )cpp",
1255           [](HoverInfo &HI) {
1256             HI.Name = "x";
1257             HI.Kind = index::SymbolKind::InstanceMethod;
1258             HI.NamespaceScope = "";
1259             HI.LocalScope = "Foo::";
1260             HI.Type = "int ()";
1261             HI.Definition = "int x()";
1262             HI.ReturnType = "int";
1263             HI.Parameters = std::vector<HoverInfo::Param>{};
1264           }},
1265       {
1266           R"cpp(// Static method call
1267             struct Foo { static int x(); };
1268             int main() {
1269               Foo::^[[x]]();
1270             }
1271           )cpp",
1272           [](HoverInfo &HI) {
1273             HI.Name = "x";
1274             HI.Kind = index::SymbolKind::StaticMethod;
1275             HI.NamespaceScope = "";
1276             HI.LocalScope = "Foo::";
1277             HI.Type = "int ()";
1278             HI.Definition = "static int x()";
1279             HI.ReturnType = "int";
1280             HI.Parameters = std::vector<HoverInfo::Param>{};
1281           }},
1282       {
1283           R"cpp(// Typedef
1284             typedef int Foo;
1285             int main() {
1286               ^[[Foo]] bar;
1287             }
1288           )cpp",
1289           [](HoverInfo &HI) {
1290             HI.Name = "Foo";
1291             HI.Kind = index::SymbolKind::TypeAlias;
1292             HI.NamespaceScope = "";
1293             HI.Definition = "typedef int Foo";
1294             HI.Documentation = "Typedef";
1295             // FIXME: Maybe put underlying type into HI.Type for aliases?
1296           }},
1297       {
1298           R"cpp(// Typedef with embedded definition
1299             typedef struct Bar {} Foo;
1300             int main() {
1301               ^[[Foo]] bar;
1302             }
1303           )cpp",
1304           [](HoverInfo &HI) {
1305             HI.Name = "Foo";
1306             HI.Kind = index::SymbolKind::TypeAlias;
1307             HI.NamespaceScope = "";
1308             HI.Definition = "typedef struct Bar Foo";
1309             HI.Documentation = "Typedef with embedded definition";
1310           }},
1311       {
1312           R"cpp(// Namespace
1313             namespace ns {
1314             struct Foo { static void bar(); };
1315             } // namespace ns
1316             int main() { ^[[ns]]::Foo::bar(); }
1317           )cpp",
1318           [](HoverInfo &HI) {
1319             HI.Name = "ns";
1320             HI.Kind = index::SymbolKind::Namespace;
1321             HI.NamespaceScope = "";
1322             HI.Definition = "namespace ns {}";
1323           }},
1324       {
1325           R"cpp(// Anonymous namespace
1326             namespace ns {
1327               namespace {
1328                 int foo;
1329               } // anonymous namespace
1330             } // namespace ns
1331             int main() { ns::[[f^oo]]++; }
1332           )cpp",
1333           [](HoverInfo &HI) {
1334             HI.Name = "foo";
1335             HI.Kind = index::SymbolKind::Variable;
1336             HI.NamespaceScope = "ns::";
1337             HI.Type = "int";
1338             HI.Definition = "int foo";
1339           }},
1340       {
1341           R"cpp(// Macro
1342             #define MACRO 0
1343             int main() { return ^[[MACRO]]; }
1344           )cpp",
1345           [](HoverInfo &HI) {
1346             HI.Name = "MACRO";
1347             HI.Kind = index::SymbolKind::Macro;
1348             HI.Definition = "#define MACRO 0";
1349           }},
1350       {
1351           R"cpp(// Macro
1352             #define MACRO 0
1353             #define MACRO2 ^[[MACRO]]
1354           )cpp",
1355           [](HoverInfo &HI) {
1356             HI.Name = "MACRO";
1357             HI.Kind = index::SymbolKind::Macro;
1358             HI.Definition = "#define MACRO 0";
1359           }},
1360       {
1361           R"cpp(// Macro
1362             #define MACRO {\
1363               return 0;\
1364             }
1365             int main() ^[[MACRO]]
1366           )cpp",
1367           [](HoverInfo &HI) {
1368             HI.Name = "MACRO";
1369             HI.Kind = index::SymbolKind::Macro;
1370             HI.Definition =
1371                 R"cpp(#define MACRO                                                                  \
1372   { return 0; })cpp";
1373           }},
1374       {
1375           R"cpp(// Forward class declaration
1376             class Foo;
1377             class Foo {};
1378             [[F^oo]]* foo();
1379           )cpp",
1380           [](HoverInfo &HI) {
1381             HI.Name = "Foo";
1382             HI.Kind = index::SymbolKind::Class;
1383             HI.NamespaceScope = "";
1384             HI.Definition = "class Foo {}";
1385             HI.Documentation = "Forward class declaration";
1386           }},
1387       {
1388           R"cpp(// Function declaration
1389             void foo();
1390             void g() { [[f^oo]](); }
1391             void foo() {}
1392           )cpp",
1393           [](HoverInfo &HI) {
1394             HI.Name = "foo";
1395             HI.Kind = index::SymbolKind::Function;
1396             HI.NamespaceScope = "";
1397             HI.Type = "void ()";
1398             HI.Definition = "void foo()";
1399             HI.Documentation = "Function declaration";
1400             HI.ReturnType = "void";
1401             HI.Parameters = std::vector<HoverInfo::Param>{};
1402           }},
1403       {
1404           R"cpp(// Enum declaration
1405             enum Hello {
1406               ONE, TWO, THREE,
1407             };
1408             void foo() {
1409               [[Hel^lo]] hello = ONE;
1410             }
1411           )cpp",
1412           [](HoverInfo &HI) {
1413             HI.Name = "Hello";
1414             HI.Kind = index::SymbolKind::Enum;
1415             HI.NamespaceScope = "";
1416             HI.Definition = "enum Hello {}";
1417             HI.Documentation = "Enum declaration";
1418           }},
1419       {
1420           R"cpp(// Enumerator
1421             enum Hello {
1422               ONE, TWO, THREE,
1423             };
1424             void foo() {
1425               Hello hello = [[O^NE]];
1426             }
1427           )cpp",
1428           [](HoverInfo &HI) {
1429             HI.Name = "ONE";
1430             HI.Kind = index::SymbolKind::EnumConstant;
1431             HI.NamespaceScope = "";
1432             HI.LocalScope = "Hello::";
1433             HI.Type = "enum Hello";
1434             HI.Definition = "ONE";
1435             HI.Value = "0";
1436           }},
1437       {
1438           R"cpp(// Enumerator in anonymous enum
1439             enum {
1440               ONE, TWO, THREE,
1441             };
1442             void foo() {
1443               int hello = [[O^NE]];
1444             }
1445           )cpp",
1446           [](HoverInfo &HI) {
1447             HI.Name = "ONE";
1448             HI.Kind = index::SymbolKind::EnumConstant;
1449             HI.NamespaceScope = "";
1450             // FIXME: This should be `(anon enum)::`
1451             HI.LocalScope = "";
1452             HI.Type = "enum (anonymous)";
1453             HI.Definition = "ONE";
1454             HI.Value = "0";
1455           }},
1456       {
1457           R"cpp(// Global variable
1458             static int hey = 10;
1459             void foo() {
1460               [[he^y]]++;
1461             }
1462           )cpp",
1463           [](HoverInfo &HI) {
1464             HI.Name = "hey";
1465             HI.Kind = index::SymbolKind::Variable;
1466             HI.NamespaceScope = "";
1467             HI.Type = "int";
1468             HI.Definition = "static int hey = 10";
1469             HI.Documentation = "Global variable";
1470             // FIXME: Value shouldn't be set in this case
1471             HI.Value = "10";
1472           }},
1473       {
1474           R"cpp(// Global variable in namespace
1475             namespace ns1 {
1476               static int hey = 10;
1477             }
1478             void foo() {
1479               ns1::[[he^y]]++;
1480             }
1481           )cpp",
1482           [](HoverInfo &HI) {
1483             HI.Name = "hey";
1484             HI.Kind = index::SymbolKind::Variable;
1485             HI.NamespaceScope = "ns1::";
1486             HI.Type = "int";
1487             HI.Definition = "static int hey = 10";
1488             HI.Value = "10";
1489           }},
1490       {
1491           R"cpp(// Field in anonymous struct
1492             static struct {
1493               int hello;
1494             } s;
1495             void foo() {
1496               s.[[he^llo]]++;
1497             }
1498           )cpp",
1499           [](HoverInfo &HI) {
1500             HI.Name = "hello";
1501             HI.Kind = index::SymbolKind::Field;
1502             HI.NamespaceScope = "";
1503             HI.LocalScope = "(anonymous struct)::";
1504             HI.Type = "int";
1505             HI.Definition = "int hello";
1506           }},
1507       {
1508           R"cpp(// Templated function
1509             template <typename T>
1510             T foo() {
1511               return 17;
1512             }
1513             void g() { auto x = [[f^oo]]<int>(); }
1514           )cpp",
1515           [](HoverInfo &HI) {
1516             HI.Name = "foo";
1517             HI.Kind = index::SymbolKind::Function;
1518             HI.NamespaceScope = "";
1519             HI.Type = "int ()";
1520             HI.Definition = "template <> int foo<int>()";
1521             HI.Documentation = "Templated function";
1522             HI.ReturnType = "int";
1523             HI.Parameters = std::vector<HoverInfo::Param>{};
1524             // FIXME: We should populate template parameters with arguments in
1525             // case of instantiations.
1526           }},
1527       {
1528           R"cpp(// Anonymous union
1529             struct outer {
1530               union {
1531                 int abc, def;
1532               } v;
1533             };
1534             void g() { struct outer o; o.v.[[d^ef]]++; }
1535           )cpp",
1536           [](HoverInfo &HI) {
1537             HI.Name = "def";
1538             HI.Kind = index::SymbolKind::Field;
1539             HI.NamespaceScope = "";
1540             HI.LocalScope = "outer::(anonymous union)::";
1541             HI.Type = "int";
1542             HI.Definition = "int def";
1543           }},
1544       {
1545           R"cpp(// documentation from index
1546             int nextSymbolIsAForwardDeclFromIndexWithNoLocalDocs;
1547             void indexSymbol();
1548             void g() { [[ind^exSymbol]](); }
1549           )cpp",
1550           [](HoverInfo &HI) {
1551             HI.Name = "indexSymbol";
1552             HI.Kind = index::SymbolKind::Function;
1553             HI.NamespaceScope = "";
1554             HI.Type = "void ()";
1555             HI.Definition = "void indexSymbol()";
1556             HI.ReturnType = "void";
1557             HI.Parameters = std::vector<HoverInfo::Param>{};
1558             HI.Documentation = "comment from index";
1559           }},
1560       {
1561           R"cpp(// Simple initialization with auto
1562             void foo() {
1563               ^[[auto]] i = 1;
1564             }
1565           )cpp",
1566           [](HoverInfo &HI) {
1567             HI.Name = "auto";
1568             HI.Kind = index::SymbolKind::TypeAlias;
1569             HI.Definition = "int";
1570           }},
1571       {
1572           R"cpp(// Simple initialization with const auto
1573             void foo() {
1574               const ^[[auto]] i = 1;
1575             }
1576           )cpp",
1577           [](HoverInfo &HI) {
1578             HI.Name = "auto";
1579             HI.Kind = index::SymbolKind::TypeAlias;
1580             HI.Definition = "int";
1581           }},
1582       {
1583           R"cpp(// Simple initialization with const auto&
1584             void foo() {
1585               const ^[[auto]]& i = 1;
1586             }
1587           )cpp",
1588           [](HoverInfo &HI) {
1589             HI.Name = "auto";
1590             HI.Kind = index::SymbolKind::TypeAlias;
1591             HI.Definition = "int";
1592           }},
1593       {
1594           R"cpp(// Simple initialization with auto&
1595             void foo() {
1596               int x;
1597               ^[[auto]]& i = x;
1598             }
1599           )cpp",
1600           [](HoverInfo &HI) {
1601             HI.Name = "auto";
1602             HI.Kind = index::SymbolKind::TypeAlias;
1603             HI.Definition = "int";
1604           }},
1605       {
1606           R"cpp(// Simple initialization with auto*
1607             void foo() {
1608               int a = 1;
1609               ^[[auto]]* i = &a;
1610             }
1611           )cpp",
1612           [](HoverInfo &HI) {
1613             HI.Name = "auto";
1614             HI.Kind = index::SymbolKind::TypeAlias;
1615             HI.Definition = "int";
1616           }},
1617       {
1618           R"cpp(// Simple initialization with auto from pointer
1619             void foo() {
1620               int a = 1;
1621               ^[[auto]] i = &a;
1622             }
1623           )cpp",
1624           [](HoverInfo &HI) {
1625             HI.Name = "auto";
1626             HI.Kind = index::SymbolKind::TypeAlias;
1627             HI.Definition = "int *";
1628           }},
1629       {
1630           R"cpp(// Auto with initializer list.
1631             namespace std
1632             {
1633               template<class _E>
1634               class initializer_list {};
1635             }
1636             void foo() {
1637               ^[[auto]] i = {1,2};
1638             }
1639           )cpp",
1640           [](HoverInfo &HI) {
1641             HI.Name = "auto";
1642             HI.Kind = index::SymbolKind::TypeAlias;
1643             HI.Definition = "class std::initializer_list<int>";
1644           }},
1645       {
1646           R"cpp(// User defined conversion to auto
1647             struct Bar {
1648               operator ^[[auto]]() const { return 10; }
1649             };
1650           )cpp",
1651           [](HoverInfo &HI) {
1652             HI.Name = "auto";
1653             HI.Kind = index::SymbolKind::TypeAlias;
1654             HI.Definition = "int";
1655           }},
1656       {
1657           R"cpp(// Simple initialization with decltype(auto)
1658             void foo() {
1659               ^[[decltype]](auto) i = 1;
1660             }
1661           )cpp",
1662           [](HoverInfo &HI) {
1663             HI.Name = "decltype";
1664             HI.Kind = index::SymbolKind::TypeAlias;
1665             HI.Definition = "int";
1666           }},
1667       {
1668           R"cpp(// Simple initialization with const decltype(auto)
1669             void foo() {
1670               const int j = 0;
1671               ^[[decltype]](auto) i = j;
1672             }
1673           )cpp",
1674           [](HoverInfo &HI) {
1675             HI.Name = "decltype";
1676             HI.Kind = index::SymbolKind::TypeAlias;
1677             HI.Definition = "const int";
1678           }},
1679       {
1680           R"cpp(// Simple initialization with const& decltype(auto)
1681             void foo() {
1682               int k = 0;
1683               const int& j = k;
1684               ^[[decltype]](auto) i = j;
1685             }
1686           )cpp",
1687           [](HoverInfo &HI) {
1688             HI.Name = "decltype";
1689             HI.Kind = index::SymbolKind::TypeAlias;
1690             HI.Definition = "const int &";
1691           }},
1692       {
1693           R"cpp(// Simple initialization with & decltype(auto)
1694             void foo() {
1695               int k = 0;
1696               int& j = k;
1697               ^[[decltype]](auto) i = j;
1698             }
1699           )cpp",
1700           [](HoverInfo &HI) {
1701             HI.Name = "decltype";
1702             HI.Kind = index::SymbolKind::TypeAlias;
1703             HI.Definition = "int &";
1704           }},
1705       {
1706           R"cpp(// simple trailing return type
1707             ^[[auto]] main() -> int {
1708               return 0;
1709             }
1710           )cpp",
1711           [](HoverInfo &HI) {
1712             HI.Name = "auto";
1713             HI.Kind = index::SymbolKind::TypeAlias;
1714             HI.Definition = "int";
1715           }},
1716       {
1717           R"cpp(// auto function return with trailing type
1718             struct Bar {};
1719             ^[[auto]] test() -> decltype(Bar()) {
1720               return Bar();
1721             }
1722           )cpp",
1723           [](HoverInfo &HI) {
1724             HI.Name = "auto";
1725             HI.Kind = index::SymbolKind::TypeAlias;
1726             HI.Definition = "struct Bar";
1727             HI.Documentation = "auto function return with trailing type";
1728           }},
1729       {
1730           R"cpp(// trailing return type
1731             struct Bar {};
1732             auto test() -> ^[[decltype]](Bar()) {
1733               return Bar();
1734             }
1735           )cpp",
1736           [](HoverInfo &HI) {
1737             HI.Name = "decltype";
1738             HI.Kind = index::SymbolKind::TypeAlias;
1739             HI.Definition = "struct Bar";
1740             HI.Documentation = "trailing return type";
1741           }},
1742       {
1743           R"cpp(// auto in function return
1744             struct Bar {};
1745             ^[[auto]] test() {
1746               return Bar();
1747             }
1748           )cpp",
1749           [](HoverInfo &HI) {
1750             HI.Name = "auto";
1751             HI.Kind = index::SymbolKind::TypeAlias;
1752             HI.Definition = "struct Bar";
1753             HI.Documentation = "auto in function return";
1754           }},
1755       {
1756           R"cpp(// auto& in function return
1757             struct Bar {};
1758             ^[[auto]]& test() {
1759               static Bar x;
1760               return x;
1761             }
1762           )cpp",
1763           [](HoverInfo &HI) {
1764             HI.Name = "auto";
1765             HI.Kind = index::SymbolKind::TypeAlias;
1766             HI.Definition = "struct Bar";
1767             HI.Documentation = "auto& in function return";
1768           }},
1769       {
1770           R"cpp(// auto* in function return
1771             struct Bar {};
1772             ^[[auto]]* test() {
1773               Bar* bar;
1774               return bar;
1775             }
1776           )cpp",
1777           [](HoverInfo &HI) {
1778             HI.Name = "auto";
1779             HI.Kind = index::SymbolKind::TypeAlias;
1780             HI.Definition = "struct Bar";
1781             HI.Documentation = "auto* in function return";
1782           }},
1783       {
1784           R"cpp(// const auto& in function return
1785             struct Bar {};
1786             const ^[[auto]]& test() {
1787               static Bar x;
1788               return x;
1789             }
1790           )cpp",
1791           [](HoverInfo &HI) {
1792             HI.Name = "auto";
1793             HI.Kind = index::SymbolKind::TypeAlias;
1794             HI.Definition = "struct Bar";
1795             HI.Documentation = "const auto& in function return";
1796           }},
1797       {
1798           R"cpp(// decltype(auto) in function return
1799             struct Bar {};
1800             ^[[decltype]](auto) test() {
1801               return Bar();
1802             }
1803           )cpp",
1804           [](HoverInfo &HI) {
1805             HI.Name = "decltype";
1806             HI.Kind = index::SymbolKind::TypeAlias;
1807             HI.Definition = "struct Bar";
1808             HI.Documentation = "decltype(auto) in function return";
1809           }},
1810       {
1811           R"cpp(// decltype(auto) reference in function return
1812             ^[[decltype]](auto) test() {
1813               static int a;
1814               return (a);
1815             }
1816           )cpp",
1817           [](HoverInfo &HI) {
1818             HI.Name = "decltype";
1819             HI.Kind = index::SymbolKind::TypeAlias;
1820             HI.Definition = "int &";
1821           }},
1822       {
1823           R"cpp(// decltype lvalue reference
1824             void foo() {
1825               int I = 0;
1826               ^[[decltype]](I) J = I;
1827             }
1828           )cpp",
1829           [](HoverInfo &HI) {
1830             HI.Name = "decltype";
1831             HI.Kind = index::SymbolKind::TypeAlias;
1832             HI.Definition = "int";
1833           }},
1834       {
1835           R"cpp(// decltype lvalue reference
1836             void foo() {
1837               int I= 0;
1838               int &K = I;
1839               ^[[decltype]](K) J = I;
1840             }
1841           )cpp",
1842           [](HoverInfo &HI) {
1843             HI.Name = "decltype";
1844             HI.Kind = index::SymbolKind::TypeAlias;
1845             HI.Definition = "int &";
1846           }},
1847       {
1848           R"cpp(// decltype lvalue reference parenthesis
1849             void foo() {
1850               int I = 0;
1851               ^[[decltype]]((I)) J = I;
1852             }
1853           )cpp",
1854           [](HoverInfo &HI) {
1855             HI.Name = "decltype";
1856             HI.Kind = index::SymbolKind::TypeAlias;
1857             HI.Definition = "int &";
1858           }},
1859       {
1860           R"cpp(// decltype rvalue reference
1861             void foo() {
1862               int I = 0;
1863               ^[[decltype]](static_cast<int&&>(I)) J = static_cast<int&&>(I);
1864             }
1865           )cpp",
1866           [](HoverInfo &HI) {
1867             HI.Name = "decltype";
1868             HI.Kind = index::SymbolKind::TypeAlias;
1869             HI.Definition = "int &&";
1870           }},
1871       {
1872           R"cpp(// decltype rvalue reference function call
1873             int && bar();
1874             void foo() {
1875               int I = 0;
1876               ^[[decltype]](bar()) J = bar();
1877             }
1878           )cpp",
1879           [](HoverInfo &HI) {
1880             HI.Name = "decltype";
1881             HI.Kind = index::SymbolKind::TypeAlias;
1882             HI.Definition = "int &&";
1883           }},
1884       {
1885           R"cpp(// decltype of function with trailing return type.
1886             struct Bar {};
1887             auto test() -> decltype(Bar()) {
1888               return Bar();
1889             }
1890             void foo() {
1891               ^[[decltype]](test()) i = test();
1892             }
1893           )cpp",
1894           [](HoverInfo &HI) {
1895             HI.Name = "decltype";
1896             HI.Kind = index::SymbolKind::TypeAlias;
1897             HI.Definition = "struct Bar";
1898             HI.Documentation =
1899                 "decltype of function with trailing return type.";
1900           }},
1901       {
1902           R"cpp(// decltype of var with decltype.
1903             void foo() {
1904               int I = 0;
1905               decltype(I) J = I;
1906               ^[[decltype]](J) K = J;
1907             }
1908           )cpp",
1909           [](HoverInfo &HI) {
1910             HI.Name = "decltype";
1911             HI.Kind = index::SymbolKind::TypeAlias;
1912             HI.Definition = "int";
1913           }},
1914       {
1915           R"cpp(// decltype of dependent type
1916             template <typename T>
1917             struct X {
1918               using Y = ^[[decltype]](T::Z);
1919             };
1920           )cpp",
1921           [](HoverInfo &HI) {
1922             HI.Name = "decltype";
1923             HI.Kind = index::SymbolKind::TypeAlias;
1924             HI.Definition = "<dependent type>";
1925           }},
1926       {
1927           R"cpp(// More complicated structured types.
1928             int bar();
1929             ^[[auto]] (*foo)() = bar;
1930           )cpp",
1931           [](HoverInfo &HI) {
1932             HI.Name = "auto";
1933             HI.Kind = index::SymbolKind::TypeAlias;
1934             HI.Definition = "int";
1935           }},
1936       {
1937           R"cpp(// Should not crash when evaluating the initializer.
1938             struct Test {};
1939             void test() { Test && [[te^st]] = {}; }
1940           )cpp",
1941           [](HoverInfo &HI) {
1942             HI.Name = "test";
1943             HI.Kind = index::SymbolKind::Variable;
1944             HI.NamespaceScope = "";
1945             HI.LocalScope = "test::";
1946             HI.Type = "Test &&";
1947             HI.Definition = "Test &&test = {}";
1948           }},
1949       {
1950           R"cpp(// auto on alias
1951           typedef int int_type;
1952           ^[[auto]] x = int_type();
1953           )cpp",
1954           [](HoverInfo &HI) {
1955             HI.Name = "auto";
1956             HI.Kind = index::SymbolKind::TypeAlias;
1957             HI.Definition = "int";
1958           }},
1959       {
1960           R"cpp(// auto on alias
1961           struct cls {};
1962           typedef cls cls_type;
1963           ^[[auto]] y = cls_type();
1964           )cpp",
1965           [](HoverInfo &HI) {
1966             HI.Name = "auto";
1967             HI.Kind = index::SymbolKind::TypeAlias;
1968             HI.Definition = "struct cls";
1969             HI.Documentation = "auto on alias";
1970           }},
1971       {
1972           R"cpp(// auto on alias
1973           template <class>
1974           struct templ {};
1975           ^[[auto]] z = templ<int>();
1976           )cpp",
1977           [](HoverInfo &HI) {
1978             HI.Name = "auto";
1979             HI.Kind = index::SymbolKind::TypeAlias;
1980             HI.Definition = "struct templ<int>";
1981             HI.Documentation = "auto on alias";
1982           }},
1983       {
1984           R"cpp(// Undeduced auto declaration
1985             template<typename T>
1986             void foo() {
1987               ^[[auto]] x = T();
1988             }
1989           )cpp",
1990           [](HoverInfo &HI) {
1991             HI.Name = "auto";
1992             HI.Kind = index::SymbolKind::TypeAlias;
1993             HI.Definition = "/* not deduced */";
1994           }},
1995       {
1996           R"cpp(// Undeduced auto return type
1997             template<typename T>
1998             ^[[auto]] foo() {
1999               return T();
2000             }
2001           )cpp",
2002           [](HoverInfo &HI) {
2003             HI.Name = "auto";
2004             HI.Kind = index::SymbolKind::TypeAlias;
2005             HI.Definition = "/* not deduced */";
2006           }},
2007       {
2008           R"cpp(// Template auto parameter
2009             template<[[a^uto]] T>
2010               void func() {
2011             }
2012           )cpp",
2013           [](HoverInfo &HI) {
2014             // FIXME: not sure this is what we want, but this
2015             // is what we currently get with getDeducedType
2016             HI.Name = "auto";
2017             HI.Kind = index::SymbolKind::TypeAlias;
2018             HI.Definition = "/* not deduced */";
2019           }},
2020       {
2021           R"cpp(// Undeduced decltype(auto) return type
2022             template<typename T>
2023             ^[[decltype]](auto) foo() {
2024               return T();
2025             }
2026           )cpp",
2027           [](HoverInfo &HI) {
2028             HI.Name = "decltype";
2029             HI.Kind = index::SymbolKind::TypeAlias;
2030             HI.Definition = "/* not deduced */";
2031           }},
2032       {
2033           R"cpp(// should not crash.
2034           template <class T> struct cls {
2035             int method();
2036           };
2037 
2038           auto test = cls<int>().[[m^ethod]]();
2039           )cpp",
2040           [](HoverInfo &HI) {
2041             HI.Definition = "int method()";
2042             HI.Kind = index::SymbolKind::InstanceMethod;
2043             HI.NamespaceScope = "";
2044             HI.LocalScope = "cls<int>::";
2045             HI.Name = "method";
2046             HI.Parameters.emplace();
2047             HI.ReturnType = "int";
2048             HI.Type = "int ()";
2049           }},
2050       {
2051           R"cpp(// type of nested templates.
2052           template <class T> struct cls {};
2053           cls<cls<cls<int>>> [[fo^o]];
2054           )cpp",
2055           [](HoverInfo &HI) {
2056             HI.Definition = "cls<cls<cls<int>>> foo";
2057             HI.Kind = index::SymbolKind::Variable;
2058             HI.NamespaceScope = "";
2059             HI.Name = "foo";
2060             HI.Type = "cls<cls<cls<int>>>";
2061           }},
2062       {
2063           R"cpp(// type of nested templates.
2064           template <class T> struct cls {};
2065           [[cl^s]]<cls<cls<int>>> foo;
2066           )cpp",
2067           [](HoverInfo &HI) {
2068             HI.Definition = "template <> struct cls<cls<cls<int>>> {}";
2069             HI.Kind = index::SymbolKind::Struct;
2070             HI.NamespaceScope = "";
2071             HI.Name = "cls<cls<cls<int>>>";
2072             HI.Documentation = "type of nested templates.";
2073           }},
2074       {
2075           R"cpp(// type with decltype
2076           int a;
2077           decltype(a) [[b^]] = a;)cpp",
2078           [](HoverInfo &HI) {
2079             HI.Definition = "decltype(a) b = a";
2080             HI.Kind = index::SymbolKind::Variable;
2081             HI.NamespaceScope = "";
2082             HI.Name = "b";
2083             HI.Type = "int";
2084           }},
2085       {
2086           R"cpp(// type with decltype
2087           int a;
2088           decltype(a) c;
2089           decltype(c) [[b^]] = a;)cpp",
2090           [](HoverInfo &HI) {
2091             HI.Definition = "decltype(c) b = a";
2092             HI.Kind = index::SymbolKind::Variable;
2093             HI.NamespaceScope = "";
2094             HI.Name = "b";
2095             HI.Type = "int";
2096           }},
2097       {
2098           R"cpp(// type with decltype
2099           int a;
2100           const decltype(a) [[b^]] = a;)cpp",
2101           [](HoverInfo &HI) {
2102             HI.Definition = "const decltype(a) b = a";
2103             HI.Kind = index::SymbolKind::Variable;
2104             HI.NamespaceScope = "";
2105             HI.Name = "b";
2106             HI.Type = "int";
2107           }},
2108       {
2109           R"cpp(// type with decltype
2110           int a;
2111           auto [[f^oo]](decltype(a) x) -> decltype(a) { return 0; })cpp",
2112           [](HoverInfo &HI) {
2113             HI.Definition = "auto foo(decltype(a) x) -> decltype(a)";
2114             HI.Kind = index::SymbolKind::Function;
2115             HI.NamespaceScope = "";
2116             HI.Name = "foo";
2117             // FIXME: Handle composite types with decltype with a printing
2118             // policy.
2119             HI.Type = "auto (decltype(a)) -> decltype(a)";
2120             HI.ReturnType = "int";
2121             HI.Parameters = {
2122                 {std::string("int"), std::string("x"), llvm::None}};
2123           }},
2124       {
2125           R"cpp(// sizeof expr
2126           void foo() {
2127             (void)[[size^of]](char);
2128           })cpp",
2129           [](HoverInfo &HI) {
2130             HI.Name = "expression";
2131             HI.Type = "unsigned long";
2132             HI.Value = "1";
2133           }},
2134       {
2135           R"cpp(// alignof expr
2136           void foo() {
2137             (void)[[align^of]](char);
2138           })cpp",
2139           [](HoverInfo &HI) {
2140             HI.Name = "expression";
2141             HI.Type = "unsigned long";
2142             HI.Value = "1";
2143           }},
2144       {
2145           R"cpp(
2146           template <typename T = int>
2147           void foo(const T& = T()) {
2148             [[f^oo]]<>(3);
2149           })cpp",
2150           [](HoverInfo &HI) {
2151             HI.Name = "foo";
2152             HI.Kind = index::SymbolKind::Function;
2153             HI.Type = "void (const int &)";
2154             HI.ReturnType = "void";
2155             HI.Parameters = {
2156                 {std::string("const int &"), llvm::None, std::string("T()")}};
2157             HI.Definition = "template <> void foo<int>(const int &)";
2158             HI.NamespaceScope = "";
2159           }},
2160       {
2161           R"cpp(// should not crash
2162            @interface ObjC {
2163              char [[da^ta]];
2164            }@end
2165           )cpp",
2166           [](HoverInfo &HI) {
2167             HI.Name = "data";
2168             HI.Type = "char";
2169             HI.Kind = index::SymbolKind::Field;
2170             HI.NamespaceScope = "ObjC::"; // FIXME: fix it
2171             HI.Definition = "char data";
2172           }},
2173       {
2174           R"cpp(
2175           @interface MYObject
2176           @end
2177           @interface Interface
2178           @property(retain) [[MYOb^ject]] *x;
2179           @end
2180           )cpp",
2181           [](HoverInfo &HI) {
2182             HI.Name = "MYObject";
2183             HI.Kind = index::SymbolKind::Class;
2184             HI.NamespaceScope = "";
2185             HI.Definition = "@interface MYObject\n@end";
2186           }},
2187       {
2188           R"cpp(
2189           @interface MYObject
2190           @end
2191           @interface Interface
2192           - (void)doWith:([[MYOb^ject]] *)object;
2193           @end
2194           )cpp",
2195           [](HoverInfo &HI) {
2196             HI.Name = "MYObject";
2197             HI.Kind = index::SymbolKind::Class;
2198             HI.NamespaceScope = "";
2199             HI.Definition = "@interface MYObject\n@end";
2200           }},
2201       {
2202           R"cpp(// this expr
2203           // comment
2204           namespace ns {
2205             class Foo {
2206               Foo* bar() {
2207                 return [[t^his]];
2208               }
2209             };
2210           }
2211           )cpp",
2212           [](HoverInfo &HI) {
2213             HI.Name = "this";
2214             HI.Definition = "ns::Foo *";
2215           }},
2216       {
2217           R"cpp(// this expr for template class
2218           namespace ns {
2219             template <typename T>
2220             class Foo {
2221               Foo* bar() const {
2222                 return [[t^his]];
2223               }
2224             };
2225           }
2226           )cpp",
2227           [](HoverInfo &HI) {
2228             HI.Name = "this";
2229             HI.Definition = "const Foo<T> *";
2230           }},
2231       {
2232           R"cpp(// this expr for specialization class
2233           namespace ns {
2234             template <typename T> class Foo {};
2235             template <>
2236             struct Foo<int> {
2237               Foo* bar() {
2238                 return [[thi^s]];
2239               }
2240             };
2241           }
2242           )cpp",
2243           [](HoverInfo &HI) {
2244             HI.Name = "this";
2245             HI.Definition = "Foo<int> *";
2246           }},
2247       {
2248           R"cpp(// this expr for partial specialization struct
2249           namespace ns {
2250             template <typename T, typename F> struct Foo {};
2251             template <typename F>
2252             struct Foo<int, F> {
2253               Foo* bar() const {
2254                 return [[thi^s]];
2255               }
2256             };
2257           }
2258           )cpp",
2259           [](HoverInfo &HI) {
2260             HI.Name = "this";
2261             HI.Definition = "const Foo<int, F> *";
2262           }},
2263   };
2264 
2265   // Create a tiny index, so tests above can verify documentation is fetched.
2266   Symbol IndexSym = func("indexSymbol");
2267   IndexSym.Documentation = "comment from index";
2268   SymbolSlab::Builder Symbols;
2269   Symbols.insert(IndexSym);
2270   auto Index =
2271       MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab());
2272 
2273   for (const auto &Case : Cases) {
2274     SCOPED_TRACE(Case.Code);
2275 
2276     Annotations T(Case.Code);
2277     TestTU TU = TestTU::withCode(T.code());
2278     TU.ExtraArgs.push_back("-std=c++17");
2279     TU.ExtraArgs.push_back("-xobjective-c++");
2280 
2281     TU.ExtraArgs.push_back("-Wno-gnu-designator");
2282     // Types might be different depending on the target triplet, we chose a
2283     // fixed one to make sure tests passes on different platform.
2284     TU.ExtraArgs.push_back("--target=x86_64-pc-linux-gnu");
2285     auto AST = TU.build();
2286 
2287     auto H = getHover(AST, T.point(), format::getLLVMStyle(), Index.get());
2288     ASSERT_TRUE(H);
2289     HoverInfo Expected;
2290     Expected.SymRange = T.range();
2291     Case.ExpectedBuilder(Expected);
2292 
2293     SCOPED_TRACE(H->present().asPlainText());
2294     EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
2295     EXPECT_EQ(H->LocalScope, Expected.LocalScope);
2296     EXPECT_EQ(H->Name, Expected.Name);
2297     EXPECT_EQ(H->Kind, Expected.Kind);
2298     EXPECT_EQ(H->Documentation, Expected.Documentation);
2299     EXPECT_EQ(H->Definition, Expected.Definition);
2300     EXPECT_EQ(H->Type, Expected.Type);
2301     EXPECT_EQ(H->ReturnType, Expected.ReturnType);
2302     EXPECT_EQ(H->Parameters, Expected.Parameters);
2303     EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
2304     EXPECT_EQ(H->SymRange, Expected.SymRange);
2305     EXPECT_EQ(H->Value, Expected.Value);
2306   }
2307 }
2308 
TEST(Hover,DocsFromIndex)2309 TEST(Hover, DocsFromIndex) {
2310   Annotations T(R"cpp(
2311   template <typename T> class X {};
2312   void foo() {
2313     auto t = X<int>();
2314     X^<int> w;
2315     (void)w;
2316   })cpp");
2317 
2318   TestTU TU = TestTU::withCode(T.code());
2319   auto AST = TU.build();
2320   Symbol IndexSym;
2321   IndexSym.ID = getSymbolID(&findDecl(AST, "X"));
2322   IndexSym.Documentation = "comment from index";
2323   SymbolSlab::Builder Symbols;
2324   Symbols.insert(IndexSym);
2325   auto Index =
2326       MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab());
2327 
2328   for (const auto &P : T.points()) {
2329     auto H = getHover(AST, P, format::getLLVMStyle(), Index.get());
2330     ASSERT_TRUE(H);
2331     EXPECT_EQ(H->Documentation, IndexSym.Documentation);
2332   }
2333 }
2334 
TEST(Hover,DocsFromAST)2335 TEST(Hover, DocsFromAST) {
2336   Annotations T(R"cpp(
2337   // doc
2338   template <typename T> class X {};
2339   // doc
2340   template <typename T> void bar() {}
2341   // doc
2342   template <typename T> T baz;
2343   void foo() {
2344     au^to t = X<int>();
2345     X^<int>();
2346     b^ar<int>();
2347     au^to T = ba^z<X<int>>;
2348     ba^z<int> = 0;
2349   })cpp");
2350 
2351   TestTU TU = TestTU::withCode(T.code());
2352   auto AST = TU.build();
2353   for (const auto &P : T.points()) {
2354     auto H = getHover(AST, P, format::getLLVMStyle(), nullptr);
2355     ASSERT_TRUE(H);
2356     EXPECT_EQ(H->Documentation, "doc");
2357   }
2358 }
2359 
TEST(Hover,DocsFromMostSpecial)2360 TEST(Hover, DocsFromMostSpecial) {
2361   Annotations T(R"cpp(
2362   // doc1
2363   template <typename T> class $doc1^X {};
2364   // doc2
2365   template <> class $doc2^X<int> {};
2366   // doc3
2367   template <typename T> class $doc3^X<T*> {};
2368   void foo() {
2369     X$doc1^<char>();
2370     X$doc2^<int>();
2371     X$doc3^<int*>();
2372   })cpp");
2373 
2374   TestTU TU = TestTU::withCode(T.code());
2375   auto AST = TU.build();
2376   for (auto Comment : {"doc1", "doc2", "doc3"}) {
2377     for (const auto &P : T.points(Comment)) {
2378       auto H = getHover(AST, P, format::getLLVMStyle(), nullptr);
2379       ASSERT_TRUE(H);
2380       EXPECT_EQ(H->Documentation, Comment);
2381     }
2382   }
2383 }
2384 
TEST(Hover,Present)2385 TEST(Hover, Present) {
2386   struct {
2387     const std::function<void(HoverInfo &)> Builder;
2388     llvm::StringRef ExpectedRender;
2389   } Cases[] = {
2390       {
2391           [](HoverInfo &HI) {
2392             HI.Kind = index::SymbolKind::Unknown;
2393             HI.Name = "X";
2394           },
2395           R"(X)",
2396       },
2397       {
2398           [](HoverInfo &HI) {
2399             HI.Kind = index::SymbolKind::NamespaceAlias;
2400             HI.Name = "foo";
2401           },
2402           R"(namespace-alias foo)",
2403       },
2404       {
2405           [](HoverInfo &HI) {
2406             HI.Kind = index::SymbolKind::Class;
2407             HI.Size = 10;
2408             HI.TemplateParameters = {
2409                 {std::string("typename"), std::string("T"), llvm::None},
2410                 {std::string("typename"), std::string("C"),
2411                  std::string("bool")},
2412             };
2413             HI.Documentation = "documentation";
2414             HI.Definition =
2415                 "template <typename T, typename C = bool> class Foo {}";
2416             HI.Name = "foo";
2417             HI.NamespaceScope.emplace();
2418           },
2419           R"(class foo
2420 
2421 Size: 10 bytes
2422 documentation
2423 
2424 template <typename T, typename C = bool> class Foo {})",
2425       },
2426       {
2427           [](HoverInfo &HI) {
2428             HI.Kind = index::SymbolKind::Function;
2429             HI.Name = "foo";
2430             HI.Type = "type";
2431             HI.ReturnType = "ret_type";
2432             HI.Parameters.emplace();
2433             HoverInfo::Param P;
2434             HI.Parameters->push_back(P);
2435             P.Type = "type";
2436             HI.Parameters->push_back(P);
2437             P.Name = "foo";
2438             HI.Parameters->push_back(P);
2439             P.Default = "default";
2440             HI.Parameters->push_back(P);
2441             HI.NamespaceScope = "ns::";
2442             HI.Definition = "ret_type foo(params) {}";
2443           },
2444           "function foo\n"
2445           "\n"
2446           "→ ret_type\n"
2447           "Parameters:\n"
2448           "- \n"
2449           "- type\n"
2450           "- type foo\n"
2451           "- type foo = default\n"
2452           "\n"
2453           "// In namespace ns\n"
2454           "ret_type foo(params) {}",
2455       },
2456       {
2457           [](HoverInfo &HI) {
2458             HI.Kind = index::SymbolKind::Field;
2459             HI.LocalScope = "test::Bar::";
2460             HI.Value = "value";
2461             HI.Name = "foo";
2462             HI.Type = "type";
2463             HI.Definition = "def";
2464             HI.Size = 4;
2465             HI.Offset = 12;
2466           },
2467           R"(field foo
2468 
2469 Type: type
2470 Value = value
2471 Offset: 12 bytes
2472 Size: 4 bytes
2473 
2474 // In test::Bar
2475 def)",
2476       },
2477       {
2478           [](HoverInfo &HI) {
2479             HI.Kind = index::SymbolKind::Field;
2480             HI.AccessSpecifier = "public";
2481             HI.Name = "foo";
2482             HI.LocalScope = "test::Bar::";
2483             HI.Definition = "def";
2484           },
2485           R"(field foo
2486 
2487 // In test::Bar
2488 public: def)",
2489       },
2490       {
2491           [](HoverInfo &HI) {
2492             HI.Definition = "int method()";
2493             HI.AccessSpecifier = "protected";
2494             HI.Kind = index::SymbolKind::InstanceMethod;
2495             HI.NamespaceScope = "";
2496             HI.LocalScope = "cls<int>::";
2497             HI.Name = "method";
2498             HI.Parameters.emplace();
2499             HI.ReturnType = "int";
2500             HI.Type = "int ()";
2501           },
2502           R"(instance-method method
2503 
2504 → int
2505 
2506 // In cls<int>
2507 protected: int method())",
2508       },
2509       {
2510           [](HoverInfo &HI) {
2511             HI.Kind = index::SymbolKind::Union;
2512             HI.AccessSpecifier = "private";
2513             HI.Name = "foo";
2514             HI.NamespaceScope = "ns1::";
2515             HI.Definition = "union foo {}";
2516           },
2517           R"(union foo
2518 
2519 // In namespace ns1
2520 private: union foo {})",
2521       },
2522       {
2523           [](HoverInfo &HI) {
2524             HI.Kind = index::SymbolKind::Variable;
2525             HI.Name = "foo";
2526             HI.Definition = "int foo = 3";
2527             HI.LocalScope = "test::Bar::";
2528             HI.Value = "3";
2529             HI.Type = "int";
2530             HI.CalleeArgInfo.emplace();
2531             HI.CalleeArgInfo->Name = "arg_a";
2532             HI.CalleeArgInfo->Type = "int";
2533             HI.CalleeArgInfo->Default = "7";
2534             HI.CallPassType.emplace();
2535             HI.CallPassType->PassBy = PassMode::Value;
2536             HI.CallPassType->Converted = false;
2537           },
2538           R"(variable foo
2539 
2540 Type: int
2541 Value = 3
2542 Passed as arg_a
2543 
2544 // In test::Bar
2545 int foo = 3)",
2546       },
2547       {
2548           [](HoverInfo &HI) {
2549             HI.Kind = index::SymbolKind::Variable;
2550             HI.Name = "foo";
2551             HI.Definition = "int foo = 3";
2552             HI.LocalScope = "test::Bar::";
2553             HI.Value = "3";
2554             HI.Type = "int";
2555             HI.CalleeArgInfo.emplace();
2556             HI.CalleeArgInfo->Name = "arg_a";
2557             HI.CalleeArgInfo->Type = "int";
2558             HI.CalleeArgInfo->Default = "7";
2559             HI.CallPassType.emplace();
2560             HI.CallPassType->PassBy = PassMode::Ref;
2561             HI.CallPassType->Converted = false;
2562           },
2563           R"(variable foo
2564 
2565 Type: int
2566 Value = 3
2567 Passed by reference as arg_a
2568 
2569 // In test::Bar
2570 int foo = 3)",
2571       },
2572       {
2573           [](HoverInfo &HI) {
2574             HI.Kind = index::SymbolKind::Variable;
2575             HI.Name = "foo";
2576             HI.Definition = "int foo = 3";
2577             HI.LocalScope = "test::Bar::";
2578             HI.Value = "3";
2579             HI.Type = "int";
2580             HI.CalleeArgInfo.emplace();
2581             HI.CalleeArgInfo->Name = "arg_a";
2582             HI.CalleeArgInfo->Type = "int";
2583             HI.CalleeArgInfo->Default = "7";
2584             HI.CallPassType.emplace();
2585             HI.CallPassType->PassBy = PassMode::Value;
2586             HI.CallPassType->Converted = true;
2587           },
2588           R"(variable foo
2589 
2590 Type: int
2591 Value = 3
2592 Passed as arg_a (converted to int)
2593 
2594 // In test::Bar
2595 int foo = 3)",
2596       },
2597       {
2598           [](HoverInfo &HI) {
2599             HI.Kind = index::SymbolKind::Variable;
2600             HI.Name = "foo";
2601             HI.Definition = "int foo = 3";
2602             HI.LocalScope = "test::Bar::";
2603             HI.Value = "3";
2604             HI.Type = "int";
2605             HI.CalleeArgInfo.emplace();
2606             HI.CalleeArgInfo->Name = "arg_a";
2607             HI.CalleeArgInfo->Type = "int";
2608             HI.CalleeArgInfo->Default = "7";
2609             HI.CallPassType.emplace();
2610             HI.CallPassType->PassBy = PassMode::ConstRef;
2611             HI.CallPassType->Converted = true;
2612           },
2613           R"(variable foo
2614 
2615 Type: int
2616 Value = 3
2617 Passed by const reference as arg_a (converted to int)
2618 
2619 // In test::Bar
2620 int foo = 3)",
2621       }};
2622 
2623   for (const auto &C : Cases) {
2624     HoverInfo HI;
2625     C.Builder(HI);
2626     EXPECT_EQ(HI.present().asPlainText(), C.ExpectedRender);
2627   }
2628 }
2629 
TEST(Hover,ParseDocumentation)2630 TEST(Hover, ParseDocumentation) {
2631   struct Case {
2632     llvm::StringRef Documentation;
2633     llvm::StringRef ExpectedRenderMarkdown;
2634     llvm::StringRef ExpectedRenderPlainText;
2635   } Cases[] = {{
2636                    " \n foo\nbar",
2637                    "foo bar",
2638                    "foo bar",
2639                },
2640                {
2641                    "foo\nbar \n  ",
2642                    "foo bar",
2643                    "foo bar",
2644                },
2645                {
2646                    "foo  \nbar",
2647                    "foo bar",
2648                    "foo bar",
2649                },
2650                {
2651                    "foo    \nbar",
2652                    "foo bar",
2653                    "foo bar",
2654                },
2655                {
2656                    "foo\n\n\nbar",
2657                    "foo  \nbar",
2658                    "foo\nbar",
2659                },
2660                {
2661                    "foo\n\n\n\tbar",
2662                    "foo  \nbar",
2663                    "foo\nbar",
2664                },
2665                {
2666                    "foo\n\n\n bar",
2667                    "foo  \nbar",
2668                    "foo\nbar",
2669                },
2670                {
2671                    "foo.\nbar",
2672                    "foo.  \nbar",
2673                    "foo.\nbar",
2674                },
2675                {
2676                    "foo. \nbar",
2677                    "foo.  \nbar",
2678                    "foo.\nbar",
2679                },
2680                {
2681                    "foo\n*bar",
2682                    "foo  \n\\*bar",
2683                    "foo\n*bar",
2684                },
2685                {
2686                    "foo\nbar",
2687                    "foo bar",
2688                    "foo bar",
2689                },
2690                {
2691                    "Tests primality of `p`.",
2692                    "Tests primality of `p`.",
2693                    "Tests primality of `p`.",
2694                },
2695                {
2696                    "'`' should not occur in `Code`",
2697                    "'\\`' should not occur in `Code`",
2698                    "'`' should not occur in `Code`",
2699                },
2700                {
2701                    "`not\nparsed`",
2702                    "\\`not parsed\\`",
2703                    "`not parsed`",
2704                }};
2705 
2706   for (const auto &C : Cases) {
2707     markup::Document Output;
2708     parseDocumentation(C.Documentation, Output);
2709 
2710     EXPECT_EQ(Output.asMarkdown(), C.ExpectedRenderMarkdown);
2711     EXPECT_EQ(Output.asPlainText(), C.ExpectedRenderPlainText);
2712   }
2713 }
2714 
2715 // This is a separate test as headings don't create any differences in plaintext
2716 // mode.
TEST(Hover,PresentHeadings)2717 TEST(Hover, PresentHeadings) {
2718   HoverInfo HI;
2719   HI.Kind = index::SymbolKind::Variable;
2720   HI.Name = "foo";
2721 
2722   EXPECT_EQ(HI.present().asMarkdown(), "### variable `foo`");
2723 }
2724 
2725 // This is a separate test as rulers behave differently in markdown vs
2726 // plaintext.
TEST(Hover,PresentRulers)2727 TEST(Hover, PresentRulers) {
2728   HoverInfo HI;
2729   HI.Kind = index::SymbolKind::Variable;
2730   HI.Name = "foo";
2731   HI.Value = "val";
2732   HI.Definition = "def";
2733 
2734   llvm::StringRef ExpectedMarkdown = //
2735       "### variable `foo`  \n"
2736       "\n"
2737       "---\n"
2738       "Value = `val`  \n"
2739       "\n"
2740       "---\n"
2741       "```cpp\n"
2742       "def\n"
2743       "```";
2744   EXPECT_EQ(HI.present().asMarkdown(), ExpectedMarkdown);
2745 
2746   llvm::StringRef ExpectedPlaintext = R"pt(variable foo
2747 
2748 Value = val
2749 
2750 def)pt";
2751   EXPECT_EQ(HI.present().asPlainText(), ExpectedPlaintext);
2752 }
2753 } // namespace
2754 } // namespace clangd
2755 } // namespace clang
2756