xref: /llvm-project/clang-tools-extra/clangd/unittests/HoverTests.cpp (revision 7f78f99fe5af82361d37adcbd2daa4d04afba13d)
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 "Config.h"
12 #include "Hover.h"
13 #include "TestFS.h"
14 #include "TestIndex.h"
15 #include "TestTU.h"
16 #include "index/MemIndex.h"
17 #include "clang/AST/Attr.h"
18 #include "clang/Format/Format.h"
19 #include "clang/Index/IndexSymbol.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/Twine.h"
22 
23 #include "gtest/gtest.h"
24 #include <functional>
25 #include <optional>
26 #include <string>
27 #include <vector>
28 
29 namespace clang {
30 namespace clangd {
31 namespace {
32 
33 using PassMode = HoverInfo::PassType::PassMode;
34 
35 std::string guard(llvm::StringRef Code) {
36   return "#pragma once\n" + Code.str();
37 }
38 
39 TEST(Hover, Structured) {
40   struct {
41     const char *const Code;
42     const std::function<void(HoverInfo &)> ExpectedBuilder;
43   } Cases[] = {
44       // Global scope.
45       {R"cpp(
46           // Best foo ever.
47           void [[fo^o]]() {}
48           )cpp",
49        [](HoverInfo &HI) {
50          HI.NamespaceScope = "";
51          HI.Name = "foo";
52          HI.Kind = index::SymbolKind::Function;
53          HI.Documentation = "Best foo ever.";
54          HI.Definition = "void foo()";
55          HI.ReturnType = "void";
56          HI.Type = "void ()";
57          HI.Parameters.emplace();
58        }},
59       // Inside namespace
60       {R"cpp(
61           namespace ns1 { namespace ns2 {
62             /// Best foo ever.
63             void [[fo^o]]() {}
64           }}
65           )cpp",
66        [](HoverInfo &HI) {
67          HI.NamespaceScope = "ns1::ns2::";
68          HI.Name = "foo";
69          HI.Kind = index::SymbolKind::Function;
70          HI.Documentation = "Best foo ever.";
71          HI.Definition = "void foo()";
72          HI.ReturnType = "void";
73          HI.Type = "void ()";
74          HI.Parameters.emplace();
75        }},
76       // Field
77       {R"cpp(
78           namespace ns1 { namespace ns2 {
79             class Foo {
80               char [[b^ar]];
81               double y[2];
82             };
83           }}
84           )cpp",
85        [](HoverInfo &HI) {
86          HI.NamespaceScope = "ns1::ns2::";
87          HI.LocalScope = "Foo::";
88          HI.Name = "bar";
89          HI.Kind = index::SymbolKind::Field;
90          HI.Definition = "char bar";
91          HI.Type = "char";
92          HI.Offset = 0;
93          HI.Size = 8;
94          HI.Padding = 56;
95          HI.Align = 8;
96          HI.AccessSpecifier = "private";
97        }},
98       // Union field
99       {R"cpp(
100             union Foo {
101               char [[b^ar]];
102               double y[2];
103             };
104           )cpp",
105        [](HoverInfo &HI) {
106          HI.NamespaceScope = "";
107          HI.LocalScope = "Foo::";
108          HI.Name = "bar";
109          HI.Kind = index::SymbolKind::Field;
110          HI.Definition = "char bar";
111          HI.Type = "char";
112          HI.Size = 8;
113          HI.Padding = 120;
114          HI.Align = 8;
115          HI.AccessSpecifier = "public";
116        }},
117       // Bitfield
118       {R"cpp(
119             struct Foo {
120               int [[^x]] : 1;
121               int y : 1;
122             };
123           )cpp",
124        [](HoverInfo &HI) {
125          HI.NamespaceScope = "";
126          HI.LocalScope = "Foo::";
127          HI.Name = "x";
128          HI.Kind = index::SymbolKind::Field;
129          HI.Definition = "int x : 1";
130          HI.Type = "int";
131          HI.Offset = 0;
132          HI.Size = 1;
133          HI.Align = 32;
134          HI.AccessSpecifier = "public";
135        }},
136       // Local to class method.
137       {R"cpp(
138           namespace ns1 { namespace ns2 {
139             struct Foo {
140               void foo() {
141                 int [[b^ar]];
142               }
143             };
144           }}
145           )cpp",
146        [](HoverInfo &HI) {
147          HI.NamespaceScope = "ns1::ns2::";
148          HI.LocalScope = "Foo::foo::";
149          HI.Name = "bar";
150          HI.Kind = index::SymbolKind::Variable;
151          HI.Definition = "int bar";
152          HI.Type = "int";
153        }},
154       // Predefined variable
155       {R"cpp(
156           void foo() {
157             [[__f^unc__]];
158           }
159           )cpp",
160        [](HoverInfo &HI) {
161          HI.Name = "__func__";
162          HI.Kind = index::SymbolKind::Variable;
163          HI.Documentation =
164              "Name of the current function (predefined variable)";
165          HI.Value = "\"foo\"";
166          HI.Type = "const char[4]";
167        }},
168       // Predefined variable (dependent)
169       {R"cpp(
170           template<int> void foo() {
171             [[__f^unc__]];
172           }
173           )cpp",
174        [](HoverInfo &HI) {
175          HI.Name = "__func__";
176          HI.Kind = index::SymbolKind::Variable;
177          HI.Documentation =
178              "Name of the current function (predefined variable)";
179          HI.Type = "const char[]";
180        }},
181       // Anon namespace and local scope.
182       {R"cpp(
183           namespace ns1 { namespace {
184             struct {
185               char [[b^ar]];
186             } T;
187           }}
188           )cpp",
189        [](HoverInfo &HI) {
190          HI.NamespaceScope = "ns1::";
191          HI.LocalScope = "(anonymous struct)::";
192          HI.Name = "bar";
193          HI.Kind = index::SymbolKind::Field;
194          HI.Definition = "char bar";
195          HI.Type = "char";
196          HI.Offset = 0;
197          HI.Size = 8;
198          HI.Align = 8;
199          HI.AccessSpecifier = "public";
200        }},
201       // Struct definition shows size.
202       {R"cpp(
203           struct [[^X]]{};
204           )cpp",
205        [](HoverInfo &HI) {
206          HI.NamespaceScope = "";
207          HI.Name = "X";
208          HI.Kind = index::SymbolKind::Struct;
209          HI.Definition = "struct X {}";
210          HI.Size = 8;
211          HI.Align = 8;
212        }},
213       // Variable with template type
214       {R"cpp(
215           template <typename T, class... Ts> class Foo { public: Foo(int); };
216           Foo<int, char, bool> [[fo^o]] = Foo<int, char, bool>(5);
217           )cpp",
218        [](HoverInfo &HI) {
219          HI.NamespaceScope = "";
220          HI.Name = "foo";
221          HI.Kind = index::SymbolKind::Variable;
222          HI.Definition = "Foo<int, char, bool> foo = Foo<int, char, bool>(5)";
223          HI.Type = "Foo<int, char, bool>";
224        }},
225       // Implicit template instantiation
226       {R"cpp(
227           template <typename T> class vector{};
228           [[vec^tor]]<int> foo;
229           )cpp",
230        [](HoverInfo &HI) {
231          HI.NamespaceScope = "";
232          HI.Name = "vector<int>";
233          HI.Kind = index::SymbolKind::Class;
234          HI.Definition = "template <> class vector<int> {}";
235        }},
236       // Class template
237       {R"cpp(
238           template <template<typename, bool...> class C,
239                     typename = char,
240                     int = 0,
241                     bool Q = false,
242                     class... Ts> class Foo final {};
243           template <template<typename, bool...> class T>
244           [[F^oo]]<T> foo;
245           )cpp",
246        [](HoverInfo &HI) {
247          HI.NamespaceScope = "";
248          HI.Name = "Foo";
249          HI.Kind = index::SymbolKind::Class;
250          HI.Definition =
251              R"cpp(template <template <typename, bool...> class C, typename = char, int = 0,
252           bool Q = false, class... Ts>
253 class Foo final {})cpp";
254          HI.TemplateParameters = {
255              {{"template <typename, bool...> class"},
256               std::string("C"),
257               std::nullopt},
258              {{"typename"}, std::nullopt, std::string("char")},
259              {{"int"}, std::nullopt, std::string("0")},
260              {{"bool"}, std::string("Q"), std::string("false")},
261              {{"class..."}, std::string("Ts"), std::nullopt},
262          };
263        }},
264       // Function template
265       {R"cpp(
266           template <template<typename, bool...> class C,
267                     typename = char,
268                     int = 0,
269                     bool Q = false,
270                     class... Ts> void foo();
271           template<typename, bool...> class Foo;
272 
273           void bar() {
274             [[fo^o]]<Foo>();
275           }
276           )cpp",
277        [](HoverInfo &HI) {
278          HI.NamespaceScope = "";
279          HI.Name = "foo";
280          HI.Kind = index::SymbolKind::Function;
281          HI.Definition = "template <> void foo<Foo, char, 0, false, <>>()";
282          HI.ReturnType = "void";
283          HI.Type = "void ()";
284          HI.Parameters.emplace();
285        }},
286       // Function decl
287       {R"cpp(
288           template<typename, bool...> class Foo {};
289           Foo<bool, true, false> foo(int, bool T = false);
290 
291           void bar() {
292             [[fo^o]](3);
293           }
294           )cpp",
295        [](HoverInfo &HI) {
296          HI.NamespaceScope = "";
297          HI.Name = "foo";
298          HI.Kind = index::SymbolKind::Function;
299          HI.Definition = "Foo<bool, true, false> foo(int, bool T = false)";
300          HI.ReturnType = "Foo<bool, true, false>";
301          HI.Type = "Foo<bool, true, false> (int, bool)";
302          HI.Parameters = {
303              {{"int"}, std::nullopt, std::nullopt},
304              {{"bool"}, std::string("T"), std::string("false")},
305          };
306        }},
307       // Pointers to lambdas
308       {R"cpp(
309         void foo() {
310           auto lamb = [](int T, bool B) -> bool { return T && B; };
311           auto *b = &lamb;
312           auto *[[^c]] = &b;
313         }
314         )cpp",
315        [](HoverInfo &HI) {
316          HI.NamespaceScope = "";
317          HI.LocalScope = "foo::";
318          HI.Name = "c";
319          HI.Kind = index::SymbolKind::Variable;
320          HI.Definition = "auto *c = &b";
321          HI.Type = "(lambda) **";
322          HI.ReturnType = "bool";
323          HI.Parameters = {
324              {{"int"}, std::string("T"), std::nullopt},
325              {{"bool"}, std::string("B"), std::nullopt},
326          };
327          return HI;
328        }},
329       // Lambda parameter with decltype reference
330       {R"cpp(
331         auto lamb = [](int T, bool B) -> bool { return T && B; };
332         void foo(decltype(lamb)& bar) {
333           [[ba^r]](0, false);
334         }
335         )cpp",
336        [](HoverInfo &HI) {
337          HI.NamespaceScope = "";
338          HI.LocalScope = "foo::";
339          HI.Name = "bar";
340          HI.Kind = index::SymbolKind::Parameter;
341          HI.Definition = "decltype(lamb) &bar";
342          HI.Type = {"decltype(lamb) &", "(lambda) &"};
343          HI.ReturnType = "bool";
344          HI.Parameters = {
345              {{"int"}, std::string("T"), std::nullopt},
346              {{"bool"}, std::string("B"), std::nullopt},
347          };
348          return HI;
349        }},
350       // Lambda parameter with decltype
351       {R"cpp(
352         auto lamb = [](int T, bool B) -> bool { return T && B; };
353         void foo(decltype(lamb) bar) {
354           [[ba^r]](0, false);
355         }
356         )cpp",
357        [](HoverInfo &HI) {
358          HI.NamespaceScope = "";
359          HI.LocalScope = "foo::";
360          HI.Name = "bar";
361          HI.Kind = index::SymbolKind::Parameter;
362          HI.Definition = "decltype(lamb) bar";
363          HI.Type = "class (lambda)";
364          HI.ReturnType = "bool";
365          HI.Parameters = {
366              {{"int"}, std::string("T"), std::nullopt},
367              {{"bool"}, std::string("B"), std::nullopt},
368          };
369          HI.Value = "false";
370          return HI;
371        }},
372       // Lambda variable
373       {R"cpp(
374         void foo() {
375           int bar = 5;
376           auto lamb = [&bar](int T, bool B) -> bool { return T && B && bar; };
377           bool res = [[lam^b]](bar, false);
378         }
379         )cpp",
380        [](HoverInfo &HI) {
381          HI.NamespaceScope = "";
382          HI.LocalScope = "foo::";
383          HI.Name = "lamb";
384          HI.Kind = index::SymbolKind::Variable;
385          HI.Definition = "auto lamb = [&bar](int T, bool B) -> bool {}";
386          HI.Type = "class (lambda)";
387          HI.ReturnType = "bool";
388          HI.Parameters = {
389              {{"int"}, std::string("T"), std::nullopt},
390              {{"bool"}, std::string("B"), std::nullopt},
391          };
392          return HI;
393        }},
394       // Local variable in lambda
395       {R"cpp(
396         void foo() {
397           auto lamb = []{int [[te^st]];};
398         }
399         )cpp",
400        [](HoverInfo &HI) {
401          HI.NamespaceScope = "";
402          HI.LocalScope = "foo::(anonymous class)::operator()::";
403          HI.Name = "test";
404          HI.Kind = index::SymbolKind::Variable;
405          HI.Definition = "int test";
406          HI.Type = "int";
407        }},
408       // Partially-specialized class template. (formerly type-parameter-0-0)
409       {R"cpp(
410         template <typename T> class X;
411         template <typename T> class [[^X]]<T*> {};
412         )cpp",
413        [](HoverInfo &HI) {
414          HI.Name = "X<T *>";
415          HI.NamespaceScope = "";
416          HI.Kind = index::SymbolKind::Class;
417          HI.Definition = "template <typename T> class X<T *> {}";
418        }},
419       // Constructor of partially-specialized class template
420       {R"cpp(
421           template<typename, typename=void> struct X;
422           template<typename T> struct X<T*>{ [[^X]](); };
423           )cpp",
424        [](HoverInfo &HI) {
425          HI.NamespaceScope = "";
426          HI.Name = "X";
427          HI.LocalScope = "X<T *>::"; // FIXME: X<T *, void>::
428          HI.Kind = index::SymbolKind::Constructor;
429          HI.Definition = "X()";
430          HI.Parameters.emplace();
431          HI.AccessSpecifier = "public";
432        }},
433       {"class X { [[^~]]X(); };", // FIXME: Should be [[~X]]()
434        [](HoverInfo &HI) {
435          HI.NamespaceScope = "";
436          HI.Name = "~X";
437          HI.LocalScope = "X::";
438          HI.Kind = index::SymbolKind::Destructor;
439          HI.Definition = "~X()";
440          HI.Parameters.emplace();
441          HI.AccessSpecifier = "private";
442        }},
443       {"class X { [[op^erator]] int(); };",
444        [](HoverInfo &HI) {
445          HI.NamespaceScope = "";
446          HI.Name = "operator int";
447          HI.LocalScope = "X::";
448          HI.Kind = index::SymbolKind::ConversionFunction;
449          HI.Definition = "operator int()";
450          HI.Parameters.emplace();
451          HI.AccessSpecifier = "private";
452        }},
453       {"class X { operator [[^X]](); };",
454        [](HoverInfo &HI) {
455          HI.NamespaceScope = "";
456          HI.Name = "X";
457          HI.Kind = index::SymbolKind::Class;
458          HI.Definition = "class X {}";
459        }},
460 
461       // auto on structured bindings
462       {R"cpp(
463         void foo() {
464           struct S { int x; float y; };
465           [[au^to]] [x, y] = S();
466         }
467         )cpp",
468        [](HoverInfo &HI) {
469          HI.Name = "auto";
470          HI.Kind = index::SymbolKind::TypeAlias;
471          HI.Definition = "S";
472        }},
473       // undeduced auto
474       {R"cpp(
475         template<typename T>
476         void foo() {
477           [[au^to]] x = T{};
478         }
479         )cpp",
480        [](HoverInfo &HI) {
481          HI.Name = "auto";
482          HI.Kind = index::SymbolKind::TypeAlias;
483          HI.Definition = "/* not deduced */";
484        }},
485       // constrained auto
486       {R"cpp(
487         template <class T> concept F = true;
488         F [[au^to]] x = 1;
489         )cpp",
490        [](HoverInfo &HI) {
491          HI.Name = "auto";
492          HI.Kind = index::SymbolKind::TypeAlias;
493          HI.Definition = "int";
494        }},
495       {R"cpp(
496         template <class T> concept F = true;
497         [[^F]] auto x = 1;
498         )cpp",
499        [](HoverInfo &HI) {
500          HI.NamespaceScope = "";
501          HI.Name = "F";
502          HI.Kind = index::SymbolKind::Concept;
503          HI.Definition = "template <class T>\nconcept F = true";
504        }},
505       // auto on lambda
506       {R"cpp(
507         void foo() {
508           [[au^to]] lamb = []{};
509         }
510         )cpp",
511        [](HoverInfo &HI) {
512          HI.Name = "auto";
513          HI.Kind = index::SymbolKind::TypeAlias;
514          HI.Definition = "class(lambda)";
515        }},
516       // auto on template instantiation
517       {R"cpp(
518         template<typename T> class Foo{};
519         void foo() {
520           [[au^to]] x = Foo<int>();
521         }
522         )cpp",
523        [](HoverInfo &HI) {
524          HI.Name = "auto";
525          HI.Kind = index::SymbolKind::TypeAlias;
526          HI.Definition = "Foo<int>";
527        }},
528       // auto on specialized template
529       {R"cpp(
530         template<typename T> class Foo{};
531         template<> class Foo<int>{};
532         void foo() {
533           [[au^to]] x = Foo<int>();
534         }
535         )cpp",
536        [](HoverInfo &HI) {
537          HI.Name = "auto";
538          HI.Kind = index::SymbolKind::TypeAlias;
539          HI.Definition = "Foo<int>";
540        }},
541       // constrained template parameter
542       {R"cpp(
543         template<class T> concept Fooable = true;
544         template<[[Foo^able]] T>
545         void bar(T t) {}
546         )cpp",
547        [](HoverInfo &HI) {
548          HI.NamespaceScope = "";
549          HI.Name = "Fooable";
550          HI.Kind = index::SymbolKind::Concept;
551          HI.Definition = "template <class T>\nconcept Fooable = true";
552        }},
553       {R"cpp(
554         template<class T> concept Fooable = true;
555         template<Fooable [[T^T]]>
556         void bar(TT t) {}
557         )cpp",
558        [](HoverInfo &HI) {
559          HI.Name = "TT";
560          HI.Type = "class";
561          HI.AccessSpecifier = "public";
562          HI.NamespaceScope = "";
563          HI.LocalScope = "bar::";
564          HI.Kind = index::SymbolKind::TemplateTypeParm;
565          HI.Definition = "Fooable TT";
566        }},
567       {R"cpp(
568         template<class T> concept Fooable = true;
569         void bar([[Foo^able]] auto t) {}
570         )cpp",
571        [](HoverInfo &HI) {
572          HI.NamespaceScope = "";
573          HI.Name = "Fooable";
574          HI.Kind = index::SymbolKind::Concept;
575          HI.Definition = "template <class T>\nconcept Fooable = true";
576        }},
577       // concept reference
578       {R"cpp(
579         template<class T> concept Fooable = true;
580         auto X = [[Fooa^ble]]<int>;
581         )cpp",
582        [](HoverInfo &HI) {
583          HI.NamespaceScope = "";
584          HI.Name = "Fooable";
585          HI.Kind = index::SymbolKind::Concept;
586          HI.Definition = "template <class T>\nconcept Fooable = true";
587          HI.Value = "true";
588        }},
589 
590       // empty macro
591       {R"cpp(
592         #define MACRO
593         [[MAC^RO]]
594         )cpp",
595        [](HoverInfo &HI) {
596          HI.Name = "MACRO";
597          HI.Kind = index::SymbolKind::Macro;
598          HI.Definition = "#define MACRO";
599        }},
600 
601       // object-like macro
602       {R"cpp(
603         #define MACRO 41
604         int x = [[MAC^RO]];
605         )cpp",
606        [](HoverInfo &HI) {
607          HI.Name = "MACRO";
608          HI.Kind = index::SymbolKind::Macro;
609          HI.Value = "41 (0x29)";
610          HI.Type = "int";
611          HI.Definition = "#define MACRO 41\n\n"
612                          "// Expands to\n"
613                          "41";
614        }},
615 
616       // function-like macro
617       {R"cpp(
618         // Best MACRO ever.
619         #define MACRO(x,y,z) void foo(x, y, z)
620         [[MAC^RO]](int, double d, bool z = false);
621         )cpp",
622        [](HoverInfo &HI) {
623          HI.Name = "MACRO";
624          HI.Kind = index::SymbolKind::Macro;
625          HI.Definition = "#define MACRO(x, y, z) void foo(x, y, z)\n\n"
626                          "// Expands to\n"
627                          "void foo(int, double d, bool z = false)";
628        }},
629 
630       // nested macro
631       {R"cpp(
632         #define STRINGIFY_AUX(s) #s
633         #define STRINGIFY(s) STRINGIFY_AUX(s)
634         #define DECL_STR(NAME, VALUE) const char *v_##NAME = STRINGIFY(VALUE)
635         #define FOO 41
636 
637         [[DECL^_STR]](foo, FOO);
638         )cpp",
639        [](HoverInfo &HI) {
640          HI.Name = "DECL_STR";
641          HI.Kind = index::SymbolKind::Macro;
642          HI.Type = HoverInfo::PrintedType("const char *");
643          HI.Definition = "#define DECL_STR(NAME, VALUE) const char *v_##NAME = "
644                          "STRINGIFY(VALUE)\n\n"
645                          "// Expands to\n"
646                          "const char *v_foo = \"41\"";
647        }},
648 
649       // constexprs
650       {R"cpp(
651         constexpr int add(int a, int b) { return a + b; }
652         int [[b^ar]] = add(1, 2);
653         )cpp",
654        [](HoverInfo &HI) {
655          HI.Name = "bar";
656          HI.Definition = "int bar = add(1, 2)";
657          HI.Kind = index::SymbolKind::Variable;
658          HI.Type = "int";
659          HI.NamespaceScope = "";
660          HI.Value = "3";
661        }},
662       {R"cpp(
663         int [[b^ar]] = sizeof(char);
664         )cpp",
665        [](HoverInfo &HI) {
666          HI.Name = "bar";
667          HI.Definition = "int bar = sizeof(char)";
668          HI.Kind = index::SymbolKind::Variable;
669          HI.Type = "int";
670          HI.NamespaceScope = "";
671          HI.Value = "1";
672        }},
673       {R"cpp(
674         template<int a, int b> struct Add {
675           static constexpr int result = a + b;
676         };
677         int [[ba^r]] = Add<1, 2>::result;
678         )cpp",
679        [](HoverInfo &HI) {
680          HI.Name = "bar";
681          HI.Definition = "int bar = Add<1, 2>::result";
682          HI.Kind = index::SymbolKind::Variable;
683          HI.Type = "int";
684          HI.NamespaceScope = "";
685          HI.Value = "3";
686        }},
687       {R"cpp(
688         enum Color { RED = -123, GREEN = 5, };
689         Color x = [[GR^EEN]];
690        )cpp",
691        [](HoverInfo &HI) {
692          HI.Name = "GREEN";
693          HI.NamespaceScope = "";
694          HI.LocalScope = "Color::";
695          HI.Definition = "GREEN = 5";
696          HI.Kind = index::SymbolKind::EnumConstant;
697          HI.Type = "enum Color";
698          HI.Value = "5"; // Numeric on the enumerator name, no hex as small.
699        }},
700       {R"cpp(
701         enum Color { RED = -123, GREEN = 5, };
702         Color x = RED;
703         Color y = [[^x]];
704        )cpp",
705        [](HoverInfo &HI) {
706          HI.Name = "x";
707          HI.NamespaceScope = "";
708          HI.Definition = "Color x = RED";
709          HI.Kind = index::SymbolKind::Variable;
710          HI.Type = "Color";
711          HI.Value = "RED (0xffffff85)"; // Symbolic on an expression.
712        }},
713       {R"cpp(
714         template<int a, int b> struct Add {
715           static constexpr int result = a + b;
716         };
717         int bar = Add<1, 2>::[[resu^lt]];
718         )cpp",
719        [](HoverInfo &HI) {
720          HI.Name = "result";
721          HI.Definition = "static constexpr int result = a + b";
722          HI.Kind = index::SymbolKind::StaticProperty;
723          HI.Type = "const int";
724          HI.NamespaceScope = "";
725          HI.LocalScope = "Add<1, 2>::";
726          HI.Value = "3";
727          HI.AccessSpecifier = "public";
728        }},
729       {R"cpp(
730         using my_int = int;
731         constexpr my_int answer() { return 40 + 2; }
732         int x = [[ans^wer]]();
733         )cpp",
734        [](HoverInfo &HI) {
735          HI.Name = "answer";
736          HI.Definition = "constexpr my_int answer()";
737          HI.Kind = index::SymbolKind::Function;
738          HI.Type = {"my_int ()", "int ()"};
739          HI.ReturnType = {"my_int", "int"};
740          HI.Parameters.emplace();
741          HI.NamespaceScope = "";
742          HI.Value = "42 (0x2a)";
743        }},
744       {R"cpp(
745         const char *[[ba^r]] = "1234";
746         )cpp",
747        [](HoverInfo &HI) {
748          HI.Name = "bar";
749          HI.Definition = "const char *bar = \"1234\"";
750          HI.Kind = index::SymbolKind::Variable;
751          HI.Type = "const char *";
752          HI.NamespaceScope = "";
753          HI.Value = "&\"1234\"[0]";
754        }},
755       {R"cpp(// Should not crash
756         template <typename T>
757         struct Tmpl {
758           Tmpl(int name);
759         };
760 
761         template <typename A>
762         void boom(int name) {
763           new Tmpl<A>([[na^me]]);
764         })cpp",
765        [](HoverInfo &HI) {
766          HI.Name = "name";
767          HI.Definition = "int name";
768          HI.Kind = index::SymbolKind::Parameter;
769          HI.Type = "int";
770          HI.NamespaceScope = "";
771          HI.LocalScope = "boom::";
772        }},
773       {
774           R"cpp(// Should not print inline or anon namespaces.
775           namespace ns {
776             inline namespace in_ns {
777               namespace a {
778                 namespace {
779                   namespace b {
780                     inline namespace in_ns2 {
781                       class Foo {};
782                     } // in_ns2
783                   } // b
784                 } // anon
785               } // a
786             } // in_ns
787           } // ns
788           void foo() {
789             ns::a::b::[[F^oo]] x;
790             (void)x;
791           }
792           )cpp",
793           [](HoverInfo &HI) {
794             HI.Name = "Foo";
795             HI.Kind = index::SymbolKind::Class;
796             HI.NamespaceScope = "ns::a::b::";
797             HI.Definition = "class Foo {}";
798           }},
799       {
800           R"cpp(
801           template <typename T> class Foo {};
802           class X;
803           void foo() {
804             [[^auto]] x = Foo<X>();
805           }
806           )cpp",
807           [](HoverInfo &HI) {
808             HI.Name = "auto";
809             HI.Kind = index::SymbolKind::TypeAlias;
810             HI.Definition = "Foo<X>";
811           }},
812       {// Falls back to primary template, when the type is not instantiated.
813        R"cpp(
814           // comment from primary
815           template <typename T> class Foo {};
816           // comment from specialization
817           template <typename T> class Foo<T*> {};
818           void foo() {
819             [[Fo^o]]<int*> *x = nullptr;
820           }
821           )cpp",
822        [](HoverInfo &HI) {
823          HI.Name = "Foo<int *>";
824          HI.Kind = index::SymbolKind::Class;
825          HI.NamespaceScope = "";
826          HI.Definition = "template <> class Foo<int *>";
827          // FIXME: Maybe force instantiation to make use of real template
828          // pattern.
829          HI.Documentation = "comment from primary";
830        }},
831       {// Template Type Parameter
832        R"cpp(
833           template <typename [[^T]] = int> void foo();
834           )cpp",
835        [](HoverInfo &HI) {
836          HI.Name = "T";
837          HI.Kind = index::SymbolKind::TemplateTypeParm;
838          HI.NamespaceScope = "";
839          HI.Definition = "typename T = int";
840          HI.LocalScope = "foo::";
841          HI.Type = "typename";
842          HI.AccessSpecifier = "public";
843        }},
844       {// TemplateTemplate Type Parameter
845        R"cpp(
846           template <template<typename> class [[^T]]> void foo();
847           )cpp",
848        [](HoverInfo &HI) {
849          HI.Name = "T";
850          HI.Kind = index::SymbolKind::TemplateTemplateParm;
851          HI.NamespaceScope = "";
852          HI.Definition = "template <typename> class T";
853          HI.LocalScope = "foo::";
854          HI.Type = "template <typename> class";
855          HI.AccessSpecifier = "public";
856        }},
857       {// NonType Template Parameter
858        R"cpp(
859           template <int [[^T]] = 5> void foo();
860           )cpp",
861        [](HoverInfo &HI) {
862          HI.Name = "T";
863          HI.Kind = index::SymbolKind::NonTypeTemplateParm;
864          HI.NamespaceScope = "";
865          HI.Definition = "int T = 5";
866          HI.LocalScope = "foo::";
867          HI.Type = "int";
868          HI.AccessSpecifier = "public";
869        }},
870 
871       {// Getter
872        R"cpp(
873           struct X { int Y; float [[^y]]() { return Y; } };
874           )cpp",
875        [](HoverInfo &HI) {
876          HI.Name = "y";
877          HI.Kind = index::SymbolKind::InstanceMethod;
878          HI.NamespaceScope = "";
879          HI.Definition = "float y()";
880          HI.LocalScope = "X::";
881          HI.Documentation = "Trivial accessor for `Y`.";
882          HI.Type = "float ()";
883          HI.ReturnType = "float";
884          HI.Parameters.emplace();
885          HI.AccessSpecifier = "public";
886        }},
887       {// Setter
888        R"cpp(
889           struct X { int Y; void [[^setY]](float v) { Y = v; } };
890           )cpp",
891        [](HoverInfo &HI) {
892          HI.Name = "setY";
893          HI.Kind = index::SymbolKind::InstanceMethod;
894          HI.NamespaceScope = "";
895          HI.Definition = "void setY(float v)";
896          HI.LocalScope = "X::";
897          HI.Documentation = "Trivial setter for `Y`.";
898          HI.Type = "void (float)";
899          HI.ReturnType = "void";
900          HI.Parameters.emplace();
901          HI.Parameters->emplace_back();
902          HI.Parameters->back().Type = "float";
903          HI.Parameters->back().Name = "v";
904          HI.AccessSpecifier = "public";
905        }},
906       {// Setter (builder)
907        R"cpp(
908           struct X { int Y; X& [[^setY]](float v) { Y = v; return *this; } };
909           )cpp",
910        [](HoverInfo &HI) {
911          HI.Name = "setY";
912          HI.Kind = index::SymbolKind::InstanceMethod;
913          HI.NamespaceScope = "";
914          HI.Definition = "X &setY(float v)";
915          HI.LocalScope = "X::";
916          HI.Documentation = "Trivial setter for `Y`.";
917          HI.Type = "X &(float)";
918          HI.ReturnType = "X &";
919          HI.Parameters.emplace();
920          HI.Parameters->emplace_back();
921          HI.Parameters->back().Type = "float";
922          HI.Parameters->back().Name = "v";
923          HI.AccessSpecifier = "public";
924        }},
925       {// Setter (move)
926        R"cpp(
927           namespace std { template<typename T> T&& move(T&& t); }
928           struct X { int Y; void [[^setY]](float v) { Y = std::move(v); } };
929           )cpp",
930        [](HoverInfo &HI) {
931          HI.Name = "setY";
932          HI.Kind = index::SymbolKind::InstanceMethod;
933          HI.NamespaceScope = "";
934          HI.Definition = "void setY(float v)";
935          HI.LocalScope = "X::";
936          HI.Documentation = "Trivial setter for `Y`.";
937          HI.Type = "void (float)";
938          HI.ReturnType = "void";
939          HI.Parameters.emplace();
940          HI.Parameters->emplace_back();
941          HI.Parameters->back().Type = "float";
942          HI.Parameters->back().Name = "v";
943          HI.AccessSpecifier = "public";
944        }},
945       {// Field type initializer.
946        R"cpp(
947           struct X { int x = 2; };
948           X ^[[x]];
949           )cpp",
950        [](HoverInfo &HI) {
951          HI.Name = "x";
952          HI.Kind = index::SymbolKind::Variable;
953          HI.NamespaceScope = "";
954          HI.Definition = "X x";
955          HI.Type = "X";
956        }},
957       {// Don't crash on null types.
958        R"cpp(auto [^[[x]]] = 1; /*error-ok*/)cpp",
959        [](HoverInfo &HI) {
960          HI.Name = "x";
961          HI.Kind = index::SymbolKind::Variable;
962          HI.NamespaceScope = "";
963          HI.Definition = "";
964          HI.Type = "NULL TYPE";
965          // Bindings are in theory public members of an anonymous struct.
966          HI.AccessSpecifier = "public";
967        }},
968       {// Don't crash on invalid decl with invalid init expr.
969        R"cpp(
970           Unknown [[^abc]] = invalid;
971           // error-ok
972           )cpp",
973        [](HoverInfo &HI) {
974          HI.Name = "abc";
975          HI.Kind = index::SymbolKind::Variable;
976          HI.NamespaceScope = "";
977          HI.Definition = "int abc = <recovery - expr>()";
978          HI.Type = "int";
979          HI.AccessSpecifier = "public";
980        }},
981       {// Extra info for function call.
982        R"cpp(
983           void fun(int arg_a, int &arg_b) {};
984           void code() {
985             int a = 1, b = 2;
986             fun(a, [[^b]]);
987           }
988           )cpp",
989        [](HoverInfo &HI) {
990          HI.Name = "b";
991          HI.Kind = index::SymbolKind::Variable;
992          HI.NamespaceScope = "";
993          HI.Definition = "int b = 2";
994          HI.LocalScope = "code::";
995          HI.Value = "2";
996          HI.Type = "int";
997          HI.CalleeArgInfo.emplace();
998          HI.CalleeArgInfo->Name = "arg_b";
999          HI.CalleeArgInfo->Type = "int &";
1000          HI.CallPassType = HoverInfo::PassType{PassMode::Ref, false};
1001        }},
1002       {// make_unique-like function call
1003        R"cpp(
1004           struct Foo {
1005             explicit Foo(int arg_a) {}
1006           };
1007           template<class T, class... Args>
1008           T make(Args&&... args)
1009           {
1010               return T(args...);
1011           }
1012 
1013           void code() {
1014             int a = 1;
1015             auto foo = make<Foo>([[^a]]);
1016           }
1017           )cpp",
1018        [](HoverInfo &HI) {
1019          HI.Name = "a";
1020          HI.Kind = index::SymbolKind::Variable;
1021          HI.NamespaceScope = "";
1022          HI.Definition = "int a = 1";
1023          HI.LocalScope = "code::";
1024          HI.Value = "1";
1025          HI.Type = "int";
1026          HI.CalleeArgInfo.emplace();
1027          HI.CalleeArgInfo->Name = "arg_a";
1028          HI.CalleeArgInfo->Type = "int";
1029          HI.CallPassType = HoverInfo::PassType{PassMode::Value, false};
1030        }},
1031       {
1032           R"cpp(
1033           void foobar(const float &arg);
1034           int main() {
1035             int a = 0;
1036             foobar([[^a]]);
1037           }
1038           )cpp",
1039           [](HoverInfo &HI) {
1040             HI.Name = "a";
1041             HI.Kind = index::SymbolKind::Variable;
1042             HI.NamespaceScope = "";
1043             HI.Definition = "int a = 0";
1044             HI.LocalScope = "main::";
1045             HI.Value = "0";
1046             HI.Type = "int";
1047             HI.CalleeArgInfo.emplace();
1048             HI.CalleeArgInfo->Name = "arg";
1049             HI.CalleeArgInfo->Type = "const float &";
1050             HI.CallPassType = HoverInfo::PassType{PassMode::Value, true};
1051           }},
1052       {
1053           R"cpp(
1054           struct Foo {
1055             explicit Foo(const float& arg) {}
1056           };
1057           int main() {
1058             int a = 0;
1059             Foo foo([[^a]]);
1060           }
1061           )cpp",
1062           [](HoverInfo &HI) {
1063             HI.Name = "a";
1064             HI.Kind = index::SymbolKind::Variable;
1065             HI.NamespaceScope = "";
1066             HI.Definition = "int a = 0";
1067             HI.LocalScope = "main::";
1068             HI.Value = "0";
1069             HI.Type = "int";
1070             HI.CalleeArgInfo.emplace();
1071             HI.CalleeArgInfo->Name = "arg";
1072             HI.CalleeArgInfo->Type = "const float &";
1073             HI.CallPassType = HoverInfo::PassType{PassMode::Value, true};
1074           }},
1075       {// Literal passed to function call
1076        R"cpp(
1077           void fun(int arg_a, const int &arg_b) {};
1078           void code() {
1079             int a = 1;
1080             fun(a, [[^2]]);
1081           }
1082           )cpp",
1083        [](HoverInfo &HI) {
1084          HI.Name = "literal";
1085          HI.Kind = index::SymbolKind::Unknown;
1086          HI.CalleeArgInfo.emplace();
1087          HI.CalleeArgInfo->Name = "arg_b";
1088          HI.CalleeArgInfo->Type = "const int &";
1089          HI.CallPassType = HoverInfo::PassType{PassMode::ConstRef, false};
1090        }},
1091       {// Expression passed to function call
1092        R"cpp(
1093           void fun(int arg_a, const int &arg_b) {};
1094           void code() {
1095             int a = 1;
1096             fun(a, 1 [[^+]] 2);
1097           }
1098           )cpp",
1099        [](HoverInfo &HI) {
1100          HI.Name = "expression";
1101          HI.Kind = index::SymbolKind::Unknown;
1102          HI.Type = "int";
1103          HI.Value = "3";
1104          HI.CalleeArgInfo.emplace();
1105          HI.CalleeArgInfo->Name = "arg_b";
1106          HI.CalleeArgInfo->Type = "const int &";
1107          HI.CallPassType = HoverInfo::PassType{PassMode::ConstRef, false};
1108        }},
1109       {
1110           R"cpp(
1111         int add(int lhs, int rhs);
1112         int main() {
1113           add(1 [[^+]] 2, 3);
1114         }
1115         )cpp",
1116           [](HoverInfo &HI) {
1117             HI.Name = "expression";
1118             HI.Kind = index::SymbolKind::Unknown;
1119             HI.Type = "int";
1120             HI.Value = "3";
1121             HI.CalleeArgInfo.emplace();
1122             HI.CalleeArgInfo->Name = "lhs";
1123             HI.CalleeArgInfo->Type = "int";
1124             HI.CallPassType = HoverInfo::PassType{PassMode::Value, false};
1125           }},
1126       {
1127           R"cpp(
1128         void foobar(const float &arg);
1129         int main() {
1130           foobar([[^0]]);
1131         }
1132         )cpp",
1133           [](HoverInfo &HI) {
1134             HI.Name = "literal";
1135             HI.Kind = index::SymbolKind::Unknown;
1136             HI.CalleeArgInfo.emplace();
1137             HI.CalleeArgInfo->Name = "arg";
1138             HI.CalleeArgInfo->Type = "const float &";
1139             HI.CallPassType = HoverInfo::PassType{PassMode::Value, true};
1140           }},
1141       {// Extra info for method call.
1142        R"cpp(
1143           class C {
1144            public:
1145             void fun(int arg_a = 3, int arg_b = 4) {}
1146           };
1147           void code() {
1148             int a = 1, b = 2;
1149             C c;
1150             c.fun([[^a]], b);
1151           }
1152           )cpp",
1153        [](HoverInfo &HI) {
1154          HI.Name = "a";
1155          HI.Kind = index::SymbolKind::Variable;
1156          HI.NamespaceScope = "";
1157          HI.Definition = "int a = 1";
1158          HI.LocalScope = "code::";
1159          HI.Value = "1";
1160          HI.Type = "int";
1161          HI.CalleeArgInfo.emplace();
1162          HI.CalleeArgInfo->Name = "arg_a";
1163          HI.CalleeArgInfo->Type = "int";
1164          HI.CalleeArgInfo->Default = "3";
1165          HI.CallPassType = HoverInfo::PassType{PassMode::Value, false};
1166        }},
1167       {
1168           R"cpp(
1169           struct Foo {
1170             Foo(const int &);
1171           };
1172           void foo(Foo);
1173           void bar() {
1174             const int x = 0;
1175             foo([[^x]]);
1176           }
1177        )cpp",
1178           [](HoverInfo &HI) {
1179             HI.Name = "x";
1180             HI.Kind = index::SymbolKind::Variable;
1181             HI.NamespaceScope = "";
1182             HI.Definition = "const int x = 0";
1183             HI.LocalScope = "bar::";
1184             HI.Value = "0";
1185             HI.Type = "const int";
1186             HI.CalleeArgInfo.emplace();
1187             HI.CalleeArgInfo->Type = "Foo";
1188             HI.CallPassType = HoverInfo::PassType{PassMode::ConstRef, true};
1189           }},
1190       {// Dont crash on invalid decl
1191        R"cpp(
1192         // error-ok
1193         struct Foo {
1194           Bar [[x^x]];
1195         };)cpp",
1196        [](HoverInfo &HI) {
1197          HI.Name = "xx";
1198          HI.Kind = index::SymbolKind::Field;
1199          HI.NamespaceScope = "";
1200          HI.Definition = "int xx";
1201          HI.LocalScope = "Foo::";
1202          HI.Type = "int";
1203          HI.AccessSpecifier = "public";
1204        }},
1205       {R"cpp(
1206         // error-ok
1207         struct Foo {
1208           Bar xx;
1209           int [[y^y]];
1210         };)cpp",
1211        [](HoverInfo &HI) {
1212          HI.Name = "yy";
1213          HI.Kind = index::SymbolKind::Field;
1214          HI.NamespaceScope = "";
1215          HI.Definition = "int yy";
1216          HI.LocalScope = "Foo::";
1217          HI.Type = "int";
1218          HI.AccessSpecifier = "public";
1219        }},
1220       {// No crash on InitListExpr.
1221        R"cpp(
1222           struct Foo {
1223             int a[10];
1224           };
1225           constexpr Foo k2 = {
1226             ^[[{]]1} // FIXME: why the hover range is 1 character?
1227           };
1228          )cpp",
1229        [](HoverInfo &HI) {
1230          HI.Name = "expression";
1231          HI.Kind = index::SymbolKind::Unknown;
1232          HI.Type = "int[10]";
1233          HI.Value = "{1}";
1234        }},
1235       {// Var template decl
1236        R"cpp(
1237           using m_int = int;
1238 
1239           template <int Size> m_int ^[[arr]][Size];
1240          )cpp",
1241        [](HoverInfo &HI) {
1242          HI.Name = "arr";
1243          HI.Kind = index::SymbolKind::Variable;
1244          HI.Type = {"m_int[Size]", "int[Size]"};
1245          HI.NamespaceScope = "";
1246          HI.Definition = "template <int Size> m_int arr[Size]";
1247          HI.TemplateParameters = {{{"int"}, {"Size"}, std::nullopt}};
1248        }},
1249       {// Var template decl specialization
1250        R"cpp(
1251           using m_int = int;
1252 
1253           template <int Size> m_int arr[Size];
1254 
1255           template <> m_int ^[[arr]]<4>[4];
1256          )cpp",
1257        [](HoverInfo &HI) {
1258          HI.Name = "arr<4>";
1259          HI.Kind = index::SymbolKind::Variable;
1260          HI.Type = {"m_int[4]", "int[4]"};
1261          HI.NamespaceScope = "";
1262          HI.Definition = "m_int arr[4]";
1263        }},
1264       {// Canonical type
1265        R"cpp(
1266           template<typename T>
1267           struct TestHover {
1268             using Type = T;
1269           };
1270 
1271           void code() {
1272             TestHover<int>::Type ^[[a]];
1273           }
1274          )cpp",
1275        [](HoverInfo &HI) {
1276          HI.Name = "a";
1277          HI.NamespaceScope = "";
1278          HI.LocalScope = "code::";
1279          HI.Definition = "TestHover<int>::Type a";
1280          HI.Kind = index::SymbolKind::Variable;
1281          HI.Type = {"TestHover<int>::Type", "int"};
1282        }},
1283       {// Canonical template type
1284        R"cpp(
1285           template<typename T>
1286           void ^[[foo]](T arg) {}
1287          )cpp",
1288        [](HoverInfo &HI) {
1289          HI.Name = "foo";
1290          HI.Kind = index::SymbolKind::Function;
1291          HI.NamespaceScope = "";
1292          HI.Definition = "template <typename T> void foo(T arg)";
1293          HI.Type = "void (T)";
1294          HI.ReturnType = "void";
1295          HI.Parameters = {{{"T"}, std::string("arg"), std::nullopt}};
1296          HI.TemplateParameters = {
1297              {{"typename"}, std::string("T"), std::nullopt}};
1298        }},
1299       {// TypeAlias Template
1300        R"cpp(
1301           template<typename T>
1302           using ^[[alias]] = T;
1303          )cpp",
1304        [](HoverInfo &HI) {
1305          HI.Name = "alias";
1306          HI.NamespaceScope = "";
1307          HI.LocalScope = "";
1308          HI.Kind = index::SymbolKind::TypeAlias;
1309          HI.Definition = "template <typename T> using alias = T";
1310          HI.Type = "T";
1311          HI.TemplateParameters = {
1312              {{"typename"}, std::string("T"), std::nullopt}};
1313        }},
1314       {// TypeAlias Template
1315        R"cpp(
1316           template<typename T>
1317           using A = T;
1318 
1319           template<typename T>
1320           using ^[[AA]] = A<T>;
1321          )cpp",
1322        [](HoverInfo &HI) {
1323          HI.Name = "AA";
1324          HI.NamespaceScope = "";
1325          HI.LocalScope = "";
1326          HI.Kind = index::SymbolKind::TypeAlias;
1327          HI.Definition = "template <typename T> using AA = A<T>";
1328          HI.Type = {"A<T>", "T"};
1329          HI.TemplateParameters = {
1330              {{"typename"}, std::string("T"), std::nullopt}};
1331        }},
1332       {// Constant array
1333        R"cpp(
1334           using m_int = int;
1335 
1336           m_int ^[[arr]][10];
1337          )cpp",
1338        [](HoverInfo &HI) {
1339          HI.Name = "arr";
1340          HI.NamespaceScope = "";
1341          HI.LocalScope = "";
1342          HI.Kind = index::SymbolKind::Variable;
1343          HI.Definition = "m_int arr[10]";
1344          HI.Type = {"m_int[10]", "int[10]"};
1345        }},
1346       {// Incomplete array
1347        R"cpp(
1348           using m_int = int;
1349 
1350           extern m_int ^[[arr]][];
1351          )cpp",
1352        [](HoverInfo &HI) {
1353          HI.Name = "arr";
1354          HI.NamespaceScope = "";
1355          HI.LocalScope = "";
1356          HI.Kind = index::SymbolKind::Variable;
1357          HI.Definition = "extern m_int arr[]";
1358          HI.Type = {"m_int[]", "int[]"};
1359        }},
1360       {// Dependent size array
1361        R"cpp(
1362           using m_int = int;
1363 
1364           template<int Size>
1365           struct Test {
1366             m_int ^[[arr]][Size];
1367           };
1368          )cpp",
1369        [](HoverInfo &HI) {
1370          HI.Name = "arr";
1371          HI.NamespaceScope = "";
1372          HI.LocalScope = "Test<Size>::";
1373          HI.AccessSpecifier = "public";
1374          HI.Kind = index::SymbolKind::Field;
1375          HI.Definition = "m_int arr[Size]";
1376          HI.Type = {"m_int[Size]", "int[Size]"};
1377        }},
1378       {// Bitfield offset, size and padding
1379        R"cpp(
1380             struct Foo {
1381               char x;
1382               char [[^y]] : 1;
1383               int z;
1384             };
1385           )cpp",
1386        [](HoverInfo &HI) {
1387          HI.NamespaceScope = "";
1388          HI.LocalScope = "Foo::";
1389          HI.Name = "y";
1390          HI.Kind = index::SymbolKind::Field;
1391          HI.Definition = "char y : 1";
1392          HI.Type = "char";
1393          HI.Offset = 8;
1394          HI.Size = 1;
1395          HI.Padding = 23;
1396          HI.Align = 8;
1397          HI.AccessSpecifier = "public";
1398        }}};
1399   for (const auto &Case : Cases) {
1400     SCOPED_TRACE(Case.Code);
1401 
1402     Annotations T(Case.Code);
1403     TestTU TU = TestTU::withCode(T.code());
1404     TU.ExtraArgs.push_back("-std=c++20");
1405     // Types might be different depending on the target triplet, we chose a
1406     // fixed one to make sure tests passes on different platform.
1407     TU.ExtraArgs.push_back("--target=x86_64-pc-linux-gnu");
1408     auto AST = TU.build();
1409     Config Cfg;
1410     Cfg.Hover.ShowAKA = true;
1411     WithContextValue WithCfg(Config::Key, std::move(Cfg));
1412 
1413     auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
1414     ASSERT_TRUE(H);
1415     HoverInfo Expected;
1416     Expected.SymRange = T.range();
1417     Case.ExpectedBuilder(Expected);
1418 
1419     EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
1420     EXPECT_EQ(H->LocalScope, Expected.LocalScope);
1421     EXPECT_EQ(H->Name, Expected.Name);
1422     EXPECT_EQ(H->Kind, Expected.Kind);
1423     EXPECT_EQ(H->Documentation, Expected.Documentation);
1424     EXPECT_EQ(H->Definition, Expected.Definition);
1425     EXPECT_EQ(H->Type, Expected.Type);
1426     EXPECT_EQ(H->ReturnType, Expected.ReturnType);
1427     EXPECT_EQ(H->Parameters, Expected.Parameters);
1428     EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
1429     EXPECT_EQ(H->SymRange, Expected.SymRange);
1430     EXPECT_EQ(H->Value, Expected.Value);
1431     EXPECT_EQ(H->Size, Expected.Size);
1432     EXPECT_EQ(H->Offset, Expected.Offset);
1433     EXPECT_EQ(H->Align, Expected.Align);
1434     EXPECT_EQ(H->AccessSpecifier, Expected.AccessSpecifier);
1435     EXPECT_EQ(H->CalleeArgInfo, Expected.CalleeArgInfo);
1436     EXPECT_EQ(H->CallPassType, Expected.CallPassType);
1437   }
1438 }
1439 
1440 TEST(Hover, DefinitionLanuage) {
1441   struct {
1442     const char *const Code;
1443     const std::string ClangLanguageFlag;
1444     const char *const ExpectedDefinitionLanguage;
1445   } Cases[] = {{R"cpp(
1446           void [[some^Global]]() {}
1447           )cpp",
1448                 "", "cpp"},
1449                {R"cpp(
1450           void [[some^Global]]() {}
1451           )cpp",
1452                 "-xobjective-c++", "objective-cpp"},
1453                {R"cpp(
1454           void [[some^Global]]() {}
1455           )cpp",
1456                 "-xobjective-c", "objective-c"}};
1457   for (const auto &Case : Cases) {
1458     SCOPED_TRACE(Case.Code);
1459 
1460     Annotations T(Case.Code);
1461     TestTU TU = TestTU::withCode(T.code());
1462     if (!Case.ClangLanguageFlag.empty())
1463       TU.ExtraArgs.push_back(Case.ClangLanguageFlag);
1464     auto AST = TU.build();
1465 
1466     auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
1467     ASSERT_TRUE(H);
1468 
1469     EXPECT_STREQ(H->DefinitionLanguage, Case.ExpectedDefinitionLanguage);
1470   }
1471 }
1472 
1473 TEST(Hover, CallPassType) {
1474   const llvm::StringRef CodePrefix = R"cpp(
1475 class Base {};
1476 class Derived : public Base {};
1477 class CustomClass {
1478  public:
1479   CustomClass() {}
1480   CustomClass(const Base &x) {}
1481   CustomClass(int &x) {}
1482   CustomClass(float x) {}
1483   CustomClass(int x, int y) {}
1484 };
1485 
1486 void int_by_ref(int &x) {}
1487 void int_by_const_ref(const int &x) {}
1488 void int_by_value(int x) {}
1489 void base_by_ref(Base &x) {}
1490 void base_by_const_ref(const Base &x) {}
1491 void base_by_value(Base x) {}
1492 void float_by_value(float x) {}
1493 void custom_by_value(CustomClass x) {}
1494 
1495 void fun() {
1496   int int_x;
1497   int &int_ref = int_x;
1498   const int &int_const_ref = int_x;
1499   Base base;
1500   const Base &base_const_ref = base;
1501   Derived derived;
1502   float float_x;
1503 )cpp";
1504   const llvm::StringRef CodeSuffix = "}";
1505 
1506   struct {
1507     const char *const Code;
1508     HoverInfo::PassType::PassMode PassBy;
1509     bool Converted;
1510   } Tests[] = {
1511       // Integer tests
1512       {"int_by_value([[^int_x]]);", PassMode::Value, false},
1513       {"int_by_value([[^123]]);", PassMode::Value, false},
1514       {"int_by_ref([[^int_x]]);", PassMode::Ref, false},
1515       {"int_by_const_ref([[^int_x]]);", PassMode::ConstRef, false},
1516       {"int_by_const_ref([[^123]]);", PassMode::ConstRef, false},
1517       {"int_by_value([[^int_ref]]);", PassMode::Value, false},
1518       {"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef, false},
1519       {"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef, false},
1520       {"int_by_const_ref([[^int_const_ref]]);", PassMode::ConstRef, false},
1521       // Custom class tests
1522       {"base_by_ref([[^base]]);", PassMode::Ref, false},
1523       {"base_by_const_ref([[^base]]);", PassMode::ConstRef, false},
1524       {"base_by_const_ref([[^base_const_ref]]);", PassMode::ConstRef, false},
1525       {"base_by_value([[^base]]);", PassMode::Value, false},
1526       {"base_by_value([[^base_const_ref]]);", PassMode::Value, false},
1527       {"base_by_ref([[^derived]]);", PassMode::Ref, false},
1528       {"base_by_const_ref([[^derived]]);", PassMode::ConstRef, false},
1529       {"base_by_value([[^derived]]);", PassMode::Value, false},
1530       // Custom class constructor tests
1531       {"CustomClass c1([[^base]]);", PassMode::ConstRef, false},
1532       {"auto c2 = new CustomClass([[^base]]);", PassMode::ConstRef, false},
1533       {"CustomClass c3([[^int_x]]);", PassMode::Ref, false},
1534       {"CustomClass c3(int_x, [[^int_x]]);", PassMode::Value, false},
1535       // Converted tests
1536       {"float_by_value([[^int_x]]);", PassMode::Value, true},
1537       {"float_by_value([[^int_ref]]);", PassMode::Value, true},
1538       {"float_by_value([[^int_const_ref]]);", PassMode::Value, true},
1539       {"float_by_value([[^123.0f]]);", PassMode::Value, false},
1540       {"float_by_value([[^123]]);", PassMode::Value, true},
1541       {"custom_by_value([[^int_x]]);", PassMode::Ref, true},
1542       {"custom_by_value([[^float_x]]);", PassMode::Value, true},
1543       {"custom_by_value([[^base]]);", PassMode::ConstRef, true},
1544   };
1545   for (const auto &Test : Tests) {
1546     SCOPED_TRACE(Test.Code);
1547 
1548     const auto Code = (CodePrefix + Test.Code + CodeSuffix).str();
1549     Annotations T(Code);
1550     TestTU TU = TestTU::withCode(T.code());
1551     TU.ExtraArgs.push_back("-std=c++17");
1552     auto AST = TU.build();
1553     auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
1554     ASSERT_TRUE(H);
1555     EXPECT_EQ(H->CallPassType->PassBy, Test.PassBy);
1556     EXPECT_EQ(H->CallPassType->Converted, Test.Converted);
1557   }
1558 }
1559 
1560 TEST(Hover, NoHover) {
1561   llvm::StringRef Tests[] = {
1562       "^int main() {}",
1563       "void foo() {^}",
1564       // FIXME: "decltype(auto)" should be a single hover
1565       "decltype(au^to) x = 0;",
1566       // FIXME: not supported yet
1567       R"cpp(// Lambda auto parameter
1568             auto lamb = [](a^uto){};
1569           )cpp",
1570       R"cpp(// non-named decls don't get hover. Don't crash!
1571             ^static_assert(1, "");
1572           )cpp",
1573       R"cpp(// non-evaluatable expr
1574           template <typename T> void foo() {
1575             (void)[[size^of]](T);
1576           })cpp",
1577       R"cpp(// should not crash on invalid semantic form of init-list-expr.
1578             /*error-ok*/
1579             struct Foo {
1580               int xyz = 0;
1581             };
1582             class Bar {};
1583             constexpr Foo s = ^{
1584               .xyz = Bar(),
1585             };
1586           )cpp",
1587       // literals
1588       "auto x = t^rue;",
1589       "auto x = ^(int){42};",
1590       "auto x = ^42.;",
1591       "auto x = ^42.0i;",
1592       "auto x = ^42;",
1593       "auto x = ^nullptr;",
1594   };
1595 
1596   for (const auto &Test : Tests) {
1597     SCOPED_TRACE(Test);
1598 
1599     Annotations T(Test);
1600     TestTU TU = TestTU::withCode(T.code());
1601     TU.ExtraArgs.push_back("-std=c++17");
1602     auto AST = TU.build();
1603     auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
1604     ASSERT_FALSE(H);
1605   }
1606 }
1607 
1608 TEST(Hover, All) {
1609   struct {
1610     const char *const Code;
1611     const std::function<void(HoverInfo &)> ExpectedBuilder;
1612   } Cases[] = {
1613       {"auto x = [['^A']]; // character literal",
1614        [](HoverInfo &HI) {
1615          HI.Name = "expression";
1616          HI.Type = "char";
1617          HI.Value = "65 (0x41)";
1618        }},
1619       {"auto s = ^[[\"Hello, world!\"]]; // string literal",
1620        [](HoverInfo &HI) {
1621          HI.Name = "string-literal";
1622          HI.Size = 112;
1623          HI.Type = "const char[14]";
1624        }},
1625       {
1626           R"cpp(// Local variable
1627             int main() {
1628               int bonjour;
1629               ^[[bonjour]] = 2;
1630               int test1 = bonjour;
1631             }
1632           )cpp",
1633           [](HoverInfo &HI) {
1634             HI.Name = "bonjour";
1635             HI.Kind = index::SymbolKind::Variable;
1636             HI.NamespaceScope = "";
1637             HI.LocalScope = "main::";
1638             HI.Type = "int";
1639             HI.Definition = "int bonjour";
1640           }},
1641       {
1642           R"cpp(// Local variable in method
1643             struct s {
1644               void method() {
1645                 int bonjour;
1646                 ^[[bonjour]] = 2;
1647               }
1648             };
1649           )cpp",
1650           [](HoverInfo &HI) {
1651             HI.Name = "bonjour";
1652             HI.Kind = index::SymbolKind::Variable;
1653             HI.NamespaceScope = "";
1654             HI.LocalScope = "s::method::";
1655             HI.Type = "int";
1656             HI.Definition = "int bonjour";
1657           }},
1658       {
1659           R"cpp(// Struct
1660             namespace ns1 {
1661               struct MyClass {};
1662             } // namespace ns1
1663             int main() {
1664               ns1::[[My^Class]]* Params;
1665             }
1666           )cpp",
1667           [](HoverInfo &HI) {
1668             HI.Name = "MyClass";
1669             HI.Kind = index::SymbolKind::Struct;
1670             HI.NamespaceScope = "ns1::";
1671             HI.Definition = "struct MyClass {}";
1672           }},
1673       {
1674           R"cpp(// Class
1675             namespace ns1 {
1676               class MyClass {};
1677             } // namespace ns1
1678             int main() {
1679               ns1::[[My^Class]]* Params;
1680             }
1681           )cpp",
1682           [](HoverInfo &HI) {
1683             HI.Name = "MyClass";
1684             HI.Kind = index::SymbolKind::Class;
1685             HI.NamespaceScope = "ns1::";
1686             HI.Definition = "class MyClass {}";
1687           }},
1688       {
1689           R"cpp(// Union
1690             namespace ns1 {
1691               union MyUnion { int x; int y; };
1692             } // namespace ns1
1693             int main() {
1694               ns1::[[My^Union]] Params;
1695             }
1696           )cpp",
1697           [](HoverInfo &HI) {
1698             HI.Name = "MyUnion";
1699             HI.Kind = index::SymbolKind::Union;
1700             HI.NamespaceScope = "ns1::";
1701             HI.Definition = "union MyUnion {}";
1702           }},
1703       {
1704           R"cpp(// Function definition via pointer
1705             void foo(int) {}
1706             int main() {
1707               auto *X = &^[[foo]];
1708             }
1709           )cpp",
1710           [](HoverInfo &HI) {
1711             HI.Name = "foo";
1712             HI.Kind = index::SymbolKind::Function;
1713             HI.NamespaceScope = "";
1714             HI.Type = "void (int)";
1715             HI.Definition = "void foo(int)";
1716             HI.Documentation = "Function definition via pointer";
1717             HI.ReturnType = "void";
1718             HI.Parameters = {
1719                 {{"int"}, std::nullopt, std::nullopt},
1720             };
1721           }},
1722       {
1723           R"cpp(// Function declaration via call
1724             int foo(int);
1725             int main() {
1726               return ^[[foo]](42);
1727             }
1728           )cpp",
1729           [](HoverInfo &HI) {
1730             HI.Name = "foo";
1731             HI.Kind = index::SymbolKind::Function;
1732             HI.NamespaceScope = "";
1733             HI.Type = "int (int)";
1734             HI.Definition = "int foo(int)";
1735             HI.Documentation = "Function declaration via call";
1736             HI.ReturnType = "int";
1737             HI.Parameters = {
1738                 {{"int"}, std::nullopt, std::nullopt},
1739             };
1740           }},
1741       {
1742           R"cpp(// Field
1743             struct Foo { int x; };
1744             int main() {
1745               Foo bar;
1746               (void)bar.^[[x]];
1747             }
1748           )cpp",
1749           [](HoverInfo &HI) {
1750             HI.Name = "x";
1751             HI.Kind = index::SymbolKind::Field;
1752             HI.NamespaceScope = "";
1753             HI.LocalScope = "Foo::";
1754             HI.Type = "int";
1755             HI.Definition = "int x";
1756           }},
1757       {
1758           R"cpp(// Field with initialization
1759             struct Foo { int x = 5; };
1760             int main() {
1761               Foo bar;
1762               (void)bar.^[[x]];
1763             }
1764           )cpp",
1765           [](HoverInfo &HI) {
1766             HI.Name = "x";
1767             HI.Kind = index::SymbolKind::Field;
1768             HI.NamespaceScope = "";
1769             HI.LocalScope = "Foo::";
1770             HI.Type = "int";
1771             HI.Definition = "int x = 5";
1772           }},
1773       {
1774           R"cpp(// Static field
1775             struct Foo { static int x; };
1776             int main() {
1777               (void)Foo::^[[x]];
1778             }
1779           )cpp",
1780           [](HoverInfo &HI) {
1781             HI.Name = "x";
1782             HI.Kind = index::SymbolKind::StaticProperty;
1783             HI.NamespaceScope = "";
1784             HI.LocalScope = "Foo::";
1785             HI.Type = "int";
1786             HI.Definition = "static int x";
1787           }},
1788       {
1789           R"cpp(// Field, member initializer
1790             struct Foo {
1791               int x;
1792               Foo() : ^[[x]](0) {}
1793             };
1794           )cpp",
1795           [](HoverInfo &HI) {
1796             HI.Name = "x";
1797             HI.Kind = index::SymbolKind::Field;
1798             HI.NamespaceScope = "";
1799             HI.LocalScope = "Foo::";
1800             HI.Type = "int";
1801             HI.Definition = "int x";
1802           }},
1803       {
1804           R"cpp(// Field, GNU old-style field designator
1805             struct Foo { int x; };
1806             int main() {
1807               Foo bar = { ^[[x]] : 1 };
1808             }
1809           )cpp",
1810           [](HoverInfo &HI) {
1811             HI.Name = "x";
1812             HI.Kind = index::SymbolKind::Field;
1813             HI.NamespaceScope = "";
1814             HI.LocalScope = "Foo::";
1815             HI.Type = "int";
1816             HI.Definition = "int x";
1817             // FIXME: Initializer for x is a DesignatedInitListExpr, hence it is
1818             // of struct type and omitted.
1819           }},
1820       {
1821           R"cpp(// Field, field designator
1822             struct Foo { int x; int y; };
1823             int main() {
1824               Foo bar = { .^[[x]] = 2, .y = 2 };
1825             }
1826           )cpp",
1827           [](HoverInfo &HI) {
1828             HI.Name = "x";
1829             HI.Kind = index::SymbolKind::Field;
1830             HI.NamespaceScope = "";
1831             HI.LocalScope = "Foo::";
1832             HI.Type = "int";
1833             HI.Definition = "int x";
1834           }},
1835       {
1836           R"cpp(// Method call
1837             struct Foo { int x(); };
1838             int main() {
1839               Foo bar;
1840               bar.^[[x]]();
1841             }
1842           )cpp",
1843           [](HoverInfo &HI) {
1844             HI.Name = "x";
1845             HI.Kind = index::SymbolKind::InstanceMethod;
1846             HI.NamespaceScope = "";
1847             HI.LocalScope = "Foo::";
1848             HI.Type = "int ()";
1849             HI.Definition = "int x()";
1850             HI.ReturnType = "int";
1851             HI.Parameters = std::vector<HoverInfo::Param>{};
1852           }},
1853       {
1854           R"cpp(// Static method call
1855             struct Foo { static int x(); };
1856             int main() {
1857               Foo::^[[x]]();
1858             }
1859           )cpp",
1860           [](HoverInfo &HI) {
1861             HI.Name = "x";
1862             HI.Kind = index::SymbolKind::StaticMethod;
1863             HI.NamespaceScope = "";
1864             HI.LocalScope = "Foo::";
1865             HI.Type = "int ()";
1866             HI.Definition = "static int x()";
1867             HI.ReturnType = "int";
1868             HI.Parameters = std::vector<HoverInfo::Param>{};
1869           }},
1870       {
1871           R"cpp(// Typedef
1872             typedef int Foo;
1873             int main() {
1874               ^[[Foo]] bar;
1875             }
1876           )cpp",
1877           [](HoverInfo &HI) {
1878             HI.Name = "Foo";
1879             HI.Kind = index::SymbolKind::TypeAlias;
1880             HI.NamespaceScope = "";
1881             HI.Definition = "typedef int Foo";
1882             HI.Type = "int";
1883             HI.Documentation = "Typedef";
1884           }},
1885       {
1886           R"cpp(// Typedef with embedded definition
1887             typedef struct Bar {} Foo;
1888             int main() {
1889               ^[[Foo]] bar;
1890             }
1891           )cpp",
1892           [](HoverInfo &HI) {
1893             HI.Name = "Foo";
1894             HI.Kind = index::SymbolKind::TypeAlias;
1895             HI.NamespaceScope = "";
1896             HI.Definition = "typedef struct Bar Foo";
1897             HI.Type = "struct Bar";
1898             HI.Documentation = "Typedef with embedded definition";
1899           }},
1900       {
1901           R"cpp(// Namespace
1902             namespace ns {
1903             struct Foo { static void bar(); };
1904             } // namespace ns
1905             int main() { ^[[ns]]::Foo::bar(); }
1906           )cpp",
1907           [](HoverInfo &HI) {
1908             HI.Name = "ns";
1909             HI.Kind = index::SymbolKind::Namespace;
1910             HI.NamespaceScope = "";
1911             HI.Definition = "namespace ns {}";
1912           }},
1913       {
1914           R"cpp(// Anonymous namespace
1915             namespace ns {
1916               namespace {
1917                 int foo;
1918               } // anonymous namespace
1919             } // namespace ns
1920             int main() { ns::[[f^oo]]++; }
1921           )cpp",
1922           [](HoverInfo &HI) {
1923             HI.Name = "foo";
1924             HI.Kind = index::SymbolKind::Variable;
1925             HI.NamespaceScope = "ns::";
1926             HI.Type = "int";
1927             HI.Definition = "int foo";
1928           }},
1929       {
1930           R"cpp(// Function definition via using declaration
1931             namespace ns {
1932               void foo();
1933             }
1934             int main() {
1935               using ns::foo;
1936               ^[[foo]]();
1937             }
1938           )cpp",
1939           [](HoverInfo &HI) {
1940             HI.Name = "foo";
1941             HI.Kind = index::SymbolKind::Function;
1942             HI.NamespaceScope = "ns::";
1943             HI.Type = "void ()";
1944             HI.Definition = "void foo()";
1945             HI.Documentation = "";
1946             HI.ReturnType = "void";
1947             HI.Parameters = std::vector<HoverInfo::Param>{};
1948           }},
1949       {
1950           R"cpp( // using declaration and two possible function declarations
1951             namespace ns { void foo(int); void foo(char); }
1952             using ns::foo;
1953             template <typename T> void bar() { [[f^oo]](T{}); }
1954           )cpp",
1955           [](HoverInfo &HI) {
1956             HI.Name = "foo";
1957             HI.Kind = index::SymbolKind::Using;
1958             HI.NamespaceScope = "";
1959             HI.Definition = "using ns::foo";
1960           }},
1961       {
1962           R"cpp(// Macro
1963             #define MACRO 0
1964             int main() { return ^[[MACRO]]; }
1965           )cpp",
1966           [](HoverInfo &HI) {
1967             HI.Name = "MACRO";
1968             HI.Value = "0";
1969             HI.Type = "int";
1970             HI.Kind = index::SymbolKind::Macro;
1971             HI.Definition = "#define MACRO 0\n\n"
1972                             "// Expands to\n"
1973                             "0";
1974           }},
1975       {
1976           R"cpp(// Macro
1977             #define MACRO 0
1978             #define MACRO2 ^[[MACRO]]
1979           )cpp",
1980           [](HoverInfo &HI) {
1981             HI.Name = "MACRO";
1982             HI.Kind = index::SymbolKind::Macro;
1983             HI.Definition = "#define MACRO 0";
1984             // NOTE MACRO doesn't have expansion since it technically isn't
1985             // expanded here
1986           }},
1987       {
1988           R"cpp(// Macro
1989             #define MACRO {\
1990               return 0;\
1991             }
1992             int main() ^[[MACRO]]
1993           )cpp",
1994           [](HoverInfo &HI) {
1995             HI.Name = "MACRO";
1996             HI.Kind = index::SymbolKind::Macro;
1997             HI.Definition =
1998                 R"cpp(#define MACRO                                                                  \
1999   {                                                                            \
2000     return 0;                                                                  \
2001   }
2002 
2003 // Expands to
2004 {
2005   return 0;
2006 })cpp";
2007           }},
2008       {
2009           R"cpp(// Forward class declaration
2010             class Foo;
2011             class Foo {};
2012             [[F^oo]]* foo();
2013           )cpp",
2014           [](HoverInfo &HI) {
2015             HI.Name = "Foo";
2016             HI.Kind = index::SymbolKind::Class;
2017             HI.NamespaceScope = "";
2018             HI.Definition = "class Foo {}";
2019             HI.Documentation = "Forward class declaration";
2020           }},
2021       {
2022           R"cpp(// Function declaration
2023             void foo();
2024             void g() { [[f^oo]](); }
2025             void foo() {}
2026           )cpp",
2027           [](HoverInfo &HI) {
2028             HI.Name = "foo";
2029             HI.Kind = index::SymbolKind::Function;
2030             HI.NamespaceScope = "";
2031             HI.Type = "void ()";
2032             HI.Definition = "void foo()";
2033             HI.Documentation = "Function declaration";
2034             HI.ReturnType = "void";
2035             HI.Parameters = std::vector<HoverInfo::Param>{};
2036           }},
2037       {
2038           R"cpp(// Enum declaration
2039             enum Hello {
2040               ONE, TWO, THREE,
2041             };
2042             void foo() {
2043               [[Hel^lo]] hello = ONE;
2044             }
2045           )cpp",
2046           [](HoverInfo &HI) {
2047             HI.Name = "Hello";
2048             HI.Kind = index::SymbolKind::Enum;
2049             HI.NamespaceScope = "";
2050             HI.Definition = "enum Hello {}";
2051             HI.Documentation = "Enum declaration";
2052           }},
2053       {
2054           R"cpp(// Enumerator
2055             enum Hello {
2056               ONE, TWO, THREE,
2057             };
2058             void foo() {
2059               Hello hello = [[O^NE]];
2060             }
2061           )cpp",
2062           [](HoverInfo &HI) {
2063             HI.Name = "ONE";
2064             HI.Kind = index::SymbolKind::EnumConstant;
2065             HI.NamespaceScope = "";
2066             HI.LocalScope = "Hello::";
2067             HI.Type = "enum Hello";
2068             HI.Definition = "ONE";
2069             HI.Value = "0";
2070           }},
2071       {
2072           R"cpp(// C++20's using enum
2073             enum class Hello {
2074               ONE, TWO, THREE,
2075             };
2076             void foo() {
2077               using enum Hello;
2078               Hello hello = [[O^NE]];
2079             }
2080           )cpp",
2081           [](HoverInfo &HI) {
2082             HI.Name = "ONE";
2083             HI.Kind = index::SymbolKind::EnumConstant;
2084             HI.NamespaceScope = "";
2085             HI.LocalScope = "Hello::";
2086             HI.Type = "enum Hello";
2087             HI.Definition = "ONE";
2088             HI.Value = "0";
2089           }},
2090       {
2091           R"cpp(// Enumerator in anonymous enum
2092             enum {
2093               ONE, TWO, THREE,
2094             };
2095             void foo() {
2096               int hello = [[O^NE]];
2097             }
2098           )cpp",
2099           [](HoverInfo &HI) {
2100             HI.Name = "ONE";
2101             HI.Kind = index::SymbolKind::EnumConstant;
2102             HI.NamespaceScope = "";
2103             // FIXME: This should be `(anon enum)::`
2104             HI.LocalScope = "";
2105             HI.Type = "enum (unnamed)";
2106             HI.Definition = "ONE";
2107             HI.Value = "0";
2108           }},
2109       {
2110           R"cpp(// Global variable
2111             static int hey = 10;
2112             void foo() {
2113               [[he^y]]++;
2114             }
2115           )cpp",
2116           [](HoverInfo &HI) {
2117             HI.Name = "hey";
2118             HI.Kind = index::SymbolKind::Variable;
2119             HI.NamespaceScope = "";
2120             HI.Type = "int";
2121             HI.Definition = "static int hey = 10";
2122             HI.Documentation = "Global variable";
2123             // FIXME: Value shouldn't be set in this case
2124             HI.Value = "10 (0xa)";
2125           }},
2126       {
2127           R"cpp(// Global variable in namespace
2128             namespace ns1 {
2129               static long long hey = -36637162602497;
2130             }
2131             void foo() {
2132               ns1::[[he^y]]++;
2133             }
2134           )cpp",
2135           [](HoverInfo &HI) {
2136             HI.Name = "hey";
2137             HI.Kind = index::SymbolKind::Variable;
2138             HI.NamespaceScope = "ns1::";
2139             HI.Type = "long long";
2140             HI.Definition = "static long long hey = -36637162602497";
2141             HI.Value = "-36637162602497 (0xffffdeadbeefffff)"; // needs 64 bits
2142           }},
2143       {
2144           R"cpp(// Field in anonymous struct
2145             static struct {
2146               int hello;
2147             } s;
2148             void foo() {
2149               s.[[he^llo]]++;
2150             }
2151           )cpp",
2152           [](HoverInfo &HI) {
2153             HI.Name = "hello";
2154             HI.Kind = index::SymbolKind::Field;
2155             HI.NamespaceScope = "";
2156             HI.LocalScope = "(anonymous struct)::";
2157             HI.Type = "int";
2158             HI.Definition = "int hello";
2159           }},
2160       {
2161           R"cpp(// Templated function
2162             template <typename T>
2163             T foo() {
2164               return 17;
2165             }
2166             void g() { auto x = [[f^oo]]<int>(); }
2167           )cpp",
2168           [](HoverInfo &HI) {
2169             HI.Name = "foo";
2170             HI.Kind = index::SymbolKind::Function;
2171             HI.NamespaceScope = "";
2172             HI.Type = "int ()";
2173             HI.Definition = "template <> int foo<int>()";
2174             HI.Documentation = "Templated function";
2175             HI.ReturnType = "int";
2176             HI.Parameters = std::vector<HoverInfo::Param>{};
2177             // FIXME: We should populate template parameters with arguments in
2178             // case of instantiations.
2179           }},
2180       {
2181           R"cpp(// Anonymous union
2182             struct outer {
2183               union {
2184                 int abc, def;
2185               } v;
2186             };
2187             void g() { struct outer o; o.v.[[d^ef]]++; }
2188           )cpp",
2189           [](HoverInfo &HI) {
2190             HI.Name = "def";
2191             HI.Kind = index::SymbolKind::Field;
2192             HI.NamespaceScope = "";
2193             HI.LocalScope = "outer::(anonymous union)::";
2194             HI.Type = "int";
2195             HI.Definition = "int def";
2196           }},
2197       {
2198           R"cpp(// documentation from index
2199             int nextSymbolIsAForwardDeclFromIndexWithNoLocalDocs;
2200             void indexSymbol();
2201             void g() { [[ind^exSymbol]](); }
2202           )cpp",
2203           [](HoverInfo &HI) {
2204             HI.Name = "indexSymbol";
2205             HI.Kind = index::SymbolKind::Function;
2206             HI.NamespaceScope = "";
2207             HI.Type = "void ()";
2208             HI.Definition = "void indexSymbol()";
2209             HI.ReturnType = "void";
2210             HI.Parameters = std::vector<HoverInfo::Param>{};
2211             HI.Documentation = "comment from index";
2212           }},
2213       {
2214           R"cpp(// Simple initialization with auto
2215             void foo() {
2216               ^[[auto]] i = 1;
2217             }
2218           )cpp",
2219           [](HoverInfo &HI) {
2220             HI.Name = "auto";
2221             HI.Kind = index::SymbolKind::TypeAlias;
2222             HI.Definition = "int";
2223           }},
2224       {
2225           R"cpp(// Simple initialization with const auto
2226             void foo() {
2227               const ^[[auto]] i = 1;
2228             }
2229           )cpp",
2230           [](HoverInfo &HI) {
2231             HI.Name = "auto";
2232             HI.Kind = index::SymbolKind::TypeAlias;
2233             HI.Definition = "int";
2234           }},
2235       {
2236           R"cpp(// Simple initialization with const auto&
2237             void foo() {
2238               const ^[[auto]]& i = 1;
2239             }
2240           )cpp",
2241           [](HoverInfo &HI) {
2242             HI.Name = "auto";
2243             HI.Kind = index::SymbolKind::TypeAlias;
2244             HI.Definition = "int";
2245           }},
2246       {
2247           R"cpp(// Simple initialization with auto&
2248             void foo() {
2249               int x;
2250               ^[[auto]]& i = x;
2251             }
2252           )cpp",
2253           [](HoverInfo &HI) {
2254             HI.Name = "auto";
2255             HI.Kind = index::SymbolKind::TypeAlias;
2256             HI.Definition = "int";
2257           }},
2258       {
2259           R"cpp(// Simple initialization with auto*
2260             void foo() {
2261               int a = 1;
2262               ^[[auto]]* i = &a;
2263             }
2264           )cpp",
2265           [](HoverInfo &HI) {
2266             HI.Name = "auto";
2267             HI.Kind = index::SymbolKind::TypeAlias;
2268             HI.Definition = "int";
2269           }},
2270       {
2271           R"cpp(// Simple initialization with auto from pointer
2272             void foo() {
2273               int a = 1;
2274               ^[[auto]] i = &a;
2275             }
2276           )cpp",
2277           [](HoverInfo &HI) {
2278             HI.Name = "auto";
2279             HI.Kind = index::SymbolKind::TypeAlias;
2280             HI.Definition = "int *";
2281           }},
2282       {
2283           R"cpp(// Auto with initializer list.
2284             namespace std
2285             {
2286               template<class _E>
2287               class initializer_list { const _E *a, *b; };
2288             }
2289             void foo() {
2290               ^[[auto]] i = {1,2};
2291             }
2292           )cpp",
2293           [](HoverInfo &HI) {
2294             HI.Name = "auto";
2295             HI.Kind = index::SymbolKind::TypeAlias;
2296             HI.Definition = "std::initializer_list<int>";
2297           }},
2298       {
2299           R"cpp(// User defined conversion to auto
2300             struct Bar {
2301               operator ^[[auto]]() const { return 10; }
2302             };
2303           )cpp",
2304           [](HoverInfo &HI) {
2305             HI.Name = "auto";
2306             HI.Kind = index::SymbolKind::TypeAlias;
2307             HI.Definition = "int";
2308           }},
2309       {
2310           R"cpp(// Simple initialization with decltype(auto)
2311             void foo() {
2312               ^[[decltype]](auto) i = 1;
2313             }
2314           )cpp",
2315           [](HoverInfo &HI) {
2316             HI.Name = "decltype";
2317             HI.Kind = index::SymbolKind::TypeAlias;
2318             HI.Definition = "int";
2319           }},
2320       {
2321           R"cpp(// Simple initialization with const decltype(auto)
2322             void foo() {
2323               const int j = 0;
2324               ^[[decltype]](auto) i = j;
2325             }
2326           )cpp",
2327           [](HoverInfo &HI) {
2328             HI.Name = "decltype";
2329             HI.Kind = index::SymbolKind::TypeAlias;
2330             HI.Definition = "const int";
2331           }},
2332       {
2333           R"cpp(// Simple initialization with const& decltype(auto)
2334             void foo() {
2335               int k = 0;
2336               const int& j = k;
2337               ^[[decltype]](auto) i = j;
2338             }
2339           )cpp",
2340           [](HoverInfo &HI) {
2341             HI.Name = "decltype";
2342             HI.Kind = index::SymbolKind::TypeAlias;
2343             HI.Definition = "const int &";
2344           }},
2345       {
2346           R"cpp(// Simple initialization with & decltype(auto)
2347             void foo() {
2348               int k = 0;
2349               int& j = k;
2350               ^[[decltype]](auto) i = j;
2351             }
2352           )cpp",
2353           [](HoverInfo &HI) {
2354             HI.Name = "decltype";
2355             HI.Kind = index::SymbolKind::TypeAlias;
2356             HI.Definition = "int &";
2357           }},
2358       {
2359           R"cpp(// simple trailing return type
2360             ^[[auto]] main() -> int {
2361               return 0;
2362             }
2363           )cpp",
2364           [](HoverInfo &HI) {
2365             HI.Name = "auto";
2366             HI.Kind = index::SymbolKind::TypeAlias;
2367             HI.Definition = "int";
2368           }},
2369       {
2370           R"cpp(// auto function return with trailing type
2371             struct Bar {};
2372             ^[[auto]] test() -> decltype(Bar()) {
2373               return Bar();
2374             }
2375           )cpp",
2376           [](HoverInfo &HI) {
2377             HI.Name = "auto";
2378             HI.Kind = index::SymbolKind::TypeAlias;
2379             HI.Definition = "Bar";
2380             HI.Documentation = "auto function return with trailing type";
2381           }},
2382       {
2383           R"cpp(// trailing return type
2384             struct Bar {};
2385             auto test() -> ^[[decltype]](Bar()) {
2386               return Bar();
2387             }
2388           )cpp",
2389           [](HoverInfo &HI) {
2390             HI.Name = "decltype";
2391             HI.Kind = index::SymbolKind::TypeAlias;
2392             HI.Definition = "Bar";
2393             HI.Documentation = "trailing return type";
2394           }},
2395       {
2396           R"cpp(// auto in function return
2397             struct Bar {};
2398             ^[[auto]] test() {
2399               return Bar();
2400             }
2401           )cpp",
2402           [](HoverInfo &HI) {
2403             HI.Name = "auto";
2404             HI.Kind = index::SymbolKind::TypeAlias;
2405             HI.Definition = "Bar";
2406             HI.Documentation = "auto in function return";
2407           }},
2408       {
2409           R"cpp(// auto& in function return
2410             struct Bar {};
2411             ^[[auto]]& test() {
2412               static Bar x;
2413               return x;
2414             }
2415           )cpp",
2416           [](HoverInfo &HI) {
2417             HI.Name = "auto";
2418             HI.Kind = index::SymbolKind::TypeAlias;
2419             HI.Definition = "Bar";
2420             HI.Documentation = "auto& in function return";
2421           }},
2422       {
2423           R"cpp(// auto* in function return
2424             struct Bar {};
2425             ^[[auto]]* test() {
2426               Bar* bar;
2427               return bar;
2428             }
2429           )cpp",
2430           [](HoverInfo &HI) {
2431             HI.Name = "auto";
2432             HI.Kind = index::SymbolKind::TypeAlias;
2433             HI.Definition = "Bar";
2434             HI.Documentation = "auto* in function return";
2435           }},
2436       {
2437           R"cpp(// const auto& in function return
2438             struct Bar {};
2439             const ^[[auto]]& test() {
2440               static Bar x;
2441               return x;
2442             }
2443           )cpp",
2444           [](HoverInfo &HI) {
2445             HI.Name = "auto";
2446             HI.Kind = index::SymbolKind::TypeAlias;
2447             HI.Definition = "Bar";
2448             HI.Documentation = "const auto& in function return";
2449           }},
2450       {
2451           R"cpp(// decltype(auto) in function return
2452             struct Bar {};
2453             ^[[decltype]](auto) test() {
2454               return Bar();
2455             }
2456           )cpp",
2457           [](HoverInfo &HI) {
2458             HI.Name = "decltype";
2459             HI.Kind = index::SymbolKind::TypeAlias;
2460             HI.Definition = "Bar";
2461             HI.Documentation = "decltype(auto) in function return";
2462           }},
2463       {
2464           R"cpp(// decltype(auto) reference in function return
2465             ^[[decltype]](auto) test() {
2466               static int a;
2467               return (a);
2468             }
2469           )cpp",
2470           [](HoverInfo &HI) {
2471             HI.Name = "decltype";
2472             HI.Kind = index::SymbolKind::TypeAlias;
2473             HI.Definition = "int &";
2474           }},
2475       {
2476           R"cpp(// decltype lvalue reference
2477             void foo() {
2478               int I = 0;
2479               ^[[decltype]](I) J = I;
2480             }
2481           )cpp",
2482           [](HoverInfo &HI) {
2483             HI.Name = "decltype";
2484             HI.Kind = index::SymbolKind::TypeAlias;
2485             HI.Definition = "int";
2486           }},
2487       {
2488           R"cpp(// decltype lvalue reference
2489             void foo() {
2490               int I= 0;
2491               int &K = I;
2492               ^[[decltype]](K) J = I;
2493             }
2494           )cpp",
2495           [](HoverInfo &HI) {
2496             HI.Name = "decltype";
2497             HI.Kind = index::SymbolKind::TypeAlias;
2498             HI.Definition = "int &";
2499           }},
2500       {
2501           R"cpp(// decltype lvalue reference parenthesis
2502             void foo() {
2503               int I = 0;
2504               ^[[decltype]]((I)) J = I;
2505             }
2506           )cpp",
2507           [](HoverInfo &HI) {
2508             HI.Name = "decltype";
2509             HI.Kind = index::SymbolKind::TypeAlias;
2510             HI.Definition = "int &";
2511           }},
2512       {
2513           R"cpp(// decltype rvalue reference
2514             void foo() {
2515               int I = 0;
2516               ^[[decltype]](static_cast<int&&>(I)) J = static_cast<int&&>(I);
2517             }
2518           )cpp",
2519           [](HoverInfo &HI) {
2520             HI.Name = "decltype";
2521             HI.Kind = index::SymbolKind::TypeAlias;
2522             HI.Definition = "int &&";
2523           }},
2524       {
2525           R"cpp(// decltype rvalue reference function call
2526             int && bar();
2527             void foo() {
2528               int I = 0;
2529               ^[[decltype]](bar()) J = bar();
2530             }
2531           )cpp",
2532           [](HoverInfo &HI) {
2533             HI.Name = "decltype";
2534             HI.Kind = index::SymbolKind::TypeAlias;
2535             HI.Definition = "int &&";
2536           }},
2537       {
2538           R"cpp(// decltype of function with trailing return type.
2539             struct Bar {};
2540             auto test() -> decltype(Bar()) {
2541               return Bar();
2542             }
2543             void foo() {
2544               ^[[decltype]](test()) i = test();
2545             }
2546           )cpp",
2547           [](HoverInfo &HI) {
2548             HI.Name = "decltype";
2549             HI.Kind = index::SymbolKind::TypeAlias;
2550             HI.Definition = "Bar";
2551             HI.Documentation =
2552                 "decltype of function with trailing return type.";
2553           }},
2554       {
2555           R"cpp(// decltype of var with decltype.
2556             void foo() {
2557               int I = 0;
2558               decltype(I) J = I;
2559               ^[[decltype]](J) K = J;
2560             }
2561           )cpp",
2562           [](HoverInfo &HI) {
2563             HI.Name = "decltype";
2564             HI.Kind = index::SymbolKind::TypeAlias;
2565             HI.Definition = "int";
2566           }},
2567       {
2568           R"cpp(// decltype of dependent type
2569             template <typename T>
2570             struct X {
2571               using Y = ^[[decltype]](T::Z);
2572             };
2573           )cpp",
2574           [](HoverInfo &HI) {
2575             HI.Name = "decltype";
2576             HI.Kind = index::SymbolKind::TypeAlias;
2577             HI.Definition = "<dependent type>";
2578           }},
2579       {
2580           R"cpp(// More complicated structured types.
2581             int bar();
2582             ^[[auto]] (*foo)() = bar;
2583           )cpp",
2584           [](HoverInfo &HI) {
2585             HI.Name = "auto";
2586             HI.Kind = index::SymbolKind::TypeAlias;
2587             HI.Definition = "int";
2588           }},
2589       {
2590           R"cpp(// Should not crash when evaluating the initializer.
2591             struct Test {};
2592             void test() { Test && [[te^st]] = {}; }
2593           )cpp",
2594           [](HoverInfo &HI) {
2595             HI.Name = "test";
2596             HI.Kind = index::SymbolKind::Variable;
2597             HI.NamespaceScope = "";
2598             HI.LocalScope = "test::";
2599             HI.Type = "Test &&";
2600             HI.Definition = "Test &&test = {}";
2601           }},
2602       {
2603           R"cpp(// Shouldn't crash when evaluating the initializer.
2604             struct Bar {}; // error-ok
2605             struct Foo { void foo(Bar x = y); }
2606             void Foo::foo(Bar [[^x]]) {})cpp",
2607           [](HoverInfo &HI) {
2608             HI.Name = "x";
2609             HI.Kind = index::SymbolKind::Parameter;
2610             HI.NamespaceScope = "";
2611             HI.LocalScope = "Foo::foo::";
2612             HI.Type = "Bar";
2613             HI.Definition = "Bar x = <recovery - expr>()";
2614           }},
2615       {
2616           R"cpp(// auto on alias
2617           typedef int int_type;
2618           ^[[auto]] x = int_type();
2619           )cpp",
2620           [](HoverInfo &HI) {
2621             HI.Name = "auto";
2622             HI.Kind = index::SymbolKind::TypeAlias;
2623             HI.Definition = "int_type // aka: int";
2624           }},
2625       {
2626           R"cpp(// auto on alias
2627           struct cls {};
2628           typedef cls cls_type;
2629           ^[[auto]] y = cls_type();
2630           )cpp",
2631           [](HoverInfo &HI) {
2632             HI.Name = "auto";
2633             HI.Kind = index::SymbolKind::TypeAlias;
2634             HI.Definition = "cls_type // aka: cls";
2635             HI.Documentation = "auto on alias";
2636           }},
2637       {
2638           R"cpp(// auto on alias
2639           template <class>
2640           struct templ {};
2641           ^[[auto]] z = templ<int>();
2642           )cpp",
2643           [](HoverInfo &HI) {
2644             HI.Name = "auto";
2645             HI.Kind = index::SymbolKind::TypeAlias;
2646             HI.Definition = "templ<int>";
2647             HI.Documentation = "auto on alias";
2648           }},
2649       {
2650           R"cpp(// Undeduced auto declaration
2651             template<typename T>
2652             void foo() {
2653               ^[[auto]] x = T();
2654             }
2655           )cpp",
2656           [](HoverInfo &HI) {
2657             HI.Name = "auto";
2658             HI.Kind = index::SymbolKind::TypeAlias;
2659             HI.Definition = "/* not deduced */";
2660           }},
2661       {
2662           R"cpp(// Undeduced auto return type
2663             template<typename T>
2664             ^[[auto]] foo() {
2665               return T();
2666             }
2667           )cpp",
2668           [](HoverInfo &HI) {
2669             HI.Name = "auto";
2670             HI.Kind = index::SymbolKind::TypeAlias;
2671             HI.Definition = "/* not deduced */";
2672           }},
2673       {
2674           R"cpp(// Template auto parameter
2675             template<[[a^uto]] T>
2676               void func() {
2677             }
2678           )cpp",
2679           [](HoverInfo &HI) {
2680             // FIXME: not sure this is what we want, but this
2681             // is what we currently get with getDeducedType
2682             HI.Name = "auto";
2683             HI.Kind = index::SymbolKind::TypeAlias;
2684             HI.Definition = "/* not deduced */";
2685           }},
2686       {
2687           R"cpp(// Undeduced decltype(auto) return type
2688             template<typename T>
2689             ^[[decltype]](auto) foo() {
2690               return T();
2691             }
2692           )cpp",
2693           [](HoverInfo &HI) {
2694             HI.Name = "decltype";
2695             HI.Kind = index::SymbolKind::TypeAlias;
2696             HI.Definition = "/* not deduced */";
2697           }},
2698       {
2699           R"cpp(// should not crash.
2700           template <class T> struct cls {
2701             int method();
2702           };
2703 
2704           auto test = cls<int>().[[m^ethod]]();
2705           )cpp",
2706           [](HoverInfo &HI) {
2707             HI.Definition = "int method()";
2708             HI.Kind = index::SymbolKind::InstanceMethod;
2709             HI.NamespaceScope = "";
2710             HI.LocalScope = "cls<int>::";
2711             HI.Name = "method";
2712             HI.Parameters.emplace();
2713             HI.ReturnType = "int";
2714             HI.Type = "int ()";
2715           }},
2716       {
2717           R"cpp(// type of nested templates.
2718           template <class T> struct cls {};
2719           cls<cls<cls<int>>> [[fo^o]];
2720           )cpp",
2721           [](HoverInfo &HI) {
2722             HI.Definition = "cls<cls<cls<int>>> foo";
2723             HI.Kind = index::SymbolKind::Variable;
2724             HI.NamespaceScope = "";
2725             HI.Name = "foo";
2726             HI.Type = "cls<cls<cls<int>>>";
2727           }},
2728       {
2729           R"cpp(// type of nested templates.
2730           template <class T> struct cls {};
2731           [[cl^s]]<cls<cls<int>>> foo;
2732           )cpp",
2733           [](HoverInfo &HI) {
2734             HI.Definition = "template <> struct cls<cls<cls<int>>> {}";
2735             HI.Kind = index::SymbolKind::Struct;
2736             HI.NamespaceScope = "";
2737             HI.Name = "cls<cls<cls<int>>>";
2738             HI.Documentation = "type of nested templates.";
2739           }},
2740       {
2741           R"cpp(// type with decltype
2742           int a;
2743           decltype(a) [[b^]] = a;)cpp",
2744           [](HoverInfo &HI) {
2745             HI.Definition = "decltype(a) b = a";
2746             HI.Kind = index::SymbolKind::Variable;
2747             HI.NamespaceScope = "";
2748             HI.Name = "b";
2749             HI.Type = "int";
2750           }},
2751       {
2752           R"cpp(// type with decltype
2753           int a;
2754           decltype(a) c;
2755           decltype(c) [[b^]] = a;)cpp",
2756           [](HoverInfo &HI) {
2757             HI.Definition = "decltype(c) b = a";
2758             HI.Kind = index::SymbolKind::Variable;
2759             HI.NamespaceScope = "";
2760             HI.Name = "b";
2761             HI.Type = "int";
2762           }},
2763       {
2764           R"cpp(// type with decltype
2765           int a;
2766           const decltype(a) [[b^]] = a;)cpp",
2767           [](HoverInfo &HI) {
2768             HI.Definition = "const decltype(a) b = a";
2769             HI.Kind = index::SymbolKind::Variable;
2770             HI.NamespaceScope = "";
2771             HI.Name = "b";
2772             HI.Type = "int";
2773           }},
2774       {
2775           R"cpp(// type with decltype
2776           int a;
2777           auto [[f^oo]](decltype(a) x) -> decltype(a) { return 0; })cpp",
2778           [](HoverInfo &HI) {
2779             HI.Definition = "auto foo(decltype(a) x) -> decltype(a)";
2780             HI.Kind = index::SymbolKind::Function;
2781             HI.NamespaceScope = "";
2782             HI.Name = "foo";
2783             // FIXME: Handle composite types with decltype with a printing
2784             // policy.
2785             HI.Type = {"auto (decltype(a)) -> decltype(a)",
2786                        "auto (int) -> int"};
2787             HI.ReturnType = "int";
2788             HI.Parameters = {{{"int"}, std::string("x"), std::nullopt}};
2789           }},
2790       {
2791           R"cpp(// sizeof expr
2792           void foo() {
2793             (void)[[size^of]](char);
2794           })cpp",
2795           [](HoverInfo &HI) {
2796             HI.Name = "expression";
2797             HI.Type = "unsigned long";
2798             HI.Value = "1";
2799           }},
2800       {
2801           R"cpp(// alignof expr
2802           void foo() {
2803             (void)[[align^of]](char);
2804           })cpp",
2805           [](HoverInfo &HI) {
2806             HI.Name = "expression";
2807             HI.Type = "unsigned long";
2808             HI.Value = "1";
2809           }},
2810       {
2811           R"cpp(
2812           template <typename T = int>
2813           void foo(const T& = T()) {
2814             [[f^oo]]<>(3);
2815           })cpp",
2816           [](HoverInfo &HI) {
2817             HI.Name = "foo";
2818             HI.Kind = index::SymbolKind::Function;
2819             HI.Type = "void (const int &)";
2820             HI.ReturnType = "void";
2821             HI.Parameters = {
2822                 {{"const int &"}, std::nullopt, std::string("T()")}};
2823             HI.Definition = "template <> void foo<int>(const int &)";
2824             HI.NamespaceScope = "";
2825           }},
2826       {
2827           R"cpp(// should not crash
2828            @interface ObjC {
2829              char [[da^ta]];
2830            }@end
2831           )cpp",
2832           [](HoverInfo &HI) {
2833             HI.Name = "data";
2834             HI.Type = "char";
2835             HI.Kind = index::SymbolKind::Field;
2836             HI.LocalScope = "ObjC::";
2837             HI.NamespaceScope = "";
2838             HI.Definition = "char data";
2839           }},
2840       {
2841           R"cpp(
2842           @interface MYObject
2843           @end
2844           @interface Interface
2845           @property(retain) [[MYOb^ject]] *x;
2846           @end
2847           )cpp",
2848           [](HoverInfo &HI) {
2849             HI.Name = "MYObject";
2850             HI.Kind = index::SymbolKind::Class;
2851             HI.NamespaceScope = "";
2852             HI.Definition = "@interface MYObject\n@end";
2853           }},
2854       {
2855           R"cpp(
2856           @interface MYObject
2857           @end
2858           @interface Interface
2859           - (void)doWith:([[MYOb^ject]] *)object;
2860           @end
2861           )cpp",
2862           [](HoverInfo &HI) {
2863             HI.Name = "MYObject";
2864             HI.Kind = index::SymbolKind::Class;
2865             HI.NamespaceScope = "";
2866             HI.Definition = "@interface MYObject\n@end";
2867           }},
2868       {
2869           R"cpp(// this expr
2870           // comment
2871           namespace ns {
2872             class Foo {
2873               Foo* bar() {
2874                 return [[t^his]];
2875               }
2876             };
2877           }
2878           )cpp",
2879           [](HoverInfo &HI) {
2880             HI.Name = "this";
2881             HI.Definition = "ns::Foo *";
2882           }},
2883       {
2884           R"cpp(// this expr for template class
2885           namespace ns {
2886             template <typename T>
2887             class Foo {
2888               Foo* bar() const {
2889                 return [[t^his]];
2890               }
2891             };
2892           }
2893           )cpp",
2894           [](HoverInfo &HI) {
2895             HI.Name = "this";
2896             HI.Definition = "const Foo<T> *";
2897           }},
2898       {
2899           R"cpp(// this expr for specialization class
2900           namespace ns {
2901             template <typename T> class Foo {};
2902             template <>
2903             struct Foo<int> {
2904               Foo* bar() {
2905                 return [[thi^s]];
2906               }
2907             };
2908           }
2909           )cpp",
2910           [](HoverInfo &HI) {
2911             HI.Name = "this";
2912             HI.Definition = "Foo<int> *";
2913           }},
2914       {
2915           R"cpp(// this expr for partial specialization struct
2916           namespace ns {
2917             template <typename T, typename F> struct Foo {};
2918             template <typename F>
2919             struct Foo<int, F> {
2920               Foo* bar() const {
2921                 return [[thi^s]];
2922               }
2923             };
2924           }
2925           )cpp",
2926           [](HoverInfo &HI) {
2927             HI.Name = "this";
2928             HI.Definition = "const Foo<int, F> *";
2929           }},
2930       {
2931           R"cpp(
2932           @interface MYObject
2933           @end
2934           @interface MYObject (Private)
2935           @property(nonatomic, assign) int privateField;
2936           @end
2937 
2938           int someFunction() {
2939             MYObject *obj = [MYObject sharedInstance];
2940             return obj.[[private^Field]];
2941           }
2942           )cpp",
2943           [](HoverInfo &HI) {
2944             HI.Name = "privateField";
2945             HI.Kind = index::SymbolKind::InstanceProperty;
2946             HI.LocalScope = "MYObject(Private)::";
2947             HI.NamespaceScope = "";
2948             HI.Definition = "@property(nonatomic, assign, unsafe_unretained, "
2949                             "readwrite) int privateField;";
2950           }},
2951       {
2952           R"cpp(
2953           @protocol MYProtocol
2954           @property(nonatomic, assign) int prop1;
2955           @end
2956 
2957           int someFunction() {
2958             id<MYProtocol> obj = 0;
2959             return obj.[[pro^p1]];
2960           }
2961           )cpp",
2962           [](HoverInfo &HI) {
2963             HI.Name = "prop1";
2964             HI.Kind = index::SymbolKind::InstanceProperty;
2965             HI.LocalScope = "MYProtocol::";
2966             HI.NamespaceScope = "";
2967             HI.Definition = "@property(nonatomic, assign, unsafe_unretained, "
2968                             "readwrite) int prop1;";
2969           }},
2970       {
2971           R"cpp(
2972           @protocol MYProtocol
2973           @end
2974           @interface MYObject
2975           @end
2976 
2977           @interface MYObject (Ext) <[[MYProt^ocol]]>
2978           @end
2979           )cpp",
2980           [](HoverInfo &HI) {
2981             HI.Name = "MYProtocol";
2982             HI.Kind = index::SymbolKind::Protocol;
2983             HI.NamespaceScope = "";
2984             HI.Definition = "@protocol MYProtocol\n@end";
2985           }},
2986       {R"objc(
2987         @interface Foo
2988         @end
2989 
2990         @implementation Foo(Private)
2991         + (int)somePrivateMethod {
2992           int [[res^ult]] = 2;
2993           return result;
2994         }
2995         @end
2996         )objc",
2997        [](HoverInfo &HI) {
2998          HI.Name = "result";
2999          HI.Definition = "int result = 2";
3000          HI.Kind = index::SymbolKind::Variable;
3001          HI.Type = "int";
3002          HI.LocalScope = "+[Foo(Private) somePrivateMethod]::";
3003          HI.NamespaceScope = "";
3004          HI.Value = "2";
3005        }},
3006       {R"objc(
3007         @interface Foo
3008         @end
3009 
3010         @implementation Foo
3011         - (int)variadicArgMethod:(id)first, ... {
3012           int [[res^ult]] = 0;
3013           return result;
3014         }
3015         @end
3016         )objc",
3017        [](HoverInfo &HI) {
3018          HI.Name = "result";
3019          HI.Definition = "int result = 0";
3020          HI.Kind = index::SymbolKind::Variable;
3021          HI.Type = "int";
3022          HI.LocalScope = "-[Foo variadicArgMethod:, ...]::";
3023          HI.NamespaceScope = "";
3024          HI.Value = "0";
3025        }},
3026       // Should not crash.
3027       {R"objc(
3028         typedef struct MyRect {} MyRect;
3029 
3030         @interface IFace
3031         @property(nonatomic) MyRect frame;
3032         @end
3033 
3034         MyRect foobar() {
3035           MyRect mr;
3036           return mr;
3037         }
3038         void test() {
3039           IFace *v;
3040           v.frame = [[foo^bar]]();
3041         }
3042         )objc",
3043        [](HoverInfo &HI) {
3044          HI.Name = "foobar";
3045          HI.Kind = index::SymbolKind::Function;
3046          HI.NamespaceScope = "";
3047          HI.Definition = "MyRect foobar()";
3048          HI.Type = {"MyRect ()", "MyRect ()"};
3049          HI.ReturnType = {"MyRect", "MyRect"};
3050          HI.Parameters.emplace();
3051        }},
3052       {R"cpp(
3053          void foo(int * __attribute__(([[non^null]], noescape)) );
3054          )cpp",
3055        [](HoverInfo &HI) {
3056          HI.Name = "nonnull";
3057          HI.Kind = index::SymbolKind::Unknown; // FIXME: no suitable value
3058          HI.Definition = "__attribute__((nonnull))";
3059          HI.Documentation = Attr::getDocumentation(attr::NonNull).str();
3060        }},
3061       {
3062           R"cpp(
3063           namespace std {
3064           struct strong_ordering {
3065             int n;
3066             constexpr operator int() const { return n; }
3067             static const strong_ordering equal, greater, less;
3068           };
3069           constexpr strong_ordering strong_ordering::equal = {0};
3070           constexpr strong_ordering strong_ordering::greater = {1};
3071           constexpr strong_ordering strong_ordering::less = {-1};
3072           }
3073 
3074           struct Foo
3075           {
3076             int x;
3077             // Foo spaceship
3078             auto operator<=>(const Foo&) const = default;
3079           };
3080 
3081           bool x = Foo(1) [[!^=]] Foo(2);
3082          )cpp",
3083           [](HoverInfo &HI) {
3084             HI.Type = "bool (const Foo &) const noexcept";
3085             HI.Value = "true";
3086             HI.Name = "operator==";
3087             HI.Parameters = {{{"const Foo &"}, std::nullopt, std::nullopt}};
3088             HI.ReturnType = "bool";
3089             HI.Kind = index::SymbolKind::InstanceMethod;
3090             HI.LocalScope = "Foo::";
3091             HI.NamespaceScope = "";
3092             HI.Definition =
3093                 "bool operator==(const Foo &) const noexcept = default";
3094             HI.Documentation = "";
3095           }},
3096   };
3097 
3098   // Create a tiny index, so tests above can verify documentation is fetched.
3099   Symbol IndexSym = func("indexSymbol");
3100   IndexSym.Documentation = "comment from index";
3101   SymbolSlab::Builder Symbols;
3102   Symbols.insert(IndexSym);
3103   auto Index =
3104       MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab());
3105 
3106   for (const auto &Case : Cases) {
3107     SCOPED_TRACE(Case.Code);
3108 
3109     Annotations T(Case.Code);
3110     TestTU TU = TestTU::withCode(T.code());
3111     TU.ExtraArgs.push_back("-std=c++20");
3112     TU.ExtraArgs.push_back("-xobjective-c++");
3113 
3114     TU.ExtraArgs.push_back("-Wno-gnu-designator");
3115     // Types might be different depending on the target triplet, we chose a
3116     // fixed one to make sure tests passes on different platform.
3117     TU.ExtraArgs.push_back("--target=x86_64-pc-linux-gnu");
3118     auto AST = TU.build();
3119     Config Cfg;
3120     Cfg.Hover.ShowAKA = true;
3121     WithContextValue WithCfg(Config::Key, std::move(Cfg));
3122     auto H = getHover(AST, T.point(), format::getLLVMStyle(), Index.get());
3123     ASSERT_TRUE(H);
3124     HoverInfo Expected;
3125     Expected.SymRange = T.range();
3126     Case.ExpectedBuilder(Expected);
3127 
3128     SCOPED_TRACE(H->present().asPlainText());
3129     EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
3130     EXPECT_EQ(H->LocalScope, Expected.LocalScope);
3131     EXPECT_EQ(H->Name, Expected.Name);
3132     EXPECT_EQ(H->Kind, Expected.Kind);
3133     EXPECT_EQ(H->Documentation, Expected.Documentation);
3134     EXPECT_EQ(H->Definition, Expected.Definition);
3135     EXPECT_EQ(H->Type, Expected.Type);
3136     EXPECT_EQ(H->ReturnType, Expected.ReturnType);
3137     EXPECT_EQ(H->Parameters, Expected.Parameters);
3138     EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
3139     EXPECT_EQ(H->SymRange, Expected.SymRange);
3140     EXPECT_EQ(H->Value, Expected.Value);
3141   }
3142 }
3143 
3144 TEST(Hover, Providers) {
3145   struct {
3146     const char *Code;
3147     const std::function<void(HoverInfo &)> ExpectedBuilder;
3148   } Cases[] = {{R"cpp(
3149                   struct Foo {};
3150                   Foo F = Fo^o{};
3151                 )cpp",
3152                 [](HoverInfo &HI) { HI.Provider = ""; }},
3153                {R"cpp(
3154                   #include "foo.h"
3155                   Foo F = Fo^o{};
3156                 )cpp",
3157                 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3158                {R"cpp(
3159                   #include "all.h"
3160                   Foo F = Fo^o{};
3161                 )cpp",
3162                 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3163                {R"cpp(
3164                   #define FOO 5
3165                   int F = ^FOO;
3166                 )cpp",
3167                 [](HoverInfo &HI) { HI.Provider = ""; }},
3168                {R"cpp(
3169                   #include "foo.h"
3170                   int F = ^FOO;
3171                 )cpp",
3172                 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3173                {R"cpp(
3174                   #include "all.h"
3175                   int F = ^FOO;
3176                 )cpp",
3177                 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3178                {R"cpp(
3179                   #include "foo.h"
3180                   Foo A;
3181                   Foo B;
3182                   Foo C = A ^+ B;
3183                 )cpp",
3184                 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3185                // Hover selects the underlying decl of the using decl
3186                {R"cpp(
3187                   #include "foo.h"
3188                   namespace ns {
3189                     using ::Foo;
3190                   }
3191                   ns::F^oo d;
3192                 )cpp",
3193                 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3194                 {R"cpp(
3195                   namespace foo {};
3196                   using namespace fo^o;
3197                 )cpp",
3198                 [](HoverInfo &HI) { HI.Provider = ""; }},
3199                 };
3200 
3201   for (const auto &Case : Cases) {
3202     Annotations Code{Case.Code};
3203     SCOPED_TRACE(Code.code());
3204 
3205     TestTU TU;
3206     TU.Filename = "foo.cpp";
3207     TU.Code = Code.code();
3208     TU.AdditionalFiles["foo.h"] = guard(R"cpp(
3209                                           #define FOO 1
3210                                           class Foo {};
3211                                           Foo& operator+(const Foo, const Foo);
3212                                         )cpp");
3213     TU.AdditionalFiles["all.h"] = guard("#include \"foo.h\"");
3214 
3215     auto AST = TU.build();
3216     auto H = getHover(AST, Code.point(), format::getLLVMStyle(), nullptr);
3217     ASSERT_TRUE(H);
3218     HoverInfo Expected;
3219     Case.ExpectedBuilder(Expected);
3220     SCOPED_TRACE(H->present().asMarkdown());
3221     EXPECT_EQ(H->Provider, Expected.Provider);
3222   }
3223 }
3224 
3225 TEST(Hover, ParseProviderInfo) {
3226   HoverInfo HIFoo;
3227   HIFoo.Name = "foo";
3228   HIFoo.Provider = "\"foo.h\"";
3229 
3230   HoverInfo HIFooBar;
3231   HIFooBar.Name = "foo";
3232   HIFooBar.Provider = "<bar.h>";
3233   struct Case {
3234     HoverInfo HI;
3235     llvm::StringRef ExpectedMarkdown;
3236   } Cases[] = {{HIFoo, "### `foo`  \nprovided by `\"foo.h\"`"},
3237                {HIFooBar, "### `foo`  \nprovided by `<bar.h>`"}};
3238 
3239   for (const auto &Case : Cases)
3240     EXPECT_EQ(Case.HI.present().asMarkdown(), Case.ExpectedMarkdown);
3241 }
3242 
3243 TEST(Hover, UsedSymbols) {
3244   struct {
3245     const char *Code;
3246     const std::function<void(HoverInfo &)> ExpectedBuilder;
3247   } Cases[] = {{R"cpp(
3248                   #include ^"bar.h"
3249                   int fstBar = bar1();
3250                   int another= bar1(0);
3251                   int sndBar = bar2();
3252                   Bar bar;
3253                   int macroBar = BAR;
3254                 )cpp",
3255                 [](HoverInfo &HI) {
3256                   HI.UsedSymbolNames = {"BAR", "Bar", "bar1", "bar2"};
3257                 }},
3258                {R"cpp(
3259                   #in^clude <vector>
3260                   std::vector<int> vec;
3261                 )cpp",
3262                 [](HoverInfo &HI) { HI.UsedSymbolNames = {"vector"}; }}};
3263   for (const auto &Case : Cases) {
3264     Annotations Code{Case.Code};
3265     SCOPED_TRACE(Code.code());
3266 
3267     TestTU TU;
3268     TU.Filename = "foo.cpp";
3269     TU.Code = Code.code();
3270     TU.AdditionalFiles["bar.h"] = guard(R"cpp(
3271                                           #define BAR 5
3272                                           int bar1();
3273                                           int bar2();
3274                                           int bar1(double);
3275                                           class Bar {};
3276                                         )cpp");
3277     TU.AdditionalFiles["system/vector"] = guard(R"cpp(
3278       namespace std {
3279         template<typename>
3280         class vector{};
3281       }
3282     )cpp");
3283     TU.ExtraArgs.push_back("-isystem" + testPath("system"));
3284 
3285     auto AST = TU.build();
3286     auto H = getHover(AST, Code.point(), format::getLLVMStyle(), nullptr);
3287     ASSERT_TRUE(H);
3288     HoverInfo Expected;
3289     Case.ExpectedBuilder(Expected);
3290     SCOPED_TRACE(H->present().asMarkdown());
3291     EXPECT_EQ(H->UsedSymbolNames, Expected.UsedSymbolNames);
3292   }
3293 }
3294 
3295 TEST(Hover, DocsFromIndex) {
3296   Annotations T(R"cpp(
3297   template <typename T> class X {};
3298   void foo() {
3299     auto t = X<int>();
3300     X^<int> w;
3301     (void)w;
3302   })cpp");
3303 
3304   TestTU TU = TestTU::withCode(T.code());
3305   auto AST = TU.build();
3306   Symbol IndexSym;
3307   IndexSym.ID = getSymbolID(&findDecl(AST, "X"));
3308   IndexSym.Documentation = "comment from index";
3309   SymbolSlab::Builder Symbols;
3310   Symbols.insert(IndexSym);
3311   auto Index =
3312       MemIndex::build(std::move(Symbols).build(), RefSlab(), RelationSlab());
3313 
3314   for (const auto &P : T.points()) {
3315     auto H = getHover(AST, P, format::getLLVMStyle(), Index.get());
3316     ASSERT_TRUE(H);
3317     EXPECT_EQ(H->Documentation, IndexSym.Documentation);
3318   }
3319 }
3320 
3321 TEST(Hover, DocsFromAST) {
3322   Annotations T(R"cpp(
3323   // doc
3324   template <typename T> class X {};
3325   // doc
3326   template <typename T> void bar() {}
3327   // doc
3328   template <typename T> T baz;
3329   void foo() {
3330     au^to t = X<int>();
3331     X^<int>();
3332     b^ar<int>();
3333     au^to T = ba^z<X<int>>;
3334     ba^z<int> = 0;
3335   })cpp");
3336 
3337   TestTU TU = TestTU::withCode(T.code());
3338   auto AST = TU.build();
3339   for (const auto &P : T.points()) {
3340     auto H = getHover(AST, P, format::getLLVMStyle(), nullptr);
3341     ASSERT_TRUE(H);
3342     EXPECT_EQ(H->Documentation, "doc");
3343   }
3344 }
3345 
3346 TEST(Hover, NoCrash) {
3347   Annotations T(R"cpp(
3348     /* error-ok */
3349     template<typename T> T foo(T);
3350 
3351     // Setter variable heuristic might fail if the callexpr is broken.
3352     struct X { int Y; void [[^setY]](float) { Y = foo(undefined); } };)cpp");
3353 
3354   TestTU TU = TestTU::withCode(T.code());
3355   auto AST = TU.build();
3356   for (const auto &P : T.points())
3357     getHover(AST, P, format::getLLVMStyle(), nullptr);
3358 }
3359 
3360 TEST(Hover, NoCrashAPInt64) {
3361   Annotations T(R"cpp(
3362     constexpr unsigned long value = -1; // wrap around
3363     void foo() { va^lue; }
3364   )cpp");
3365   auto AST = TestTU::withCode(T.code()).build();
3366   getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
3367 }
3368 
3369 TEST(Hover, NoCrashInt128) {
3370   Annotations T(R"cpp(
3371     constexpr __int128_t value = -4;
3372     void foo() { va^lue; }
3373   )cpp");
3374   auto TU = TestTU::withCode(T.code());
3375   // Need a triple that support __int128_t.
3376   TU.ExtraArgs.push_back("--target=x86_64-pc-linux-gnu");
3377   auto AST = TU.build();
3378   auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
3379   ASSERT_TRUE(H);
3380   EXPECT_EQ(H->Value, "-4 (0xfffffffc)");
3381 }
3382 
3383 TEST(Hover, DocsFromMostSpecial) {
3384   Annotations T(R"cpp(
3385   // doc1
3386   template <typename T> class $doc1^X {};
3387   // doc2
3388   template <> class $doc2^X<int> {};
3389   // doc3
3390   template <typename T> class $doc3^X<T*> {};
3391   void foo() {
3392     X$doc1^<char>();
3393     X$doc2^<int>();
3394     X$doc3^<int*>();
3395   })cpp");
3396 
3397   TestTU TU = TestTU::withCode(T.code());
3398   auto AST = TU.build();
3399   for (const auto *Comment : {"doc1", "doc2", "doc3"}) {
3400     for (const auto &P : T.points(Comment)) {
3401       auto H = getHover(AST, P, format::getLLVMStyle(), nullptr);
3402       ASSERT_TRUE(H);
3403       EXPECT_EQ(H->Documentation, Comment);
3404     }
3405   }
3406 }
3407 
3408 TEST(Hover, Present) {
3409   struct {
3410     const std::function<void(HoverInfo &)> Builder;
3411     llvm::StringRef ExpectedRender;
3412   } Cases[] = {
3413       {
3414           [](HoverInfo &HI) {
3415             HI.Kind = index::SymbolKind::Unknown;
3416             HI.Name = "X";
3417           },
3418           R"(X)",
3419       },
3420       {
3421           [](HoverInfo &HI) {
3422             HI.Kind = index::SymbolKind::NamespaceAlias;
3423             HI.Name = "foo";
3424           },
3425           R"(namespace-alias foo)",
3426       },
3427       {
3428           [](HoverInfo &HI) {
3429             HI.Kind = index::SymbolKind::Class;
3430             HI.Size = 80;
3431             HI.TemplateParameters = {
3432                 {{"typename"}, std::string("T"), std::nullopt},
3433                 {{"typename"}, std::string("C"), std::string("bool")},
3434             };
3435             HI.Documentation = "documentation";
3436             HI.Definition =
3437                 "template <typename T, typename C = bool> class Foo {}";
3438             HI.Name = "foo";
3439             HI.NamespaceScope.emplace();
3440           },
3441           R"(class foo
3442 
3443 Size: 10 bytes
3444 documentation
3445 
3446 template <typename T, typename C = bool> class Foo {})",
3447       },
3448       {
3449           [](HoverInfo &HI) {
3450             HI.Kind = index::SymbolKind::Function;
3451             HI.Name = "foo";
3452             HI.Type = {"type", "c_type"};
3453             HI.ReturnType = {"ret_type", "can_ret_type"};
3454             HI.Parameters.emplace();
3455             HoverInfo::Param P;
3456             HI.Parameters->push_back(P);
3457             P.Type = {"type", "can_type"};
3458             HI.Parameters->push_back(P);
3459             P.Name = "foo";
3460             HI.Parameters->push_back(P);
3461             P.Default = "default";
3462             HI.Parameters->push_back(P);
3463             HI.NamespaceScope = "ns::";
3464             HI.Definition = "ret_type foo(params) {}";
3465           },
3466           "function foo\n"
3467           "\n"
3468           "→ ret_type (aka can_ret_type)\n"
3469           "Parameters:\n"
3470           "- \n"
3471           "- type (aka can_type)\n"
3472           "- type foo (aka can_type)\n"
3473           "- type foo = default (aka can_type)\n"
3474           "\n"
3475           "// In namespace ns\n"
3476           "ret_type foo(params) {}",
3477       },
3478       {
3479           [](HoverInfo &HI) {
3480             HI.Kind = index::SymbolKind::Field;
3481             HI.LocalScope = "test::Bar::";
3482             HI.Value = "value";
3483             HI.Name = "foo";
3484             HI.Type = {"type", "can_type"};
3485             HI.Definition = "def";
3486             HI.Size = 32;
3487             HI.Offset = 96;
3488             HI.Padding = 32;
3489             HI.Align = 32;
3490           },
3491           R"(field foo
3492 
3493 Type: type (aka can_type)
3494 Value = value
3495 Offset: 12 bytes
3496 Size: 4 bytes (+4 bytes padding), alignment 4 bytes
3497 
3498 // In test::Bar
3499 def)",
3500       },
3501       {
3502           [](HoverInfo &HI) {
3503             HI.Kind = index::SymbolKind::Field;
3504             HI.LocalScope = "test::Bar::";
3505             HI.Value = "value";
3506             HI.Name = "foo";
3507             HI.Type = {"type", "can_type"};
3508             HI.Definition = "def";
3509             HI.Size = 25;
3510             HI.Offset = 35;
3511             HI.Padding = 4;
3512             HI.Align = 64;
3513           },
3514           R"(field foo
3515 
3516 Type: type (aka can_type)
3517 Value = value
3518 Offset: 4 bytes and 3 bits
3519 Size: 25 bits (+4 bits padding), alignment 8 bytes
3520 
3521 // In test::Bar
3522 def)",
3523       },
3524       {
3525           [](HoverInfo &HI) {
3526             HI.Kind = index::SymbolKind::Field;
3527             HI.AccessSpecifier = "public";
3528             HI.Name = "foo";
3529             HI.LocalScope = "test::Bar::";
3530             HI.Definition = "def";
3531           },
3532           R"(field foo
3533 
3534 // In test::Bar
3535 public: def)",
3536       },
3537       {
3538           [](HoverInfo &HI) {
3539             HI.Definition = "size_t method()";
3540             HI.AccessSpecifier = "protected";
3541             HI.Kind = index::SymbolKind::InstanceMethod;
3542             HI.NamespaceScope = "";
3543             HI.LocalScope = "cls<int>::";
3544             HI.Name = "method";
3545             HI.Parameters.emplace();
3546             HI.ReturnType = {"size_t", "unsigned long"};
3547             HI.Type = {"size_t ()", "unsigned long ()"};
3548           },
3549           R"(instance-method method
3550 
3551 → size_t (aka unsigned long)
3552 
3553 // In cls<int>
3554 protected: size_t method())",
3555       },
3556       {
3557           [](HoverInfo &HI) {
3558             HI.Definition = "cls(int a, int b = 5)";
3559             HI.AccessSpecifier = "public";
3560             HI.Kind = index::SymbolKind::Constructor;
3561             HI.NamespaceScope = "";
3562             HI.LocalScope = "cls";
3563             HI.Name = "cls";
3564             HI.Parameters.emplace();
3565             HI.Parameters->emplace_back();
3566             HI.Parameters->back().Type = "int";
3567             HI.Parameters->back().Name = "a";
3568             HI.Parameters->emplace_back();
3569             HI.Parameters->back().Type = "int";
3570             HI.Parameters->back().Name = "b";
3571             HI.Parameters->back().Default = "5";
3572           },
3573           R"(constructor cls
3574 
3575 Parameters:
3576 - int a
3577 - int b = 5
3578 
3579 // In cls
3580 public: cls(int a, int b = 5))",
3581       },
3582       {
3583           [](HoverInfo &HI) {
3584             HI.Kind = index::SymbolKind::Union;
3585             HI.AccessSpecifier = "private";
3586             HI.Name = "foo";
3587             HI.NamespaceScope = "ns1::";
3588             HI.Definition = "union foo {}";
3589           },
3590           R"(union foo
3591 
3592 // In namespace ns1
3593 private: union foo {})",
3594       },
3595       {
3596           [](HoverInfo &HI) {
3597             HI.Kind = index::SymbolKind::Variable;
3598             HI.Name = "foo";
3599             HI.Definition = "int foo = 3";
3600             HI.LocalScope = "test::Bar::";
3601             HI.Value = "3";
3602             HI.Type = "int";
3603             HI.CalleeArgInfo.emplace();
3604             HI.CalleeArgInfo->Name = "arg_a";
3605             HI.CalleeArgInfo->Type = "int";
3606             HI.CalleeArgInfo->Default = "7";
3607             HI.CallPassType = HoverInfo::PassType{PassMode::Value, false};
3608           },
3609           R"(variable foo
3610 
3611 Type: int
3612 Value = 3
3613 Passed as arg_a
3614 
3615 // In test::Bar
3616 int foo = 3)",
3617       },
3618       {
3619           [](HoverInfo &HI) {
3620             HI.Kind = index::SymbolKind::Variable;
3621             HI.Name = "foo";
3622             HI.CalleeArgInfo.emplace();
3623             HI.CalleeArgInfo->Type = "int";
3624             HI.CallPassType = HoverInfo::PassType{PassMode::Value, false};
3625           },
3626           R"(variable foo
3627 
3628 Passed by value)",
3629       },
3630       {
3631           [](HoverInfo &HI) {
3632             HI.Kind = index::SymbolKind::Variable;
3633             HI.Name = "foo";
3634             HI.Definition = "int foo = 3";
3635             HI.LocalScope = "test::Bar::";
3636             HI.Value = "3";
3637             HI.Type = "int";
3638             HI.CalleeArgInfo.emplace();
3639             HI.CalleeArgInfo->Name = "arg_a";
3640             HI.CalleeArgInfo->Type = "int";
3641             HI.CalleeArgInfo->Default = "7";
3642             HI.CallPassType = HoverInfo::PassType{PassMode::Ref, false};
3643           },
3644           R"(variable foo
3645 
3646 Type: int
3647 Value = 3
3648 Passed by reference as arg_a
3649 
3650 // In test::Bar
3651 int foo = 3)",
3652       },
3653       {
3654           [](HoverInfo &HI) {
3655             HI.Kind = index::SymbolKind::Variable;
3656             HI.Name = "foo";
3657             HI.Definition = "int foo = 3";
3658             HI.LocalScope = "test::Bar::";
3659             HI.Value = "3";
3660             HI.Type = "int";
3661             HI.CalleeArgInfo.emplace();
3662             HI.CalleeArgInfo->Name = "arg_a";
3663             HI.CalleeArgInfo->Type = {"alias_int", "int"};
3664             HI.CalleeArgInfo->Default = "7";
3665             HI.CallPassType = HoverInfo::PassType{PassMode::Value, true};
3666           },
3667           R"(variable foo
3668 
3669 Type: int
3670 Value = 3
3671 Passed as arg_a (converted to alias_int)
3672 
3673 // In test::Bar
3674 int foo = 3)",
3675       },
3676       {
3677           [](HoverInfo &HI) {
3678             HI.Kind = index::SymbolKind::Macro;
3679             HI.Name = "PLUS_ONE";
3680             HI.Definition = "#define PLUS_ONE(X) (X+1)\n\n"
3681                             "// Expands to\n"
3682                             "(1 + 1)";
3683           },
3684           R"(macro PLUS_ONE
3685 
3686 #define PLUS_ONE(X) (X+1)
3687 
3688 // Expands to
3689 (1 + 1))",
3690       },
3691       {
3692           [](HoverInfo &HI) {
3693             HI.Kind = index::SymbolKind::Variable;
3694             HI.Name = "foo";
3695             HI.Definition = "int foo = 3";
3696             HI.LocalScope = "test::Bar::";
3697             HI.Value = "3";
3698             HI.Type = "int";
3699             HI.CalleeArgInfo.emplace();
3700             HI.CalleeArgInfo->Name = "arg_a";
3701             HI.CalleeArgInfo->Type = "int";
3702             HI.CalleeArgInfo->Default = "7";
3703             HI.CallPassType = HoverInfo::PassType{PassMode::ConstRef, true};
3704           },
3705           R"(variable foo
3706 
3707 Type: int
3708 Value = 3
3709 Passed by const reference as arg_a (converted to int)
3710 
3711 // In test::Bar
3712 int foo = 3)",
3713       },
3714       {
3715           [](HoverInfo &HI) {
3716             HI.Name = "stdio.h";
3717             HI.Definition = "/usr/include/stdio.h";
3718           },
3719           R"(stdio.h
3720 
3721 /usr/include/stdio.h)",
3722       },
3723       {[](HoverInfo &HI) {
3724          HI.Name = "foo.h";
3725          HI.UsedSymbolNames = {"Foo", "Bar", "Bar"};
3726        },
3727        R"(foo.h
3728 
3729 provides Foo, Bar, Bar)"},
3730       {[](HoverInfo &HI) {
3731          HI.Name = "foo.h";
3732          HI.UsedSymbolNames = {"Foo", "Bar", "Baz", "Foobar", "Qux", "Quux"};
3733        },
3734        R"(foo.h
3735 
3736 provides Foo, Bar, Baz, Foobar, Qux and 1 more)"}};
3737 
3738   for (const auto &C : Cases) {
3739     HoverInfo HI;
3740     C.Builder(HI);
3741     Config Cfg;
3742     Cfg.Hover.ShowAKA = true;
3743     WithContextValue WithCfg(Config::Key, std::move(Cfg));
3744     EXPECT_EQ(HI.present().asPlainText(), C.ExpectedRender);
3745   }
3746 }
3747 
3748 TEST(Hover, ParseDocumentation) {
3749   struct Case {
3750     llvm::StringRef Documentation;
3751     llvm::StringRef ExpectedRenderMarkdown;
3752     llvm::StringRef ExpectedRenderPlainText;
3753   } Cases[] = {{
3754                    " \n foo\nbar",
3755                    "foo bar",
3756                    "foo bar",
3757                },
3758                {
3759                    "foo\nbar \n  ",
3760                    "foo bar",
3761                    "foo bar",
3762                },
3763                {
3764                    "foo  \nbar",
3765                    "foo bar",
3766                    "foo bar",
3767                },
3768                {
3769                    "foo    \nbar",
3770                    "foo bar",
3771                    "foo bar",
3772                },
3773                {
3774                    "foo\n\n\nbar",
3775                    "foo  \nbar",
3776                    "foo\nbar",
3777                },
3778                {
3779                    "foo\n\n\n\tbar",
3780                    "foo  \nbar",
3781                    "foo\nbar",
3782                },
3783                {
3784                    "foo\n\n\n bar",
3785                    "foo  \nbar",
3786                    "foo\nbar",
3787                },
3788                {
3789                    "foo.\nbar",
3790                    "foo.  \nbar",
3791                    "foo.\nbar",
3792                },
3793                {
3794                    "foo. \nbar",
3795                    "foo.  \nbar",
3796                    "foo.\nbar",
3797                },
3798                {
3799                    "foo\n*bar",
3800                    "foo  \n\\*bar",
3801                    "foo\n*bar",
3802                },
3803                {
3804                    "foo\nbar",
3805                    "foo bar",
3806                    "foo bar",
3807                },
3808                {
3809                    "Tests primality of `p`.",
3810                    "Tests primality of `p`.",
3811                    "Tests primality of `p`.",
3812                },
3813                {
3814                    "'`' should not occur in `Code`",
3815                    "'\\`' should not occur in `Code`",
3816                    "'`' should not occur in `Code`",
3817                },
3818                {
3819                    "`not\nparsed`",
3820                    "\\`not parsed\\`",
3821                    "`not parsed`",
3822                }};
3823 
3824   for (const auto &C : Cases) {
3825     markup::Document Output;
3826     parseDocumentation(C.Documentation, Output);
3827 
3828     EXPECT_EQ(Output.asMarkdown(), C.ExpectedRenderMarkdown);
3829     EXPECT_EQ(Output.asPlainText(), C.ExpectedRenderPlainText);
3830   }
3831 }
3832 
3833 // This is a separate test as headings don't create any differences in
3834 // plaintext mode.
3835 TEST(Hover, PresentHeadings) {
3836   HoverInfo HI;
3837   HI.Kind = index::SymbolKind::Variable;
3838   HI.Name = "foo";
3839 
3840   EXPECT_EQ(HI.present().asMarkdown(), "### variable `foo`");
3841 }
3842 
3843 // This is a separate test as rulers behave differently in markdown vs
3844 // plaintext.
3845 TEST(Hover, PresentRulers) {
3846   HoverInfo HI;
3847   HI.Kind = index::SymbolKind::Variable;
3848   HI.Name = "foo";
3849   HI.Value = "val";
3850   HI.Definition = "def";
3851 
3852   llvm::StringRef ExpectedMarkdown = //
3853       "### variable `foo`  \n"
3854       "\n"
3855       "---\n"
3856       "Value = `val`  \n"
3857       "\n"
3858       "---\n"
3859       "```cpp\n"
3860       "def\n"
3861       "```";
3862   EXPECT_EQ(HI.present().asMarkdown(), ExpectedMarkdown);
3863 
3864   llvm::StringRef ExpectedPlaintext = R"pt(variable foo
3865 
3866 Value = val
3867 
3868 def)pt";
3869   EXPECT_EQ(HI.present().asPlainText(), ExpectedPlaintext);
3870 }
3871 
3872 TEST(Hover, SpaceshipTemplateNoCrash) {
3873   Annotations T(R"cpp(
3874   namespace std {
3875   struct strong_ordering {
3876     int n;
3877     constexpr operator int() const { return n; }
3878     static const strong_ordering equal, greater, less;
3879   };
3880   constexpr strong_ordering strong_ordering::equal = {0};
3881   constexpr strong_ordering strong_ordering::greater = {1};
3882   constexpr strong_ordering strong_ordering::less = {-1};
3883   }
3884 
3885   template <typename T>
3886   struct S {
3887     // Foo bar baz
3888     friend auto operator<=>(S, S) = default;
3889   };
3890   static_assert(S<void>() =^= S<void>());
3891     )cpp");
3892 
3893   TestTU TU = TestTU::withCode(T.code());
3894   TU.ExtraArgs.push_back("-std=c++20");
3895   auto AST = TU.build();
3896   auto HI = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
3897   EXPECT_EQ(HI->Documentation, "");
3898 }
3899 
3900 TEST(Hover, ForwardStructNoCrash) {
3901   Annotations T(R"cpp(
3902   struct Foo;
3903   int bar;
3904   auto baz = (Fo^o*)&bar;
3905     )cpp");
3906 
3907   TestTU TU = TestTU::withCode(T.code());
3908   auto AST = TU.build();
3909   auto HI = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
3910   ASSERT_TRUE(HI);
3911   EXPECT_EQ(*HI->Value, "&bar");
3912 }
3913 
3914 TEST(Hover, FunctionParameterDefaulValueNotEvaluatedOnInvalidDecls) {
3915   struct {
3916     const char *const Code;
3917     const std::optional<std::string> HoverValue;
3918   } Cases[] = {
3919       {R"cpp(
3920         // error-ok testing behavior on invalid decl
3921         class Foo {};
3922         void foo(Foo p^aram = nullptr);
3923         )cpp",
3924        std::nullopt},
3925       {R"cpp(
3926         class Foo {};
3927         void foo(Foo *p^aram = nullptr);
3928         )cpp",
3929        "nullptr"},
3930   };
3931 
3932   for (const auto &C : Cases) {
3933     Annotations T(C.Code);
3934     TestTU TU = TestTU::withCode(T.code());
3935     auto AST = TU.build();
3936     auto HI = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
3937     ASSERT_TRUE(HI);
3938     ASSERT_EQ(HI->Value, C.HoverValue);
3939   }
3940 }
3941 
3942 TEST(Hover, DisableShowAKA) {
3943   Annotations T(R"cpp(
3944     using m_int = int;
3945     m_int ^[[a]];
3946   )cpp");
3947 
3948   Config Cfg;
3949   Cfg.Hover.ShowAKA = false;
3950   WithContextValue WithCfg(Config::Key, std::move(Cfg));
3951 
3952   TestTU TU = TestTU::withCode(T.code());
3953   TU.ExtraArgs.push_back("-std=c++17");
3954   auto AST = TU.build();
3955   auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
3956 
3957   ASSERT_TRUE(H);
3958   EXPECT_EQ(H->Type, HoverInfo::PrintedType("m_int"));
3959 }
3960 
3961 TEST(Hover, HideBigInitializers) {
3962   Annotations T(R"cpp(
3963   #define A(x) x, x, x, x
3964   #define B(x) A(A(A(A(x))))
3965   int a^rr[] = {B(0)};
3966   )cpp");
3967 
3968   TestTU TU = TestTU::withCode(T.code());
3969   auto AST = TU.build();
3970   auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
3971 
3972   ASSERT_TRUE(H);
3973   EXPECT_EQ(H->Definition, "int arr[]");
3974 }
3975 
3976 #if defined(__aarch64__)
3977 // FIXME: AARCH64 sanitizer buildbots are broken after 72142fbac4.
3978 #define PREDEFINEMACROS_TEST(x) DISABLED_##x
3979 #else
3980 #define PREDEFINEMACROS_TEST(x) x
3981 #endif
3982 
3983 TEST(Hover, PREDEFINEMACROS_TEST(GlobalVarEnumeralCastNoCrash)) {
3984   Annotations T(R"cpp(
3985     using uintptr_t = __UINTPTR_TYPE__;
3986     enum Test : uintptr_t {};
3987     unsigned global_var;
3988     void foo() {
3989       Test v^al = static_cast<Test>(reinterpret_cast<uintptr_t>(&global_var));
3990     }
3991   )cpp");
3992 
3993   TestTU TU = TestTU::withCode(T.code());
3994   TU.PredefineMacros = true;
3995   auto AST = TU.build();
3996   auto HI = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
3997   ASSERT_TRUE(HI);
3998   EXPECT_EQ(*HI->Value, "&global_var");
3999 }
4000 
4001 TEST(Hover, PREDEFINEMACROS_TEST(GlobalVarIntCastNoCrash)) {
4002   Annotations T(R"cpp(
4003     using uintptr_t = __UINTPTR_TYPE__;
4004     unsigned global_var;
4005     void foo() {
4006       uintptr_t a^ddress = reinterpret_cast<uintptr_t>(&global_var);
4007     }
4008   )cpp");
4009 
4010   TestTU TU = TestTU::withCode(T.code());
4011   TU.PredefineMacros = true;
4012   auto AST = TU.build();
4013   auto HI = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
4014   ASSERT_TRUE(HI);
4015   EXPECT_EQ(*HI->Value, "&global_var");
4016 }
4017 
4018 TEST(Hover, Typedefs) {
4019   Annotations T(R"cpp(
4020   template <bool X, typename T, typename F>
4021   struct cond { using type = T; };
4022   template <typename T, typename F>
4023   struct cond<false, T, F> { using type = F; };
4024 
4025   template <bool X, typename T, typename F>
4026   using type = typename cond<X, T, F>::type;
4027 
4028   void foo() {
4029     using f^oo = type<true, int, double>;
4030   }
4031   )cpp");
4032 
4033   TestTU TU = TestTU::withCode(T.code());
4034   auto AST = TU.build();
4035   auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
4036 
4037   ASSERT_TRUE(H && H->Type);
4038   EXPECT_EQ(H->Type->Type, "int");
4039   EXPECT_EQ(H->Definition, "using foo = type<true, int, double>");
4040 }
4041 
4042 TEST(Hover, EvaluateMacros) {
4043   llvm::StringRef PredefinedCXX = R"cpp(
4044 #define X 42
4045 #define SizeOf sizeof
4046 #define AlignOf alignof
4047 #define PLUS_TWO +2
4048 #define TWO 2
4049 
4050 using u64 = unsigned long long;
4051 // calculate (a ** b) % p
4052 constexpr u64 pow_with_mod(u64 a, u64 b, u64 p) {
4053   u64 ret = 1;
4054   while (b) {
4055     if (b & 1)
4056       ret = (ret * a) % p;
4057     a = (a * a) % p;
4058     b >>= 1;
4059   }
4060   return ret;
4061 }
4062 #define last_n_digit(x, y, n)                                                  \
4063   pow_with_mod(x, y, pow_with_mod(10, n, 2147483647))
4064 #define declare_struct(X, name, value)                                         \
4065   struct X {                                                                   \
4066     constexpr auto name() { return value; }                                    \
4067   }
4068 #define gnu_statement_expression(value)                                        \
4069   ({                                                                           \
4070     declare_struct(Widget, getter, value);                                     \
4071     Widget().getter();                                                         \
4072   })
4073 #define define_lambda_begin(lambda, ...)                                       \
4074   [&](__VA_ARGS__) {
4075 #define define_lambda_end() }
4076 
4077 #define left_bracket [
4078 #define right_bracket ]
4079 #define dg_left_bracket <:
4080 #define dg_right_bracket :>
4081 #define array_decl(type, name, size) type name left_bracket size right_bracket
4082   )cpp";
4083 
4084   struct {
4085     llvm::StringRef Code;
4086     const std::function<void(std::optional<HoverInfo>, size_t /*Id*/)>
4087         Validator;
4088   } Cases[] = {
4089       {
4090           /*Code=*/R"cpp(
4091             X^;
4092           )cpp",
4093           /*Validator=*/
4094           [](std::optional<HoverInfo> HI, size_t) {
4095             EXPECT_EQ(HI->Value, "42 (0x2a)");
4096             EXPECT_EQ(HI->Type, HoverInfo::PrintedType("int"));
4097           },
4098       },
4099       {
4100           /*Code=*/R"cpp(
4101             Size^Of(int);
4102           )cpp",
4103           /*Validator=*/
4104           [](std::optional<HoverInfo> HI, size_t) {
4105             EXPECT_TRUE(HI->Value);
4106             EXPECT_TRUE(HI->Type);
4107             // Don't validate type or value of `sizeof` and `alignof` as we're
4108             // getting different values or desugared types on different
4109             // platforms. Same as below.
4110           },
4111       },
4112       {
4113           /*Code=*/R"cpp(
4114           struct Y {
4115             int y;
4116             double z;
4117           };
4118           Alig^nOf(Y);
4119         )cpp",
4120           /*Validator=*/
4121           [](std::optional<HoverInfo> HI, size_t) {
4122             EXPECT_TRUE(HI->Value);
4123             EXPECT_TRUE(HI->Type);
4124           },
4125       },
4126       {
4127           /*Code=*/R"cpp(
4128           // 2**32 == 4294967296
4129           last_n_di^git(2, 32, 6);
4130         )cpp",
4131           /*Validator=*/
4132           [](std::optional<HoverInfo> HI, size_t) {
4133             EXPECT_EQ(HI->Value, "967296 (0xec280)");
4134             EXPECT_EQ(HI->Type, "u64");
4135           },
4136       },
4137       {
4138           /*Code=*/R"cpp(
4139           gnu_statement_exp^ression(42);
4140         )cpp",
4141           /*Validator=*/
4142           [](std::optional<HoverInfo> HI, size_t) {
4143             EXPECT_EQ(HI->Value, "42 (0x2a)");
4144             EXPECT_EQ(HI->Type, "int");
4145           },
4146       },
4147       {
4148           /*Code=*/R"cpp(
4149           40 + PLU^S_TWO;
4150         )cpp",
4151           /*Validator=*/
4152           [](std::optional<HoverInfo> HI, size_t) {
4153             EXPECT_EQ(HI->Value, "2");
4154             EXPECT_EQ(HI->Type, "int");
4155           },
4156       },
4157       {
4158           /*Code=*/R"cpp(
4159           40 PLU^S_TWO;
4160         )cpp",
4161           /*Validator=*/
4162           [](std::optional<HoverInfo> HI, size_t) {
4163             EXPECT_FALSE(HI->Value) << HI->Value;
4164             EXPECT_FALSE(HI->Type) << HI->Type;
4165           },
4166       },
4167       {
4168           /*Code=*/R"cpp(
4169           40 + TW^O;
4170         )cpp",
4171           /*Validator=*/
4172           [](std::optional<HoverInfo> HI, size_t) {
4173             EXPECT_EQ(HI->Value, "2");
4174             EXPECT_EQ(HI->Type, "int");
4175           },
4176       },
4177       {
4178           /*Code=*/R"cpp(
4179           arra^y_decl(int, vector, 10);
4180           vector left_b^racket 3 right_b^racket;
4181           vector dg_le^ft_bracket 3 dg_righ^t_bracket;
4182         )cpp",
4183           /*Validator=*/
4184           [](std::optional<HoverInfo> HI, size_t Id) {
4185             switch (Id) {
4186             case 0:
4187               EXPECT_EQ(HI->Type, HoverInfo::PrintedType("int[10]"));
4188               break;
4189             case 1:
4190             case 2:
4191             case 3:
4192             case 4:
4193               EXPECT_FALSE(HI->Type) << HI->Type;
4194               EXPECT_FALSE(HI->Value) << HI->Value;
4195               break;
4196             default:
4197               ASSERT_TRUE(false) << "Unhandled id: " << Id;
4198             }
4199           },
4200       },
4201       {
4202           /*Code=*/R"cpp(
4203           constexpr auto value = define_lamb^da_begin(lambda, int, char)
4204             // Check if the expansion range is right.
4205             return ^last_n_digit(10, 3, 3)^;
4206           define_lam^bda_end();
4207         )cpp",
4208           /*Validator=*/
4209           [](std::optional<HoverInfo> HI, size_t Id) {
4210             switch (Id) {
4211             case 0:
4212               EXPECT_FALSE(HI->Value);
4213               EXPECT_EQ(HI->Type, HoverInfo::PrintedType("const (lambda)"));
4214               break;
4215             case 1:
4216               EXPECT_EQ(HI->Value, "0");
4217               EXPECT_EQ(HI->Type, HoverInfo::PrintedType("u64"));
4218               break;
4219             case 2:
4220               EXPECT_FALSE(HI);
4221               break;
4222             case 3:
4223               EXPECT_FALSE(HI->Type) << HI->Type;
4224               EXPECT_FALSE(HI->Value) << HI->Value;
4225               break;
4226             default:
4227               ASSERT_TRUE(false) << "Unhandled id: " << Id;
4228             }
4229           },
4230       },
4231   };
4232 
4233   Config Cfg;
4234   Cfg.Hover.ShowAKA = false;
4235   WithContextValue WithCfg(Config::Key, std::move(Cfg));
4236   for (const auto &C : Cases) {
4237     Annotations Code(
4238         (PredefinedCXX + "void function() {\n" + C.Code + "}\n").str());
4239     auto TU = TestTU::withCode(Code.code());
4240     TU.ExtraArgs.push_back("-std=c++17");
4241     auto AST = TU.build();
4242     for (auto [Index, Position] : llvm::enumerate(Code.points())) {
4243       C.Validator(getHover(AST, Position, format::getLLVMStyle(), nullptr),
4244                   Index);
4245     }
4246   }
4247 
4248   Annotations C(R"c(
4249     #define alignof _Alignof
4250     void foo() {
4251       al^ignof(struct { int x; char y[10]; });
4252     }
4253   )c");
4254 
4255   auto TU = TestTU::withCode(C.code());
4256   TU.Filename = "TestTU.c";
4257   TU.ExtraArgs = {
4258       "-std=c17",
4259   };
4260   auto AST = TU.build();
4261   auto H = getHover(AST, C.point(), format::getLLVMStyle(), nullptr);
4262 
4263   ASSERT_TRUE(H);
4264   EXPECT_TRUE(H->Value);
4265   EXPECT_TRUE(H->Type);
4266 }
4267 } // namespace
4268 } // namespace clangd
4269 } // namespace clang
4270