18#include "clang/AST/Attr.h"
19#include "clang/Format/Format.h"
20#include "clang/Index/IndexSymbol.h"
21#include "llvm/ADT/StringRef.h"
22#include "llvm/ADT/Twine.h"
24#include "gtest/gtest.h"
36std::string guard(llvm::StringRef Code) {
37 return "#pragma once\n" + Code.str();
42 const char *
const Code;
43 const std::function<void(
HoverInfo &)> ExpectedBuilder;
51 HI.NamespaceScope = "";
53 HI.Kind = index::SymbolKind::Function;
54 HI.Documentation =
"Best foo ever.";
55 HI.Definition =
"void foo()";
56 HI.ReturnType =
"void";
58 HI.Parameters.emplace();
62 void [[fo^o]](auto x) {}
65 HI.NamespaceScope = "";
67 HI.Kind = index::SymbolKind::Function;
68 HI.Documentation =
"Best foo ever.";
69 HI.Definition =
"void foo(auto x)";
70 HI.ReturnType =
"void";
71 HI.Type =
"void (auto)";
72 HI.TemplateParameters = {
73 {{
"class"}, std::string(
"x:auto"), std::nullopt},
76 {{
"auto"}, std::string(
"x"), std::nullopt},
85 HI.NamespaceScope = "";
87 HI.Kind = index::SymbolKind::Function;
88 HI.Documentation =
"Best foo ever.";
89 HI.Definition =
"template <class T> void foo(T x)";
90 HI.ReturnType =
"void";
92 HI.TemplateParameters = {
93 {{
"class"}, std::string(
"T"), std::nullopt},
96 {{
"T"}, std::string(
"x"), std::nullopt},
102 void [[fo^o]](T x, auto y) {}
105 HI.NamespaceScope = "";
107 HI.Kind = index::SymbolKind::Function;
108 HI.Documentation =
"Best foo ever.";
109 HI.Definition =
"template <class T> void foo(T x, auto y)";
110 HI.ReturnType =
"void";
111 HI.Type =
"void (T, auto)";
112 HI.TemplateParameters = {
113 {{
"class"}, std::string(
"T"), std::nullopt},
114 {{
"class"}, std::string(
"y:auto"), std::nullopt},
117 {{
"T"}, std::string(
"x"), std::nullopt},
118 {{
"auto"}, std::string(
"y"), std::nullopt},
122 template<typename T1, typename T2>
123 concept C = requires () { true; };
127 void [[fo^o]](T x) {}
130 HI.NamespaceScope = "";
132 HI.Kind = index::SymbolKind::Function;
133 HI.Documentation =
"Best foo ever.";
134 HI.Definition =
"template <C<int> T> void foo(T x)";
135 HI.ReturnType =
"void";
136 HI.Type =
"void (T)";
137 HI.TemplateParameters = {
138 {{
"class"}, std::string(
"T"), std::nullopt},
141 {{
"T"}, std::string(
"x"), std::nullopt},
145 template<typename T1, typename T2>
146 concept C = requires () { true; };
149 void [[fo^o]](C<int> auto x) {}
152 HI.NamespaceScope = "";
154 HI.Kind = index::SymbolKind::Function;
155 HI.Documentation =
"Best foo ever.";
156 HI.Definition =
"void foo(C<int> auto x)";
157 HI.ReturnType =
"void";
158 HI.Type =
"void (C<int> auto)";
159 HI.TemplateParameters = {
160 {{
"class"}, std::string(
"x:auto"), std::nullopt},
163 {{
"C<int> auto"}, std::string(
"x"), std::nullopt},
167 template<typename T1, typename T2>
168 concept C = requires () { true; };
172 void [[fo^o]](T x, C<int> auto y) {}
175 HI.NamespaceScope = "";
177 HI.Kind = index::SymbolKind::Function;
178 HI.Documentation =
"Best foo ever.";
179 HI.Definition =
"template <C<int> T> void foo(T x, C<int> auto y)";
180 HI.ReturnType =
"void";
181 HI.Type =
"void (T, C<int> auto)";
182 HI.TemplateParameters = {
183 {{
"class"}, std::string(
"T"), std::nullopt},
184 {{
"class"}, std::string(
"y:auto"), std::nullopt},
187 {{
"T"}, std::string(
"x"), std::nullopt},
188 {{
"C<int> auto"}, std::string(
"y"), std::nullopt},
193 namespace ns1 { namespace ns2 {
199 HI.NamespaceScope =
"ns1::ns2::";
201 HI.Kind = index::SymbolKind::Function;
202 HI.Documentation =
"Best foo ever.";
203 HI.Definition =
"void foo()";
204 HI.ReturnType =
"void";
206 HI.Parameters.emplace();
210 namespace ns1 { namespace ns2 {
218 HI.NamespaceScope = "ns1::ns2::";
219 HI.LocalScope =
"Foo::";
221 HI.Kind = index::SymbolKind::Field;
222 HI.Definition =
"char bar";
228 HI.AccessSpecifier =
"private";
238 HI.NamespaceScope = "";
239 HI.LocalScope =
"Foo::";
241 HI.Kind = index::SymbolKind::Field;
242 HI.Definition =
"char bar";
247 HI.AccessSpecifier =
"public";
257 HI.NamespaceScope = "";
258 HI.LocalScope =
"Foo::";
260 HI.Kind = index::SymbolKind::Field;
261 HI.Definition =
"int x : 1";
266 HI.AccessSpecifier =
"public";
270 namespace ns1 { namespace ns2 {
279 HI.NamespaceScope = "ns1::ns2::";
280 HI.LocalScope =
"Foo::foo::";
282 HI.Kind = index::SymbolKind::Variable;
283 HI.Definition =
"int bar";
293 HI.Name = "__func__";
294 HI.Kind = index::SymbolKind::Variable;
296 "Name of the current function (predefined variable)";
297 HI.Value =
"\"foo\"";
298 HI.Type =
"const char[4]";
302 template<int> void foo() {
307 HI.Name = "__func__";
308 HI.Kind = index::SymbolKind::Variable;
310 "Name of the current function (predefined variable)";
311 HI.Type =
"const char[]";
315 namespace ns1 { namespace {
322 HI.NamespaceScope = "ns1::";
323 HI.LocalScope =
"(anonymous struct)::";
325 HI.Kind = index::SymbolKind::Field;
326 HI.Definition =
"char bar";
331 HI.AccessSpecifier =
"public";
338 HI.NamespaceScope = "";
340 HI.Kind = index::SymbolKind::Struct;
341 HI.Definition =
"struct X {}";
347 template <typename T, class... Ts> class Foo { public: Foo(int); };
348 Foo<int, char, bool> [[fo^o]] = Foo<int, char, bool>(5);
351 HI.NamespaceScope = "";
353 HI.Kind = index::SymbolKind::Variable;
354 HI.Definition =
"Foo<int, char, bool> foo = Foo<int, char, bool>(5)";
355 HI.Type =
"Foo<int, char, bool>";
359 template <typename T> class vector{};
360 [[vec^tor]]<int> foo;
363 HI.NamespaceScope = "";
364 HI.Name =
"vector<int>";
365 HI.Kind = index::SymbolKind::Class;
366 HI.Definition =
"template <> class vector<int> {}";
370 template <template<typename, bool...> class C,
374 class... Ts> class Foo final {};
375 template <template<typename, bool...> class T>
379 HI.NamespaceScope = "";
381 HI.Kind = index::SymbolKind::Class;
383 R
"cpp(template <template <typename, bool...> class C, typename = char, int = 0,
384 bool Q = false, class... Ts>
385class Foo final {})cpp";
386 HI.TemplateParameters = {
387 {{"template <typename, bool...> class"},
390 {{
"typename"}, std::nullopt, std::string(
"char")},
391 {{
"int"}, std::nullopt, std::string(
"0")},
392 {{
"bool"}, std::string(
"Q"), std::string(
"false")},
393 {{
"class..."}, std::string(
"Ts"), std::nullopt},
398 template <template<typename, bool...> class C,
402 class... Ts> void foo();
403 template<typename, bool...> class Foo;
410 HI.NamespaceScope = "";
412 HI.Kind = index::SymbolKind::Function;
413 HI.Definition =
"template <> void foo<Foo, char, 0, false, <>>()";
414 HI.ReturnType =
"void";
416 HI.Parameters.emplace();
420 template<typename, bool...> class Foo {};
421 Foo<bool, true, false> foo(int, bool T = false);
428 HI.NamespaceScope = "";
430 HI.Kind = index::SymbolKind::Function;
431 HI.Definition =
"Foo<bool, true, false> foo(int, bool T = false)";
432 HI.ReturnType =
"Foo<bool, true, false>";
433 HI.Type =
"Foo<bool, true, false> (int, bool)";
435 {{
"int"}, std::nullopt, std::nullopt},
436 {{
"bool"}, std::string(
"T"), std::string(
"false")},
442 auto lamb = [](int T, bool B) -> bool { return T && B; };
448 HI.NamespaceScope = "";
449 HI.LocalScope =
"foo::";
451 HI.Kind = index::SymbolKind::Variable;
452 HI.Definition =
"auto *c = &b";
453 HI.Type =
"(lambda) **";
454 HI.ReturnType =
"bool";
456 {{
"int"}, std::string(
"T"), std::nullopt},
457 {{
"bool"}, std::string(
"B"), std::nullopt},
463 auto lamb = [](int T, bool B) -> bool { return T && B; };
464 void foo(decltype(lamb)& bar) {
469 HI.NamespaceScope = "";
470 HI.LocalScope =
"foo::";
472 HI.Kind = index::SymbolKind::Parameter;
473 HI.Definition =
"decltype(lamb) &bar";
474 HI.Type = {
"decltype(lamb) &",
"(lambda) &"};
475 HI.ReturnType =
"bool";
477 {{
"int"}, std::string(
"T"), std::nullopt},
478 {{
"bool"}, std::string(
"B"), std::nullopt},
484 auto lamb = [](int T, bool B) -> bool { return T && B; };
485 void foo(decltype(lamb) bar) {
490 HI.NamespaceScope = "";
491 HI.LocalScope =
"foo::";
493 HI.Kind = index::SymbolKind::Parameter;
494 HI.Definition =
"decltype(lamb) bar";
495 HI.Type =
"class (lambda)";
496 HI.ReturnType =
"bool";
498 {{
"int"}, std::string(
"T"), std::nullopt},
499 {{
"bool"}, std::string(
"B"), std::nullopt},
508 auto lamb = [&bar](int T, bool B) -> bool { return T && B && bar; };
509 bool res = [[lam^b]](bar, false);
513 HI.NamespaceScope = "";
514 HI.LocalScope =
"foo::";
516 HI.Kind = index::SymbolKind::Variable;
517 HI.Definition =
"auto lamb = [&bar](int T, bool B) -> bool {}";
518 HI.Type =
"class (lambda)";
519 HI.ReturnType =
"bool";
521 {{
"int"}, std::string(
"T"), std::nullopt},
522 {{
"bool"}, std::string(
"B"), std::nullopt},
529 auto lamb = []{int [[te^st]];};
533 HI.NamespaceScope = "";
534 HI.LocalScope =
"foo::(anonymous class)::operator()::";
536 HI.Kind = index::SymbolKind::Variable;
537 HI.Definition =
"int test";
542 template <typename T> class X;
543 template <typename T> class [[^X]]<T*> {};
547 HI.NamespaceScope =
"";
548 HI.Kind = index::SymbolKind::Class;
549 HI.Definition =
"template <typename T> class X<T *> {}";
553 template<typename, typename=void> struct X;
554 template<typename T> struct X<T*>{ [[^X]](); };
557 HI.NamespaceScope = "";
559 HI.LocalScope =
"X<T *>::";
560 HI.Kind = index::SymbolKind::Constructor;
561 HI.Definition =
"X()";
562 HI.Parameters.emplace();
563 HI.AccessSpecifier =
"public";
565 {
"class X { [[^~]]X(); };",
567 HI.NamespaceScope =
"";
569 HI.LocalScope =
"X::";
570 HI.Kind = index::SymbolKind::Destructor;
571 HI.Definition =
"~X()";
572 HI.Parameters.emplace();
573 HI.AccessSpecifier =
"private";
575 {
"class X { [[op^erator]] int(); };",
577 HI.NamespaceScope =
"";
578 HI.Name =
"operator int";
579 HI.LocalScope =
"X::";
580 HI.Kind = index::SymbolKind::ConversionFunction;
581 HI.Definition =
"operator int()";
582 HI.Parameters.emplace();
583 HI.AccessSpecifier =
"private";
585 {
"class X { operator [[^X]](); };",
587 HI.NamespaceScope =
"";
589 HI.Kind = index::SymbolKind::Class;
590 HI.Definition =
"class X {}";
596 struct S { int x; float y; };
597 [[au^to]] [x, y] = S();
602 HI.Kind = index::SymbolKind::TypeAlias;
614 HI.Kind = index::SymbolKind::TypeAlias;
619 template <class T> concept F = true;
624 HI.Kind = index::SymbolKind::TypeAlias;
625 HI.Definition =
"int";
628 template <class T> concept F = true;
632 HI.NamespaceScope = "";
634 HI.Kind = index::SymbolKind::Concept;
635 HI.Definition =
"template <class T>\nconcept F = true";
640 [[au^to]] lamb = []{};
645 HI.Kind = index::SymbolKind::TypeAlias;
646 HI.Definition =
"class(lambda)";
650 template<typename T> class Foo{};
652 [[au^to]] x = Foo<int>();
657 HI.Kind = index::SymbolKind::TypeAlias;
658 HI.Definition =
"Foo<int>";
662 template<typename T> class Foo{};
663 template<> class Foo<int>{};
665 [[au^to]] x = Foo<int>();
670 HI.Kind = index::SymbolKind::TypeAlias;
671 HI.Definition =
"Foo<int>";
675 template<class T> concept Fooable = true;
676 template<[[Foo^able]] T>
680 HI.NamespaceScope = "";
682 HI.Kind = index::SymbolKind::Concept;
683 HI.Definition =
"template <class T>\nconcept Fooable = true";
686 template<class T> concept Fooable = true;
687 template<Fooable [[T^T]]>
693 HI.AccessSpecifier =
"public";
694 HI.NamespaceScope =
"";
695 HI.LocalScope =
"bar::";
696 HI.Kind = index::SymbolKind::TemplateTypeParm;
697 HI.Definition =
"Fooable TT";
700 template<class T> concept Fooable = true;
701 void bar([[Foo^able]] auto t) {}
704 HI.NamespaceScope = "";
706 HI.Kind = index::SymbolKind::Concept;
707 HI.Definition =
"template <class T>\nconcept Fooable = true";
711 template<class T> concept Fooable = true;
712 auto X = [[Fooa^ble]]<int>;
715 HI.NamespaceScope = "";
717 HI.Kind = index::SymbolKind::Concept;
718 HI.Definition =
"template <class T>\nconcept Fooable = true";
729 HI.Kind = index::SymbolKind::Macro;
730 HI.Definition =
"#define MACRO";
740 HI.Kind = index::SymbolKind::Macro;
741 HI.Value =
"41 (0x29)";
743 HI.Definition =
"#define MACRO 41\n\n"
751 #define MACRO(x,y,z) void foo(x, y, z)
752 [[MAC^RO]](int, double d, bool z = false);
756 HI.Kind = index::SymbolKind::Macro;
757 HI.Definition =
"#define MACRO(x, y, z) void foo(x, y, z)\n\n"
759 "void foo(int, double d, bool z = false)";
764 #define STRINGIFY_AUX(s) #s
765 #define STRINGIFY(s) STRINGIFY_AUX(s)
766 #define DECL_STR(NAME, VALUE) const char *v_##NAME = STRINGIFY(VALUE)
769 [[DECL^_STR]](foo, FOO);
772 HI.Name = "DECL_STR";
773 HI.Kind = index::SymbolKind::Macro;
775 HI.Definition =
"#define DECL_STR(NAME, VALUE) const char *v_##NAME = "
776 "STRINGIFY(VALUE)\n\n"
778 "const char *v_foo = \"41\"";
783 constexpr int add(int a, int b) { return a + b; }
784 int [[b^ar]] = add(1, 2);
788 HI.Definition =
"int bar = add(1, 2)";
789 HI.Kind = index::SymbolKind::Variable;
791 HI.NamespaceScope =
"";
795 int [[b^ar]] = sizeof(char);
799 HI.Definition =
"int bar = sizeof(char)";
800 HI.Kind = index::SymbolKind::Variable;
802 HI.NamespaceScope =
"";
806 template<int a, int b> struct Add {
807 static constexpr int result = a + b;
809 int [[ba^r]] = Add<1, 2>::result;
813 HI.Definition =
"int bar = Add<1, 2>::result";
814 HI.Kind = index::SymbolKind::Variable;
816 HI.NamespaceScope =
"";
820 enum Color { RED = -123, GREEN = 5, };
821 Color x = [[GR^EEN]];
825 HI.NamespaceScope =
"";
826 HI.LocalScope =
"Color::";
827 HI.Definition =
"GREEN = 5";
828 HI.Kind = index::SymbolKind::EnumConstant;
829 HI.Type =
"enum Color";
833 enum Color { RED = -123, GREEN = 5, };
839 HI.NamespaceScope =
"";
840 HI.Definition =
"Color x = RED";
841 HI.Kind = index::SymbolKind::Variable;
843 HI.Value =
"RED (0xffffff85)";
846 template<int a, int b> struct Add {
847 static constexpr int result = a + b;
849 int bar = Add<1, 2>::[[resu^lt]];
853 HI.Definition =
"static constexpr int result = a + b";
854 HI.Kind = index::SymbolKind::StaticProperty;
855 HI.Type =
"const int";
856 HI.NamespaceScope =
"";
857 HI.LocalScope =
"Add<1, 2>::";
859 HI.AccessSpecifier =
"public";
863 constexpr my_int answer() { return 40 + 2; }
864 int x = [[ans^wer]]();
868 HI.Definition =
"constexpr my_int answer()";
869 HI.Kind = index::SymbolKind::Function;
870 HI.Type = {
"my_int ()",
"int ()"};
871 HI.ReturnType = {
"my_int",
"int"};
872 HI.Parameters.emplace();
873 HI.NamespaceScope =
"";
874 HI.Value =
"42 (0x2a)";
877 const char *[[ba^r]] = "1234";
881 HI.Definition =
"const char *bar = \"1234\"";
882 HI.Kind = index::SymbolKind::Variable;
883 HI.Type =
"const char *";
884 HI.NamespaceScope =
"";
885 HI.Value =
"&\"1234\"[0]";
887 {R
"cpp(// Should not crash
888 template <typename T>
893 template <typename A>
894 void boom(int name) {
895 new Tmpl<A>([[na^me]]);
899 HI.Definition =
"int name";
900 HI.Kind = index::SymbolKind::Parameter;
902 HI.NamespaceScope =
"";
903 HI.LocalScope =
"boom::";
906 R
"cpp(// Should not print inline or anon namespaces.
908 inline namespace in_ns {
912 inline namespace in_ns2 {
921 ns::a::b::[[F^oo]] x;
927 HI.Kind = index::SymbolKind::Class;
928 HI.NamespaceScope =
"ns::a::b::";
929 HI.Definition =
"class Foo {}";
933 template <typename T> class Foo {};
936 [[^auto]] x = Foo<X>();
941 HI.Kind = index::SymbolKind::TypeAlias;
942 HI.Definition =
"Foo<X>";
946 // comment from primary
947 template <typename T> class Foo {};
948 // comment from specialization
949 template <typename T> class Foo<T*> {};
951 [[Fo^o]]<int*> *x = nullptr;
955 HI.Name = "Foo<int *>";
956 HI.Kind = index::SymbolKind::Class;
957 HI.NamespaceScope =
"";
958 HI.Definition =
"template <> class Foo<int *>";
961 HI.Documentation =
"comment from primary";
965 template <typename [[^T]] = int> void foo();
969 HI.Kind = index::SymbolKind::TemplateTypeParm;
970 HI.NamespaceScope =
"";
971 HI.Definition =
"typename T = int";
972 HI.LocalScope =
"foo::";
973 HI.Type =
"typename";
974 HI.AccessSpecifier =
"public";
978 template <template<typename> class [[^T]]> void foo();
982 HI.Kind = index::SymbolKind::TemplateTemplateParm;
983 HI.NamespaceScope =
"";
984 HI.Definition =
"template <typename> class T";
985 HI.LocalScope =
"foo::";
986 HI.Type =
"template <typename> class";
987 HI.AccessSpecifier =
"public";
991 template <int [[^T]] = 5> void foo();
995 HI.Kind = index::SymbolKind::NonTypeTemplateParm;
996 HI.NamespaceScope =
"";
997 HI.Definition =
"int T = 5";
998 HI.LocalScope =
"foo::";
1000 HI.AccessSpecifier =
"public";
1005 struct X { int Y; float [[^y]]() { return Y; } };
1009 HI.Kind = index::SymbolKind::InstanceMethod;
1010 HI.NamespaceScope =
"";
1011 HI.Definition =
"float y()";
1012 HI.LocalScope =
"X::";
1013 HI.Documentation =
"Trivial accessor for `Y`.";
1014 HI.Type =
"float ()";
1015 HI.ReturnType =
"float";
1016 HI.Parameters.emplace();
1017 HI.AccessSpecifier =
"public";
1021 struct X { int Y; void [[^setY]](float v) { Y = v; } };
1025 HI.Kind = index::SymbolKind::InstanceMethod;
1026 HI.NamespaceScope =
"";
1027 HI.Definition =
"void setY(float v)";
1028 HI.LocalScope =
"X::";
1029 HI.Documentation =
"Trivial setter for `Y`.";
1030 HI.Type =
"void (float)";
1031 HI.ReturnType =
"void";
1032 HI.Parameters.emplace();
1033 HI.Parameters->emplace_back();
1034 HI.Parameters->back().Type =
"float";
1035 HI.Parameters->back().Name =
"v";
1036 HI.AccessSpecifier =
"public";
1040 struct X { int Y; X& [[^setY]](float v) { Y = v; return *this; } };
1044 HI.Kind = index::SymbolKind::InstanceMethod;
1045 HI.NamespaceScope =
"";
1046 HI.Definition =
"X &setY(float v)";
1047 HI.LocalScope =
"X::";
1048 HI.Documentation =
"Trivial setter for `Y`.";
1049 HI.Type =
"X &(float)";
1050 HI.ReturnType =
"X &";
1051 HI.Parameters.emplace();
1052 HI.Parameters->emplace_back();
1053 HI.Parameters->back().Type =
"float";
1054 HI.Parameters->back().Name =
"v";
1055 HI.AccessSpecifier =
"public";
1059 namespace std { template<typename T> T&& move(T&& t); }
1060 struct X { int Y; void [[^setY]](float v) { Y = std::move(v); } };
1064 HI.Kind = index::SymbolKind::InstanceMethod;
1065 HI.NamespaceScope =
"";
1066 HI.Definition =
"void setY(float v)";
1067 HI.LocalScope =
"X::";
1068 HI.Documentation =
"Trivial setter for `Y`.";
1069 HI.Type =
"void (float)";
1070 HI.ReturnType =
"void";
1071 HI.Parameters.emplace();
1072 HI.Parameters->emplace_back();
1073 HI.Parameters->back().Type =
"float";
1074 HI.Parameters->back().Name =
"v";
1075 HI.AccessSpecifier =
"public";
1079 struct X { int x = 2; };
1084 HI.Kind = index::SymbolKind::Variable;
1085 HI.NamespaceScope =
"";
1086 HI.Definition =
"X x";
1090 R
"cpp(auto [^[[x]]] = 1; /*error-ok*/)cpp",
1093 HI.Kind = index::SymbolKind::Variable;
1094 HI.NamespaceScope =
"";
1096 HI.Type =
"NULL TYPE";
1098 HI.AccessSpecifier =
"public";
1102 Unknown [[^abc]] = invalid;
1107 HI.Kind = index::SymbolKind::Variable;
1108 HI.NamespaceScope =
"";
1109 HI.Definition =
"int abc";
1111 HI.AccessSpecifier =
"public";
1115 void fun(int arg_a, int &arg_b) {};
1123 HI.Kind = index::SymbolKind::Variable;
1124 HI.NamespaceScope =
"";
1125 HI.Definition =
"int b = 2";
1126 HI.LocalScope =
"code::";
1129 HI.CalleeArgInfo.emplace();
1130 HI.CalleeArgInfo->Name =
"arg_b";
1131 HI.CalleeArgInfo->Type =
"int &";
1137 explicit Foo(int arg_a) {}
1139 template<class T, class... Args>
1140 T make(Args&&... args)
1147 auto foo = make<Foo>([[^a]]);
1152 HI.Kind = index::SymbolKind::Variable;
1153 HI.NamespaceScope =
"";
1154 HI.Definition =
"int a = 1";
1155 HI.LocalScope =
"code::";
1158 HI.CalleeArgInfo.emplace();
1159 HI.CalleeArgInfo->Name =
"arg_a";
1160 HI.CalleeArgInfo->Type =
"int";
1165 void foobar(const float &arg);
1173 HI.Kind = index::SymbolKind::Variable;
1174 HI.NamespaceScope =
"";
1175 HI.Definition =
"int a = 0";
1176 HI.LocalScope =
"main::";
1179 HI.CalleeArgInfo.emplace();
1180 HI.CalleeArgInfo->Name =
"arg";
1181 HI.CalleeArgInfo->Type =
"const float &";
1187 explicit Foo(const float& arg) {}
1196 HI.Kind = index::SymbolKind::Variable;
1197 HI.NamespaceScope =
"";
1198 HI.Definition =
"int a = 0";
1199 HI.LocalScope =
"main::";
1202 HI.CalleeArgInfo.emplace();
1203 HI.CalleeArgInfo->Name =
"arg";
1204 HI.CalleeArgInfo->Type =
"const float &";
1209 void fun(int arg_a, const int &arg_b) {};
1216 HI.Name = "literal";
1217 HI.Kind = index::SymbolKind::Unknown;
1218 HI.CalleeArgInfo.emplace();
1219 HI.CalleeArgInfo->Name =
"arg_b";
1220 HI.CalleeArgInfo->Type =
"const int &";
1225 void fun(int arg_a, const int &arg_b) {};
1232 HI.Name = "expression";
1233 HI.Kind = index::SymbolKind::Unknown;
1236 HI.CalleeArgInfo.emplace();
1237 HI.CalleeArgInfo->Name =
"arg_b";
1238 HI.CalleeArgInfo->Type =
"const int &";
1243 int add(int lhs, int rhs);
1249 HI.Name = "expression";
1250 HI.Kind = index::SymbolKind::Unknown;
1253 HI.CalleeArgInfo.emplace();
1254 HI.CalleeArgInfo->Name =
"lhs";
1255 HI.CalleeArgInfo->Type =
"int";
1260 void foobar(const float &arg);
1266 HI.Name = "literal";
1267 HI.Kind = index::SymbolKind::Unknown;
1268 HI.CalleeArgInfo.emplace();
1269 HI.CalleeArgInfo->Name =
"arg";
1270 HI.CalleeArgInfo->Type =
"const float &";
1277 void fun(int arg_a = 3, int arg_b = 4) {}
1287 HI.Kind = index::SymbolKind::Variable;
1288 HI.NamespaceScope =
"";
1289 HI.Definition =
"int a = 1";
1290 HI.LocalScope =
"code::";
1293 HI.CalleeArgInfo.emplace();
1294 HI.CalleeArgInfo->Name =
"arg_a";
1295 HI.CalleeArgInfo->Type =
"int";
1296 HI.CalleeArgInfo->Default =
"3";
1312 HI.Kind = index::SymbolKind::Variable;
1313 HI.NamespaceScope =
"";
1314 HI.Definition =
"const int x = 0";
1315 HI.LocalScope =
"bar::";
1317 HI.Type =
"const int";
1318 HI.CalleeArgInfo.emplace();
1319 HI.CalleeArgInfo->Type =
"Foo";
1330 HI.Kind = index::SymbolKind::Field;
1331 HI.NamespaceScope =
"";
1332 HI.Definition =
"int xx";
1333 HI.LocalScope =
"Foo::";
1335 HI.AccessSpecifier =
"public";
1345 HI.Kind = index::SymbolKind::Field;
1346 HI.NamespaceScope =
"";
1347 HI.Definition =
"int yy";
1348 HI.LocalScope =
"Foo::";
1350 HI.AccessSpecifier =
"public";
1357 constexpr Foo k2 = {
1358 ^[[{]]1} // FIXME: why the hover range is 1 character?
1362 HI.Name = "expression";
1363 HI.Kind = index::SymbolKind::Unknown;
1364 HI.Type =
"int[10]";
1371 template <int Size> m_int ^[[arr]][Size];
1375 HI.Kind = index::SymbolKind::Variable;
1376 HI.Type = {
"m_int[Size]",
"int[Size]"};
1377 HI.NamespaceScope =
"";
1378 HI.Definition =
"template <int Size> m_int arr[Size]";
1379 HI.TemplateParameters = {{{
"int"}, {
"Size"}, std::nullopt}};
1385 template <int Size> m_int arr[Size];
1387 template <> m_int ^[[arr]]<4>[4];
1391 HI.Kind = index::SymbolKind::Variable;
1392 HI.Type = {
"m_int[4]",
"int[4]"};
1393 HI.NamespaceScope =
"";
1394 HI.Definition =
"m_int arr[4]";
1398 template<typename T>
1404 TestHover<int>::Type ^[[a]];
1409 HI.NamespaceScope =
"";
1410 HI.LocalScope =
"code::";
1411 HI.Definition =
"TestHover<int>::Type a";
1412 HI.Kind = index::SymbolKind::Variable;
1413 HI.Type = {
"TestHover<int>::Type",
"int"};
1417 template<typename T>
1418 void ^[[foo]](T arg) {}
1422 HI.Kind = index::SymbolKind::Function;
1423 HI.NamespaceScope =
"";
1424 HI.Definition =
"template <typename T> void foo(T arg)";
1425 HI.Type =
"void (T)";
1426 HI.ReturnType =
"void";
1427 HI.Parameters = {{{
"T"}, std::string(
"arg"), std::nullopt}};
1428 HI.TemplateParameters = {
1429 {{
"typename"}, std::string(
"T"), std::nullopt}};
1433 template<typename T>
1434 using ^[[alias]] = T;
1438 HI.NamespaceScope =
"";
1440 HI.Kind = index::SymbolKind::TypeAlias;
1441 HI.Definition =
"template <typename T> using alias = T";
1443 HI.TemplateParameters = {
1444 {{
"typename"}, std::string(
"T"), std::nullopt}};
1448 template<typename T>
1451 template<typename T>
1452 using ^[[AA]] = A<T>;
1456 HI.NamespaceScope =
"";
1458 HI.Kind = index::SymbolKind::TypeAlias;
1459 HI.Definition =
"template <typename T> using AA = A<T>";
1460 HI.Type = {
"A<T>",
"T"};
1461 HI.TemplateParameters = {
1462 {{
"typename"}, std::string(
"T"), std::nullopt}};
1472 HI.NamespaceScope =
"";
1474 HI.Kind = index::SymbolKind::Variable;
1475 HI.Definition =
"m_int arr[10]";
1476 HI.Type = {
"m_int[10]",
"int[10]"};
1482 extern m_int ^[[arr]][];
1486 HI.NamespaceScope =
"";
1488 HI.Kind = index::SymbolKind::Variable;
1489 HI.Definition =
"extern m_int arr[]";
1490 HI.Type = {
"m_int[]",
"int[]"};
1498 m_int ^[[arr]][Size];
1503 HI.NamespaceScope =
"";
1504 HI.LocalScope =
"Test<Size>::";
1505 HI.AccessSpecifier =
"public";
1506 HI.Kind = index::SymbolKind::Field;
1507 HI.Definition =
"m_int arr[Size]";
1508 HI.Type = {
"m_int[Size]",
"int[Size]"};
1519 HI.NamespaceScope = "";
1520 HI.LocalScope =
"Foo::";
1522 HI.Kind = index::SymbolKind::Field;
1523 HI.Definition =
"char y : 1";
1529 HI.AccessSpecifier =
"public";
1531 for (
const auto &Case : Cases) {
1532 SCOPED_TRACE(Case.Code);
1536 TU.ExtraArgs.push_back(
"-std=c++20");
1539 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
1540 auto AST = TU.build();
1545 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
1549 Case.ExpectedBuilder(Expected);
1551 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
1552 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
1553 EXPECT_EQ(H->Name, Expected.Name);
1554 EXPECT_EQ(H->Kind, Expected.Kind);
1555 EXPECT_EQ(H->Documentation, Expected.Documentation);
1556 EXPECT_EQ(H->Definition, Expected.Definition);
1557 EXPECT_EQ(H->Type, Expected.Type);
1558 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
1559 EXPECT_EQ(H->Parameters, Expected.Parameters);
1560 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
1561 EXPECT_EQ(H->SymRange, Expected.SymRange);
1562 EXPECT_EQ(H->Value, Expected.Value);
1563 EXPECT_EQ(H->Size, Expected.Size);
1564 EXPECT_EQ(H->Offset, Expected.Offset);
1565 EXPECT_EQ(H->Align, Expected.Align);
1566 EXPECT_EQ(H->AccessSpecifier, Expected.AccessSpecifier);
1567 EXPECT_EQ(H->CalleeArgInfo, Expected.CalleeArgInfo);
1568 EXPECT_EQ(H->CallPassType, Expected.CallPassType);
1574 const char *
const Code;
1575 const std::string ClangLanguageFlag;
1576 const char *
const ExpectedDefinitionLanguage;
1577 } Cases[] = {{R
"cpp(
1578 void [[some^Global]]() {}
1582 void [[some^Global]]() {}
1584 "-xobjective-c++",
"objective-cpp"},
1586 void [[some^Global]]() {}
1588 "-xobjective-c",
"objective-c"}};
1589 for (
const auto &Case : Cases) {
1590 SCOPED_TRACE(Case.Code);
1594 if (!Case.ClangLanguageFlag.empty())
1595 TU.ExtraArgs.push_back(Case.ClangLanguageFlag);
1596 auto AST = TU.build();
1598 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
1601 EXPECT_STREQ(H->DefinitionLanguage, Case.ExpectedDefinitionLanguage);
1606 const llvm::StringRef CodePrefix = R
"cpp(
1608class Derived : public Base {};
1612 CustomClass(const Base &x) {}
1613 CustomClass(int &x) {}
1614 CustomClass(float x) {}
1615 CustomClass(int x, int y) {}
1618void int_by_ref(int &x) {}
1619void int_by_const_ref(const int &x) {}
1620void int_by_value(int x) {}
1621void base_by_ref(Base &x) {}
1622void base_by_const_ref(const Base &x) {}
1623void base_by_value(Base x) {}
1624void float_by_value(float x) {}
1625void custom_by_value(CustomClass x) {}
1629 int &int_ref = int_x;
1630 const int &int_const_ref = int_x;
1632 const Base &base_const_ref = base;
1636 const llvm::StringRef CodeSuffix =
"}";
1639 const char *
const Code;
1644 {
"int_by_value([[^int_x]]);", PassMode::Value,
false},
1645 {
"int_by_value([[^123]]);", PassMode::Value,
false},
1646 {
"int_by_ref([[^int_x]]);", PassMode::Ref,
false},
1647 {
"int_by_const_ref([[^int_x]]);", PassMode::ConstRef,
false},
1648 {
"int_by_const_ref([[^123]]);", PassMode::ConstRef,
false},
1649 {
"int_by_value([[^int_ref]]);", PassMode::Value,
false},
1650 {
"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef,
false},
1651 {
"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef,
false},
1652 {
"int_by_const_ref([[^int_const_ref]]);", PassMode::ConstRef,
false},
1654 {
"base_by_ref([[^base]]);", PassMode::Ref,
false},
1655 {
"base_by_const_ref([[^base]]);", PassMode::ConstRef,
false},
1656 {
"base_by_const_ref([[^base_const_ref]]);", PassMode::ConstRef,
false},
1657 {
"base_by_value([[^base]]);", PassMode::Value,
false},
1658 {
"base_by_value([[^base_const_ref]]);", PassMode::Value,
false},
1659 {
"base_by_ref([[^derived]]);", PassMode::Ref,
false},
1660 {
"base_by_const_ref([[^derived]]);", PassMode::ConstRef,
false},
1661 {
"base_by_value([[^derived]]);", PassMode::Value,
false},
1663 {
"CustomClass c1([[^base]]);", PassMode::ConstRef,
false},
1664 {
"auto c2 = new CustomClass([[^base]]);", PassMode::ConstRef,
false},
1665 {
"CustomClass c3([[^int_x]]);", PassMode::Ref,
false},
1666 {
"CustomClass c3(int_x, [[^int_x]]);", PassMode::Value,
false},
1668 {
"float_by_value([[^int_x]]);", PassMode::Value,
true},
1669 {
"float_by_value([[^int_ref]]);", PassMode::Value,
true},
1670 {
"float_by_value([[^int_const_ref]]);", PassMode::Value,
true},
1671 {
"float_by_value([[^123.0f]]);", PassMode::Value,
false},
1672 {
"float_by_value([[^123]]);", PassMode::Value,
true},
1673 {
"custom_by_value([[^int_x]]);", PassMode::Ref,
true},
1674 {
"custom_by_value([[^float_x]]);", PassMode::Value,
true},
1675 {
"custom_by_value([[^base]]);", PassMode::ConstRef,
true},
1677 for (
const auto &Test : Tests) {
1678 SCOPED_TRACE(Test.Code);
1680 const auto Code = (CodePrefix + Test.Code + CodeSuffix).str();
1683 TU.ExtraArgs.push_back(
"-std=c++17");
1684 auto AST = TU.build();
1685 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
1687 EXPECT_EQ(H->CallPassType->PassBy, Test.PassBy);
1688 EXPECT_EQ(H->CallPassType->Converted, Test.Converted);
1693 llvm::StringRef Tests[] = {
1697 "decltype(au^to) x = 0;",
1699 R
"cpp(// Lambda auto parameter
1700 auto lamb = [](a^uto){};
1702 R"cpp(// non-named decls don't get hover. Don't crash!
1703 ^static_assert(1, "");
1705 R"cpp(// non-evaluatable expr
1706 template <typename T> void foo() {
1707 (void)[[size^of]](T);
1709 R"cpp(// should not crash on invalid semantic form of init-list-expr.
1715 constexpr Foo s = ^{
1721 "auto x = ^(int){42};",
1725 "auto x = ^nullptr;",
1728 for (
const auto &Test : Tests) {
1733 TU.ExtraArgs.push_back(
"-std=c++17");
1734 auto AST = TU.build();
1735 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
1742 const char *
const Code;
1743 const std::function<void(
HoverInfo &)> ExpectedBuilder;
1745 {
"auto x = [['^A']]; // character literal",
1747 HI.Name =
"expression";
1749 HI.Value =
"65 (0x41)";
1751 {
"auto s = ^[[\"Hello, world!\"]]; // string literal",
1753 HI.Name =
"string-literal";
1755 HI.Type =
"const char[14]";
1758 R
"cpp(// Local variable
1762 int test1 = bonjour;
1766 HI.Name = "bonjour";
1767 HI.Kind = index::SymbolKind::Variable;
1768 HI.NamespaceScope =
"";
1769 HI.LocalScope =
"main::";
1771 HI.Definition =
"int bonjour";
1774 R
"cpp(// Local variable in method
1783 HI.Name = "bonjour";
1784 HI.Kind = index::SymbolKind::Variable;
1785 HI.NamespaceScope =
"";
1786 HI.LocalScope =
"s::method::";
1788 HI.Definition =
"int bonjour";
1796 ns1::[[My^Class]]* Params;
1800 HI.Name = "MyClass";
1801 HI.Kind = index::SymbolKind::Struct;
1802 HI.NamespaceScope =
"ns1::";
1803 HI.Definition =
"struct MyClass {}";
1811 ns1::[[My^Class]]* Params;
1815 HI.Name = "MyClass";
1816 HI.Kind = index::SymbolKind::Class;
1817 HI.NamespaceScope =
"ns1::";
1818 HI.Definition =
"class MyClass {}";
1823 union MyUnion { int x; int y; };
1826 ns1::[[My^Union]] Params;
1830 HI.Name = "MyUnion";
1831 HI.Kind = index::SymbolKind::Union;
1832 HI.NamespaceScope =
"ns1::";
1833 HI.Definition =
"union MyUnion {}";
1836 R
"cpp(// Function definition via pointer
1839 auto *X = &^[[foo]];
1844 HI.Kind = index::SymbolKind::Function;
1845 HI.NamespaceScope =
"";
1846 HI.Type =
"void (int)";
1847 HI.Definition =
"void foo(int)";
1848 HI.Documentation =
"Function definition via pointer";
1849 HI.ReturnType =
"void";
1851 {{
"int"}, std::nullopt, std::nullopt},
1855 R
"cpp(// Function declaration via call
1858 return ^[[foo]](42);
1863 HI.Kind = index::SymbolKind::Function;
1864 HI.NamespaceScope =
"";
1865 HI.Type =
"int (int)";
1866 HI.Definition =
"int foo(int)";
1867 HI.Documentation =
"Function declaration via call";
1868 HI.ReturnType =
"int";
1870 {{
"int"}, std::nullopt, std::nullopt},
1875 struct Foo { int x; };
1883 HI.Kind = index::SymbolKind::Field;
1884 HI.NamespaceScope =
"";
1885 HI.LocalScope =
"Foo::";
1887 HI.Definition =
"int x";
1890 R
"cpp(// Field with initialization
1891 struct Foo { int x = 5; };
1899 HI.Kind = index::SymbolKind::Field;
1900 HI.NamespaceScope =
"";
1901 HI.LocalScope =
"Foo::";
1903 HI.Definition =
"int x = 5";
1906 R
"cpp(// Static field
1907 struct Foo { static int x; };
1914 HI.Kind = index::SymbolKind::StaticProperty;
1915 HI.NamespaceScope =
"";
1916 HI.LocalScope =
"Foo::";
1918 HI.Definition =
"static int x";
1921 R
"cpp(// Field, member initializer
1924 Foo() : ^[[x]](0) {}
1929 HI.Kind = index::SymbolKind::Field;
1930 HI.NamespaceScope =
"";
1931 HI.LocalScope =
"Foo::";
1933 HI.Definition =
"int x";
1936 R
"cpp(// Field, GNU old-style field designator
1937 struct Foo { int x; };
1939 Foo bar = { ^[[x]] : 1 };
1944 HI.Kind = index::SymbolKind::Field;
1945 HI.NamespaceScope =
"";
1946 HI.LocalScope =
"Foo::";
1948 HI.Definition =
"int x";
1953 R
"cpp(// Field, field designator
1954 struct Foo { int x; int y; };
1956 Foo bar = { .^[[x]] = 2, .y = 2 };
1961 HI.Kind = index::SymbolKind::Field;
1962 HI.NamespaceScope =
"";
1963 HI.LocalScope =
"Foo::";
1965 HI.Definition =
"int x";
1968 R
"cpp(// Method call
1969 struct Foo { int x(); };
1977 HI.Kind = index::SymbolKind::InstanceMethod;
1978 HI.NamespaceScope =
"";
1979 HI.LocalScope =
"Foo::";
1981 HI.Definition =
"int x()";
1982 HI.ReturnType =
"int";
1983 HI.Parameters = std::vector<HoverInfo::Param>{};
1986 R
"cpp(// Static method call
1987 struct Foo { static int x(); };
1994 HI.Kind = index::SymbolKind::StaticMethod;
1995 HI.NamespaceScope =
"";
1996 HI.LocalScope =
"Foo::";
1998 HI.Definition =
"static int x()";
1999 HI.ReturnType =
"int";
2000 HI.Parameters = std::vector<HoverInfo::Param>{};
2011 HI.Kind = index::SymbolKind::TypeAlias;
2012 HI.NamespaceScope =
"";
2013 HI.Definition =
"typedef int Foo";
2015 HI.Documentation =
"Typedef";
2018 R
"cpp(// Typedef with embedded definition
2019 typedef struct Bar {} Foo;
2026 HI.Kind = index::SymbolKind::TypeAlias;
2027 HI.NamespaceScope =
"";
2028 HI.Definition =
"typedef struct Bar Foo";
2029 HI.Type =
"struct Bar";
2030 HI.Documentation =
"Typedef with embedded definition";
2035 struct Foo { static void bar(); };
2037 int main() { ^[[ns]]::Foo::bar(); }
2041 HI.Kind = index::SymbolKind::Namespace;
2042 HI.NamespaceScope =
"";
2043 HI.Definition =
"namespace ns {}";
2046 R
"cpp(// Anonymous namespace
2050 } // anonymous namespace
2052 int main() { ns::[[f^oo]]++; }
2056 HI.Kind = index::SymbolKind::Variable;
2057 HI.NamespaceScope =
"ns::";
2059 HI.Definition =
"int foo";
2062 R
"cpp(// Function definition via using declaration
2073 HI.Kind = index::SymbolKind::Function;
2074 HI.NamespaceScope =
"ns::";
2075 HI.Type =
"void ()";
2076 HI.Definition =
"void foo()";
2077 HI.Documentation =
"";
2078 HI.ReturnType =
"void";
2079 HI.Parameters = std::vector<HoverInfo::Param>{};
2082 R
"cpp( // using declaration and two possible function declarations
2083 namespace ns { void foo(int); void foo(char); }
2085 template <typename T> void bar() { [[f^oo]](T{}); }
2089 HI.Kind = index::SymbolKind::Using;
2090 HI.NamespaceScope =
"";
2091 HI.Definition =
"using ns::foo";
2096 int main() { return ^[[MACRO]]; }
2102 HI.Kind = index::SymbolKind::Macro;
2103 HI.Definition =
"#define MACRO 0\n\n"
2110 #define MACRO2 ^[[MACRO]]
2114 HI.Kind = index::SymbolKind::Macro;
2115 HI.Definition =
"#define MACRO 0";
2124 int main() ^[[MACRO]]
2128 HI.Kind = index::SymbolKind::Macro;
2130 R
"cpp(#define MACRO \
2141 R"cpp(// Forward class declaration
2148 HI.Kind = index::SymbolKind::Class;
2149 HI.NamespaceScope =
"";
2150 HI.Definition =
"class Foo {}";
2151 HI.Documentation =
"Forward class declaration";
2154 R
"cpp(// Function declaration
2156 void g() { [[f^oo]](); }
2161 HI.Kind = index::SymbolKind::Function;
2162 HI.NamespaceScope =
"";
2163 HI.Type =
"void ()";
2164 HI.Definition =
"void foo()";
2165 HI.Documentation =
"Function declaration";
2166 HI.ReturnType =
"void";
2167 HI.Parameters = std::vector<HoverInfo::Param>{};
2170 R
"cpp(// Enum declaration
2175 [[Hel^lo]] hello = ONE;
2180 HI.Kind = index::SymbolKind::Enum;
2181 HI.NamespaceScope =
"";
2182 HI.Definition =
"enum Hello {}";
2183 HI.Documentation =
"Enum declaration";
2191 Hello hello = [[O^NE]];
2196 HI.Kind = index::SymbolKind::EnumConstant;
2197 HI.NamespaceScope =
"";
2198 HI.LocalScope =
"Hello::";
2199 HI.Type =
"enum Hello";
2200 HI.Definition =
"ONE";
2204 R
"cpp(// C++20's using enum
2210 Hello hello = [[O^NE]];
2215 HI.Kind = index::SymbolKind::EnumConstant;
2216 HI.NamespaceScope =
"";
2217 HI.LocalScope =
"Hello::";
2218 HI.Type =
"enum Hello";
2219 HI.Definition =
"ONE";
2223 R
"cpp(// Enumerator in anonymous enum
2228 int hello = [[O^NE]];
2233 HI.Kind = index::SymbolKind::EnumConstant;
2234 HI.NamespaceScope =
"";
2237 HI.Type =
"enum (unnamed)";
2238 HI.Definition =
"ONE";
2242 R
"cpp(// Global variable
2243 static int hey = 10;
2250 HI.Kind = index::SymbolKind::Variable;
2251 HI.NamespaceScope =
"";
2253 HI.Definition =
"static int hey = 10";
2254 HI.Documentation =
"Global variable";
2256 HI.Value =
"10 (0xa)";
2259 R
"cpp(// Global variable in namespace
2261 static long long hey = -36637162602497;
2269 HI.Kind = index::SymbolKind::Variable;
2270 HI.NamespaceScope =
"ns1::";
2271 HI.Type =
"long long";
2272 HI.Definition =
"static long long hey = -36637162602497";
2273 HI.Value =
"-36637162602497 (0xffffdeadbeefffff)";
2276 R
"cpp(// Field in anonymous struct
2286 HI.Kind = index::SymbolKind::Field;
2287 HI.NamespaceScope =
"";
2288 HI.LocalScope =
"(anonymous struct)::";
2290 HI.Definition =
"int hello";
2293 R
"cpp(// Templated function
2294 template <typename T>
2298 void g() { auto x = [[f^oo]]<int>(); }
2302 HI.Kind = index::SymbolKind::Function;
2303 HI.NamespaceScope =
"";
2305 HI.Definition =
"template <> int foo<int>()";
2306 HI.Documentation =
"Templated function";
2307 HI.ReturnType =
"int";
2308 HI.Parameters = std::vector<HoverInfo::Param>{};
2313 R
"cpp(// Anonymous union
2319 void g() { struct outer o; o.v.[[d^ef]]++; }
2323 HI.Kind = index::SymbolKind::Field;
2324 HI.NamespaceScope =
"";
2325 HI.LocalScope =
"outer::(anonymous union)::";
2327 HI.Definition =
"int def";
2330 R
"cpp(// documentation from index
2331 int nextSymbolIsAForwardDeclFromIndexWithNoLocalDocs;
2333 void g() { [[ind^exSymbol]](); }
2336 HI.Name = "indexSymbol";
2337 HI.Kind = index::SymbolKind::Function;
2338 HI.NamespaceScope =
"";
2339 HI.Type =
"void ()";
2340 HI.Definition =
"void indexSymbol()";
2341 HI.ReturnType =
"void";
2342 HI.Parameters = std::vector<HoverInfo::Param>{};
2343 HI.Documentation =
"comment from index";
2346 R
"cpp(// Simple initialization with auto
2353 HI.Kind = index::SymbolKind::TypeAlias;
2354 HI.Definition =
"int";
2357 R
"cpp(// Simple initialization with const auto
2359 const ^[[auto]] i = 1;
2364 HI.Kind = index::SymbolKind::TypeAlias;
2365 HI.Definition =
"int";
2368 R
"cpp(// Simple initialization with const auto&
2370 const ^[[auto]]& i = 1;
2375 HI.Kind = index::SymbolKind::TypeAlias;
2376 HI.Definition =
"int";
2379 R
"cpp(// Simple initialization with auto&
2387 HI.Kind = index::SymbolKind::TypeAlias;
2388 HI.Definition =
"int";
2391 R
"cpp(// Simple initialization with auto*
2399 HI.Kind = index::SymbolKind::TypeAlias;
2400 HI.Definition =
"int";
2403 R
"cpp(// Simple initialization with auto from pointer
2411 HI.Kind = index::SymbolKind::TypeAlias;
2412 HI.Definition =
"int *";
2415 R
"cpp(// Auto with initializer list.
2419 class initializer_list { const _E *a, *b; };
2422 ^[[auto]] i = {1,2};
2427 HI.Kind = index::SymbolKind::TypeAlias;
2428 HI.Definition =
"std::initializer_list<int>";
2431 R
"cpp(// User defined conversion to auto
2433 operator ^[[auto]]() const { return 10; }
2438 HI.Kind = index::SymbolKind::TypeAlias;
2439 HI.Definition =
"int";
2442 R
"cpp(// Simple initialization with decltype(auto)
2444 ^[[decltype]](auto) i = 1;
2448 HI.Name = "decltype";
2449 HI.Kind = index::SymbolKind::TypeAlias;
2450 HI.Definition =
"int";
2453 R
"cpp(// Simple initialization with const decltype(auto)
2456 ^[[decltype]](auto) i = j;
2460 HI.Name = "decltype";
2461 HI.Kind = index::SymbolKind::TypeAlias;
2462 HI.Definition =
"const int";
2465 R
"cpp(// Simple initialization with const& decltype(auto)
2469 ^[[decltype]](auto) i = j;
2473 HI.Name = "decltype";
2474 HI.Kind = index::SymbolKind::TypeAlias;
2475 HI.Definition =
"const int &";
2478 R
"cpp(// Simple initialization with & decltype(auto)
2482 ^[[decltype]](auto) i = j;
2486 HI.Name = "decltype";
2487 HI.Kind = index::SymbolKind::TypeAlias;
2488 HI.Definition =
"int &";
2491 R
"cpp(// simple trailing return type
2492 ^[[auto]] main() -> int {
2498 HI.Kind = index::SymbolKind::TypeAlias;
2499 HI.Definition =
"int";
2502 R
"cpp(// auto function return with trailing type
2504 ^[[auto]] test() -> decltype(Bar()) {
2510 HI.Kind = index::SymbolKind::TypeAlias;
2511 HI.Definition =
"Bar";
2512 HI.Documentation =
"auto function return with trailing type";
2515 R
"cpp(// trailing return type
2517 auto test() -> ^[[decltype]](Bar()) {
2522 HI.Name = "decltype";
2523 HI.Kind = index::SymbolKind::TypeAlias;
2524 HI.Definition =
"Bar";
2525 HI.Documentation =
"trailing return type";
2528 R
"cpp(// auto in function return
2536 HI.Kind = index::SymbolKind::TypeAlias;
2537 HI.Definition =
"Bar";
2538 HI.Documentation =
"auto in function return";
2541 R
"cpp(// auto& in function return
2550 HI.Kind = index::SymbolKind::TypeAlias;
2551 HI.Definition =
"Bar";
2552 HI.Documentation =
"auto& in function return";
2555 R
"cpp(// auto* in function return
2564 HI.Kind = index::SymbolKind::TypeAlias;
2565 HI.Definition =
"Bar";
2566 HI.Documentation =
"auto* in function return";
2569 R
"cpp(// const auto& in function return
2571 const ^[[auto]]& test() {
2578 HI.Kind = index::SymbolKind::TypeAlias;
2579 HI.Definition =
"Bar";
2580 HI.Documentation =
"const auto& in function return";
2583 R
"cpp(// decltype(auto) in function return
2585 ^[[decltype]](auto) test() {
2590 HI.Name = "decltype";
2591 HI.Kind = index::SymbolKind::TypeAlias;
2592 HI.Definition =
"Bar";
2593 HI.Documentation =
"decltype(auto) in function return";
2596 R
"cpp(// decltype(auto) reference in function return
2597 ^[[decltype]](auto) test() {
2603 HI.Name = "decltype";
2604 HI.Kind = index::SymbolKind::TypeAlias;
2605 HI.Definition =
"int &";
2608 R
"cpp(// decltype lvalue reference
2611 ^[[decltype]](I) J = I;
2615 HI.Name = "decltype";
2616 HI.Kind = index::SymbolKind::TypeAlias;
2617 HI.Definition =
"int";
2620 R
"cpp(// decltype lvalue reference
2624 ^[[decltype]](K) J = I;
2628 HI.Name = "decltype";
2629 HI.Kind = index::SymbolKind::TypeAlias;
2630 HI.Definition =
"int &";
2633 R
"cpp(// decltype lvalue reference parenthesis
2636 ^[[decltype]]((I)) J = I;
2640 HI.Name = "decltype";
2641 HI.Kind = index::SymbolKind::TypeAlias;
2642 HI.Definition =
"int &";
2645 R
"cpp(// decltype rvalue reference
2648 ^[[decltype]](static_cast<int&&>(I)) J = static_cast<int&&>(I);
2652 HI.Name = "decltype";
2653 HI.Kind = index::SymbolKind::TypeAlias;
2654 HI.Definition =
"int &&";
2657 R
"cpp(// decltype rvalue reference function call
2661 ^[[decltype]](bar()) J = bar();
2665 HI.Name = "decltype";
2666 HI.Kind = index::SymbolKind::TypeAlias;
2667 HI.Definition =
"int &&";
2670 R
"cpp(// decltype of function with trailing return type.
2672 auto test() -> decltype(Bar()) {
2676 ^[[decltype]](test()) i = test();
2680 HI.Name = "decltype";
2681 HI.Kind = index::SymbolKind::TypeAlias;
2682 HI.Definition =
"Bar";
2684 "decltype of function with trailing return type.";
2687 R
"cpp(// decltype of var with decltype.
2691 ^[[decltype]](J) K = J;
2695 HI.Name = "decltype";
2696 HI.Kind = index::SymbolKind::TypeAlias;
2697 HI.Definition =
"int";
2700 R
"cpp(// decltype of dependent type
2701 template <typename T>
2703 using Y = ^[[decltype]](T::Z);
2707 HI.Name = "decltype";
2708 HI.Kind = index::SymbolKind::TypeAlias;
2709 HI.Definition =
"<dependent type>";
2712 R
"cpp(// More complicated structured types.
2714 ^[[auto]] (*foo)() = bar;
2718 HI.Kind = index::SymbolKind::TypeAlias;
2719 HI.Definition =
"int";
2722 R
"cpp(// Should not crash when evaluating the initializer.
2724 void test() { Test && [[te^st]] = {}; }
2728 HI.Kind = index::SymbolKind::Variable;
2729 HI.NamespaceScope =
"";
2730 HI.LocalScope =
"test::";
2731 HI.Type =
"Test &&";
2732 HI.Definition =
"Test &&test = {}";
2735 R
"cpp(// Shouldn't crash when evaluating the initializer.
2736 struct Bar {}; // error-ok
2737 struct Foo { void foo(Bar x = y); }
2738 void Foo::foo(Bar [[^x]]) {})cpp",
2741 HI.Kind = index::SymbolKind::Parameter;
2742 HI.NamespaceScope =
"";
2743 HI.LocalScope =
"Foo::foo::";
2745 HI.Definition =
"Bar x = <recovery - expr>()";
2748 R
"cpp(// auto on alias
2749 typedef int int_type;
2750 ^[[auto]] x = int_type();
2754 HI.Kind = index::SymbolKind::TypeAlias;
2755 HI.Definition =
"int_type // aka: int";
2758 R
"cpp(// auto on alias
2760 typedef cls cls_type;
2761 ^[[auto]] y = cls_type();
2765 HI.Kind = index::SymbolKind::TypeAlias;
2766 HI.Definition =
"cls_type // aka: cls";
2767 HI.Documentation =
"auto on alias";
2770 R
"cpp(// auto on alias
2773 ^[[auto]] z = templ<int>();
2777 HI.Kind = index::SymbolKind::TypeAlias;
2778 HI.Definition =
"templ<int>";
2779 HI.Documentation =
"auto on alias";
2782 R
"cpp(// Undeduced auto declaration
2783 template<typename T>
2790 HI.Kind = index::SymbolKind::TypeAlias;
2791 HI.Definition =
"T";
2794 R
"cpp(// Undeduced auto return type
2795 template<typename T>
2802 HI.Kind = index::SymbolKind::TypeAlias;
2803 HI.Definition =
"/* not deduced */";
2806 R
"cpp(// Template auto parameter
2807 template<[[a^uto]] T>
2815 HI.Kind = index::SymbolKind::TypeAlias;
2816 HI.Definition =
"/* not deduced */";
2819 R
"cpp(// Undeduced decltype(auto) return type
2820 template<typename T>
2821 ^[[decltype]](auto) foo() {
2826 HI.Name = "decltype";
2827 HI.Kind = index::SymbolKind::TypeAlias;
2828 HI.Definition =
"/* not deduced */";
2831 R
"cpp(// should not crash.
2832 template <class T> struct cls {
2836 auto test = cls<int>().[[m^ethod]]();
2839 HI.Definition = "int method()";
2840 HI.Kind = index::SymbolKind::InstanceMethod;
2841 HI.NamespaceScope =
"";
2842 HI.LocalScope =
"cls<int>::";
2844 HI.Parameters.emplace();
2845 HI.ReturnType =
"int";
2849 R
"cpp(// type of nested templates.
2850 template <class T> struct cls {};
2851 cls<cls<cls<int>>> [[fo^o]];
2854 HI.Definition = "cls<cls<cls<int>>> foo";
2855 HI.Kind = index::SymbolKind::Variable;
2856 HI.NamespaceScope =
"";
2858 HI.Type =
"cls<cls<cls<int>>>";
2861 R
"cpp(// type of nested templates.
2862 template <class T> struct cls {};
2863 [[cl^s]]<cls<cls<int>>> foo;
2866 HI.Definition = "template <> struct cls<cls<cls<int>>> {}";
2867 HI.Kind = index::SymbolKind::Struct;
2868 HI.NamespaceScope =
"";
2869 HI.Name =
"cls<cls<cls<int>>>";
2870 HI.Documentation =
"type of nested templates.";
2873 R
"cpp(// type with decltype
2875 decltype(a) [[b^]] = a;)cpp",
2877 HI.Definition = "decltype(a) b = a";
2878 HI.Kind = index::SymbolKind::Variable;
2879 HI.NamespaceScope =
"";
2884 R
"cpp(// type with decltype
2887 decltype(c) [[b^]] = a;)cpp",
2889 HI.Definition = "decltype(c) b = a";
2890 HI.Kind = index::SymbolKind::Variable;
2891 HI.NamespaceScope =
"";
2896 R
"cpp(// type with decltype
2898 const decltype(a) [[b^]] = a;)cpp",
2900 HI.Definition = "const decltype(a) b = a";
2901 HI.Kind = index::SymbolKind::Variable;
2902 HI.NamespaceScope =
"";
2907 R
"cpp(// type with decltype
2909 auto [[f^oo]](decltype(a) x) -> decltype(a) { return 0; })cpp",
2911 HI.Definition = "auto foo(decltype(a) x) -> decltype(a)";
2912 HI.Kind = index::SymbolKind::Function;
2913 HI.NamespaceScope =
"";
2917 HI.Type = {
"auto (decltype(a)) -> decltype(a)",
2918 "auto (int) -> int"};
2919 HI.ReturnType =
"int";
2920 HI.Parameters = {{{
"int"}, std::string(
"x"), std::nullopt}};
2923 R
"cpp(// sizeof expr
2925 (void)[[size^of]](char);
2928 HI.Name = "expression";
2929 HI.Type = {
"__size_t",
"unsigned long"};
2933 R
"cpp(// alignof expr
2935 (void)[[align^of]](char);
2938 HI.Name = "expression";
2939 HI.Type = {
"__size_t",
"unsigned long"};
2944 template <typename T = int>
2945 void foo(const T& = T()) {
2950 HI.Kind = index::SymbolKind::Function;
2951 HI.Type =
"void (const int &)";
2952 HI.ReturnType =
"void";
2954 {{
"const int &"}, std::nullopt, std::string(
"T()")}};
2955 HI.Definition =
"template <> void foo<int>(const int &)";
2956 HI.NamespaceScope =
"";
2959 R
"cpp(// should not crash
2967 HI.Kind = index::SymbolKind::Field;
2968 HI.LocalScope =
"ObjC::";
2969 HI.NamespaceScope =
"";
2970 HI.Definition =
"char data";
2976 @interface Interface
2977 @property(retain) [[MYOb^ject]] *x;
2981 HI.Name = "MYObject";
2982 HI.Kind = index::SymbolKind::Class;
2983 HI.NamespaceScope =
"";
2984 HI.Definition =
"@interface MYObject\n@end";
2990 @interface Interface
2991 - (void)doWith:([[MYOb^ject]] *)object;
2995 HI.Name = "MYObject";
2996 HI.Kind = index::SymbolKind::Class;
2997 HI.NamespaceScope =
"";
2998 HI.Definition =
"@interface MYObject\n@end";
3013 HI.Definition =
"ns::Foo *";
3016 R
"cpp(// this expr for template class
3018 template <typename T>
3028 HI.Definition =
"const ns::Foo<T> *";
3031 R
"cpp(// this expr for specialization class
3033 template <typename T> class Foo {};
3044 HI.Definition =
"ns::Foo<int> *";
3047 R
"cpp(// this expr for partial specialization struct
3049 template <typename T, typename F> struct Foo {};
3050 template <typename F>
3051 struct Foo<int, F> {
3060 HI.Definition =
"const ns::Foo<int, F> *";
3066 @interface MYObject (Private)
3067 @property(nonatomic, assign) int privateField;
3070 int someFunction() {
3071 MYObject *obj = [MYObject sharedInstance];
3072 return obj.[[private^Field]];
3076 HI.Name = "privateField";
3077 HI.Kind = index::SymbolKind::InstanceProperty;
3078 HI.LocalScope =
"MYObject(Private)::";
3079 HI.NamespaceScope =
"";
3080 HI.Definition =
"@property(nonatomic, assign, unsafe_unretained, "
3081 "readwrite) int privateField;";
3085 @protocol MYProtocol
3086 @property(nonatomic, assign) int prop1;
3089 int someFunction() {
3090 id<MYProtocol> obj = 0;
3091 return obj.[[pro^p1]];
3096 HI.Kind = index::SymbolKind::InstanceProperty;
3097 HI.LocalScope =
"MYProtocol::";
3098 HI.NamespaceScope =
"";
3099 HI.Definition =
"@property(nonatomic, assign, unsafe_unretained, "
3100 "readwrite) int prop1;";
3104 @protocol MYProtocol
3109 @interface MYObject (Ext) <[[MYProt^ocol]]>
3113 HI.Name = "MYProtocol";
3114 HI.Kind = index::SymbolKind::Protocol;
3115 HI.NamespaceScope =
"";
3116 HI.Definition =
"@protocol MYProtocol\n@end";
3122 @implementation Foo(Private)
3123 + (int)somePrivateMethod {
3124 int [[res^ult]] = 2;
3131 HI.Definition =
"int result = 2";
3132 HI.Kind = index::SymbolKind::Variable;
3134 HI.LocalScope =
"+[Foo(Private) somePrivateMethod]::";
3135 HI.NamespaceScope =
"";
3143 - (int)variadicArgMethod:(id)first, ... {
3144 int [[res^ult]] = 0;
3151 HI.Definition =
"int result = 0";
3152 HI.Kind = index::SymbolKind::Variable;
3154 HI.LocalScope =
"-[Foo variadicArgMethod:, ...]::";
3155 HI.NamespaceScope =
"";
3160 typedef struct MyRect {} MyRect;
3163 @property(nonatomic) MyRect frame;
3172 v.frame = [[foo^bar]]();
3177 HI.Kind = index::SymbolKind::Function;
3178 HI.NamespaceScope =
"";
3179 HI.Definition =
"MyRect foobar()";
3180 HI.Type = {
"MyRect ()",
"struct MyRect ()"};
3181 HI.ReturnType = {
"MyRect",
"struct MyRect"};
3182 HI.Parameters.emplace();
3185 void foo(int * __attribute__(([[non^null]], noescape)) );
3188 HI.Name = "nonnull";
3189 HI.Kind = index::SymbolKind::Unknown;
3190 HI.Definition =
"__attribute__((nonnull))";
3191 HI.Documentation = Attr::getDocumentation(attr::NonNull).str();
3196 struct strong_ordering {
3198 constexpr operator int() const { return n; }
3199 static const strong_ordering equal, greater, less;
3201 constexpr strong_ordering strong_ordering::equal = {0};
3202 constexpr strong_ordering strong_ordering::greater = {1};
3203 constexpr strong_ordering strong_ordering::less = {-1};
3210 auto operator<=>(const Foo&) const = default;
3213 bool x = Foo(1) [[!^=]] Foo(2);
3216 HI.Type = "bool (const Foo &) const noexcept";
3218 HI.Name =
"operator==";
3219 HI.Parameters = {{{
"const Foo &"}, std::nullopt, std::nullopt}};
3220 HI.ReturnType =
"bool";
3221 HI.Kind = index::SymbolKind::InstanceMethod;
3222 HI.LocalScope =
"Foo::";
3223 HI.NamespaceScope =
"";
3225 "bool operator==(const Foo &) const noexcept = default";
3226 HI.Documentation =
"";
3232 IndexSym.Documentation =
"comment from index";
3238 for (
const auto &Case : Cases) {
3239 SCOPED_TRACE(Case.Code);
3243 TU.ExtraArgs.push_back(
"-std=c++20");
3244 TU.ExtraArgs.push_back(
"-xobjective-c++");
3246 TU.ExtraArgs.push_back(
"-Wno-gnu-designator");
3249 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
3250 auto AST = TU.build();
3254 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(), Index.get());
3258 Case.ExpectedBuilder(Expected);
3261 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
3262 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
3263 EXPECT_EQ(H->Name, Expected.Name);
3264 EXPECT_EQ(H->Kind, Expected.Kind);
3265 EXPECT_EQ(H->Documentation, Expected.Documentation);
3266 EXPECT_EQ(H->Definition, Expected.Definition);
3267 EXPECT_EQ(H->Type, Expected.Type);
3268 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
3269 EXPECT_EQ(H->Parameters, Expected.Parameters);
3270 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
3271 EXPECT_EQ(H->SymRange, Expected.SymRange);
3272 EXPECT_EQ(H->Value, Expected.Value);
3279 const std::function<void(
HoverInfo &)> ExpectedBuilder;
3280 } Cases[] = {{R
"cpp(
3284 [](HoverInfo &HI) { HI.Provider = ""; }},
3289 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3294 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3299 [](HoverInfo &HI) { HI.Provider = ""; }},
3304 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3309 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3316 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3325 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3328 using namespace fo^o;
3330 [](HoverInfo &HI) { HI.Provider = ""; }},
3333 for (
const auto &Case : Cases) {
3335 SCOPED_TRACE(Code.code());
3339 TU.Code = Code.code();
3340 TU.AdditionalFiles[
"foo.h"] = guard(R
"cpp(
3343 Foo& operator+(const Foo, const Foo);
3345 TU.AdditionalFiles["all.h"] = guard(
"#include \"foo.h\"");
3347 auto AST = TU.build();
3348 auto H =
getHover(
AST, Code.point(), format::getLLVMStyle(),
nullptr);
3351 Case.ExpectedBuilder(Expected);
3353 EXPECT_EQ(H->Provider, Expected.Provider);
3360 HIFoo.Provider =
"\"foo.h\"";
3363 HIFooBar.
Name =
"foo";
3364 HIFooBar.Provider =
"<bar.h>";
3367 llvm::StringRef ExpectedMarkdown;
3368 } Cases[] = {{HIFoo,
"### `foo`\n\nprovided by `\"foo.h\"`"},
3369 {HIFooBar,
"### `foo`\n\nprovided by `<bar.h>`"}};
3371 for (
const auto &Case : Cases)
3378 const std::function<void(
HoverInfo &)> ExpectedBuilder;
3379 } Cases[] = {{R
"cpp(
3381 int fstBar = bar1();
3382 int another= bar1(0);
3383 int sndBar = bar2();
3388 HI.UsedSymbolNames = {"BAR",
"Bar",
"bar1",
"bar2"};
3392 std::vector<int> vec;
3394 [](HoverInfo &HI) { HI.UsedSymbolNames = {"vector"}; }}};
3395 for (
const auto &Case : Cases) {
3397 SCOPED_TRACE(Code.code());
3401 TU.Code = Code.code();
3402 TU.AdditionalFiles[
"bar.h"] = guard(R
"cpp(
3409 TU.AdditionalFiles["system/vector"] = guard(R
"cpp(
3415 TU.ExtraArgs.push_back("-isystem" +
testPath(
"system"));
3417 auto AST = TU.build();
3418 auto H =
getHover(
AST, Code.point(), format::getLLVMStyle(),
nullptr);
3421 Case.ExpectedBuilder(Expected);
3423 EXPECT_EQ(H->UsedSymbolNames, Expected.UsedSymbolNames);
3429 template <typename T> class X {};
3437 auto AST = TU.build();
3440 IndexSym.Documentation =
"comment from index";
3446 for (
const auto &P :
T.points()) {
3447 auto H =
getHover(
AST, P, format::getLLVMStyle(), Index.get());
3449 EXPECT_EQ(H->Documentation, IndexSym.Documentation);
3456 template <typename T> class X {};
3458 template <typename T> void bar() {}
3460 template <typename T> T baz;
3465 au^to T = ba^z<X<int>>;
3470 auto AST = TU.build();
3471 for (
const auto &P :
T.points()) {
3472 auto H =
getHover(
AST, P, format::getLLVMStyle(),
nullptr);
3474 EXPECT_EQ(H->Documentation,
"doc");
3481 template<typename T> T foo(T);
3483 // Setter variable heuristic might fail if the callexpr is broken.
3484 struct X { int Y; void [[^setY]](float) { Y = foo(undefined); } };)cpp");
3487 auto AST = TU.build();
3488 for (
const auto &P :
T.points())
3489 getHover(
AST, P, format::getLLVMStyle(),
nullptr);
3494 constexpr unsigned long value = -1; // wrap around
3495 void foo() { va^lue; }
3498 getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
3503 constexpr __int128_t value = -4;
3504 void foo() { va^lue; }
3508 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
3509 auto AST = TU.build();
3510 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
3512 EXPECT_EQ(H->Value,
"-4 (0xfffffffc)");
3518 template <typename T> class $doc1^X {};
3520 template <> class $doc2^X<int> {};
3522 template <typename T> class $doc3^X<T*> {};
3530 auto AST = TU.build();
3531 for (
const auto *Comment : {
"doc1",
"doc2",
"doc3"}) {
3532 for (
const auto &P :
T.points(Comment)) {
3533 auto H =
getHover(
AST, P, format::getLLVMStyle(),
nullptr);
3535 EXPECT_EQ(H->Documentation, Comment);
3542 const std::function<void(
HoverInfo &)> Builder;
3543 llvm::StringRef ExpectedMarkdownRender;
3544 llvm::StringRef ExpectedDoxygenRender;
3548 HI.Kind = index::SymbolKind::Unknown;
3556 HI.Kind = index::SymbolKind::NamespaceAlias;
3559 R
"(namespace-alias foo)",
3560 R"(### namespace-alias `foo`)",
3564 HI.Kind = index::SymbolKind::Class;
3566 HI.TemplateParameters = {
3567 {{"typename"}, std::string(
"T"), std::nullopt},
3568 {{
"typename"}, std::string(
"C"), std::string(
"bool")},
3570 HI.Documentation =
"documentation";
3572 "template <typename T, typename C = bool> class Foo {}";
3574 HI.NamespaceScope.emplace();
3582template <typename T, typename C = bool> class Foo {})",
3587template <typename T, typename C = bool> class Foo {}
3596### Template Parameters
3599- `typename C = bool`
3606 HI.Kind = index::SymbolKind::Function;
3608 HI.Type = {
"type",
"c_type"};
3609 HI.ReturnType = {
"ret_type",
"can_ret_type"};
3610 HI.Parameters.emplace();
3612 HI.Parameters->push_back(P);
3613 P.Type = {
"type",
"can_type"};
3614 HI.Parameters->push_back(P);
3616 HI.Parameters->push_back(P);
3617 P.Default =
"default";
3618 HI.Parameters->push_back(P);
3619 HI.NamespaceScope =
"ns::";
3620 HI.Definition =
"ret_type foo(params) {}";
3624 "→ ret_type (aka can_ret_type)\n\n"
3627 "- type (aka can_type)\n"
3628 "- type foo (aka can_type)\n"
3629 "- type foo = default (aka can_type)\n"
3631 "// In namespace ns\n"
3632 "ret_type foo(params) {}",
3638ret_type foo(params) {}
3645- `type (aka can_type)`
3646- `type foo (aka can_type)`
3647- `type foo = default (aka can_type)`
3652`ret_type (aka can_ret_type)`)",
3656 HI.Kind = index::SymbolKind::Field;
3657 HI.LocalScope = "test::Bar::";
3660 HI.Type = {
"type",
"can_type"};
3661 HI.Definition =
"def";
3669Type: type (aka can_type)
3675Size: 4 bytes (+4 bytes padding), alignment 4 bytes
3688Type: `type (aka can_type)`
3694Size: 4 bytes (+4 bytes padding), alignment 4 bytes)",
3698 HI.Kind = index::SymbolKind::Field;
3699 HI.LocalScope = "test::Bar::";
3702 HI.Type = {
"type",
"can_type"};
3703 HI.Definition =
"def";
3711Type: type (aka can_type)
3715Offset: 4 bytes and 3 bits
3717Size: 25 bits (+4 bits padding), alignment 8 bytes
3730Type: `type (aka can_type)`
3734Offset: 4 bytes and 3 bits
3736Size: 25 bits (+4 bits padding), alignment 8 bytes)",
3740 HI.Kind = index::SymbolKind::Field;
3741 HI.AccessSpecifier = "public";
3743 HI.LocalScope =
"test::Bar::";
3744 HI.Definition =
"def";
3760 HI.Definition = "size_t method()";
3761 HI.AccessSpecifier =
"protected";
3762 HI.Kind = index::SymbolKind::InstanceMethod;
3763 HI.NamespaceScope =
"";
3764 HI.LocalScope =
"cls<int>::";
3766 HI.Parameters.emplace();
3767 HI.ReturnType = {
"size_t",
"unsigned long"};
3768 HI.Type = {
"size_t ()",
"unsigned long ()"};
3770 R
"(instance-method method
3772→ size_t (aka unsigned long)
3775protected: size_t method())",
3776 R"(### instance-method
3781protected: size_t method()
3787`size_t (aka unsigned long)`)",
3791 HI.Definition = "cls(int a, int b = 5)";
3792 HI.AccessSpecifier =
"public";
3793 HI.Kind = index::SymbolKind::Constructor;
3794 HI.NamespaceScope =
"";
3795 HI.LocalScope =
"cls";
3797 HI.Parameters.emplace();
3798 HI.Parameters->emplace_back();
3799 HI.Parameters->back().Type =
"int";
3800 HI.Parameters->back().Name =
"a";
3801 HI.Parameters->emplace_back();
3802 HI.Parameters->back().Type =
"int";
3803 HI.Parameters->back().Name =
"b";
3804 HI.Parameters->back().Default =
"5";
3814public: cls(int a, int b = 5))",
3820public: cls(int a, int b = 5)
3831 HI.Kind = index::SymbolKind::Union;
3832 HI.AccessSpecifier = "private";
3834 HI.NamespaceScope =
"ns1::";
3835 HI.Definition =
"union foo {}";
3840private: union foo {})",
3846private: union foo {}
3851 HI.Kind = index::SymbolKind::Variable;
3853 HI.Definition =
"int foo = 3";
3854 HI.LocalScope =
"test::Bar::";
3857 HI.CalleeArgInfo.emplace();
3858 HI.CalleeArgInfo->Name =
"arg_a";
3859 HI.CalleeArgInfo->Type =
"int";
3860 HI.CalleeArgInfo->Default =
"7";
3890 HI.Kind = index::SymbolKind::Variable;
3892 HI.CalleeArgInfo.emplace();
3893 HI.CalleeArgInfo->Type =
"int";
3899 R"(### variable `foo`
3906 HI.Kind = index::SymbolKind::Variable;
3908 HI.Definition =
"int foo = 3";
3909 HI.LocalScope =
"test::Bar::";
3912 HI.CalleeArgInfo.emplace();
3913 HI.CalleeArgInfo->Name =
"arg_a";
3914 HI.CalleeArgInfo->Type =
"int";
3915 HI.CalleeArgInfo->Default =
"7";
3924Passed by reference as arg_a
3941Passed by reference as arg_a)",
3945 HI.Kind = index::SymbolKind::Variable;
3947 HI.Definition =
"int foo = 3";
3948 HI.LocalScope =
"test::Bar::";
3951 HI.CalleeArgInfo.emplace();
3952 HI.CalleeArgInfo->Name =
"arg_a";
3953 HI.CalleeArgInfo->Type = {
"alias_int",
"int"};
3954 HI.CalleeArgInfo->Default =
"7";
3963Passed as arg_a (converted to alias_int)
3980Passed as arg_a (converted to alias_int))",
3984 HI.Kind = index::SymbolKind::Macro;
3985 HI.Name = "PLUS_ONE";
3986 HI.Definition =
"#define PLUS_ONE(X) (X+1)\n\n"
3992#define PLUS_ONE(X) (X+1)
4000#define PLUS_ONE(X) (X+1)
4008 HI.Kind = index::SymbolKind::Variable;
4010 HI.Definition =
"int foo = 3";
4011 HI.LocalScope =
"test::Bar::";
4014 HI.CalleeArgInfo.emplace();
4015 HI.CalleeArgInfo->Name =
"arg_a";
4016 HI.CalleeArgInfo->Type =
"int";
4017 HI.CalleeArgInfo->Default =
"7";
4026Passed by const reference as arg_a (converted to int)
4043Passed by const reference as arg_a (converted to int))",
4047 HI.Name = "stdio.h";
4048 HI.Definition =
"/usr/include/stdio.h";
4049 HI.Kind = index::SymbolKind::IncludeDirective;
4053/usr/include/stdio.h)",
4056`/usr/include/stdio.h`)",
4061 HI.UsedSymbolNames = {
"Foo",
"Bar",
"Bar"};
4062 HI.Kind = index::SymbolKind::IncludeDirective;
4066provides Foo, Bar, Bar)",
4070provides `Foo`, `Bar`, `Bar`)",
4074 HI.UsedSymbolNames = {
"Foo",
"Bar",
"Baz",
"Foobar",
"Qux",
"Quux"};
4075 HI.Kind = index::SymbolKind::IncludeDirective;
4079provides Foo, Bar, Baz, Foobar, Qux and 1 more)",
4083provides `Foo`, `Bar`, `Baz`, `Foobar`, `Qux` and 1 more)"}};
4085 for (
const auto &C : Cases) {
4094 for (
const auto &C : Cases) {
4107 const std::function<void(
HoverInfo &)> Builder;
4108 llvm::StringRef ExpectedMarkdownRender;
4109 llvm::StringRef ExpectedDoxygenRender;
4112 HI.Kind = index::SymbolKind::Function;
4113 HI.Documentation =
"@brief brief doc\n\n"
4115 HI.Definition =
"void foo()";
4118 R
"(### function `foo`
4146 HI.Kind = index::SymbolKind::Function;
4147 HI.Documentation = "@brief brief doc\n\n"
4149 HI.Definition =
"int foo()";
4150 HI.ReturnType =
"int";
4153 R
"(### function `foo`
4188 HI.Kind = index::SymbolKind::Function;
4189 HI.Documentation = R"(@brief brief doc
4194As you see, notes are "inlined".
4195@warning this is a warning
4198@param a this is a param
4199@return it returns something
4200@retval 0 if successful
4201@retval 1 if failed)";
4202 HI.Definition = "int foo(int a)";
4203 HI.ReturnType =
"int";
4205 HI.Parameters.emplace();
4206 HI.Parameters->emplace_back();
4207 HI.Parameters->back().Type =
"int";
4208 HI.Parameters->back().Name =
"a";
4210 R
"(### function `foo`
4224As you see, notes are "inlined".
4225@warning this is a warning
4228@param a this is a param
4229@return it returns something
4230@retval 0 if successful
4252- `int a` - this is a param
4257`int` - it returns something
4259- `0` - if successful
4270As you see, notes are "inlined".
4275As well as warnings)"},
4277 HI.Kind = index::SymbolKind::Function;
4278 HI.Documentation = "@brief brief doc\n\n"
4279 "longer doc\n@param a this is a param\n@param b "
4280 "does not exist\n@return it returns something";
4281 HI.Definition =
"int foo(int a)";
4282 HI.ReturnType =
"int";
4284 HI.Parameters.emplace();
4285 HI.Parameters->emplace_back();
4286 HI.Parameters->back().Type =
"int";
4287 HI.Parameters->back().Name =
"a";
4289 R
"(### function `foo`
4301@param a this is a param
4302@param b does not exist
4303@return it returns something
4324- `int a` - this is a param
4329`int` - it returns something
4337 for (
const auto &C : Cases) {
4346 for (
const auto &C : Cases) {
4359 llvm::StringRef Documentation;
4360 llvm::StringRef ExpectedRenderEscapedMarkdown;
4361 llvm::StringRef ExpectedRenderMarkdown;
4362 llvm::StringRef ExpectedRenderPlainText;
4472 "Tests primality of `p`.",
4473 "Tests primality of `p`.",
4474 "Tests primality of `p`.",
4475 "Tests primality of `p`.",
4478 "'`' should not occur in `Code`",
4479 "'\\`' should not occur in `Code`",
4480 "'`' should not occur in `Code`",
4481 "'`' should not occur in `Code`",
4485 "\\`not\nparsed\\`",
4490 R
"(@brief this is a typical use case
4494 R"(@brief this is a typical use case
4498 R"(@brief this is a typical use case
4502 R"(@brief this is a typical use case
4508 for (
const auto &C : Cases) {
4509 markup::Document Output;
4512 EXPECT_EQ(Output.asEscapedMarkdown(),
C.ExpectedRenderEscapedMarkdown);
4513 EXPECT_EQ(Output.asMarkdown(),
C.ExpectedRenderMarkdown);
4514 EXPECT_EQ(Output.asPlainText(),
C.ExpectedRenderPlainText);
4522 HI.
Kind = index::SymbolKind::Variable;
4532 HI.
Kind = index::SymbolKind::Variable;
4535 HI.Definition =
"def";
4537 llvm::StringRef ExpectedMarkdown =
4538 "### variable `foo`\n"
4549 llvm::StringRef ExpectedDoxygenMarkdown =
4564 llvm::StringRef ExpectedPlaintext = R
"pt(variable foo
4575 struct strong_ordering {
4577 constexpr operator int() const { return n; }
4578 static const strong_ordering equal, greater, less;
4580 constexpr strong_ordering strong_ordering::equal = {0};
4581 constexpr strong_ordering strong_ordering::greater = {1};
4582 constexpr strong_ordering strong_ordering::less = {-1};
4585 template <typename T>
4588 friend auto operator<=>(S, S) = default;
4590 static_assert(S<void>() =^= S<void>());
4594 TU.ExtraArgs.push_back("-std=c++20");
4595 auto AST = TU.build();
4596 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4597 EXPECT_EQ(HI->Documentation,
"");
4604 auto baz = (Fo^o*)&bar;
4608 auto AST = TU.build();
4609 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4611 EXPECT_EQ(*HI->Value,
"&bar");
4614TEST(
Hover, FunctionParameterDefaulValueNotEvaluatedOnInvalidDecls) {
4616 const char *
const Code;
4617 const std::optional<std::string> HoverValue;
4620 // error-ok testing behavior on invalid decl
4622 void foo(Foo p^aram = nullptr);
4627 void foo(Foo *p^aram = nullptr);
4632 for (
const auto &C : Cases) {
4635 auto AST = TU.build();
4636 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4638 ASSERT_EQ(HI->Value,
C.HoverValue);
4653 TU.ExtraArgs.push_back(
"-std=c++17");
4654 auto AST = TU.build();
4655 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4663 #define A(x) x, x, x, x
4664 #define B(x) A(A(A(A(x))))
4665 int a^rr[] = {B(0)};
4669 auto AST = TU.build();
4670 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4673 EXPECT_EQ(H->Definition,
"int arr[]");
4676#if defined(__aarch64__)
4678#define PREDEFINEMACROS_TEST(x) DISABLED_##x
4680#define PREDEFINEMACROS_TEST(x) x
4685 using uintptr_t = __UINTPTR_TYPE__;
4686 enum Test : uintptr_t {};
4687 unsigned global_var;
4689 Test v^al = static_cast<Test>(reinterpret_cast<uintptr_t>(&global_var));
4694 TU.PredefineMacros = true;
4695 auto AST = TU.build();
4696 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4698 EXPECT_EQ(*HI->Value,
"&global_var");
4703 using uintptr_t = __UINTPTR_TYPE__;
4704 unsigned global_var;
4706 uintptr_t a^ddress = reinterpret_cast<uintptr_t>(&global_var);
4711 TU.PredefineMacros = true;
4712 auto AST = TU.build();
4713 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4715 EXPECT_EQ(*HI->Value,
"&global_var");
4720 template <bool X, typename T, typename F>
4721 struct cond { using type = T; };
4722 template <typename T, typename F>
4723 struct cond<false, T, F> { using type = F; };
4725 template <bool X, typename T, typename F>
4726 using type = typename cond<X, T, F>::type;
4729 using f^oo = type<true, int, double>;
4734 auto AST = TU.build();
4735 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4737 ASSERT_TRUE(H && H->Type);
4738 EXPECT_EQ(H->Type->Type,
"int");
4739 EXPECT_EQ(H->Definition,
"using foo = type<true, int, double>");
4743 llvm::StringRef PredefinedCXX = R
"cpp(
4745#define SizeOf sizeof
4746#define AlignOf alignof
4750using u64 = unsigned long long;
4751// calculate (a ** b) % p
4752constexpr u64 pow_with_mod(u64 a, u64 b, u64 p) {
4756 ret = (ret * a) % p;
4762#define last_n_digit(x, y, n) \
4763 pow_with_mod(x, y, pow_with_mod(10, n, 2147483647))
4764#define declare_struct(X, name, value) \
4766 constexpr auto name() { return value; } \
4768#define gnu_statement_expression(value) \
4770 declare_struct(Widget, getter, value); \
4771 Widget().getter(); \
4773#define define_lambda_begin(lambda, ...) \
4775#define define_lambda_end() }
4777#define left_bracket [
4778#define right_bracket ]
4779#define dg_left_bracket <:
4780#define dg_right_bracket :>
4781#define array_decl(type, name, size) type name left_bracket size right_bracket
4785 llvm::StringRef Code;
4786 const std::function<void(std::optional<HoverInfo>,
size_t )>
4794 [](std::optional<HoverInfo> HI, size_t) {
4795 EXPECT_EQ(HI->Value,
"42 (0x2a)");
4804 [](std::optional<HoverInfo> HI, size_t) {
4805 EXPECT_TRUE(HI->Value);
4806 EXPECT_TRUE(HI->Type);
4821 [](std::optional<HoverInfo> HI, size_t) {
4822 EXPECT_TRUE(HI->Value);
4823 EXPECT_TRUE(HI->Type);
4828 // 2**32 == 4294967296
4829 last_n_di^git(2, 32, 6);
4832 [](std::optional<HoverInfo> HI, size_t) {
4833 EXPECT_EQ(HI->Value,
"967296 (0xec280)");
4834 EXPECT_EQ(HI->Type,
"u64");
4839 gnu_statement_exp^ression(42);
4842 [](std::optional<HoverInfo> HI, size_t) {
4843 EXPECT_EQ(HI->Value,
"42 (0x2a)");
4844 EXPECT_EQ(HI->Type,
"int");
4852 [](std::optional<HoverInfo> HI, size_t) {
4853 EXPECT_EQ(HI->Value,
"2");
4854 EXPECT_EQ(HI->Type,
"int");
4862 [](std::optional<HoverInfo> HI, size_t) {
4863 EXPECT_FALSE(HI->Value) << HI->Value;
4864 EXPECT_FALSE(HI->Type) << HI->Type;
4872 [](std::optional<HoverInfo> HI, size_t) {
4873 EXPECT_EQ(HI->Value,
"2");
4874 EXPECT_EQ(HI->Type,
"int");
4879 arra^y_decl(int, vector, 10);
4880 vector left_b^racket 3 right_b^racket;
4881 vector dg_le^ft_bracket 3 dg_righ^t_bracket;
4884 [](std::optional<HoverInfo> HI,
size_t Id) {
4893 EXPECT_FALSE(HI->Type) << HI->Type;
4894 EXPECT_FALSE(HI->Value) << HI->Value;
4897 ASSERT_TRUE(
false) <<
"Unhandled id: " << Id;
4903 constexpr auto value = define_lamb^da_begin(lambda, int, char)
4904 // Check if the expansion range is right.
4905 return ^last_n_digit(10, 3, 3)^;
4906 define_lam^bda_end();
4909 [](std::optional<HoverInfo> HI,
size_t Id) {
4912 EXPECT_FALSE(HI->Value);
4916 EXPECT_EQ(HI->Value,
"0");
4923 EXPECT_FALSE(HI->Type) << HI->Type;
4924 EXPECT_FALSE(HI->Value) << HI->Value;
4927 ASSERT_TRUE(
false) <<
"Unhandled id: " << Id;
4936 for (
const auto &C : Cases) {
4938 (PredefinedCXX +
"void function() {\n" +
C.Code +
"}\n").str());
4940 TU.ExtraArgs.push_back(
"-std=c++17");
4941 auto AST = TU.build();
4942 for (
auto [Index,
Position] : llvm::enumerate(Code.points())) {
4949 #define alignof _Alignof
4951 al^ignof(struct { int x; char y[10]; });
4956 TU.Filename =
"TestTU.c";
4960 auto AST = TU.build();
4961 auto H =
getHover(
AST,
C.point(), format::getLLVMStyle(),
nullptr);
4964 EXPECT_TRUE(H->Value);
4965 EXPECT_TRUE(H->Type);
4969 const char *
const Code =
4971 #define C(A) A##A // Concatenate
4972 #define E(A) C(A) // Expand
4973 #define Z0032 00000000000000000000000000000000
4974 #define Z0064 E(Z0032)
4975 #define Z0128 E(Z0064)
4976 #define Z0256 E(Z0128)
4977 #define Z0512 E(Z0256)
4978 #define Z1024 E(Z0512)
4979 #define Z2048 E(Z1024)
4980 #define Z4096 E(Z2048) // 4096 zeroes
4981 int main() { return [[^Z4096]]; }
4985 uint32_t MacroContentsLimit;
4986 const std::string ExpectedDefinition;
4989 {2048,
"#define Z4096 E(Z2048)"},
4991 {8192, std::string(
"#define Z4096 E(Z2048)\n\n") +
4992 std::string(
"// Expands to\n") + std::string(4096,
'0')},
4994 for (
const auto &Case : Cases) {
4999 auto AST = TU.build();
5003 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
5006 EXPECT_EQ(H->Definition, Case.ExpectedDefinition);
5012 const char *
const Code;
5013 const std::function<void(
HoverInfo &)> ExpectedBuilder;
5014 std::string ExpectedRender;
5016 {R
"cpp(/// Function doc
5017 void foo(int [[^a]]);
5021 HI.Kind = index::SymbolKind::Parameter;
5022 HI.NamespaceScope =
"";
5023 HI.LocalScope =
"foo::";
5025 HI.Definition =
"int a";
5026 HI.Documentation =
"";
5028 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nType: `int`"},
5029 {R
"cpp(/// Function doc
5031 void foo(int [[^a]]);
5035 HI.Kind = index::SymbolKind::Parameter;
5036 HI.NamespaceScope =
"";
5037 HI.LocalScope =
"foo::";
5039 HI.Definition =
"int a";
5040 HI.Documentation =
"this is doc for a";
5042 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nthis is doc "
5043 "for a\n\n---\nType: `int`"},
5044 {R
"cpp(/// Function doc
5046 void foo(int [[^a]], int b);
5050 HI.Kind = index::SymbolKind::Parameter;
5051 HI.NamespaceScope =
"";
5052 HI.LocalScope =
"foo::";
5054 HI.Definition =
"int a";
5055 HI.Documentation =
"";
5057 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nType: `int`"},
5058 {R
"cpp(/// Function doc
5060 void foo(int a, int [[^b]]);
5064 HI.Kind = index::SymbolKind::Parameter;
5065 HI.NamespaceScope =
"";
5066 HI.LocalScope =
"foo::";
5068 HI.Definition =
"int b";
5069 HI.Documentation =
"this is doc for \\p b";
5071 "### param\n\n---\n```cpp\n// In foo\nint b\n```\n\n---\nthis is doc "
5072 "for `b`\n\n---\nType: `int`"},
5073 {R
"cpp(/// Function doc
5075 template <typename T>
5076 void foo(T a, T [[^b]]);
5080 HI.Kind = index::SymbolKind::Parameter;
5081 HI.NamespaceScope =
"";
5082 HI.LocalScope =
"foo::";
5084 HI.Definition =
"T b";
5085 HI.Documentation =
"this is doc for \\p b";
5087 "### param\n\n---\n```cpp\n// In foo\nT b\n```\n\n---\nthis is doc for "
5088 "`b`\n\n---\nType: `T`"},
5089 {R
"cpp(/// Function doc
5091 void foo(int a, int [[^b]]);
5095 HI.Kind = index::SymbolKind::Parameter;
5096 HI.NamespaceScope =
"";
5097 HI.LocalScope =
"foo::";
5099 HI.Definition =
"int b";
5101 "this is <b>doc</b> <html-tag attribute/> <another-html-tag "
5102 "attribute=\"value\">for</another-html-tag> \\p b";
5104 "### param\n\n---\n```cpp\n// In foo\nint b\n```\n\n---\nthis is "
5105 "\\<b>doc\\</b> \\<html-tag attribute/> \\<another-html-tag "
5106 "attribute=\"value\">for\\</another-html-tag> `b`\n\n---\nType: `int`"},
5111 IndexSym.Documentation =
"comment from index";
5117 for (
const auto &Case : Cases) {
5118 SCOPED_TRACE(Case.Code);
5122 auto AST = TU.build();
5127 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(), Index.get());
5131 Case.ExpectedBuilder(Expected);
5134 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
5135 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
5136 EXPECT_EQ(H->Name, Expected.Name);
5137 EXPECT_EQ(H->Kind, Expected.Kind);
5138 EXPECT_EQ(H->Documentation, Expected.Documentation);
5139 EXPECT_EQ(H->Definition, Expected.Definition);
5140 EXPECT_EQ(H->Type, Expected.Type);
5141 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
5142 EXPECT_EQ(H->Parameters, Expected.Parameters);
5143 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
5144 EXPECT_EQ(H->SymRange, Expected.SymRange);
5145 EXPECT_EQ(H->Value, Expected.Value);
#define PREDEFINEMACROS_TEST(x)
Same as llvm::Annotations, but adjusts functions to LSP-specific types for positions and ranges.
static std::unique_ptr< SymbolIndex > build(SymbolSlab Symbols, RefSlab Refs, RelationSlab Relations)
Builds an index from slabs. The index takes ownership of the data.
An efficient structure of storing large set of symbol references in memory.
SymbolSlab::Builder is a mutable container that can 'freeze' to SymbolSlab.
WithContextValue extends Context::current() with a single value.
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
SymbolID getSymbolID(const Decl *D)
Gets the symbol ID for a declaration. Returned SymbolID might be null.
Symbol func(llvm::StringRef Name)
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
std::string testPath(PathRef File, llvm::sys::path::Style Style)
std::optional< HoverInfo > getHover(ParsedAST &AST, Position Pos, const format::FormatStyle &Style, const SymbolIndex *Index)
Get the hover information when hovering at Pos.
TEST(BackgroundQueueTest, Priority)
void parseDocumentation(llvm::StringRef Input, markup::Document &Output)
cppcoreguidelines::ProBoundsAvoidUncheckedContainerAccessCheck P
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Settings that express user/project preferences and control clangd behavior.
static clangd::Key< Config > Key
Context key which can be used to set the current Config.
@ Markdown
Treat comments as Markdown.
@ Doxygen
Treat comments as doxygen.
struct clang::clangd::Config::@124253042262101241326257264241307221112313102042 Hover
Configures hover feature.
bool ShowAKA
Whether hover show a.k.a type.
uint32_t MacroContentsLimit
Limit the number of characters returned when hovering a macro; 0 is no limit.
Represents parameters of a function, a template or a macro.
Contains pretty-printed type and desugared type.
Contains detailed information about a Symbol.
std::optional< Range > SymRange
std::string Name
Name of the symbol, does not contain any "::".
The class presents a C++ symbol, e.g.
static TestTU withCode(llvm::StringRef Code)