15 #include "clang/Basic/Specifiers.h"
16 #include "clang/Index/IndexSymbol.h"
17 #include "llvm/ADT/None.h"
18 #include "llvm/ADT/StringRef.h"
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
31 TEST(Hover, Structured) {
33 const char *
const Code;
34 const std::function<void(HoverInfo &)> ExpectedBuilder;
42 HI.NamespaceScope = "";
44 HI.Kind = index::SymbolKind::Function;
45 HI.Documentation =
"Best foo ever.";
46 HI.Definition =
"void foo()";
47 HI.ReturnType =
"void";
49 HI.Parameters.emplace();
53 namespace ns1 { namespace ns2 {
59 HI.NamespaceScope =
"ns1::ns2::";
61 HI.Kind = index::SymbolKind::Function;
62 HI.Documentation =
"Best foo ever.";
63 HI.Definition =
"void foo()";
64 HI.ReturnType =
"void";
66 HI.Parameters.emplace();
70 namespace ns1 { namespace ns2 {
77 HI.NamespaceScope = "ns1::ns2::";
78 HI.LocalScope =
"Foo::";
80 HI.Kind = index::SymbolKind::Field;
81 HI.Definition =
"char bar";
85 HI.AccessSpecifier =
"public";
89 namespace ns1 { namespace ns2 {
98 HI.NamespaceScope = "ns1::ns2::";
99 HI.LocalScope =
"Foo::foo::";
101 HI.Kind = index::SymbolKind::Variable;
102 HI.Definition =
"int bar";
107 namespace ns1 { namespace {
114 HI.NamespaceScope = "ns1::";
115 HI.LocalScope =
"(anonymous struct)::";
117 HI.Kind = index::SymbolKind::Field;
118 HI.Definition =
"char bar";
122 HI.AccessSpecifier =
"public";
129 HI.NamespaceScope = "";
131 HI.Kind = index::SymbolKind::Struct;
132 HI.Definition =
"struct X {}";
137 template <typename T, class... Ts> class Foo { public: Foo(int); };
138 Foo<int, char, bool> [[fo^o]] = Foo<int, char, bool>(5);
141 HI.NamespaceScope = "";
143 HI.Kind = index::SymbolKind::Variable;
144 HI.Definition =
"Foo<int, char, bool> foo = Foo<int, char, bool>(5)";
145 HI.Type =
"Foo<int, char, bool>";
149 template <typename T> class vector{};
150 [[vec^tor]]<int> foo;
153 HI.NamespaceScope = "";
154 HI.Name =
"vector<int>";
155 HI.Kind = index::SymbolKind::Class;
156 HI.Definition =
"template <> class vector<int> {}";
160 template <template<typename, bool...> class C,
164 class... Ts> class Foo {};
165 template <template<typename, bool...> class T>
169 HI.NamespaceScope = "";
171 HI.Kind = index::SymbolKind::Class;
173 R
"cpp(template <template <typename, bool...> class C, typename = char, int = 0,
174 bool Q = false, class... Ts>
176 HI.TemplateParameters = {
177 {std::string("template <typename, bool...> class"),
179 {std::string(
"typename"),
llvm::None, std::string(
"char")},
180 {std::string(
"int"),
llvm::None, std::string(
"0")},
181 {std::string(
"bool"), std::string(
"Q"), std::string(
"false")},
182 {std::string(
"class..."), std::string(
"Ts"),
llvm::None},
187 template <template<typename, bool...> class C,
191 class... Ts> void foo();
192 template<typename, bool...> class Foo;
199 HI.NamespaceScope = "";
201 HI.Kind = index::SymbolKind::Function;
202 HI.Definition =
"template <> void foo<Foo, char, 0, false, <>>()";
203 HI.ReturnType =
"void";
205 HI.Parameters.emplace();
209 template<typename, bool...> class Foo {};
210 Foo<bool, true, false> foo(int, bool T = false);
217 HI.NamespaceScope = "";
219 HI.Kind = index::SymbolKind::Function;
220 HI.Definition =
"Foo<bool, true, false> foo(int, bool T = false)";
221 HI.ReturnType =
"Foo<bool, true, false>";
222 HI.Type =
"Foo<bool, true, false> (int, bool)";
225 {std::string(
"bool"), std::string(
"T"), std::string(
"false")},
231 auto lamb = [](int T, bool B) -> bool { return T && B; };
237 HI.NamespaceScope = "";
238 HI.LocalScope =
"foo::";
240 HI.Kind = index::SymbolKind::Variable;
241 HI.Definition =
"auto *c = &b";
242 HI.Type =
"class (lambda) **";
243 HI.ReturnType =
"bool";
245 {std::string(
"int"), std::string(
"T"),
llvm::None},
246 {std::string(
"bool"), std::string(
"B"),
llvm::None},
252 auto lamb = [](int T, bool B) -> bool { return T && B; };
253 void foo(decltype(lamb)& bar) {
258 HI.NamespaceScope = "";
259 HI.LocalScope =
"foo::";
261 HI.Kind = index::SymbolKind::Parameter;
262 HI.Definition =
"decltype(lamb) &bar";
263 HI.Type =
"decltype(lamb) &";
264 HI.ReturnType =
"bool";
266 {std::string(
"int"), std::string(
"T"),
llvm::None},
267 {std::string(
"bool"), std::string(
"B"),
llvm::None},
273 auto lamb = [](int T, bool B) -> bool { return T && B; };
274 void foo(decltype(lamb) bar) {
279 HI.NamespaceScope = "";
280 HI.LocalScope =
"foo::";
282 HI.Kind = index::SymbolKind::Parameter;
283 HI.Definition =
"decltype(lamb) bar";
284 HI.Type =
"class (lambda)";
285 HI.ReturnType =
"bool";
287 {std::string(
"int"), std::string(
"T"),
llvm::None},
288 {std::string(
"bool"), std::string(
"B"),
llvm::None},
297 auto lamb = [&bar](int T, bool B) -> bool { return T && B && bar; };
298 bool res = [[lam^b]](bar, false);
302 HI.NamespaceScope = "";
303 HI.LocalScope =
"foo::";
305 HI.Kind = index::SymbolKind::Variable;
306 HI.Definition =
"auto lamb = [&bar](int T, bool B) -> bool {}";
307 HI.Type =
"class (lambda)";
308 HI.ReturnType =
"bool";
310 {std::string(
"int"), std::string(
"T"),
llvm::None},
311 {std::string(
"bool"), std::string(
"B"),
llvm::None},
318 auto lamb = []{int [[te^st]];};
322 HI.NamespaceScope = "";
323 HI.LocalScope =
"foo::(anonymous class)::operator()::";
325 HI.Kind = index::SymbolKind::Variable;
326 HI.Definition =
"int test";
331 template <typename T> class X;
332 template <typename T> class [[^X]]<T*> {};
336 HI.NamespaceScope =
"";
337 HI.Kind = index::SymbolKind::Class;
338 HI.Definition =
"template <typename T> class X<T *> {}";
342 template<typename, typename=void> struct X;
343 template<typename T> struct X<T*>{ [[^X]](); };
346 HI.NamespaceScope = "";
348 HI.LocalScope =
"X<T *>::";
349 HI.Kind = index::SymbolKind::Constructor;
350 HI.Definition =
"X()";
351 HI.Parameters.emplace();
352 HI.AccessSpecifier =
"public";
354 {
"class X { [[^~]]X(); };",
356 HI.NamespaceScope =
"";
358 HI.LocalScope =
"X::";
359 HI.Kind = index::SymbolKind::Destructor;
360 HI.Definition =
"~X()";
361 HI.Parameters.emplace();
362 HI.AccessSpecifier =
"private";
364 {
"class X { [[op^erator]] int(); };",
366 HI.NamespaceScope =
"";
367 HI.Name =
"operator int";
368 HI.LocalScope =
"X::";
369 HI.Kind = index::SymbolKind::ConversionFunction;
370 HI.Definition =
"operator int()";
371 HI.Parameters.emplace();
372 HI.AccessSpecifier =
"private";
374 {
"class X { operator [[^X]](); };",
376 HI.NamespaceScope =
"";
378 HI.Kind = index::SymbolKind::Class;
379 HI.Definition =
"class X {}";
385 [[au^to]] lamb = []{};
389 HI.Name = "(lambda)";
390 HI.Kind = index::SymbolKind::Class;
394 template<typename T> class Foo{};
396 [[au^to]] x = Foo<int>();
400 HI.Name = "Foo<int>";
401 HI.Kind = index::SymbolKind::Class;
405 template<typename T> class Foo{};
406 template<> class Foo<int>{};
408 [[au^to]] x = Foo<int>();
412 HI.Name = "Foo<int>";
413 HI.Kind = index::SymbolKind::Class;
419 #define MACRO(x,y,z) void foo(x, y, z);
420 [[MAC^RO]](int, double d, bool z = false);
423 HI.Name = "MACRO", HI.Kind = index::SymbolKind::Macro,
424 HI.Definition =
"#define MACRO(x, y, z) void foo(x, y, z);";
429 constexpr int add(int a, int b) { return a + b; }
430 int [[b^ar]] = add(1, 2);
434 HI.Definition =
"int bar = add(1, 2)";
435 HI.Kind = index::SymbolKind::Variable;
437 HI.NamespaceScope =
"";
441 int [[b^ar]] = sizeof(char);
445 HI.Definition =
"int bar = sizeof(char)";
446 HI.Kind = index::SymbolKind::Variable;
448 HI.NamespaceScope =
"";
452 template<int a, int b> struct Add {
453 static constexpr int result = a + b;
455 int [[ba^r]] = Add<1, 2>::result;
459 HI.Definition =
"int bar = Add<1, 2>::result";
460 HI.Kind = index::SymbolKind::Variable;
462 HI.NamespaceScope =
"";
466 enum Color { RED, GREEN, };
467 Color x = [[GR^EEN]];
471 HI.NamespaceScope =
"";
472 HI.LocalScope =
"Color::";
473 HI.Definition =
"GREEN";
474 HI.Kind = index::SymbolKind::EnumConstant;
475 HI.Type =
"enum Color";
479 enum Color { RED, GREEN, };
485 HI.NamespaceScope =
"";
486 HI.Definition =
"Color x = GREEN";
487 HI.Kind = index::SymbolKind::Variable;
488 HI.Type =
"enum Color";
489 HI.Value =
"GREEN (1)";
492 template<int a, int b> struct Add {
493 static constexpr int result = a + b;
495 int bar = Add<1, 2>::[[resu^lt]];
499 HI.Definition =
"static constexpr int result = 1 + 2";
500 HI.Kind = index::SymbolKind::StaticProperty;
501 HI.Type =
"const int";
502 HI.NamespaceScope =
"";
503 HI.LocalScope =
"Add<1, 2>::";
505 HI.AccessSpecifier =
"public";
508 constexpr int answer() { return 40 + 2; }
509 int x = [[ans^wer]]();
513 HI.Definition =
"constexpr int answer()";
514 HI.Kind = index::SymbolKind::Function;
516 HI.ReturnType =
"int";
517 HI.Parameters.emplace();
518 HI.NamespaceScope =
"";
522 const char *[[ba^r]] = "1234";
526 HI.Definition =
"const char *bar = \"1234\"";
527 HI.Kind = index::SymbolKind::Variable;
528 HI.Type =
"const char *";
529 HI.NamespaceScope =
"";
530 HI.Value =
"&\"1234\"[0]";
532 {R
"cpp(// Should not crash
533 template <typename T>
538 template <typename A>
539 void boom(int name) {
540 new Tmpl<A>([[na^me]]);
544 HI.Definition =
"int name";
545 HI.Kind = index::SymbolKind::Parameter;
547 HI.NamespaceScope =
"";
548 HI.LocalScope =
"boom::";
551 R
"cpp(// Should not print inline or anon namespaces.
553 inline namespace in_ns {
557 inline namespace in_ns2 {
566 ns::a::b::[[F^oo]] x;
572 HI.Kind = index::SymbolKind::Class;
573 HI.NamespaceScope =
"ns::a::b::";
574 HI.Definition =
"class Foo {}";
578 template <typename T> class Foo {};
581 [[^auto]] x = Foo<X>();
586 HI.Kind = index::SymbolKind::Class;
590 // comment from primary
591 template <typename T> class Foo {};
592 // comment from specialization
593 template <typename T> class Foo<T*> {};
595 [[Fo^o]]<int*> *x = nullptr;
599 HI.Name = "Foo<int *>";
600 HI.Kind = index::SymbolKind::Class;
601 HI.NamespaceScope =
"";
602 HI.Definition =
"template <> class Foo<int *>";
605 HI.Documentation =
"comment from primary";
609 template <typename [[^T]] = int> void foo();
613 HI.Kind = index::SymbolKind::TemplateTypeParm;
614 HI.NamespaceScope =
"";
615 HI.Definition =
"typename T = int";
616 HI.LocalScope =
"foo::";
617 HI.Type =
"typename";
618 HI.AccessSpecifier =
"public";
622 template <template<typename> class [[^T]]> void foo();
626 HI.Kind = index::SymbolKind::TemplateTemplateParm;
627 HI.NamespaceScope =
"";
628 HI.Definition =
"template <typename> class T";
629 HI.LocalScope =
"foo::";
630 HI.Type =
"template <typename> class";
631 HI.AccessSpecifier =
"public";
635 template <int [[^T]] = 5> void foo();
639 HI.Kind = index::SymbolKind::NonTypeTemplateParm;
640 HI.NamespaceScope =
"";
641 HI.Definition =
"int T = 5";
642 HI.LocalScope =
"foo::";
644 HI.AccessSpecifier =
"public";
649 struct X { int Y; float [[^y]]() { return Y; } };
653 HI.Kind = index::SymbolKind::InstanceMethod;
654 HI.NamespaceScope =
"";
655 HI.Definition =
"float y()";
656 HI.LocalScope =
"X::";
657 HI.Documentation =
"Trivial accessor for `Y`.";
658 HI.Type =
"float ()";
659 HI.ReturnType =
"float";
660 HI.Parameters.emplace();
661 HI.AccessSpecifier =
"public";
665 struct X { int Y; void [[^setY]](float v) { Y = v; } };
669 HI.Kind = index::SymbolKind::InstanceMethod;
670 HI.NamespaceScope =
"";
671 HI.Definition =
"void setY(float v)";
672 HI.LocalScope =
"X::";
673 HI.Documentation =
"Trivial setter for `Y`.";
674 HI.Type =
"void (float)";
675 HI.ReturnType =
"void";
676 HI.Parameters.emplace();
677 HI.Parameters->emplace_back();
678 HI.Parameters->back().Type =
"float";
679 HI.Parameters->back().Name =
"v";
680 HI.AccessSpecifier =
"public";
684 struct X { int Y; X& [[^setY]](float v) { Y = v; return *this; } };
688 HI.Kind = index::SymbolKind::InstanceMethod;
689 HI.NamespaceScope =
"";
690 HI.Definition =
"X &setY(float v)";
691 HI.LocalScope =
"X::";
692 HI.Documentation =
"Trivial setter for `Y`.";
693 HI.Type =
"struct X &(float)";
694 HI.ReturnType =
"struct X &";
695 HI.Parameters.emplace();
696 HI.Parameters->emplace_back();
697 HI.Parameters->back().Type =
"float";
698 HI.Parameters->back().Name =
"v";
699 HI.AccessSpecifier =
"public";
703 struct X { int x = 2; };
708 HI.Kind = index::SymbolKind::Variable;
709 HI.NamespaceScope =
"";
710 HI.Definition =
"X x";
711 HI.Type =
"struct X";
714 R
"cpp(auto [^[[x]]] = 1; /*error-ok*/)cpp",
717 HI.Kind = index::SymbolKind::Variable;
718 HI.NamespaceScope =
"";
720 HI.Type =
"NULL TYPE";
722 HI.AccessSpecifier =
"public";
726 void fun(int arg_a, int &arg_b) {};
734 HI.Kind = index::SymbolKind::Variable;
735 HI.NamespaceScope =
"";
736 HI.Definition =
"int b = 2";
737 HI.LocalScope =
"code::";
740 HI.CalleeArgInfo.emplace();
741 HI.CalleeArgInfo->Name =
"arg_b";
742 HI.CalleeArgInfo->Type =
"int &";
743 HI.CallPassType.emplace();
744 HI.CallPassType->PassBy = PassMode::Ref;
745 HI.CallPassType->Converted =
false;
751 void fun(int arg_a = 3, int arg_b = 4) {}
761 HI.Kind = index::SymbolKind::Variable;
762 HI.NamespaceScope =
"";
763 HI.Definition =
"int a = 1";
764 HI.LocalScope =
"code::";
767 HI.CalleeArgInfo.emplace();
768 HI.CalleeArgInfo->Name =
"arg_a";
769 HI.CalleeArgInfo->Type =
"int";
770 HI.CalleeArgInfo->Default =
"3";
771 HI.CallPassType.emplace();
773 HI.CallPassType->Converted =
false;
783 HI.Kind = index::SymbolKind::Field;
784 HI.NamespaceScope =
"";
785 HI.Definition =
"int xx";
786 HI.LocalScope =
"Foo::";
788 HI.AccessSpecifier =
"public";
798 HI.Kind = index::SymbolKind::Field;
799 HI.NamespaceScope =
"";
800 HI.Definition =
"int yy";
801 HI.LocalScope =
"Foo::";
803 HI.AccessSpecifier =
"public";
811 ^[[{]]1} // FIXME: why the hover range is 1 character?
815 HI.Name = "expression";
816 HI.Kind = index::SymbolKind::Unknown;
817 HI.Type =
"int [10]";
820 for (
const auto &Case : Cases) {
821 SCOPED_TRACE(Case.Code);
823 Annotations T(Case.Code);
828 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
829 auto AST = TU.
build();
831 auto H =
getHover(AST, T.point(), format::getLLVMStyle(),
nullptr);
837 EXPECT_EQ(H->NamespaceScope,
Expected.NamespaceScope);
838 EXPECT_EQ(H->LocalScope,
Expected.LocalScope);
841 EXPECT_EQ(H->Documentation,
Expected.Documentation);
842 EXPECT_EQ(H->Definition,
Expected.Definition);
844 EXPECT_EQ(H->ReturnType,
Expected.ReturnType);
845 EXPECT_EQ(H->Parameters,
Expected.Parameters);
846 EXPECT_EQ(H->TemplateParameters,
Expected.TemplateParameters);
847 EXPECT_EQ(H->SymRange,
Expected.SymRange);
848 EXPECT_EQ(H->Value,
Expected.Value);
850 EXPECT_EQ(H->Offset,
Expected.Offset);
851 EXPECT_EQ(H->AccessSpecifier,
Expected.AccessSpecifier);
852 EXPECT_EQ(H->CalleeArgInfo,
Expected.CalleeArgInfo);
853 EXPECT_EQ(H->CallPassType,
Expected.CallPassType);
857 TEST(Hover, CallPassType) {
858 const llvm::StringRef CodePrefix = R
"cpp(
860 class Derived : public Base {};
864 CustomClass(const Base &x) {}
865 CustomClass(int &x) {}
866 CustomClass(float x) {}
869 void int_by_ref(int &x) {}
870 void int_by_const_ref(const int &x) {}
871 void int_by_value(int x) {}
872 void base_by_ref(Base &x) {}
873 void base_by_const_ref(const Base &x) {}
874 void base_by_value(Base x) {}
875 void float_by_value(float x) {}
876 void custom_by_value(CustomClass x) {}
880 int &int_ref = int_x;
881 const int &int_const_ref = int_x;
883 const Base &base_const_ref = base;
887 const llvm::StringRef CodeSuffix =
"}";
890 const char *
const Code;
896 {
"int_by_ref([[^int_x]]);", PassMode::Ref,
false},
897 {
"int_by_const_ref([[^int_x]]);", PassMode::ConstRef,
false},
899 {
"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef,
false},
900 {
"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef,
false},
901 {
"int_by_const_ref([[^int_const_ref]]);", PassMode::ConstRef,
false},
903 {
"base_by_ref([[^base]]);", PassMode::Ref,
false},
904 {
"base_by_const_ref([[^base]]);", PassMode::ConstRef,
false},
905 {
"base_by_const_ref([[^base_const_ref]]);", PassMode::ConstRef,
false},
908 {
"base_by_ref([[^derived]]);", PassMode::Ref,
false},
909 {
"base_by_const_ref([[^derived]]);", PassMode::ConstRef,
false},
915 {
"custom_by_value([[^int_x]]);", PassMode::Ref,
true},
917 {
"custom_by_value([[^base]]);", PassMode::ConstRef,
true},
919 for (
const auto &Test : Tests) {
920 SCOPED_TRACE(Test.Code);
922 const auto Code = (CodePrefix + Test.Code + CodeSuffix).str();
926 auto AST = TU.
build();
927 auto H =
getHover(AST, T.point(), format::getLLVMStyle(),
nullptr);
929 EXPECT_EQ(H->CallPassType->PassBy, Test.PassBy);
930 EXPECT_EQ(H->CallPassType->Converted, Test.Converted);
934 TEST(Hover, NoHover) {
935 llvm::StringRef Tests[] = {
938 R
"cpp(// structured binding. Not supported yet
945 R"cpp(// Template auto parameter. Nothing (Not useful).
953 R"cpp(// non-named decls don't get hover. Don't crash!
954 ^static_assert(1, "");
956 R"cpp(// non-evaluatable expr
957 template <typename T> void foo() {
958 (void)[[size^of]](T);
963 "auto x = ^(int){42};",
967 "auto x = ^nullptr;",
968 "auto x = ^\"asdf\";",
971 for (
const auto &Test : Tests) {
977 auto AST = TU.
build();
978 auto H =
getHover(AST, T.point(), format::getLLVMStyle(),
nullptr);
985 const char *
const Code;
986 const std::function<void(HoverInfo &)> ExpectedBuilder;
989 R
"cpp(// Local variable
998 HI.Kind = index::SymbolKind::Variable;
999 HI.NamespaceScope =
"";
1000 HI.LocalScope =
"main::";
1002 HI.Definition =
"int bonjour";
1005 R
"cpp(// Local variable in method
1014 HI.Name = "bonjour";
1015 HI.Kind = index::SymbolKind::Variable;
1016 HI.NamespaceScope =
"";
1017 HI.LocalScope =
"s::method::";
1019 HI.Definition =
"int bonjour";
1027 ns1::[[My^Class]]* Params;
1031 HI.Name = "MyClass";
1032 HI.Kind = index::SymbolKind::Struct;
1033 HI.NamespaceScope =
"ns1::";
1034 HI.Definition =
"struct MyClass {}";
1042 ns1::[[My^Class]]* Params;
1046 HI.Name = "MyClass";
1047 HI.Kind = index::SymbolKind::Class;
1048 HI.NamespaceScope =
"ns1::";
1049 HI.Definition =
"class MyClass {}";
1054 union MyUnion { int x; int y; };
1057 ns1::[[My^Union]] Params;
1061 HI.Name = "MyUnion";
1062 HI.Kind = index::SymbolKind::Union;
1063 HI.NamespaceScope =
"ns1::";
1064 HI.Definition =
"union MyUnion {}";
1067 R
"cpp(// Function definition via pointer
1070 auto *X = &^[[foo]];
1075 HI.Kind = index::SymbolKind::Function;
1076 HI.NamespaceScope =
"";
1077 HI.Type =
"void (int)";
1078 HI.Definition =
"void foo(int)";
1079 HI.Documentation =
"Function definition via pointer";
1080 HI.ReturnType =
"void";
1086 R
"cpp(// Function declaration via call
1089 return ^[[foo]](42);
1094 HI.Kind = index::SymbolKind::Function;
1095 HI.NamespaceScope =
"";
1096 HI.Type =
"int (int)";
1097 HI.Definition =
"int foo(int)";
1098 HI.Documentation =
"Function declaration via call";
1099 HI.ReturnType =
"int";
1106 struct Foo { int x; };
1114 HI.Kind = index::SymbolKind::Field;
1115 HI.NamespaceScope =
"";
1116 HI.LocalScope =
"Foo::";
1118 HI.Definition =
"int x";
1121 R
"cpp(// Field with initialization
1122 struct Foo { int x = 5; };
1130 HI.Kind = index::SymbolKind::Field;
1131 HI.NamespaceScope =
"";
1132 HI.LocalScope =
"Foo::";
1134 HI.Definition =
"int x = 5";
1137 R
"cpp(// Static field
1138 struct Foo { static int x; };
1145 HI.Kind = index::SymbolKind::StaticProperty;
1146 HI.NamespaceScope =
"";
1147 HI.LocalScope =
"Foo::";
1149 HI.Definition =
"static int x";
1152 R
"cpp(// Field, member initializer
1155 Foo() : ^[[x]](0) {}
1160 HI.Kind = index::SymbolKind::Field;
1161 HI.NamespaceScope =
"";
1162 HI.LocalScope =
"Foo::";
1164 HI.Definition =
"int x";
1167 R
"cpp(// Field, GNU old-style field designator
1168 struct Foo { int x; };
1170 Foo bar = { ^[[x]] : 1 };
1175 HI.Kind = index::SymbolKind::Field;
1176 HI.NamespaceScope =
"";
1177 HI.LocalScope =
"Foo::";
1179 HI.Definition =
"int x";
1184 R
"cpp(// Field, field designator
1185 struct Foo { int x; int y; };
1187 Foo bar = { .^[[x]] = 2, .y = 2 };
1192 HI.Kind = index::SymbolKind::Field;
1193 HI.NamespaceScope =
"";
1194 HI.LocalScope =
"Foo::";
1196 HI.Definition =
"int x";
1199 R
"cpp(// Method call
1200 struct Foo { int x(); };
1208 HI.Kind = index::SymbolKind::InstanceMethod;
1209 HI.NamespaceScope =
"";
1210 HI.LocalScope =
"Foo::";
1212 HI.Definition =
"int x()";
1213 HI.ReturnType =
"int";
1214 HI.Parameters = std::vector<HoverInfo::Param>{};
1217 R
"cpp(// Static method call
1218 struct Foo { static int x(); };
1225 HI.Kind = index::SymbolKind::StaticMethod;
1226 HI.NamespaceScope =
"";
1227 HI.LocalScope =
"Foo::";
1229 HI.Definition =
"static int x()";
1230 HI.ReturnType =
"int";
1231 HI.Parameters = std::vector<HoverInfo::Param>{};
1242 HI.Kind = index::SymbolKind::TypeAlias;
1243 HI.NamespaceScope =
"";
1244 HI.Definition =
"typedef int Foo";
1245 HI.Documentation =
"Typedef";
1249 R
"cpp(// Typedef with embedded definition
1250 typedef struct Bar {} Foo;
1257 HI.Kind = index::SymbolKind::TypeAlias;
1258 HI.NamespaceScope =
"";
1259 HI.Definition =
"typedef struct Bar Foo";
1260 HI.Documentation =
"Typedef with embedded definition";
1265 struct Foo { static void bar(); };
1267 int main() { ^[[ns]]::Foo::bar(); }
1271 HI.Kind = index::SymbolKind::Namespace;
1272 HI.NamespaceScope =
"";
1273 HI.Definition =
"namespace ns {}";
1276 R
"cpp(// Anonymous namespace
1280 } // anonymous namespace
1282 int main() { ns::[[f^oo]]++; }
1286 HI.Kind = index::SymbolKind::Variable;
1287 HI.NamespaceScope =
"ns::";
1289 HI.Definition =
"int foo";
1294 int main() { return ^[[MACRO]]; }
1298 HI.Kind = index::SymbolKind::Macro;
1299 HI.Definition =
"#define MACRO 0";
1304 #define MACRO2 ^[[MACRO]]
1308 HI.Kind = index::SymbolKind::Macro;
1309 HI.Definition =
"#define MACRO 0";
1316 int main() ^[[MACRO]]
1320 HI.Kind = index::SymbolKind::Macro;
1322 R
"cpp(#define MACRO \
1326 R"cpp(// Forward class declaration
1333 HI.Kind = index::SymbolKind::Class;
1334 HI.NamespaceScope =
"";
1335 HI.Definition =
"class Foo {}";
1336 HI.Documentation =
"Forward class declaration";
1339 R
"cpp(// Function declaration
1341 void g() { [[f^oo]](); }
1346 HI.Kind = index::SymbolKind::Function;
1347 HI.NamespaceScope =
"";
1348 HI.Type =
"void ()";
1349 HI.Definition =
"void foo()";
1350 HI.Documentation =
"Function declaration";
1351 HI.ReturnType =
"void";
1352 HI.Parameters = std::vector<HoverInfo::Param>{};
1355 R
"cpp(// Enum declaration
1360 [[Hel^lo]] hello = ONE;
1365 HI.Kind = index::SymbolKind::Enum;
1366 HI.NamespaceScope =
"";
1367 HI.Definition =
"enum Hello {}";
1368 HI.Documentation =
"Enum declaration";
1376 Hello hello = [[O^NE]];
1381 HI.Kind = index::SymbolKind::EnumConstant;
1382 HI.NamespaceScope =
"";
1383 HI.LocalScope =
"Hello::";
1384 HI.Type =
"enum Hello";
1385 HI.Definition =
"ONE";
1389 R
"cpp(// Enumerator in anonymous enum
1394 int hello = [[O^NE]];
1399 HI.Kind = index::SymbolKind::EnumConstant;
1400 HI.NamespaceScope =
"";
1403 HI.Type =
"enum (anonymous)";
1404 HI.Definition =
"ONE";
1408 R
"cpp(// Global variable
1409 static int hey = 10;
1416 HI.Kind = index::SymbolKind::Variable;
1417 HI.NamespaceScope =
"";
1419 HI.Definition =
"static int hey = 10";
1420 HI.Documentation =
"Global variable";
1425 R
"cpp(// Global variable in namespace
1427 static int hey = 10;
1435 HI.Kind = index::SymbolKind::Variable;
1436 HI.NamespaceScope =
"ns1::";
1438 HI.Definition =
"static int hey = 10";
1442 R
"cpp(// Field in anonymous struct
1452 HI.Kind = index::SymbolKind::Field;
1453 HI.NamespaceScope =
"";
1454 HI.LocalScope =
"(anonymous struct)::";
1456 HI.Definition =
"int hello";
1459 R
"cpp(// Templated function
1460 template <typename T>
1464 void g() { auto x = [[f^oo]]<int>(); }
1468 HI.Kind = index::SymbolKind::Function;
1469 HI.NamespaceScope =
"";
1471 HI.Definition =
"template <> int foo<int>()";
1472 HI.Documentation =
"Templated function";
1473 HI.ReturnType =
"int";
1474 HI.Parameters = std::vector<HoverInfo::Param>{};
1479 R
"cpp(// Anonymous union
1485 void g() { struct outer o; o.v.[[d^ef]]++; }
1489 HI.Kind = index::SymbolKind::Field;
1490 HI.NamespaceScope =
"";
1491 HI.LocalScope =
"outer::(anonymous union)::";
1493 HI.Definition =
"int def";
1496 R
"cpp(// documentation from index
1497 int nextSymbolIsAForwardDeclFromIndexWithNoLocalDocs;
1499 void g() { [[ind^exSymbol]](); }
1502 HI.Name = "indexSymbol";
1503 HI.Kind = index::SymbolKind::Function;
1504 HI.NamespaceScope =
"";
1505 HI.Type =
"void ()";
1506 HI.Definition =
"void indexSymbol()";
1507 HI.ReturnType =
"void";
1508 HI.Parameters = std::vector<HoverInfo::Param>{};
1509 HI.Documentation =
"comment from index";
1512 R
"cpp(// Simple initialization with auto
1520 HI.Kind = index::SymbolKind::Unknown;
1523 R
"cpp(// Simple initialization with const auto
1525 const ^[[auto]] i = 1;
1528 [](HoverInfo &HI) { HI.Name = "int"; }},
1530 R
"cpp(// Simple initialization with const auto&
1532 const ^[[auto]]& i = 1;
1535 [](HoverInfo &HI) { HI.Name = "int"; }},
1537 R
"cpp(// Simple initialization with auto&
1543 [](HoverInfo &HI) { HI.Name = "int"; }},
1545 R
"cpp(// Simple initialization with auto*
1551 [](HoverInfo &HI) { HI.Name = "int"; }},
1553 R
"cpp(// Auto with initializer list.
1557 class initializer_list {};
1560 ^[[auto]] i = {1,2};
1564 HI.Name = "initializer_list<int>";
1565 HI.Kind = index::SymbolKind::Class;
1568 R
"cpp(// User defined conversion to auto
1570 operator ^[[auto]]() const { return 10; }
1573 [](HoverInfo &HI) { HI.Name = "int"; }},
1575 R
"cpp(// Simple initialization with decltype(auto)
1577 ^[[decltype]](auto) i = 1;
1580 [](HoverInfo &HI) { HI.Name = "int"; }},
1582 R
"cpp(// Simple initialization with const decltype(auto)
1585 ^[[decltype]](auto) i = j;
1588 [](HoverInfo &HI) { HI.Name = "const int"; }},
1590 R
"cpp(// Simple initialization with const& decltype(auto)
1594 ^[[decltype]](auto) i = j;
1597 [](HoverInfo &HI) { HI.Name = "const int &"; }},
1599 R
"cpp(// Simple initialization with & decltype(auto)
1603 ^[[decltype]](auto) i = j;
1606 [](HoverInfo &HI) { HI.Name = "int &"; }},
1608 R
"cpp(// simple trailing return type
1609 ^[[auto]] main() -> int {
1613 [](HoverInfo &HI) { HI.Name = "int"; }},
1615 R
"cpp(// auto function return with trailing type
1617 ^[[auto]] test() -> decltype(Bar()) {
1623 HI.Kind = index::SymbolKind::Struct;
1624 HI.Documentation =
"auto function return with trailing type";
1627 R
"cpp(// trailing return type
1629 auto test() -> ^[[decltype]](Bar()) {
1635 HI.Kind = index::SymbolKind::Struct;
1636 HI.Documentation =
"trailing return type";
1639 R
"cpp(// auto in function return
1647 HI.Kind = index::SymbolKind::Struct;
1648 HI.Documentation =
"auto in function return";
1651 R
"cpp(// auto& in function return
1660 HI.Kind = index::SymbolKind::Struct;
1661 HI.Documentation =
"auto& in function return";
1664 R
"cpp(// auto* in function return
1673 HI.Kind = index::SymbolKind::Struct;
1674 HI.Documentation =
"auto* in function return";
1677 R
"cpp(// const auto& in function return
1679 const ^[[auto]]& test() {
1686 HI.Kind = index::SymbolKind::Struct;
1687 HI.Documentation =
"const auto& in function return";
1690 R
"cpp(// decltype(auto) in function return
1692 ^[[decltype]](auto) test() {
1698 HI.Kind = index::SymbolKind::Struct;
1699 HI.Documentation =
"decltype(auto) in function return";
1702 R
"cpp(// decltype(auto) reference in function return
1703 ^[[decltype]](auto) test() {
1708 [](HoverInfo &HI) { HI.Name = "int &"; }},
1710 R
"cpp(// decltype lvalue reference
1713 ^[[decltype]](I) J = I;
1716 [](HoverInfo &HI) { HI.Name = "int"; }},
1718 R
"cpp(// decltype lvalue reference
1722 ^[[decltype]](K) J = I;
1725 [](HoverInfo &HI) { HI.Name = "int &"; }},
1727 R
"cpp(// decltype lvalue reference parenthesis
1730 ^[[decltype]]((I)) J = I;
1733 [](HoverInfo &HI) { HI.Name = "int &"; }},
1735 R
"cpp(// decltype rvalue reference
1738 ^[[decltype]](static_cast<int&&>(I)) J = static_cast<int&&>(I);
1741 [](HoverInfo &HI) { HI.Name = "int &&"; }},
1743 R
"cpp(// decltype rvalue reference function call
1747 ^[[decltype]](bar()) J = bar();
1750 [](HoverInfo &HI) { HI.Name = "int &&"; }},
1752 R
"cpp(// decltype of function with trailing return type.
1754 auto test() -> decltype(Bar()) {
1758 ^[[decltype]](test()) i = test();
1763 HI.Kind = index::SymbolKind::Struct;
1765 "decltype of function with trailing return type.";
1768 R
"cpp(// decltype of var with decltype.
1772 ^[[decltype]](J) K = J;
1775 [](HoverInfo &HI) { HI.Name = "int"; }},
1777 R
"cpp(// More complicated structured types.
1779 ^[[auto]] (*foo)() = bar;
1781 [](HoverInfo &HI) { HI.Name = "int"; }},
1783 R
"cpp(// Should not crash when evaluating the initializer.
1785 void test() { Test && [[te^st]] = {}; }
1789 HI.Kind = index::SymbolKind::Variable;
1790 HI.NamespaceScope =
"";
1791 HI.LocalScope =
"test::";
1792 HI.Type =
"struct Test &&";
1793 HI.Definition =
"Test &&test = {}";
1796 R
"cpp(// auto on alias
1797 typedef int int_type;
1798 ^[[auto]] x = int_type();
1800 [](HoverInfo &HI) { HI.Name = "int"; }},
1802 R
"cpp(// auto on alias
1804 typedef cls cls_type;
1805 ^[[auto]] y = cls_type();
1809 HI.Kind = index::SymbolKind::Struct;
1810 HI.Documentation =
"auto on alias";
1813 R
"cpp(// auto on alias
1816 ^[[auto]] z = templ<int>();
1819 HI.Name = "templ<int>";
1820 HI.Kind = index::SymbolKind::Struct;
1821 HI.Documentation =
"auto on alias";
1824 R
"cpp(// should not crash.
1825 template <class T> struct cls {
1829 auto test = cls<int>().[[m^ethod]]();
1832 HI.Definition = "int method()";
1833 HI.Kind = index::SymbolKind::InstanceMethod;
1834 HI.NamespaceScope =
"";
1835 HI.LocalScope =
"cls<int>::";
1837 HI.Parameters.emplace();
1838 HI.ReturnType =
"int";
1842 R
"cpp(// type of nested templates.
1843 template <class T> struct cls {};
1844 cls<cls<cls<int>>> [[fo^o]];
1847 HI.Definition = "cls<cls<cls<int>>> foo";
1848 HI.Kind = index::SymbolKind::Variable;
1849 HI.NamespaceScope =
"";
1851 HI.Type =
"cls<cls<cls<int>>>";
1854 R
"cpp(// type of nested templates.
1855 template <class T> struct cls {};
1856 [[cl^s]]<cls<cls<int>>> foo;
1859 HI.Definition = "template <> struct cls<cls<cls<int>>> {}";
1860 HI.Kind = index::SymbolKind::Struct;
1861 HI.NamespaceScope =
"";
1862 HI.Name =
"cls<cls<cls<int>>>";
1863 HI.Documentation =
"type of nested templates.";
1866 R
"cpp(// type with decltype
1868 decltype(a) [[b^]] = a;)cpp",
1870 HI.Definition = "decltype(a) b = a";
1871 HI.Kind = index::SymbolKind::Variable;
1872 HI.NamespaceScope =
"";
1877 R
"cpp(// type with decltype
1880 decltype(c) [[b^]] = a;)cpp",
1882 HI.Definition = "decltype(c) b = a";
1883 HI.Kind = index::SymbolKind::Variable;
1884 HI.NamespaceScope =
"";
1889 R
"cpp(// type with decltype
1891 const decltype(a) [[b^]] = a;)cpp",
1893 HI.Definition = "const decltype(a) b = a";
1894 HI.Kind = index::SymbolKind::Variable;
1895 HI.NamespaceScope =
"";
1900 R
"cpp(// type with decltype
1902 auto [[f^oo]](decltype(a) x) -> decltype(a) { return 0; })cpp",
1904 HI.Definition = "auto foo(decltype(a) x) -> decltype(a)";
1905 HI.Kind = index::SymbolKind::Function;
1906 HI.NamespaceScope =
"";
1910 HI.Type =
"auto (decltype(a)) -> decltype(a)";
1911 HI.ReturnType =
"int";
1913 {std::string(
"int"), std::string(
"x"),
llvm::None}};
1916 R
"cpp(// sizeof expr
1918 (void)[[size^of]](char);
1921 HI.Name = "expression";
1922 HI.Type =
"unsigned long";
1926 R
"cpp(// alignof expr
1928 (void)[[align^of]](char);
1931 HI.Name = "expression";
1932 HI.Type =
"unsigned long";
1937 template <typename T = int>
1938 void foo(const T& = T()) {
1943 HI.Kind = index::SymbolKind::Function;
1944 HI.Type =
"void (const int &)";
1945 HI.ReturnType =
"void";
1947 {std::string(
"const int &"),
llvm::None, std::string(
"T()")}};
1948 HI.Definition =
"template <> void foo<int>(const int &)";
1949 HI.NamespaceScope =
"";
1952 R
"cpp(// should not crash
1960 HI.Kind = index::SymbolKind::Field;
1961 HI.NamespaceScope =
"ObjC::";
1962 HI.Definition =
"char data";
1967 Symbol IndexSym =
func(
"indexSymbol");
1968 IndexSym.Documentation =
"comment from index";
1974 for (
const auto &Case : Cases) {
1975 SCOPED_TRACE(Case.Code);
1977 Annotations T(Case.Code);
1980 TU.ExtraArgs.push_back(
"-xobjective-c++");
1982 TU.ExtraArgs.push_back(
"-Wno-gnu-designator");
1985 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
1986 auto AST = TU.
build();
1988 auto H =
getHover(AST, T.point(), format::getLLVMStyle(),
Index.get());
1994 SCOPED_TRACE(H->present().asPlainText());
1995 EXPECT_EQ(H->NamespaceScope,
Expected.NamespaceScope);
1996 EXPECT_EQ(H->LocalScope,
Expected.LocalScope);
1999 EXPECT_EQ(H->Documentation,
Expected.Documentation);
2000 EXPECT_EQ(H->Definition,
Expected.Definition);
2002 EXPECT_EQ(H->ReturnType,
Expected.ReturnType);
2003 EXPECT_EQ(H->Parameters,
Expected.Parameters);
2004 EXPECT_EQ(H->TemplateParameters,
Expected.TemplateParameters);
2005 EXPECT_EQ(H->SymRange,
Expected.SymRange);
2006 EXPECT_EQ(H->Value,
Expected.Value);
2010 TEST(Hover, DocsFromIndex) {
2011 Annotations T(R
"cpp(
2012 template <typename T> class X {};
2020 auto AST = TU.
build();
2023 IndexSym.Documentation =
"comment from index";
2029 for (
const auto &P : T.points()) {
2030 auto H =
getHover(AST, P, format::getLLVMStyle(),
Index.get());
2032 EXPECT_EQ(H->Documentation, IndexSym.Documentation);
2036 TEST(Hover, DocsFromAST) {
2037 Annotations T(R
"cpp(
2039 template <typename T> class X {};
2041 template <typename T> void bar() {}
2043 template <typename T> T baz;
2048 au^to T = ba^z<X<int>>;
2053 auto AST = TU.
build();
2054 for (
const auto &P : T.points()) {
2055 auto H =
getHover(AST, P, format::getLLVMStyle(),
nullptr);
2057 EXPECT_EQ(H->Documentation,
"doc");
2061 TEST(Hover, DocsFromMostSpecial) {
2062 Annotations T(R
"cpp(
2064 template <typename T> class $doc1^X {};
2066 template <> class $doc2^X<int> {};
2068 template <typename T> class $doc3^X<T*> {};
2076 auto AST = TU.
build();
2077 for (
auto Comment : {
"doc1",
"doc2",
"doc3"}) {
2078 for (
const auto &P : T.points(Comment)) {
2079 auto H =
getHover(AST, P, format::getLLVMStyle(),
nullptr);
2081 EXPECT_EQ(H->Documentation, Comment);
2086 TEST(Hover, Present) {
2088 const std::function<void(HoverInfo &)>
Builder;
2089 llvm::StringRef ExpectedRender;
2093 HI.Kind = index::SymbolKind::Unknown;
2100 HI.Kind = index::SymbolKind::NamespaceAlias;
2103 R
"(namespace-alias foo)",
2107 HI.Kind = index::SymbolKind::Class;
2109 HI.TemplateParameters = {
2110 {std::string("typename"), std::string(
"T"),
llvm::None},
2111 {std::string(
"typename"), std::string(
"C"),
2112 std::string(
"bool")},
2114 HI.Documentation =
"documentation";
2116 "template <typename T, typename C = bool> class Foo {}";
2118 HI.NamespaceScope.emplace();
2125 template <typename T, typename C = bool> class Foo {})",
2129 HI.Kind = index::SymbolKind::Function;
2132 HI.ReturnType =
"ret_type";
2133 HI.Parameters.emplace();
2135 HI.Parameters->push_back(P);
2137 HI.Parameters->push_back(P);
2139 HI.Parameters->push_back(P);
2140 P.Default =
"default";
2141 HI.Parameters->push_back(P);
2142 HI.NamespaceScope =
"ns::";
2143 HI.Definition =
"ret_type foo(params) {}";
2152 - type foo = default
2155 ret_type foo(params) {})",
2159 HI.Kind = index::SymbolKind::Field;
2160 HI.LocalScope = "test::Bar::";
2164 HI.Definition =
"def";
2180 HI.Kind = index::SymbolKind::Field;
2181 HI.AccessSpecifier = "public";
2183 HI.LocalScope =
"test::Bar::";
2184 HI.Definition =
"def";
2193 HI.Definition = "int method()";
2194 HI.AccessSpecifier =
"protected";
2195 HI.Kind = index::SymbolKind::InstanceMethod;
2196 HI.NamespaceScope =
"";
2197 HI.LocalScope =
"cls<int>::";
2199 HI.Parameters.emplace();
2200 HI.ReturnType =
"int";
2203 R
"(instance-method method
2208 protected: int method())",
2212 HI.Kind = index::SymbolKind::Union;
2213 HI.AccessSpecifier = "private";
2215 HI.NamespaceScope =
"ns1::";
2216 HI.Definition =
"union foo {}";
2221 private: union foo {})",
2225 HI.Kind = index::SymbolKind::Variable;
2227 HI.Definition =
"int foo = 3";
2228 HI.LocalScope =
"test::Bar::";
2231 HI.CalleeArgInfo.emplace();
2232 HI.CalleeArgInfo->Name =
"arg_a";
2233 HI.CalleeArgInfo->Type =
"int";
2234 HI.CalleeArgInfo->Default =
"7";
2235 HI.CallPassType.emplace();
2237 HI.CallPassType->Converted =
false;
2250 HI.Kind = index::SymbolKind::Variable;
2252 HI.Definition =
"int foo = 3";
2253 HI.LocalScope =
"test::Bar::";
2256 HI.CalleeArgInfo.emplace();
2257 HI.CalleeArgInfo->Name =
"arg_a";
2258 HI.CalleeArgInfo->Type =
"int";
2259 HI.CalleeArgInfo->Default =
"7";
2260 HI.CallPassType.emplace();
2261 HI.CallPassType->PassBy = PassMode::Ref;
2262 HI.CallPassType->Converted =
false;
2268 Passed by reference as arg_a
2275 HI.Kind = index::SymbolKind::Variable;
2277 HI.Definition =
"int foo = 3";
2278 HI.LocalScope =
"test::Bar::";
2281 HI.CalleeArgInfo.emplace();
2282 HI.CalleeArgInfo->Name =
"arg_a";
2283 HI.CalleeArgInfo->Type =
"int";
2284 HI.CalleeArgInfo->Default =
"7";
2285 HI.CallPassType.emplace();
2287 HI.CallPassType->Converted =
true;
2293 Passed as arg_a (converted to int)
2300 HI.Kind = index::SymbolKind::Variable;
2302 HI.Definition =
"int foo = 3";
2303 HI.LocalScope =
"test::Bar::";
2306 HI.CalleeArgInfo.emplace();
2307 HI.CalleeArgInfo->Name =
"arg_a";
2308 HI.CalleeArgInfo->Type =
"int";
2309 HI.CalleeArgInfo->Default =
"7";
2310 HI.CallPassType.emplace();
2311 HI.CallPassType->PassBy = PassMode::ConstRef;
2312 HI.CallPassType->Converted =
true;
2318 Passed by const reference as arg_a (converted to int)
2324 for (
const auto &C : Cases) {
2327 EXPECT_EQ(HI.present().asPlainText(), C.ExpectedRender);
2331 TEST(Hover, ParseDocumentation) {
2333 llvm::StringRef Documentation;
2334 llvm::StringRef ExpectedRenderMarkdown;
2335 llvm::StringRef ExpectedRenderPlainText;
2392 "Tests primality of `p`.",
2393 "Tests primality of `p`.",
2394 "Tests primality of `p`.",
2397 "'`' should not occur in `Code`",
2398 "'\\`' should not occur in `Code`",
2399 "'`' should not occur in `Code`",
2407 for (
const auto &C : Cases) {
2411 EXPECT_EQ(
Output.asMarkdown(), C.ExpectedRenderMarkdown);
2412 EXPECT_EQ(
Output.asPlainText(), C.ExpectedRenderPlainText);
2418 TEST(Hover, PresentHeadings) {
2420 HI.Kind = index::SymbolKind::Variable;
2423 EXPECT_EQ(HI.present().asMarkdown(),
"### variable `foo`");
2428 TEST(Hover, PresentRulers) {
2430 HI.Kind = index::SymbolKind::Variable;
2433 HI.Definition =
"def";
2435 llvm::StringRef ExpectedMarkdown = R
"md(### variable `foo`
2444 EXPECT_EQ(HI.present().asMarkdown(), ExpectedMarkdown);
2446 llvm::StringRef ExpectedPlaintext = R"pt(variable foo
2451 EXPECT_EQ(HI.present().asPlainText(), ExpectedPlaintext);