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";
1024 float [[^y]]() { return Y; }
1029 HI.Kind = index::SymbolKind::InstanceMethod;
1030 HI.NamespaceScope =
"";
1031 HI.Definition =
"float y()";
1032 HI.LocalScope =
"X::";
1033 HI.Documentation =
"Trivial accessor for `Y`.\n\nAn int named Y";
1034 HI.Type =
"float ()";
1035 HI.ReturnType =
"float";
1036 HI.Parameters.emplace();
1037 HI.AccessSpecifier =
"public";
1041 struct X { int Y; void [[^setY]](float v) { Y = v; } };
1045 HI.Kind = index::SymbolKind::InstanceMethod;
1046 HI.NamespaceScope =
"";
1047 HI.Definition =
"void setY(float v)";
1048 HI.LocalScope =
"X::";
1049 HI.Documentation =
"Trivial setter for `Y`.";
1050 HI.Type =
"void (float)";
1051 HI.ReturnType =
"void";
1052 HI.Parameters.emplace();
1053 HI.Parameters->emplace_back();
1054 HI.Parameters->back().Type =
"float";
1055 HI.Parameters->back().Name =
"v";
1056 HI.AccessSpecifier =
"public";
1060 struct X { int Y; X& [[^setY]](float v) { Y = v; return *this; } };
1064 HI.Kind = index::SymbolKind::InstanceMethod;
1065 HI.NamespaceScope =
"";
1066 HI.Definition =
"X &setY(float v)";
1067 HI.LocalScope =
"X::";
1068 HI.Documentation =
"Trivial setter for `Y`.";
1069 HI.Type =
"X &(float)";
1070 HI.ReturnType =
"X &";
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 namespace std { template<typename T> T&& move(T&& t); }
1080 struct X { int Y; void [[^setY]](float v) { Y = std::move(v); } };
1084 HI.Kind = index::SymbolKind::InstanceMethod;
1085 HI.NamespaceScope =
"";
1086 HI.Definition =
"void setY(float v)";
1087 HI.LocalScope =
"X::";
1088 HI.Documentation =
"Trivial setter for `Y`.";
1089 HI.Type =
"void (float)";
1090 HI.ReturnType =
"void";
1091 HI.Parameters.emplace();
1092 HI.Parameters->emplace_back();
1093 HI.Parameters->back().Type =
"float";
1094 HI.Parameters->back().Name =
"v";
1095 HI.AccessSpecifier =
"public";
1102 void [[^setY]](float v) { Y = v; }
1107 HI.Kind = index::SymbolKind::InstanceMethod;
1108 HI.NamespaceScope =
"";
1109 HI.Definition =
"void setY(float v)";
1110 HI.LocalScope =
"X::";
1111 HI.Documentation =
"Trivial setter for `Y`.\n\nAn int named Y";
1112 HI.Type =
"void (float)";
1113 HI.ReturnType =
"void";
1114 HI.Parameters.emplace();
1115 HI.Parameters->emplace_back();
1116 HI.Parameters->back().Type =
"float";
1117 HI.Parameters->back().Name =
"v";
1118 HI.AccessSpecifier =
"public";
1122 struct X { int x = 2; };
1127 HI.Kind = index::SymbolKind::Variable;
1128 HI.NamespaceScope =
"";
1129 HI.Definition =
"X x";
1133 R
"cpp(auto [^[[x]]] = 1; /*error-ok*/)cpp",
1136 HI.Kind = index::SymbolKind::Variable;
1137 HI.NamespaceScope =
"";
1139 HI.Type =
"NULL TYPE";
1141 HI.AccessSpecifier =
"public";
1145 Unknown [[^abc]] = invalid;
1150 HI.Kind = index::SymbolKind::Variable;
1151 HI.NamespaceScope =
"";
1152 HI.Definition =
"int abc";
1154 HI.AccessSpecifier =
"public";
1158 void fun(int arg_a, int &arg_b) {};
1166 HI.Kind = index::SymbolKind::Variable;
1167 HI.NamespaceScope =
"";
1168 HI.Definition =
"int b = 2";
1169 HI.LocalScope =
"code::";
1172 HI.CalleeArgInfo.emplace();
1173 HI.CalleeArgInfo->Name =
"arg_b";
1174 HI.CalleeArgInfo->Type =
"int &";
1180 explicit Foo(int arg_a) {}
1182 template<class T, class... Args>
1183 T make(Args&&... args)
1190 auto foo = make<Foo>([[^a]]);
1195 HI.Kind = index::SymbolKind::Variable;
1196 HI.NamespaceScope =
"";
1197 HI.Definition =
"int a = 1";
1198 HI.LocalScope =
"code::";
1201 HI.CalleeArgInfo.emplace();
1202 HI.CalleeArgInfo->Name =
"arg_a";
1203 HI.CalleeArgInfo->Type =
"int";
1208 void foobar(const float &arg);
1216 HI.Kind = index::SymbolKind::Variable;
1217 HI.NamespaceScope =
"";
1218 HI.Definition =
"int a = 0";
1219 HI.LocalScope =
"main::";
1222 HI.CalleeArgInfo.emplace();
1223 HI.CalleeArgInfo->Name =
"arg";
1224 HI.CalleeArgInfo->Type =
"const float &";
1230 explicit Foo(const float& arg) {}
1239 HI.Kind = index::SymbolKind::Variable;
1240 HI.NamespaceScope =
"";
1241 HI.Definition =
"int a = 0";
1242 HI.LocalScope =
"main::";
1245 HI.CalleeArgInfo.emplace();
1246 HI.CalleeArgInfo->Name =
"arg";
1247 HI.CalleeArgInfo->Type =
"const float &";
1252 void fun(int arg_a, const int &arg_b) {};
1259 HI.Name = "literal";
1260 HI.Kind = index::SymbolKind::Unknown;
1261 HI.CalleeArgInfo.emplace();
1262 HI.CalleeArgInfo->Name =
"arg_b";
1263 HI.CalleeArgInfo->Type =
"const int &";
1268 void fun(int arg_a, const int &arg_b) {};
1275 HI.Name = "expression";
1276 HI.Kind = index::SymbolKind::Unknown;
1279 HI.CalleeArgInfo.emplace();
1280 HI.CalleeArgInfo->Name =
"arg_b";
1281 HI.CalleeArgInfo->Type =
"const int &";
1286 int add(int lhs, int rhs);
1292 HI.Name = "expression";
1293 HI.Kind = index::SymbolKind::Unknown;
1296 HI.CalleeArgInfo.emplace();
1297 HI.CalleeArgInfo->Name =
"lhs";
1298 HI.CalleeArgInfo->Type =
"int";
1303 void foobar(const float &arg);
1309 HI.Name = "literal";
1310 HI.Kind = index::SymbolKind::Unknown;
1311 HI.CalleeArgInfo.emplace();
1312 HI.CalleeArgInfo->Name =
"arg";
1313 HI.CalleeArgInfo->Type =
"const float &";
1320 void fun(int arg_a = 3, int arg_b = 4) {}
1330 HI.Kind = index::SymbolKind::Variable;
1331 HI.NamespaceScope =
"";
1332 HI.Definition =
"int a = 1";
1333 HI.LocalScope =
"code::";
1336 HI.CalleeArgInfo.emplace();
1337 HI.CalleeArgInfo->Name =
"arg_a";
1338 HI.CalleeArgInfo->Type =
"int";
1339 HI.CalleeArgInfo->Default =
"3";
1355 HI.Kind = index::SymbolKind::Variable;
1356 HI.NamespaceScope =
"";
1357 HI.Definition =
"const int x = 0";
1358 HI.LocalScope =
"bar::";
1360 HI.Type =
"const int";
1361 HI.CalleeArgInfo.emplace();
1362 HI.CalleeArgInfo->Type =
"Foo";
1373 HI.Kind = index::SymbolKind::Field;
1374 HI.NamespaceScope =
"";
1375 HI.Definition =
"int xx";
1376 HI.LocalScope =
"Foo::";
1378 HI.AccessSpecifier =
"public";
1388 HI.Kind = index::SymbolKind::Field;
1389 HI.NamespaceScope =
"";
1390 HI.Definition =
"int yy";
1391 HI.LocalScope =
"Foo::";
1393 HI.AccessSpecifier =
"public";
1400 constexpr Foo k2 = {
1401 ^[[{]]1} // FIXME: why the hover range is 1 character?
1405 HI.Name = "expression";
1406 HI.Kind = index::SymbolKind::Unknown;
1407 HI.Type =
"int[10]";
1414 template <int Size> m_int ^[[arr]][Size];
1418 HI.Kind = index::SymbolKind::Variable;
1419 HI.Type = {
"m_int[Size]",
"int[Size]"};
1420 HI.NamespaceScope =
"";
1421 HI.Definition =
"template <int Size> m_int arr[Size]";
1422 HI.TemplateParameters = {{{
"int"}, {
"Size"}, std::nullopt}};
1428 template <int Size> m_int arr[Size];
1430 template <> m_int ^[[arr]]<4>[4];
1434 HI.Kind = index::SymbolKind::Variable;
1435 HI.Type = {
"m_int[4]",
"int[4]"};
1436 HI.NamespaceScope =
"";
1437 HI.Definition =
"m_int arr[4]";
1441 template<typename T>
1447 TestHover<int>::Type ^[[a]];
1452 HI.NamespaceScope =
"";
1453 HI.LocalScope =
"code::";
1454 HI.Definition =
"TestHover<int>::Type a";
1455 HI.Kind = index::SymbolKind::Variable;
1456 HI.Type = {
"TestHover<int>::Type",
"int"};
1460 template<typename T>
1461 void ^[[foo]](T arg) {}
1465 HI.Kind = index::SymbolKind::Function;
1466 HI.NamespaceScope =
"";
1467 HI.Definition =
"template <typename T> void foo(T arg)";
1468 HI.Type =
"void (T)";
1469 HI.ReturnType =
"void";
1470 HI.Parameters = {{{
"T"}, std::string(
"arg"), std::nullopt}};
1471 HI.TemplateParameters = {
1472 {{
"typename"}, std::string(
"T"), std::nullopt}};
1476 template<typename T>
1477 using ^[[alias]] = T;
1481 HI.NamespaceScope =
"";
1483 HI.Kind = index::SymbolKind::TypeAlias;
1484 HI.Definition =
"template <typename T> using alias = T";
1486 HI.TemplateParameters = {
1487 {{
"typename"}, std::string(
"T"), std::nullopt}};
1491 template<typename T>
1494 template<typename T>
1495 using ^[[AA]] = A<T>;
1499 HI.NamespaceScope =
"";
1501 HI.Kind = index::SymbolKind::TypeAlias;
1502 HI.Definition =
"template <typename T> using AA = A<T>";
1503 HI.Type = {
"A<T>",
"T"};
1504 HI.TemplateParameters = {
1505 {{
"typename"}, std::string(
"T"), std::nullopt}};
1515 HI.NamespaceScope =
"";
1517 HI.Kind = index::SymbolKind::Variable;
1518 HI.Definition =
"m_int arr[10]";
1519 HI.Type = {
"m_int[10]",
"int[10]"};
1525 extern m_int ^[[arr]][];
1529 HI.NamespaceScope =
"";
1531 HI.Kind = index::SymbolKind::Variable;
1532 HI.Definition =
"extern m_int arr[]";
1533 HI.Type = {
"m_int[]",
"int[]"};
1541 m_int ^[[arr]][Size];
1546 HI.NamespaceScope =
"";
1547 HI.LocalScope =
"Test<Size>::";
1548 HI.AccessSpecifier =
"public";
1549 HI.Kind = index::SymbolKind::Field;
1550 HI.Definition =
"m_int arr[Size]";
1551 HI.Type = {
"m_int[Size]",
"int[Size]"};
1562 HI.NamespaceScope = "";
1563 HI.LocalScope =
"Foo::";
1565 HI.Kind = index::SymbolKind::Field;
1566 HI.Definition =
"char y : 1";
1572 HI.AccessSpecifier =
"public";
1574 for (
const auto &Case : Cases) {
1575 SCOPED_TRACE(Case.Code);
1579 TU.ExtraArgs.push_back(
"-std=c++20");
1582 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
1583 auto AST = TU.build();
1588 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
1592 Case.ExpectedBuilder(Expected);
1594 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
1595 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
1596 EXPECT_EQ(H->Name, Expected.Name);
1597 EXPECT_EQ(H->Kind, Expected.Kind);
1598 EXPECT_EQ(H->Documentation, Expected.Documentation);
1599 EXPECT_EQ(H->Definition, Expected.Definition);
1600 EXPECT_EQ(H->Type, Expected.Type);
1601 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
1602 EXPECT_EQ(H->Parameters, Expected.Parameters);
1603 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
1604 EXPECT_EQ(H->SymRange, Expected.SymRange);
1605 EXPECT_EQ(H->Value, Expected.Value);
1606 EXPECT_EQ(H->Size, Expected.Size);
1607 EXPECT_EQ(H->Offset, Expected.Offset);
1608 EXPECT_EQ(H->Align, Expected.Align);
1609 EXPECT_EQ(H->AccessSpecifier, Expected.AccessSpecifier);
1610 EXPECT_EQ(H->CalleeArgInfo, Expected.CalleeArgInfo);
1611 EXPECT_EQ(H->CallPassType, Expected.CallPassType);
1617 const char *
const Code;
1618 const std::string ClangLanguageFlag;
1619 const char *
const ExpectedDefinitionLanguage;
1620 } Cases[] = {{R
"cpp(
1621 void [[some^Global]]() {}
1625 void [[some^Global]]() {}
1627 "-xobjective-c++",
"objective-cpp"},
1629 void [[some^Global]]() {}
1631 "-xobjective-c",
"objective-c"}};
1632 for (
const auto &Case : Cases) {
1633 SCOPED_TRACE(Case.Code);
1637 if (!Case.ClangLanguageFlag.empty())
1638 TU.ExtraArgs.push_back(Case.ClangLanguageFlag);
1639 auto AST = TU.build();
1641 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
1644 EXPECT_STREQ(H->DefinitionLanguage, Case.ExpectedDefinitionLanguage);
1649 const llvm::StringRef CodePrefix = R
"cpp(
1651class Derived : public Base {};
1655 CustomClass(const Base &x) {}
1656 CustomClass(int &x) {}
1657 CustomClass(float x) {}
1658 CustomClass(int x, int y) {}
1661void int_by_ref(int &x) {}
1662void int_by_const_ref(const int &x) {}
1663void int_by_value(int x) {}
1664void base_by_ref(Base &x) {}
1665void base_by_const_ref(const Base &x) {}
1666void base_by_value(Base x) {}
1667void float_by_value(float x) {}
1668void custom_by_value(CustomClass x) {}
1672 int &int_ref = int_x;
1673 const int &int_const_ref = int_x;
1675 const Base &base_const_ref = base;
1679 const llvm::StringRef CodeSuffix =
"}";
1682 const char *
const Code;
1687 {
"int_by_value([[^int_x]]);", PassMode::Value,
false},
1688 {
"int_by_value([[^123]]);", PassMode::Value,
false},
1689 {
"int_by_ref([[^int_x]]);", PassMode::Ref,
false},
1690 {
"int_by_const_ref([[^int_x]]);", PassMode::ConstRef,
false},
1691 {
"int_by_const_ref([[^123]]);", PassMode::ConstRef,
false},
1692 {
"int_by_value([[^int_ref]]);", PassMode::Value,
false},
1693 {
"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef,
false},
1694 {
"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef,
false},
1695 {
"int_by_const_ref([[^int_const_ref]]);", PassMode::ConstRef,
false},
1697 {
"base_by_ref([[^base]]);", PassMode::Ref,
false},
1698 {
"base_by_const_ref([[^base]]);", PassMode::ConstRef,
false},
1699 {
"base_by_const_ref([[^base_const_ref]]);", PassMode::ConstRef,
false},
1700 {
"base_by_value([[^base]]);", PassMode::Value,
false},
1701 {
"base_by_value([[^base_const_ref]]);", PassMode::Value,
false},
1702 {
"base_by_ref([[^derived]]);", PassMode::Ref,
false},
1703 {
"base_by_const_ref([[^derived]]);", PassMode::ConstRef,
false},
1704 {
"base_by_value([[^derived]]);", PassMode::Value,
false},
1706 {
"CustomClass c1([[^base]]);", PassMode::ConstRef,
false},
1707 {
"auto c2 = new CustomClass([[^base]]);", PassMode::ConstRef,
false},
1708 {
"CustomClass c3([[^int_x]]);", PassMode::Ref,
false},
1709 {
"CustomClass c3(int_x, [[^int_x]]);", PassMode::Value,
false},
1711 {
"float_by_value([[^int_x]]);", PassMode::Value,
true},
1712 {
"float_by_value([[^int_ref]]);", PassMode::Value,
true},
1713 {
"float_by_value([[^int_const_ref]]);", PassMode::Value,
true},
1714 {
"float_by_value([[^123.0f]]);", PassMode::Value,
false},
1715 {
"float_by_value([[^123]]);", PassMode::Value,
true},
1716 {
"custom_by_value([[^int_x]]);", PassMode::Ref,
true},
1717 {
"custom_by_value([[^float_x]]);", PassMode::Value,
true},
1718 {
"custom_by_value([[^base]]);", PassMode::ConstRef,
true},
1720 for (
const auto &Test : Tests) {
1721 SCOPED_TRACE(Test.Code);
1723 const auto Code = (CodePrefix + Test.Code + CodeSuffix).str();
1726 TU.ExtraArgs.push_back(
"-std=c++17");
1727 auto AST = TU.build();
1728 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
1730 EXPECT_EQ(H->CallPassType->PassBy, Test.PassBy);
1731 EXPECT_EQ(H->CallPassType->Converted, Test.Converted);
1736 llvm::StringRef Tests[] = {
1740 "decltype(au^to) x = 0;",
1742 R
"cpp(// Lambda auto parameter
1743 auto lamb = [](a^uto){};
1745 R"cpp(// non-named decls don't get hover. Don't crash!
1746 ^static_assert(1, "");
1748 R"cpp(// non-evaluatable expr
1749 template <typename T> void foo() {
1750 (void)[[size^of]](T);
1752 R"cpp(// should not crash on invalid semantic form of init-list-expr.
1758 constexpr Foo s = ^{
1764 "auto x = ^(int){42};",
1768 "auto x = ^nullptr;",
1771 for (
const auto &Test : Tests) {
1776 TU.ExtraArgs.push_back(
"-std=c++17");
1777 auto AST = TU.build();
1778 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
1785 struct Foo { int x; };
1786 int y = __builtin_o^ffsetof(Foo, x);
1789 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
1791 EXPECT_EQ(H->Name,
"expression");
1792 EXPECT_EQ(H->Kind, index::SymbolKind::Unknown);
1797 const char *
const Code;
1798 const std::function<void(
HoverInfo &)> ExpectedBuilder;
1800 {
"auto x = [['^A']]; // character literal",
1802 HI.Name =
"expression";
1804 HI.Value =
"65 (0x41)";
1806 {
"auto s = ^[[\"Hello, world!\"]]; // string literal",
1808 HI.Name =
"string-literal";
1810 HI.Type =
"const char[14]";
1813 R
"cpp(// Local variable
1817 int test1 = bonjour;
1821 HI.Name = "bonjour";
1822 HI.Kind = index::SymbolKind::Variable;
1823 HI.NamespaceScope =
"";
1824 HI.LocalScope =
"main::";
1826 HI.Definition =
"int bonjour";
1829 R
"cpp(// Local variable in method
1838 HI.Name = "bonjour";
1839 HI.Kind = index::SymbolKind::Variable;
1840 HI.NamespaceScope =
"";
1841 HI.LocalScope =
"s::method::";
1843 HI.Definition =
"int bonjour";
1851 ns1::[[My^Class]]* Params;
1855 HI.Name = "MyClass";
1856 HI.Kind = index::SymbolKind::Struct;
1857 HI.NamespaceScope =
"ns1::";
1858 HI.Definition =
"struct MyClass {}";
1866 ns1::[[My^Class]]* Params;
1870 HI.Name = "MyClass";
1871 HI.Kind = index::SymbolKind::Class;
1872 HI.NamespaceScope =
"ns1::";
1873 HI.Definition =
"class MyClass {}";
1878 union MyUnion { int x; int y; };
1881 ns1::[[My^Union]] Params;
1885 HI.Name = "MyUnion";
1886 HI.Kind = index::SymbolKind::Union;
1887 HI.NamespaceScope =
"ns1::";
1888 HI.Definition =
"union MyUnion {}";
1891 R
"cpp(// Function definition via pointer
1894 auto *X = &^[[foo]];
1899 HI.Kind = index::SymbolKind::Function;
1900 HI.NamespaceScope =
"";
1901 HI.Type =
"void (int)";
1902 HI.Definition =
"void foo(int)";
1903 HI.Documentation =
"Function definition via pointer";
1904 HI.ReturnType =
"void";
1906 {{
"int"}, std::nullopt, std::nullopt},
1910 R
"cpp(// Function declaration via call
1913 return ^[[foo]](42);
1918 HI.Kind = index::SymbolKind::Function;
1919 HI.NamespaceScope =
"";
1920 HI.Type =
"int (int)";
1921 HI.Definition =
"int foo(int)";
1922 HI.Documentation =
"Function declaration via call";
1923 HI.ReturnType =
"int";
1925 {{
"int"}, std::nullopt, std::nullopt},
1930 struct Foo { int x; };
1938 HI.Kind = index::SymbolKind::Field;
1939 HI.NamespaceScope =
"";
1940 HI.LocalScope =
"Foo::";
1942 HI.Definition =
"int x";
1945 R
"cpp(// Field with initialization
1946 struct Foo { int x = 5; };
1954 HI.Kind = index::SymbolKind::Field;
1955 HI.NamespaceScope =
"";
1956 HI.LocalScope =
"Foo::";
1958 HI.Definition =
"int x = 5";
1961 R
"cpp(// Static field
1962 struct Foo { static int x; };
1969 HI.Kind = index::SymbolKind::StaticProperty;
1970 HI.NamespaceScope =
"";
1971 HI.LocalScope =
"Foo::";
1973 HI.Definition =
"static int x";
1976 R
"cpp(// Field, member initializer
1979 Foo() : ^[[x]](0) {}
1984 HI.Kind = index::SymbolKind::Field;
1985 HI.NamespaceScope =
"";
1986 HI.LocalScope =
"Foo::";
1988 HI.Definition =
"int x";
1991 R
"cpp(// Field, GNU old-style field designator
1992 struct Foo { int x; };
1994 Foo bar = { ^[[x]] : 1 };
1999 HI.Kind = index::SymbolKind::Field;
2000 HI.NamespaceScope =
"";
2001 HI.LocalScope =
"Foo::";
2003 HI.Definition =
"int x";
2008 R
"cpp(// Field, field designator
2009 struct Foo { int x; int y; };
2011 Foo bar = { .^[[x]] = 2, .y = 2 };
2016 HI.Kind = index::SymbolKind::Field;
2017 HI.NamespaceScope =
"";
2018 HI.LocalScope =
"Foo::";
2020 HI.Definition =
"int x";
2023 R
"cpp(// Field, offsetof
2024 struct Foo { int x; int y; };
2025 int z = __builtin_offsetof(Foo, ^[[x]]);
2029 HI.Kind = index::SymbolKind::Field;
2030 HI.NamespaceScope =
"";
2031 HI.LocalScope =
"Foo::";
2033 HI.Definition =
"int x";
2037 R
"cpp(// Outer field, nested offsetof designator
2038 struct Inner { int c; };
2039 struct A { Inner B; };
2040 int z = __builtin_offsetof(A, ^[[B]].c);
2044 HI.Kind = index::SymbolKind::Field;
2045 HI.NamespaceScope =
"";
2046 HI.LocalScope =
"A::";
2048 HI.Definition =
"Inner B";
2052 R
"cpp(// Inner field, nested offsetof designator
2053 struct Inner { int c; };
2054 struct A { Inner B; };
2055 int z = __builtin_offsetof(A, B.^[[c]]);
2059 HI.Kind = index::SymbolKind::Field;
2060 HI.NamespaceScope =
"";
2061 HI.LocalScope =
"Inner::";
2063 HI.Definition =
"int c";
2067 R
"cpp(// Method call
2068 struct Foo { int x(); };
2076 HI.Kind = index::SymbolKind::InstanceMethod;
2077 HI.NamespaceScope =
"";
2078 HI.LocalScope =
"Foo::";
2080 HI.Definition =
"int x()";
2081 HI.ReturnType =
"int";
2082 HI.Parameters = std::vector<HoverInfo::Param>{};
2085 R
"cpp(// Static method call
2086 struct Foo { static int x(); };
2093 HI.Kind = index::SymbolKind::StaticMethod;
2094 HI.NamespaceScope =
"";
2095 HI.LocalScope =
"Foo::";
2097 HI.Definition =
"static int x()";
2098 HI.ReturnType =
"int";
2099 HI.Parameters = std::vector<HoverInfo::Param>{};
2110 HI.Kind = index::SymbolKind::TypeAlias;
2111 HI.NamespaceScope =
"";
2112 HI.Definition =
"typedef int Foo";
2114 HI.Documentation =
"Typedef";
2117 R
"cpp(// Typedef with embedded definition
2118 typedef struct Bar {} Foo;
2125 HI.Kind = index::SymbolKind::TypeAlias;
2126 HI.NamespaceScope =
"";
2127 HI.Definition =
"typedef struct Bar Foo";
2128 HI.Type =
"struct Bar";
2129 HI.Documentation =
"Typedef with embedded definition";
2134 struct Foo { static void bar(); };
2136 int main() { ^[[ns]]::Foo::bar(); }
2140 HI.Kind = index::SymbolKind::Namespace;
2141 HI.NamespaceScope =
"";
2142 HI.Definition =
"namespace ns {}";
2145 R
"cpp(// Anonymous namespace
2149 } // anonymous namespace
2151 int main() { ns::[[f^oo]]++; }
2155 HI.Kind = index::SymbolKind::Variable;
2156 HI.NamespaceScope =
"ns::";
2158 HI.Definition =
"int foo";
2161 R
"cpp(// Function definition via using declaration
2172 HI.Kind = index::SymbolKind::Function;
2173 HI.NamespaceScope =
"ns::";
2174 HI.Type =
"void ()";
2175 HI.Definition =
"void foo()";
2176 HI.Documentation =
"";
2177 HI.ReturnType =
"void";
2178 HI.Parameters = std::vector<HoverInfo::Param>{};
2181 R
"cpp( // using declaration and two possible function declarations
2182 namespace ns { void foo(int); void foo(char); }
2184 template <typename T> void bar() { [[f^oo]](T{}); }
2188 HI.Kind = index::SymbolKind::Using;
2189 HI.NamespaceScope =
"";
2190 HI.Definition =
"using ns::foo";
2195 int main() { return ^[[MACRO]]; }
2201 HI.Kind = index::SymbolKind::Macro;
2202 HI.Definition =
"#define MACRO 0\n\n"
2209 #define MACRO2 ^[[MACRO]]
2213 HI.Kind = index::SymbolKind::Macro;
2214 HI.Definition =
"#define MACRO 0";
2223 int main() ^[[MACRO]]
2227 HI.Kind = index::SymbolKind::Macro;
2229 R
"cpp(#define MACRO \
2240 R"cpp(// Forward class declaration
2247 HI.Kind = index::SymbolKind::Class;
2248 HI.NamespaceScope =
"";
2249 HI.Definition =
"class Foo {}";
2250 HI.Documentation =
"Forward class declaration";
2253 R
"cpp(// Function declaration
2255 void g() { [[f^oo]](); }
2260 HI.Kind = index::SymbolKind::Function;
2261 HI.NamespaceScope =
"";
2262 HI.Type =
"void ()";
2263 HI.Definition =
"void foo()";
2264 HI.Documentation =
"Function declaration";
2265 HI.ReturnType =
"void";
2266 HI.Parameters = std::vector<HoverInfo::Param>{};
2269 R
"cpp(// Enum declaration
2274 [[Hel^lo]] hello = ONE;
2279 HI.Kind = index::SymbolKind::Enum;
2280 HI.NamespaceScope =
"";
2281 HI.Definition =
"enum Hello {}";
2282 HI.Documentation =
"Enum declaration";
2290 Hello hello = [[O^NE]];
2295 HI.Kind = index::SymbolKind::EnumConstant;
2296 HI.NamespaceScope =
"";
2297 HI.LocalScope =
"Hello::";
2298 HI.Type =
"enum Hello";
2299 HI.Definition =
"ONE";
2303 R
"cpp(// C++20's using enum
2309 Hello hello = [[O^NE]];
2314 HI.Kind = index::SymbolKind::EnumConstant;
2315 HI.NamespaceScope =
"";
2316 HI.LocalScope =
"Hello::";
2317 HI.Type =
"enum Hello";
2318 HI.Definition =
"ONE";
2322 R
"cpp(// Enumerator in anonymous enum
2327 int hello = [[O^NE]];
2332 HI.Kind = index::SymbolKind::EnumConstant;
2333 HI.NamespaceScope =
"";
2336 HI.Type =
"enum (unnamed)";
2337 HI.Definition =
"ONE";
2341 R
"cpp(// Global variable
2342 static int hey = 10;
2349 HI.Kind = index::SymbolKind::Variable;
2350 HI.NamespaceScope =
"";
2352 HI.Definition =
"static int hey = 10";
2353 HI.Documentation =
"Global variable";
2355 HI.Value =
"10 (0xa)";
2358 R
"cpp(// Global variable in namespace
2360 static long long hey = -36637162602497;
2368 HI.Kind = index::SymbolKind::Variable;
2369 HI.NamespaceScope =
"ns1::";
2370 HI.Type =
"long long";
2371 HI.Definition =
"static long long hey = -36637162602497";
2372 HI.Value =
"-36637162602497 (0xffffdeadbeefffff)";
2375 R
"cpp(// Field in anonymous struct
2385 HI.Kind = index::SymbolKind::Field;
2386 HI.NamespaceScope =
"";
2387 HI.LocalScope =
"(anonymous struct)::";
2389 HI.Definition =
"int hello";
2392 R
"cpp(// Templated function
2393 template <typename T>
2397 void g() { auto x = [[f^oo]]<int>(); }
2401 HI.Kind = index::SymbolKind::Function;
2402 HI.NamespaceScope =
"";
2404 HI.Definition =
"template <> int foo<int>()";
2405 HI.Documentation =
"Templated function";
2406 HI.ReturnType =
"int";
2407 HI.Parameters = std::vector<HoverInfo::Param>{};
2412 R
"cpp(// Anonymous union
2418 void g() { struct outer o; o.v.[[d^ef]]++; }
2422 HI.Kind = index::SymbolKind::Field;
2423 HI.NamespaceScope =
"";
2424 HI.LocalScope =
"outer::(anonymous union)::";
2426 HI.Definition =
"int def";
2429 R
"cpp(// documentation from index
2430 int nextSymbolIsAForwardDeclFromIndexWithNoLocalDocs;
2432 void g() { [[ind^exSymbol]](); }
2435 HI.Name = "indexSymbol";
2436 HI.Kind = index::SymbolKind::Function;
2437 HI.NamespaceScope =
"";
2438 HI.Type =
"void ()";
2439 HI.Definition =
"void indexSymbol()";
2440 HI.ReturnType =
"void";
2441 HI.Parameters = std::vector<HoverInfo::Param>{};
2442 HI.Documentation =
"comment from index";
2445 R
"cpp(// Simple initialization with auto
2452 HI.Kind = index::SymbolKind::TypeAlias;
2453 HI.Definition =
"int";
2456 R
"cpp(// Simple initialization with const auto
2458 const ^[[auto]] i = 1;
2463 HI.Kind = index::SymbolKind::TypeAlias;
2464 HI.Definition =
"int";
2467 R
"cpp(// Simple initialization with const auto&
2469 const ^[[auto]]& i = 1;
2474 HI.Kind = index::SymbolKind::TypeAlias;
2475 HI.Definition =
"int";
2478 R
"cpp(// Simple initialization with auto&
2486 HI.Kind = index::SymbolKind::TypeAlias;
2487 HI.Definition =
"int";
2490 R
"cpp(// Simple initialization with auto*
2498 HI.Kind = index::SymbolKind::TypeAlias;
2499 HI.Definition =
"int";
2502 R
"cpp(// Simple initialization with auto from pointer
2510 HI.Kind = index::SymbolKind::TypeAlias;
2511 HI.Definition =
"int *";
2514 R
"cpp(// Auto with initializer list.
2518 class initializer_list { const _E *a, *b; };
2521 ^[[auto]] i = {1,2};
2526 HI.Kind = index::SymbolKind::TypeAlias;
2527 HI.Definition =
"std::initializer_list<int>";
2530 R
"cpp(// User defined conversion to auto
2532 operator ^[[auto]]() const { return 10; }
2537 HI.Kind = index::SymbolKind::TypeAlias;
2538 HI.Definition =
"int";
2541 R
"cpp(// Simple initialization with decltype(auto)
2543 ^[[decltype]](auto) i = 1;
2547 HI.Name = "decltype";
2548 HI.Kind = index::SymbolKind::TypeAlias;
2549 HI.Definition =
"int";
2552 R
"cpp(// Simple initialization with const decltype(auto)
2555 ^[[decltype]](auto) i = j;
2559 HI.Name = "decltype";
2560 HI.Kind = index::SymbolKind::TypeAlias;
2561 HI.Definition =
"const int";
2564 R
"cpp(// Simple initialization with const& decltype(auto)
2568 ^[[decltype]](auto) i = j;
2572 HI.Name = "decltype";
2573 HI.Kind = index::SymbolKind::TypeAlias;
2574 HI.Definition =
"const int &";
2577 R
"cpp(// Simple initialization with & decltype(auto)
2581 ^[[decltype]](auto) i = j;
2585 HI.Name = "decltype";
2586 HI.Kind = index::SymbolKind::TypeAlias;
2587 HI.Definition =
"int &";
2590 R
"cpp(// simple trailing return type
2591 ^[[auto]] main() -> int {
2597 HI.Kind = index::SymbolKind::TypeAlias;
2598 HI.Definition =
"int";
2601 R
"cpp(// auto function return with trailing type
2603 ^[[auto]] test() -> decltype(Bar()) {
2609 HI.Kind = index::SymbolKind::TypeAlias;
2610 HI.Definition =
"Bar";
2611 HI.Documentation =
"auto function return with trailing type";
2614 R
"cpp(// trailing return type
2616 auto test() -> ^[[decltype]](Bar()) {
2621 HI.Name = "decltype";
2622 HI.Kind = index::SymbolKind::TypeAlias;
2623 HI.Definition =
"Bar";
2624 HI.Documentation =
"trailing return type";
2627 R
"cpp(// auto in function return
2635 HI.Kind = index::SymbolKind::TypeAlias;
2636 HI.Definition =
"Bar";
2637 HI.Documentation =
"auto in function return";
2640 R
"cpp(// auto& in function return
2649 HI.Kind = index::SymbolKind::TypeAlias;
2650 HI.Definition =
"Bar";
2651 HI.Documentation =
"auto& in function return";
2654 R
"cpp(// auto* in function return
2663 HI.Kind = index::SymbolKind::TypeAlias;
2664 HI.Definition =
"Bar";
2665 HI.Documentation =
"auto* in function return";
2668 R
"cpp(// const auto& in function return
2670 const ^[[auto]]& test() {
2677 HI.Kind = index::SymbolKind::TypeAlias;
2678 HI.Definition =
"Bar";
2679 HI.Documentation =
"const auto& in function return";
2682 R
"cpp(// decltype(auto) in function return
2684 ^[[decltype]](auto) test() {
2689 HI.Name = "decltype";
2690 HI.Kind = index::SymbolKind::TypeAlias;
2691 HI.Definition =
"Bar";
2692 HI.Documentation =
"decltype(auto) in function return";
2695 R
"cpp(// decltype(auto) reference in function return
2696 ^[[decltype]](auto) test() {
2702 HI.Name = "decltype";
2703 HI.Kind = index::SymbolKind::TypeAlias;
2704 HI.Definition =
"int &";
2707 R
"cpp(// decltype lvalue reference
2710 ^[[decltype]](I) J = I;
2714 HI.Name = "decltype";
2715 HI.Kind = index::SymbolKind::TypeAlias;
2716 HI.Definition =
"int";
2719 R
"cpp(// decltype lvalue reference
2723 ^[[decltype]](K) J = I;
2727 HI.Name = "decltype";
2728 HI.Kind = index::SymbolKind::TypeAlias;
2729 HI.Definition =
"int &";
2732 R
"cpp(// decltype lvalue reference parenthesis
2735 ^[[decltype]]((I)) J = I;
2739 HI.Name = "decltype";
2740 HI.Kind = index::SymbolKind::TypeAlias;
2741 HI.Definition =
"int &";
2744 R
"cpp(// decltype rvalue reference
2747 ^[[decltype]](static_cast<int&&>(I)) J = static_cast<int&&>(I);
2751 HI.Name = "decltype";
2752 HI.Kind = index::SymbolKind::TypeAlias;
2753 HI.Definition =
"int &&";
2756 R
"cpp(// decltype rvalue reference function call
2760 ^[[decltype]](bar()) J = bar();
2764 HI.Name = "decltype";
2765 HI.Kind = index::SymbolKind::TypeAlias;
2766 HI.Definition =
"int &&";
2769 R
"cpp(// decltype of function with trailing return type.
2771 auto test() -> decltype(Bar()) {
2775 ^[[decltype]](test()) i = test();
2779 HI.Name = "decltype";
2780 HI.Kind = index::SymbolKind::TypeAlias;
2781 HI.Definition =
"Bar";
2783 "decltype of function with trailing return type.";
2786 R
"cpp(// decltype of var with decltype.
2790 ^[[decltype]](J) K = J;
2794 HI.Name = "decltype";
2795 HI.Kind = index::SymbolKind::TypeAlias;
2796 HI.Definition =
"int";
2799 R
"cpp(// decltype of dependent type
2800 template <typename T>
2802 using Y = ^[[decltype]](T::Z);
2806 HI.Name = "decltype";
2807 HI.Kind = index::SymbolKind::TypeAlias;
2808 HI.Definition =
"<dependent type>";
2811 R
"cpp(// More complicated structured types.
2813 ^[[auto]] (*foo)() = bar;
2817 HI.Kind = index::SymbolKind::TypeAlias;
2818 HI.Definition =
"int";
2821 R
"cpp(// Should not crash when evaluating the initializer.
2823 void test() { Test && [[te^st]] = {}; }
2827 HI.Kind = index::SymbolKind::Variable;
2828 HI.NamespaceScope =
"";
2829 HI.LocalScope =
"test::";
2830 HI.Type =
"Test &&";
2831 HI.Definition =
"Test &&test = {}";
2834 R
"cpp(// Shouldn't crash when evaluating the initializer.
2835 struct Bar {}; // error-ok
2836 struct Foo { void foo(Bar x = y); }
2837 void Foo::foo(Bar [[^x]]) {})cpp",
2840 HI.Kind = index::SymbolKind::Parameter;
2841 HI.NamespaceScope =
"";
2842 HI.LocalScope =
"Foo::foo::";
2844 HI.Definition =
"Bar x = <recovery - expr>()";
2847 R
"cpp(// auto on alias
2848 typedef int int_type;
2849 ^[[auto]] x = int_type();
2853 HI.Kind = index::SymbolKind::TypeAlias;
2854 HI.Definition =
"int_type // aka: int";
2857 R
"cpp(// auto on alias
2859 typedef cls cls_type;
2860 ^[[auto]] y = cls_type();
2864 HI.Kind = index::SymbolKind::TypeAlias;
2865 HI.Definition =
"cls_type // aka: cls";
2866 HI.Documentation =
"auto on alias";
2869 R
"cpp(// auto on alias
2872 ^[[auto]] z = templ<int>();
2876 HI.Kind = index::SymbolKind::TypeAlias;
2877 HI.Definition =
"templ<int>";
2878 HI.Documentation =
"auto on alias";
2881 R
"cpp(// Undeduced auto declaration
2882 template<typename T>
2889 HI.Kind = index::SymbolKind::TypeAlias;
2890 HI.Definition =
"T";
2893 R
"cpp(// Undeduced auto return type
2894 template<typename T>
2901 HI.Kind = index::SymbolKind::TypeAlias;
2902 HI.Definition =
"/* not deduced */";
2905 R
"cpp(// Template auto parameter
2906 template<[[a^uto]] T>
2914 HI.Kind = index::SymbolKind::TypeAlias;
2915 HI.Definition =
"/* not deduced */";
2918 R
"cpp(// Undeduced decltype(auto) return type
2919 template<typename T>
2920 ^[[decltype]](auto) foo() {
2925 HI.Name = "decltype";
2926 HI.Kind = index::SymbolKind::TypeAlias;
2927 HI.Definition =
"/* not deduced */";
2930 R
"cpp(// should not crash.
2931 template <class T> struct cls {
2935 auto test = cls<int>().[[m^ethod]]();
2938 HI.Definition = "int method()";
2939 HI.Kind = index::SymbolKind::InstanceMethod;
2940 HI.NamespaceScope =
"";
2941 HI.LocalScope =
"cls<int>::";
2943 HI.Parameters.emplace();
2944 HI.ReturnType =
"int";
2948 R
"cpp(// type of nested templates.
2949 template <class T> struct cls {};
2950 cls<cls<cls<int>>> [[fo^o]];
2953 HI.Definition = "cls<cls<cls<int>>> foo";
2954 HI.Kind = index::SymbolKind::Variable;
2955 HI.NamespaceScope =
"";
2957 HI.Type =
"cls<cls<cls<int>>>";
2960 R
"cpp(// type of nested templates.
2961 template <class T> struct cls {};
2962 [[cl^s]]<cls<cls<int>>> foo;
2965 HI.Definition = "template <> struct cls<cls<cls<int>>> {}";
2966 HI.Kind = index::SymbolKind::Struct;
2967 HI.NamespaceScope =
"";
2968 HI.Name =
"cls<cls<cls<int>>>";
2969 HI.Documentation =
"type of nested templates.";
2972 R
"cpp(// type with decltype
2974 decltype(a) [[b^]] = a;)cpp",
2976 HI.Definition = "decltype(a) b = a";
2977 HI.Kind = index::SymbolKind::Variable;
2978 HI.NamespaceScope =
"";
2983 R
"cpp(// type with decltype
2986 decltype(c) [[b^]] = a;)cpp",
2988 HI.Definition = "decltype(c) b = a";
2989 HI.Kind = index::SymbolKind::Variable;
2990 HI.NamespaceScope =
"";
2995 R
"cpp(// type with decltype
2997 const decltype(a) [[b^]] = a;)cpp",
2999 HI.Definition = "const decltype(a) b = a";
3000 HI.Kind = index::SymbolKind::Variable;
3001 HI.NamespaceScope =
"";
3006 R
"cpp(// type with decltype
3008 auto [[f^oo]](decltype(a) x) -> decltype(a) { return 0; })cpp",
3010 HI.Definition = "auto foo(decltype(a) x) -> decltype(a)";
3011 HI.Kind = index::SymbolKind::Function;
3012 HI.NamespaceScope =
"";
3016 HI.Type = {
"auto (decltype(a)) -> decltype(a)",
3017 "auto (int) -> int"};
3018 HI.ReturnType =
"int";
3019 HI.Parameters = {{{
"int"}, std::string(
"x"), std::nullopt}};
3022 R
"cpp(// sizeof expr
3024 (void)[[size^of]](char);
3027 HI.Name = "expression";
3028 HI.Type = {
"__size_t",
"unsigned long"};
3032 R
"cpp(// alignof expr
3034 (void)[[align^of]](char);
3037 HI.Name = "expression";
3038 HI.Type = {
"__size_t",
"unsigned long"};
3043 template <typename T = int>
3044 void foo(const T& = T()) {
3049 HI.Kind = index::SymbolKind::Function;
3050 HI.Type =
"void (const int &)";
3051 HI.ReturnType =
"void";
3053 {{
"const int &"}, std::nullopt, std::string(
"T()")}};
3054 HI.Definition =
"template <> void foo<int>(const int &)";
3055 HI.NamespaceScope =
"";
3058 R
"cpp(// should not crash
3066 HI.Kind = index::SymbolKind::Field;
3067 HI.LocalScope =
"ObjC::";
3068 HI.NamespaceScope =
"";
3069 HI.Definition =
"char data";
3075 @interface Interface
3076 @property(retain) [[MYOb^ject]] *x;
3080 HI.Name = "MYObject";
3081 HI.Kind = index::SymbolKind::Class;
3082 HI.NamespaceScope =
"";
3083 HI.Definition =
"@interface MYObject\n@end";
3089 @interface Interface
3090 - (void)doWith:([[MYOb^ject]] *)object;
3094 HI.Name = "MYObject";
3095 HI.Kind = index::SymbolKind::Class;
3096 HI.NamespaceScope =
"";
3097 HI.Definition =
"@interface MYObject\n@end";
3112 HI.Definition =
"ns::Foo *";
3115 R
"cpp(// this expr for template class
3117 template <typename T>
3127 HI.Definition =
"const ns::Foo<T> *";
3130 R
"cpp(// this expr for specialization class
3132 template <typename T> class Foo {};
3143 HI.Definition =
"ns::Foo<int> *";
3146 R
"cpp(// this expr for partial specialization struct
3148 template <typename T, typename F> struct Foo {};
3149 template <typename F>
3150 struct Foo<int, F> {
3159 HI.Definition =
"const ns::Foo<int, F> *";
3165 @interface MYObject (Private)
3166 @property(nonatomic, assign) int privateField;
3169 int someFunction() {
3170 MYObject *obj = [MYObject sharedInstance];
3171 return obj.[[private^Field]];
3175 HI.Name = "privateField";
3176 HI.Kind = index::SymbolKind::InstanceProperty;
3177 HI.LocalScope =
"MYObject(Private)::";
3178 HI.NamespaceScope =
"";
3179 HI.Definition =
"@property(nonatomic, assign, unsafe_unretained, "
3180 "readwrite) int privateField;";
3184 @protocol MYProtocol
3185 @property(nonatomic, assign) int prop1;
3188 int someFunction() {
3189 id<MYProtocol> obj = 0;
3190 return obj.[[pro^p1]];
3195 HI.Kind = index::SymbolKind::InstanceProperty;
3196 HI.LocalScope =
"MYProtocol::";
3197 HI.NamespaceScope =
"";
3198 HI.Definition =
"@property(nonatomic, assign, unsafe_unretained, "
3199 "readwrite) int prop1;";
3203 @protocol MYProtocol
3208 @interface MYObject (Ext) <[[MYProt^ocol]]>
3212 HI.Name = "MYProtocol";
3213 HI.Kind = index::SymbolKind::Protocol;
3214 HI.NamespaceScope =
"";
3215 HI.Definition =
"@protocol MYProtocol\n@end";
3221 @implementation Foo(Private)
3222 + (int)somePrivateMethod {
3223 int [[res^ult]] = 2;
3230 HI.Definition =
"int result = 2";
3231 HI.Kind = index::SymbolKind::Variable;
3233 HI.LocalScope =
"+[Foo(Private) somePrivateMethod]::";
3234 HI.NamespaceScope =
"";
3242 - (int)variadicArgMethod:(id)first, ... {
3243 int [[res^ult]] = 0;
3250 HI.Definition =
"int result = 0";
3251 HI.Kind = index::SymbolKind::Variable;
3253 HI.LocalScope =
"-[Foo variadicArgMethod:, ...]::";
3254 HI.NamespaceScope =
"";
3259 typedef struct MyRect {} MyRect;
3262 @property(nonatomic) MyRect frame;
3271 v.frame = [[foo^bar]]();
3276 HI.Kind = index::SymbolKind::Function;
3277 HI.NamespaceScope =
"";
3278 HI.Definition =
"MyRect foobar()";
3279 HI.Type = {
"MyRect ()",
"struct MyRect ()"};
3280 HI.ReturnType = {
"MyRect",
"struct MyRect"};
3281 HI.Parameters.emplace();
3284 void foo(int * __attribute__(([[non^null]], noescape)) );
3287 HI.Name = "nonnull";
3288 HI.Kind = index::SymbolKind::Unknown;
3289 HI.Definition =
"__attribute__((nonnull))";
3290 HI.Documentation = Attr::getDocumentation(attr::NonNull).str();
3295 struct strong_ordering {
3297 constexpr operator int() const { return n; }
3298 static const strong_ordering equal, greater, less;
3300 constexpr strong_ordering strong_ordering::equal = {0};
3301 constexpr strong_ordering strong_ordering::greater = {1};
3302 constexpr strong_ordering strong_ordering::less = {-1};
3309 auto operator<=>(const Foo&) const = default;
3312 bool x = Foo(1) [[!^=]] Foo(2);
3315 HI.Type = "bool (const Foo &) const noexcept";
3317 HI.Name =
"operator==";
3318 HI.Parameters = {{{
"const Foo &"}, std::nullopt, std::nullopt}};
3319 HI.ReturnType =
"bool";
3320 HI.Kind = index::SymbolKind::InstanceMethod;
3321 HI.LocalScope =
"Foo::";
3322 HI.NamespaceScope =
"";
3324 "bool operator==(const Foo &) const noexcept = default";
3325 HI.Documentation =
"";
3331 IndexSym.Documentation =
"comment from index";
3337 for (
const auto &Case : Cases) {
3338 SCOPED_TRACE(Case.Code);
3342 TU.ExtraArgs.push_back(
"-std=c++20");
3343 TU.ExtraArgs.push_back(
"-xobjective-c++");
3345 TU.ExtraArgs.push_back(
"-Wno-gnu-designator");
3348 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
3349 auto AST = TU.build();
3353 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(), Index.get());
3357 Case.ExpectedBuilder(Expected);
3360 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
3361 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
3362 EXPECT_EQ(H->Name, Expected.Name);
3363 EXPECT_EQ(H->Kind, Expected.Kind);
3364 EXPECT_EQ(H->Documentation, Expected.Documentation);
3365 EXPECT_EQ(H->Definition, Expected.Definition);
3366 EXPECT_EQ(H->Type, Expected.Type);
3367 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
3368 EXPECT_EQ(H->Parameters, Expected.Parameters);
3369 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
3370 EXPECT_EQ(H->SymRange, Expected.SymRange);
3371 EXPECT_EQ(H->Value, Expected.Value);
3378 const std::function<void(
HoverInfo &)> ExpectedBuilder;
3379 } Cases[] = {{R
"cpp(
3383 [](HoverInfo &HI) { HI.Provider = ""; }},
3388 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3393 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3398 [](HoverInfo &HI) { HI.Provider = ""; }},
3403 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3408 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3415 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3424 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3427 using namespace fo^o;
3429 [](HoverInfo &HI) { HI.Provider = ""; }},
3432 for (
const auto &Case : Cases) {
3434 SCOPED_TRACE(Code.code());
3438 TU.Code = Code.code();
3439 TU.AdditionalFiles[
"foo.h"] = guard(R
"cpp(
3442 Foo& operator+(const Foo, const Foo);
3444 TU.AdditionalFiles["all.h"] = guard(
"#include \"foo.h\"");
3446 auto AST = TU.build();
3447 auto H =
getHover(
AST, Code.point(), format::getLLVMStyle(),
nullptr);
3450 Case.ExpectedBuilder(Expected);
3452 EXPECT_EQ(H->Provider, Expected.Provider);
3459 HIFoo.Provider =
"\"foo.h\"";
3462 HIFooBar.
Name =
"foo";
3463 HIFooBar.Provider =
"<bar.h>";
3466 llvm::StringRef ExpectedMarkdown;
3467 } Cases[] = {{HIFoo,
"### `foo`\n\nprovided by `\"foo.h\"`"},
3468 {HIFooBar,
"### `foo`\n\nprovided by `<bar.h>`"}};
3470 for (
const auto &Case : Cases)
3477 const std::function<void(
HoverInfo &)> ExpectedBuilder;
3478 } Cases[] = {{R
"cpp(
3480 int fstBar = bar1();
3481 int another= bar1(0);
3482 int sndBar = bar2();
3487 HI.UsedSymbolNames = {"BAR",
"Bar",
"bar1",
"bar2"};
3491 std::vector<int> vec;
3493 [](HoverInfo &HI) { HI.UsedSymbolNames = {"vector"}; }}};
3494 for (
const auto &Case : Cases) {
3496 SCOPED_TRACE(Code.code());
3500 TU.Code = Code.code();
3501 TU.AdditionalFiles[
"bar.h"] = guard(R
"cpp(
3508 TU.AdditionalFiles["system/vector"] = guard(R
"cpp(
3514 TU.ExtraArgs.push_back("-isystem" +
testPath(
"system"));
3516 auto AST = TU.build();
3517 auto H =
getHover(
AST, Code.point(), format::getLLVMStyle(),
nullptr);
3520 Case.ExpectedBuilder(Expected);
3522 EXPECT_EQ(H->UsedSymbolNames, Expected.UsedSymbolNames);
3528 template <typename T> class X {};
3536 auto AST = TU.build();
3539 IndexSym.Documentation =
"comment from index";
3545 for (
const auto &P :
T.points()) {
3546 auto H =
getHover(
AST, P, format::getLLVMStyle(), Index.get());
3548 EXPECT_EQ(H->Documentation, IndexSym.Documentation);
3555 template <typename T> class X {};
3557 template <typename T> void bar() {}
3559 template <typename T> T baz;
3564 au^to T = ba^z<X<int>>;
3569 auto AST = TU.build();
3570 for (
const auto &P :
T.points()) {
3571 auto H =
getHover(
AST, P, format::getLLVMStyle(),
nullptr);
3573 EXPECT_EQ(H->Documentation,
"doc");
3580 template<typename T> T foo(T);
3582 // Setter variable heuristic might fail if the callexpr is broken.
3583 struct X { int Y; void [[^setY]](float) { Y = foo(undefined); } };)cpp");
3586 auto AST = TU.build();
3587 for (
const auto &P :
T.points())
3588 getHover(
AST, P, format::getLLVMStyle(),
nullptr);
3593 constexpr unsigned long value = -1; // wrap around
3594 void foo() { va^lue; }
3597 getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
3602 constexpr __int128_t value = -4;
3603 void foo() { va^lue; }
3607 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
3608 auto AST = TU.build();
3609 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
3611 EXPECT_EQ(H->Value,
"-4 (0xfffffffc)");
3617 template <typename T> class $doc1^X {};
3619 template <> class $doc2^X<int> {};
3621 template <typename T> class $doc3^X<T*> {};
3629 auto AST = TU.build();
3630 for (
const auto *Comment : {
"doc1",
"doc2",
"doc3"}) {
3631 for (
const auto &P :
T.points(Comment)) {
3632 auto H =
getHover(
AST, P, format::getLLVMStyle(),
nullptr);
3634 EXPECT_EQ(H->Documentation, Comment);
3641 const std::function<void(
HoverInfo &)> Builder;
3642 llvm::StringRef ExpectedMarkdownRender;
3643 llvm::StringRef ExpectedDoxygenRender;
3647 HI.Kind = index::SymbolKind::Unknown;
3655 HI.Kind = index::SymbolKind::NamespaceAlias;
3658 R
"(namespace-alias foo)",
3659 R"(### namespace-alias `foo`)",
3663 HI.Kind = index::SymbolKind::Class;
3665 HI.TemplateParameters = {
3666 {{"typename"}, std::string(
"T"), std::nullopt},
3667 {{
"typename"}, std::string(
"C"), std::string(
"bool")},
3669 HI.Documentation =
"documentation";
3671 "template <typename T, typename C = bool> class Foo {}";
3673 HI.NamespaceScope.emplace();
3681template <typename T, typename C = bool> class Foo {})",
3686template <typename T, typename C = bool> class Foo {}
3695### Template Parameters
3698- `typename C = bool`
3705 HI.Kind = index::SymbolKind::Function;
3707 HI.Type = {
"type",
"c_type"};
3708 HI.ReturnType = {
"ret_type",
"can_ret_type"};
3709 HI.Parameters.emplace();
3711 HI.Parameters->push_back(P);
3712 P.Type = {
"type",
"can_type"};
3713 HI.Parameters->push_back(P);
3715 HI.Parameters->push_back(P);
3716 P.Default =
"default";
3717 HI.Parameters->push_back(P);
3718 HI.NamespaceScope =
"ns::";
3719 HI.Definition =
"ret_type foo(params) {}";
3723 "→ ret_type (aka can_ret_type)\n\n"
3726 "- type (aka can_type)\n"
3727 "- type foo (aka can_type)\n"
3728 "- type foo = default (aka can_type)\n"
3730 "// In namespace ns\n"
3731 "ret_type foo(params) {}",
3737ret_type foo(params) {}
3744- `type (aka can_type)`
3745- `type foo (aka can_type)`
3746- `type foo = default (aka can_type)`
3751`ret_type (aka can_ret_type)`)",
3755 HI.Kind = index::SymbolKind::Field;
3756 HI.LocalScope = "test::Bar::";
3759 HI.Type = {
"type",
"can_type"};
3760 HI.Definition =
"def";
3768Type: type (aka can_type)
3774Size: 4 bytes (+4 bytes padding), alignment 4 bytes
3787Type: `type (aka can_type)`
3793Size: 4 bytes (+4 bytes padding), alignment 4 bytes)",
3797 HI.Kind = index::SymbolKind::Field;
3798 HI.LocalScope = "test::Bar::";
3801 HI.Type = {
"type",
"can_type"};
3802 HI.Definition =
"def";
3810Type: type (aka can_type)
3814Offset: 4 bytes and 3 bits
3816Size: 25 bits (+4 bits padding), alignment 8 bytes
3829Type: `type (aka can_type)`
3833Offset: 4 bytes and 3 bits
3835Size: 25 bits (+4 bits padding), alignment 8 bytes)",
3839 HI.Kind = index::SymbolKind::Field;
3840 HI.AccessSpecifier = "public";
3842 HI.LocalScope =
"test::Bar::";
3843 HI.Definition =
"def";
3859 HI.Definition = "size_t method()";
3860 HI.AccessSpecifier =
"protected";
3861 HI.Kind = index::SymbolKind::InstanceMethod;
3862 HI.NamespaceScope =
"";
3863 HI.LocalScope =
"cls<int>::";
3865 HI.Parameters.emplace();
3866 HI.ReturnType = {
"size_t",
"unsigned long"};
3867 HI.Type = {
"size_t ()",
"unsigned long ()"};
3869 R
"(instance-method method
3871→ size_t (aka unsigned long)
3874protected: size_t method())",
3875 R"(### instance-method
3880protected: size_t method()
3886`size_t (aka unsigned long)`)",
3890 HI.Definition = "cls(int a, int b = 5)";
3891 HI.AccessSpecifier =
"public";
3892 HI.Kind = index::SymbolKind::Constructor;
3893 HI.NamespaceScope =
"";
3894 HI.LocalScope =
"cls";
3896 HI.Parameters.emplace();
3897 HI.Parameters->emplace_back();
3898 HI.Parameters->back().Type =
"int";
3899 HI.Parameters->back().Name =
"a";
3900 HI.Parameters->emplace_back();
3901 HI.Parameters->back().Type =
"int";
3902 HI.Parameters->back().Name =
"b";
3903 HI.Parameters->back().Default =
"5";
3913public: cls(int a, int b = 5))",
3919public: cls(int a, int b = 5)
3930 HI.Kind = index::SymbolKind::Union;
3931 HI.AccessSpecifier = "private";
3933 HI.NamespaceScope =
"ns1::";
3934 HI.Definition =
"union foo {}";
3939private: union foo {})",
3945private: union foo {}
3950 HI.Kind = index::SymbolKind::Variable;
3952 HI.Definition =
"int foo = 3";
3953 HI.LocalScope =
"test::Bar::";
3956 HI.CalleeArgInfo.emplace();
3957 HI.CalleeArgInfo->Name =
"arg_a";
3958 HI.CalleeArgInfo->Type =
"int";
3959 HI.CalleeArgInfo->Default =
"7";
3989 HI.Kind = index::SymbolKind::Variable;
3991 HI.CalleeArgInfo.emplace();
3992 HI.CalleeArgInfo->Type =
"int";
3998 R"(### variable `foo`
4005 HI.Kind = index::SymbolKind::Variable;
4007 HI.Definition =
"int foo = 3";
4008 HI.LocalScope =
"test::Bar::";
4011 HI.CalleeArgInfo.emplace();
4012 HI.CalleeArgInfo->Name =
"arg_a";
4013 HI.CalleeArgInfo->Type =
"int";
4014 HI.CalleeArgInfo->Default =
"7";
4023Passed by reference as arg_a
4040Passed by reference as arg_a)",
4044 HI.Kind = index::SymbolKind::Variable;
4046 HI.Definition =
"int foo = 3";
4047 HI.LocalScope =
"test::Bar::";
4050 HI.CalleeArgInfo.emplace();
4051 HI.CalleeArgInfo->Name =
"arg_a";
4052 HI.CalleeArgInfo->Type = {
"alias_int",
"int"};
4053 HI.CalleeArgInfo->Default =
"7";
4062Passed as arg_a (converted to alias_int)
4079Passed as arg_a (converted to alias_int))",
4083 HI.Kind = index::SymbolKind::Macro;
4084 HI.Name = "PLUS_ONE";
4085 HI.Definition =
"#define PLUS_ONE(X) (X+1)\n\n"
4091#define PLUS_ONE(X) (X+1)
4099#define PLUS_ONE(X) (X+1)
4107 HI.Kind = index::SymbolKind::Variable;
4109 HI.Definition =
"int foo = 3";
4110 HI.LocalScope =
"test::Bar::";
4113 HI.CalleeArgInfo.emplace();
4114 HI.CalleeArgInfo->Name =
"arg_a";
4115 HI.CalleeArgInfo->Type =
"int";
4116 HI.CalleeArgInfo->Default =
"7";
4125Passed by const reference as arg_a (converted to int)
4142Passed by const reference as arg_a (converted to int))",
4146 HI.Name = "stdio.h";
4147 HI.Definition =
"/usr/include/stdio.h";
4148 HI.Kind = index::SymbolKind::IncludeDirective;
4152/usr/include/stdio.h)",
4155`/usr/include/stdio.h`)",
4160 HI.UsedSymbolNames = {
"Foo",
"Bar",
"Bar"};
4161 HI.Kind = index::SymbolKind::IncludeDirective;
4165provides Foo, Bar, Bar)",
4169provides `Foo`, `Bar`, `Bar`)",
4173 HI.UsedSymbolNames = {
"Foo",
"Bar",
"Baz",
"Foobar",
"Qux",
"Quux"};
4174 HI.Kind = index::SymbolKind::IncludeDirective;
4178provides Foo, Bar, Baz, Foobar, Qux and 1 more)",
4182provides `Foo`, `Bar`, `Baz`, `Foobar`, `Qux` and 1 more)"}};
4184 for (
const auto &C : Cases) {
4193 for (
const auto &C : Cases) {
4206 const std::function<void(
HoverInfo &)> Builder;
4207 llvm::StringRef ExpectedMarkdownRender;
4208 llvm::StringRef ExpectedDoxygenRender;
4211 HI.Kind = index::SymbolKind::Function;
4212 HI.Documentation =
"@brief brief doc\n\n"
4214 HI.Definition =
"void foo()";
4217 R
"(### function `foo`
4245 HI.Kind = index::SymbolKind::Function;
4246 HI.Documentation = "@brief brief doc\n\n"
4248 HI.Definition =
"int foo()";
4249 HI.ReturnType =
"int";
4252 R
"(### function `foo`
4287 HI.Kind = index::SymbolKind::Function;
4288 HI.Documentation = R"(@brief brief doc
4293As you see, notes are "inlined".
4294@warning this is a warning
4297@param a this is a param
4298@return it returns something
4299@retval 0 if successful
4300@retval 1 if failed)";
4301 HI.Definition = "int foo(int a)";
4302 HI.ReturnType =
"int";
4304 HI.Parameters.emplace();
4305 HI.Parameters->emplace_back();
4306 HI.Parameters->back().Type =
"int";
4307 HI.Parameters->back().Name =
"a";
4309 R
"(### function `foo`
4323As you see, notes are "inlined".
4324@warning this is a warning
4327@param a this is a param
4328@return it returns something
4329@retval 0 if successful
4351- `int a` - this is a param
4356`int` - it returns something
4358- `0` - if successful
4369As you see, notes are "inlined".
4374As well as warnings)"},
4376 HI.Kind = index::SymbolKind::Function;
4377 HI.Documentation = "@brief brief doc\n\n"
4378 "longer doc\n@param a this is a param\n@param b "
4379 "does not exist\n@return it returns something";
4380 HI.Definition =
"int foo(int a)";
4381 HI.ReturnType =
"int";
4383 HI.Parameters.emplace();
4384 HI.Parameters->emplace_back();
4385 HI.Parameters->back().Type =
"int";
4386 HI.Parameters->back().Name =
"a";
4388 R
"(### function `foo`
4400@param a this is a param
4401@param b does not exist
4402@return it returns something
4423- `int a` - this is a param
4428`int` - it returns something
4436 for (
const auto &C : Cases) {
4445 for (
const auto &C : Cases) {
4458 llvm::StringRef Documentation;
4459 llvm::StringRef ExpectedRenderEscapedMarkdown;
4460 llvm::StringRef ExpectedRenderMarkdown;
4461 llvm::StringRef ExpectedRenderPlainText;
4571 "Tests primality of `p`.",
4572 "Tests primality of `p`.",
4573 "Tests primality of `p`.",
4574 "Tests primality of `p`.",
4577 "'`' should not occur in `Code`",
4578 "'\\`' should not occur in `Code`",
4579 "'`' should not occur in `Code`",
4580 "'`' should not occur in `Code`",
4584 "\\`not\nparsed\\`",
4589 R
"(@brief this is a typical use case
4593 R"(@brief this is a typical use case
4597 R"(@brief this is a typical use case
4601 R"(@brief this is a typical use case
4607 for (
const auto &C : Cases) {
4608 markup::Document Output;
4611 EXPECT_EQ(Output.asEscapedMarkdown(),
C.ExpectedRenderEscapedMarkdown);
4612 EXPECT_EQ(Output.asMarkdown(),
C.ExpectedRenderMarkdown);
4613 EXPECT_EQ(Output.asPlainText(),
C.ExpectedRenderPlainText);
4621 HI.
Kind = index::SymbolKind::Variable;
4631 HI.
Kind = index::SymbolKind::Variable;
4634 HI.Definition =
"def";
4636 llvm::StringRef ExpectedMarkdown =
4637 "### variable `foo`\n"
4648 llvm::StringRef ExpectedDoxygenMarkdown =
4663 llvm::StringRef ExpectedPlaintext = R
"pt(variable foo
4674 struct strong_ordering {
4676 constexpr operator int() const { return n; }
4677 static const strong_ordering equal, greater, less;
4679 constexpr strong_ordering strong_ordering::equal = {0};
4680 constexpr strong_ordering strong_ordering::greater = {1};
4681 constexpr strong_ordering strong_ordering::less = {-1};
4684 template <typename T>
4687 friend auto operator<=>(S, S) = default;
4689 static_assert(S<void>() =^= S<void>());
4693 TU.ExtraArgs.push_back("-std=c++20");
4694 auto AST = TU.build();
4695 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4696 EXPECT_EQ(HI->Documentation,
"");
4703 auto baz = (Fo^o*)&bar;
4707 auto AST = TU.build();
4708 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4710 EXPECT_EQ(*HI->Value,
"&bar");
4713TEST(
Hover, FunctionParameterDefaulValueNotEvaluatedOnInvalidDecls) {
4715 const char *
const Code;
4716 const std::optional<std::string> HoverValue;
4719 // error-ok testing behavior on invalid decl
4721 void foo(Foo p^aram = nullptr);
4726 void foo(Foo *p^aram = nullptr);
4731 for (
const auto &C : Cases) {
4734 auto AST = TU.build();
4735 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4737 ASSERT_EQ(HI->Value,
C.HoverValue);
4752 TU.ExtraArgs.push_back(
"-std=c++17");
4753 auto AST = TU.build();
4754 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4762 #define A(x) x, x, x, x
4763 #define B(x) A(A(A(A(x))))
4764 int a^rr[] = {B(0)};
4768 auto AST = TU.build();
4769 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4772 EXPECT_EQ(H->Definition,
"int arr[]");
4775#if defined(__aarch64__)
4777#define PREDEFINEMACROS_TEST(x) DISABLED_##x
4779#define PREDEFINEMACROS_TEST(x) x
4784 using uintptr_t = __UINTPTR_TYPE__;
4785 enum Test : uintptr_t {};
4786 unsigned global_var;
4788 Test v^al = static_cast<Test>(reinterpret_cast<uintptr_t>(&global_var));
4793 TU.PredefineMacros = true;
4794 auto AST = TU.build();
4795 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4797 EXPECT_EQ(*HI->Value,
"&global_var");
4802 using uintptr_t = __UINTPTR_TYPE__;
4803 unsigned global_var;
4805 uintptr_t a^ddress = reinterpret_cast<uintptr_t>(&global_var);
4810 TU.PredefineMacros = true;
4811 auto AST = TU.build();
4812 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4814 EXPECT_EQ(*HI->Value,
"&global_var");
4819 template <bool X, typename T, typename F>
4820 struct cond { using type = T; };
4821 template <typename T, typename F>
4822 struct cond<false, T, F> { using type = F; };
4824 template <bool X, typename T, typename F>
4825 using type = typename cond<X, T, F>::type;
4828 using f^oo = type<true, int, double>;
4833 auto AST = TU.build();
4834 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4836 ASSERT_TRUE(H && H->Type);
4837 EXPECT_EQ(H->Type->Type,
"int");
4838 EXPECT_EQ(H->Definition,
"using foo = type<true, int, double>");
4842 llvm::StringRef PredefinedCXX = R
"cpp(
4844#define SizeOf sizeof
4845#define AlignOf alignof
4849using u64 = unsigned long long;
4850// calculate (a ** b) % p
4851constexpr u64 pow_with_mod(u64 a, u64 b, u64 p) {
4855 ret = (ret * a) % p;
4861#define last_n_digit(x, y, n) \
4862 pow_with_mod(x, y, pow_with_mod(10, n, 2147483647))
4863#define declare_struct(X, name, value) \
4865 constexpr auto name() { return value; } \
4867#define gnu_statement_expression(value) \
4869 declare_struct(Widget, getter, value); \
4870 Widget().getter(); \
4872#define define_lambda_begin(lambda, ...) \
4874#define define_lambda_end() }
4876#define left_bracket [
4877#define right_bracket ]
4878#define dg_left_bracket <:
4879#define dg_right_bracket :>
4880#define array_decl(type, name, size) type name left_bracket size right_bracket
4884 llvm::StringRef Code;
4885 const std::function<void(std::optional<HoverInfo>,
size_t )>
4893 [](std::optional<HoverInfo> HI, size_t) {
4894 EXPECT_EQ(HI->Value,
"42 (0x2a)");
4903 [](std::optional<HoverInfo> HI, size_t) {
4904 EXPECT_TRUE(HI->Value);
4905 EXPECT_TRUE(HI->Type);
4920 [](std::optional<HoverInfo> HI, size_t) {
4921 EXPECT_TRUE(HI->Value);
4922 EXPECT_TRUE(HI->Type);
4927 // 2**32 == 4294967296
4928 last_n_di^git(2, 32, 6);
4931 [](std::optional<HoverInfo> HI, size_t) {
4932 EXPECT_EQ(HI->Value,
"967296 (0xec280)");
4933 EXPECT_EQ(HI->Type,
"u64");
4938 gnu_statement_exp^ression(42);
4941 [](std::optional<HoverInfo> HI, size_t) {
4942 EXPECT_EQ(HI->Value,
"42 (0x2a)");
4943 EXPECT_EQ(HI->Type,
"int");
4951 [](std::optional<HoverInfo> HI, size_t) {
4952 EXPECT_EQ(HI->Value,
"2");
4953 EXPECT_EQ(HI->Type,
"int");
4961 [](std::optional<HoverInfo> HI, size_t) {
4962 EXPECT_FALSE(HI->Value) << HI->Value;
4963 EXPECT_FALSE(HI->Type) << HI->Type;
4971 [](std::optional<HoverInfo> HI, size_t) {
4972 EXPECT_EQ(HI->Value,
"2");
4973 EXPECT_EQ(HI->Type,
"int");
4978 arra^y_decl(int, vector, 10);
4979 vector left_b^racket 3 right_b^racket;
4980 vector dg_le^ft_bracket 3 dg_righ^t_bracket;
4983 [](std::optional<HoverInfo> HI,
size_t Id) {
4992 EXPECT_FALSE(HI->Type) << HI->Type;
4993 EXPECT_FALSE(HI->Value) << HI->Value;
4996 ASSERT_TRUE(
false) <<
"Unhandled id: " << Id;
5002 constexpr auto value = define_lamb^da_begin(lambda, int, char)
5003 // Check if the expansion range is right.
5004 return ^last_n_digit(10, 3, 3)^;
5005 define_lam^bda_end();
5008 [](std::optional<HoverInfo> HI,
size_t Id) {
5011 EXPECT_FALSE(HI->Value);
5015 EXPECT_EQ(HI->Value,
"0");
5022 EXPECT_FALSE(HI->Type) << HI->Type;
5023 EXPECT_FALSE(HI->Value) << HI->Value;
5026 ASSERT_TRUE(
false) <<
"Unhandled id: " << Id;
5035 for (
const auto &C : Cases) {
5037 (PredefinedCXX +
"void function() {\n" +
C.Code +
"}\n").str());
5039 TU.ExtraArgs.push_back(
"-std=c++17");
5040 auto AST = TU.build();
5041 for (
auto [Index,
Position] : llvm::enumerate(Code.points())) {
5048 #define alignof _Alignof
5050 al^ignof(struct { int x; char y[10]; });
5055 TU.Filename =
"TestTU.c";
5059 auto AST = TU.build();
5060 auto H =
getHover(
AST,
C.point(), format::getLLVMStyle(),
nullptr);
5063 EXPECT_TRUE(H->Value);
5064 EXPECT_TRUE(H->Type);
5068 const char *
const Code =
5070 #define C(A) A##A // Concatenate
5071 #define E(A) C(A) // Expand
5072 #define Z0032 00000000000000000000000000000000
5073 #define Z0064 E(Z0032)
5074 #define Z0128 E(Z0064)
5075 #define Z0256 E(Z0128)
5076 #define Z0512 E(Z0256)
5077 #define Z1024 E(Z0512)
5078 #define Z2048 E(Z1024)
5079 #define Z4096 E(Z2048) // 4096 zeroes
5080 int main() { return [[^Z4096]]; }
5084 uint32_t MacroContentsLimit;
5085 const std::string ExpectedDefinition;
5088 {2048,
"#define Z4096 E(Z2048)"},
5090 {8192, std::string(
"#define Z4096 E(Z2048)\n\n") +
5091 std::string(
"// Expands to\n") + std::string(4096,
'0')},
5093 for (
const auto &Case : Cases) {
5098 auto AST = TU.build();
5102 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
5105 EXPECT_EQ(H->Definition, Case.ExpectedDefinition);
5111 const char *
const Code;
5112 const std::function<void(
HoverInfo &)> ExpectedBuilder;
5113 std::string ExpectedRender;
5115 {R
"cpp(/// Function doc
5116 void foo(int [[^a]]);
5120 HI.Kind = index::SymbolKind::Parameter;
5121 HI.NamespaceScope =
"";
5122 HI.LocalScope =
"foo::";
5124 HI.Definition =
"int a";
5125 HI.Documentation =
"";
5127 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nType: `int`"},
5128 {R
"cpp(/// Function doc
5130 void foo(int [[^a]]);
5134 HI.Kind = index::SymbolKind::Parameter;
5135 HI.NamespaceScope =
"";
5136 HI.LocalScope =
"foo::";
5138 HI.Definition =
"int a";
5139 HI.Documentation =
"this is doc for a";
5141 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nthis is doc "
5142 "for a\n\n---\nType: `int`"},
5143 {R
"cpp(/// Function doc
5145 void foo(int [[^a]], int b);
5149 HI.Kind = index::SymbolKind::Parameter;
5150 HI.NamespaceScope =
"";
5151 HI.LocalScope =
"foo::";
5153 HI.Definition =
"int a";
5154 HI.Documentation =
"";
5156 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nType: `int`"},
5157 {R
"cpp(/// Function doc
5159 void foo(int a, int [[^b]]);
5163 HI.Kind = index::SymbolKind::Parameter;
5164 HI.NamespaceScope =
"";
5165 HI.LocalScope =
"foo::";
5167 HI.Definition =
"int b";
5168 HI.Documentation =
"this is doc for \\p b";
5170 "### param\n\n---\n```cpp\n// In foo\nint b\n```\n\n---\nthis is doc "
5171 "for `b`\n\n---\nType: `int`"},
5172 {R
"cpp(/// Function doc
5174 template <typename T>
5175 void foo(T a, T [[^b]]);
5179 HI.Kind = index::SymbolKind::Parameter;
5180 HI.NamespaceScope =
"";
5181 HI.LocalScope =
"foo::";
5183 HI.Definition =
"T b";
5184 HI.Documentation =
"this is doc for \\p b";
5186 "### param\n\n---\n```cpp\n// In foo\nT b\n```\n\n---\nthis is doc for "
5187 "`b`\n\n---\nType: `T`"},
5188 {R
"cpp(/// Function doc
5190 void foo(int a, int [[^b]]);
5194 HI.Kind = index::SymbolKind::Parameter;
5195 HI.NamespaceScope =
"";
5196 HI.LocalScope =
"foo::";
5198 HI.Definition =
"int b";
5200 "this is <b>doc</b> <html-tag attribute/> <another-html-tag "
5201 "attribute=\"value\">for</another-html-tag> \\p b";
5203 "### param\n\n---\n```cpp\n// In foo\nint b\n```\n\n---\nthis is "
5204 "\\<b>doc\\</b> \\<html-tag attribute/> \\<another-html-tag "
5205 "attribute=\"value\">for\\</another-html-tag> `b`\n\n---\nType: `int`"},
5210 IndexSym.Documentation =
"comment from index";
5216 for (
const auto &Case : Cases) {
5217 SCOPED_TRACE(Case.Code);
5221 auto AST = TU.build();
5226 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(), Index.get());
5230 Case.ExpectedBuilder(Expected);
5233 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
5234 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
5235 EXPECT_EQ(H->Name, Expected.Name);
5236 EXPECT_EQ(H->Kind, Expected.Kind);
5237 EXPECT_EQ(H->Documentation, Expected.Documentation);
5238 EXPECT_EQ(H->Definition, Expected.Definition);
5239 EXPECT_EQ(H->Type, Expected.Type);
5240 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
5241 EXPECT_EQ(H->Parameters, Expected.Parameters);
5242 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
5243 EXPECT_EQ(H->SymRange, Expected.SymRange);
5244 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)