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 const char *
const Code;
1786 const std::function<void(
HoverInfo &)> ExpectedBuilder;
1788 {
"auto x = [['^A']]; // character literal",
1790 HI.Name =
"expression";
1792 HI.Value =
"65 (0x41)";
1794 {
"auto s = ^[[\"Hello, world!\"]]; // string literal",
1796 HI.Name =
"string-literal";
1798 HI.Type =
"const char[14]";
1801 R
"cpp(// Local variable
1805 int test1 = bonjour;
1809 HI.Name = "bonjour";
1810 HI.Kind = index::SymbolKind::Variable;
1811 HI.NamespaceScope =
"";
1812 HI.LocalScope =
"main::";
1814 HI.Definition =
"int bonjour";
1817 R
"cpp(// Local variable in method
1826 HI.Name = "bonjour";
1827 HI.Kind = index::SymbolKind::Variable;
1828 HI.NamespaceScope =
"";
1829 HI.LocalScope =
"s::method::";
1831 HI.Definition =
"int bonjour";
1839 ns1::[[My^Class]]* Params;
1843 HI.Name = "MyClass";
1844 HI.Kind = index::SymbolKind::Struct;
1845 HI.NamespaceScope =
"ns1::";
1846 HI.Definition =
"struct MyClass {}";
1854 ns1::[[My^Class]]* Params;
1858 HI.Name = "MyClass";
1859 HI.Kind = index::SymbolKind::Class;
1860 HI.NamespaceScope =
"ns1::";
1861 HI.Definition =
"class MyClass {}";
1866 union MyUnion { int x; int y; };
1869 ns1::[[My^Union]] Params;
1873 HI.Name = "MyUnion";
1874 HI.Kind = index::SymbolKind::Union;
1875 HI.NamespaceScope =
"ns1::";
1876 HI.Definition =
"union MyUnion {}";
1879 R
"cpp(// Function definition via pointer
1882 auto *X = &^[[foo]];
1887 HI.Kind = index::SymbolKind::Function;
1888 HI.NamespaceScope =
"";
1889 HI.Type =
"void (int)";
1890 HI.Definition =
"void foo(int)";
1891 HI.Documentation =
"Function definition via pointer";
1892 HI.ReturnType =
"void";
1894 {{
"int"}, std::nullopt, std::nullopt},
1898 R
"cpp(// Function declaration via call
1901 return ^[[foo]](42);
1906 HI.Kind = index::SymbolKind::Function;
1907 HI.NamespaceScope =
"";
1908 HI.Type =
"int (int)";
1909 HI.Definition =
"int foo(int)";
1910 HI.Documentation =
"Function declaration via call";
1911 HI.ReturnType =
"int";
1913 {{
"int"}, std::nullopt, std::nullopt},
1918 struct Foo { int x; };
1926 HI.Kind = index::SymbolKind::Field;
1927 HI.NamespaceScope =
"";
1928 HI.LocalScope =
"Foo::";
1930 HI.Definition =
"int x";
1933 R
"cpp(// Field with initialization
1934 struct Foo { int x = 5; };
1942 HI.Kind = index::SymbolKind::Field;
1943 HI.NamespaceScope =
"";
1944 HI.LocalScope =
"Foo::";
1946 HI.Definition =
"int x = 5";
1949 R
"cpp(// Static field
1950 struct Foo { static int x; };
1957 HI.Kind = index::SymbolKind::StaticProperty;
1958 HI.NamespaceScope =
"";
1959 HI.LocalScope =
"Foo::";
1961 HI.Definition =
"static int x";
1964 R
"cpp(// Field, member initializer
1967 Foo() : ^[[x]](0) {}
1972 HI.Kind = index::SymbolKind::Field;
1973 HI.NamespaceScope =
"";
1974 HI.LocalScope =
"Foo::";
1976 HI.Definition =
"int x";
1979 R
"cpp(// Field, GNU old-style field designator
1980 struct Foo { int x; };
1982 Foo bar = { ^[[x]] : 1 };
1987 HI.Kind = index::SymbolKind::Field;
1988 HI.NamespaceScope =
"";
1989 HI.LocalScope =
"Foo::";
1991 HI.Definition =
"int x";
1996 R
"cpp(// Field, field designator
1997 struct Foo { int x; int y; };
1999 Foo bar = { .^[[x]] = 2, .y = 2 };
2004 HI.Kind = index::SymbolKind::Field;
2005 HI.NamespaceScope =
"";
2006 HI.LocalScope =
"Foo::";
2008 HI.Definition =
"int x";
2011 R
"cpp(// Method call
2012 struct Foo { int x(); };
2020 HI.Kind = index::SymbolKind::InstanceMethod;
2021 HI.NamespaceScope =
"";
2022 HI.LocalScope =
"Foo::";
2024 HI.Definition =
"int x()";
2025 HI.ReturnType =
"int";
2026 HI.Parameters = std::vector<HoverInfo::Param>{};
2029 R
"cpp(// Static method call
2030 struct Foo { static int x(); };
2037 HI.Kind = index::SymbolKind::StaticMethod;
2038 HI.NamespaceScope =
"";
2039 HI.LocalScope =
"Foo::";
2041 HI.Definition =
"static int x()";
2042 HI.ReturnType =
"int";
2043 HI.Parameters = std::vector<HoverInfo::Param>{};
2054 HI.Kind = index::SymbolKind::TypeAlias;
2055 HI.NamespaceScope =
"";
2056 HI.Definition =
"typedef int Foo";
2058 HI.Documentation =
"Typedef";
2061 R
"cpp(// Typedef with embedded definition
2062 typedef struct Bar {} Foo;
2069 HI.Kind = index::SymbolKind::TypeAlias;
2070 HI.NamespaceScope =
"";
2071 HI.Definition =
"typedef struct Bar Foo";
2072 HI.Type =
"struct Bar";
2073 HI.Documentation =
"Typedef with embedded definition";
2078 struct Foo { static void bar(); };
2080 int main() { ^[[ns]]::Foo::bar(); }
2084 HI.Kind = index::SymbolKind::Namespace;
2085 HI.NamespaceScope =
"";
2086 HI.Definition =
"namespace ns {}";
2089 R
"cpp(// Anonymous namespace
2093 } // anonymous namespace
2095 int main() { ns::[[f^oo]]++; }
2099 HI.Kind = index::SymbolKind::Variable;
2100 HI.NamespaceScope =
"ns::";
2102 HI.Definition =
"int foo";
2105 R
"cpp(// Function definition via using declaration
2116 HI.Kind = index::SymbolKind::Function;
2117 HI.NamespaceScope =
"ns::";
2118 HI.Type =
"void ()";
2119 HI.Definition =
"void foo()";
2120 HI.Documentation =
"";
2121 HI.ReturnType =
"void";
2122 HI.Parameters = std::vector<HoverInfo::Param>{};
2125 R
"cpp( // using declaration and two possible function declarations
2126 namespace ns { void foo(int); void foo(char); }
2128 template <typename T> void bar() { [[f^oo]](T{}); }
2132 HI.Kind = index::SymbolKind::Using;
2133 HI.NamespaceScope =
"";
2134 HI.Definition =
"using ns::foo";
2139 int main() { return ^[[MACRO]]; }
2145 HI.Kind = index::SymbolKind::Macro;
2146 HI.Definition =
"#define MACRO 0\n\n"
2153 #define MACRO2 ^[[MACRO]]
2157 HI.Kind = index::SymbolKind::Macro;
2158 HI.Definition =
"#define MACRO 0";
2167 int main() ^[[MACRO]]
2171 HI.Kind = index::SymbolKind::Macro;
2173 R
"cpp(#define MACRO \
2184 R"cpp(// Forward class declaration
2191 HI.Kind = index::SymbolKind::Class;
2192 HI.NamespaceScope =
"";
2193 HI.Definition =
"class Foo {}";
2194 HI.Documentation =
"Forward class declaration";
2197 R
"cpp(// Function declaration
2199 void g() { [[f^oo]](); }
2204 HI.Kind = index::SymbolKind::Function;
2205 HI.NamespaceScope =
"";
2206 HI.Type =
"void ()";
2207 HI.Definition =
"void foo()";
2208 HI.Documentation =
"Function declaration";
2209 HI.ReturnType =
"void";
2210 HI.Parameters = std::vector<HoverInfo::Param>{};
2213 R
"cpp(// Enum declaration
2218 [[Hel^lo]] hello = ONE;
2223 HI.Kind = index::SymbolKind::Enum;
2224 HI.NamespaceScope =
"";
2225 HI.Definition =
"enum Hello {}";
2226 HI.Documentation =
"Enum declaration";
2234 Hello hello = [[O^NE]];
2239 HI.Kind = index::SymbolKind::EnumConstant;
2240 HI.NamespaceScope =
"";
2241 HI.LocalScope =
"Hello::";
2242 HI.Type =
"enum Hello";
2243 HI.Definition =
"ONE";
2247 R
"cpp(// C++20's using enum
2253 Hello hello = [[O^NE]];
2258 HI.Kind = index::SymbolKind::EnumConstant;
2259 HI.NamespaceScope =
"";
2260 HI.LocalScope =
"Hello::";
2261 HI.Type =
"enum Hello";
2262 HI.Definition =
"ONE";
2266 R
"cpp(// Enumerator in anonymous enum
2271 int hello = [[O^NE]];
2276 HI.Kind = index::SymbolKind::EnumConstant;
2277 HI.NamespaceScope =
"";
2280 HI.Type =
"enum (unnamed)";
2281 HI.Definition =
"ONE";
2285 R
"cpp(// Global variable
2286 static int hey = 10;
2293 HI.Kind = index::SymbolKind::Variable;
2294 HI.NamespaceScope =
"";
2296 HI.Definition =
"static int hey = 10";
2297 HI.Documentation =
"Global variable";
2299 HI.Value =
"10 (0xa)";
2302 R
"cpp(// Global variable in namespace
2304 static long long hey = -36637162602497;
2312 HI.Kind = index::SymbolKind::Variable;
2313 HI.NamespaceScope =
"ns1::";
2314 HI.Type =
"long long";
2315 HI.Definition =
"static long long hey = -36637162602497";
2316 HI.Value =
"-36637162602497 (0xffffdeadbeefffff)";
2319 R
"cpp(// Field in anonymous struct
2329 HI.Kind = index::SymbolKind::Field;
2330 HI.NamespaceScope =
"";
2331 HI.LocalScope =
"(anonymous struct)::";
2333 HI.Definition =
"int hello";
2336 R
"cpp(// Templated function
2337 template <typename T>
2341 void g() { auto x = [[f^oo]]<int>(); }
2345 HI.Kind = index::SymbolKind::Function;
2346 HI.NamespaceScope =
"";
2348 HI.Definition =
"template <> int foo<int>()";
2349 HI.Documentation =
"Templated function";
2350 HI.ReturnType =
"int";
2351 HI.Parameters = std::vector<HoverInfo::Param>{};
2356 R
"cpp(// Anonymous union
2362 void g() { struct outer o; o.v.[[d^ef]]++; }
2366 HI.Kind = index::SymbolKind::Field;
2367 HI.NamespaceScope =
"";
2368 HI.LocalScope =
"outer::(anonymous union)::";
2370 HI.Definition =
"int def";
2373 R
"cpp(// documentation from index
2374 int nextSymbolIsAForwardDeclFromIndexWithNoLocalDocs;
2376 void g() { [[ind^exSymbol]](); }
2379 HI.Name = "indexSymbol";
2380 HI.Kind = index::SymbolKind::Function;
2381 HI.NamespaceScope =
"";
2382 HI.Type =
"void ()";
2383 HI.Definition =
"void indexSymbol()";
2384 HI.ReturnType =
"void";
2385 HI.Parameters = std::vector<HoverInfo::Param>{};
2386 HI.Documentation =
"comment from index";
2389 R
"cpp(// Simple initialization with auto
2396 HI.Kind = index::SymbolKind::TypeAlias;
2397 HI.Definition =
"int";
2400 R
"cpp(// Simple initialization with const auto
2402 const ^[[auto]] i = 1;
2407 HI.Kind = index::SymbolKind::TypeAlias;
2408 HI.Definition =
"int";
2411 R
"cpp(// Simple initialization with const auto&
2413 const ^[[auto]]& i = 1;
2418 HI.Kind = index::SymbolKind::TypeAlias;
2419 HI.Definition =
"int";
2422 R
"cpp(// Simple initialization with auto&
2430 HI.Kind = index::SymbolKind::TypeAlias;
2431 HI.Definition =
"int";
2434 R
"cpp(// Simple initialization with auto*
2442 HI.Kind = index::SymbolKind::TypeAlias;
2443 HI.Definition =
"int";
2446 R
"cpp(// Simple initialization with auto from pointer
2454 HI.Kind = index::SymbolKind::TypeAlias;
2455 HI.Definition =
"int *";
2458 R
"cpp(// Auto with initializer list.
2462 class initializer_list { const _E *a, *b; };
2465 ^[[auto]] i = {1,2};
2470 HI.Kind = index::SymbolKind::TypeAlias;
2471 HI.Definition =
"std::initializer_list<int>";
2474 R
"cpp(// User defined conversion to auto
2476 operator ^[[auto]]() const { return 10; }
2481 HI.Kind = index::SymbolKind::TypeAlias;
2482 HI.Definition =
"int";
2485 R
"cpp(// Simple initialization with decltype(auto)
2487 ^[[decltype]](auto) i = 1;
2491 HI.Name = "decltype";
2492 HI.Kind = index::SymbolKind::TypeAlias;
2493 HI.Definition =
"int";
2496 R
"cpp(// Simple initialization with const decltype(auto)
2499 ^[[decltype]](auto) i = j;
2503 HI.Name = "decltype";
2504 HI.Kind = index::SymbolKind::TypeAlias;
2505 HI.Definition =
"const int";
2508 R
"cpp(// Simple initialization with const& decltype(auto)
2512 ^[[decltype]](auto) i = j;
2516 HI.Name = "decltype";
2517 HI.Kind = index::SymbolKind::TypeAlias;
2518 HI.Definition =
"const int &";
2521 R
"cpp(// Simple initialization with & decltype(auto)
2525 ^[[decltype]](auto) i = j;
2529 HI.Name = "decltype";
2530 HI.Kind = index::SymbolKind::TypeAlias;
2531 HI.Definition =
"int &";
2534 R
"cpp(// simple trailing return type
2535 ^[[auto]] main() -> int {
2541 HI.Kind = index::SymbolKind::TypeAlias;
2542 HI.Definition =
"int";
2545 R
"cpp(// auto function return with trailing type
2547 ^[[auto]] test() -> decltype(Bar()) {
2553 HI.Kind = index::SymbolKind::TypeAlias;
2554 HI.Definition =
"Bar";
2555 HI.Documentation =
"auto function return with trailing type";
2558 R
"cpp(// trailing return type
2560 auto test() -> ^[[decltype]](Bar()) {
2565 HI.Name = "decltype";
2566 HI.Kind = index::SymbolKind::TypeAlias;
2567 HI.Definition =
"Bar";
2568 HI.Documentation =
"trailing return type";
2571 R
"cpp(// auto in function return
2579 HI.Kind = index::SymbolKind::TypeAlias;
2580 HI.Definition =
"Bar";
2581 HI.Documentation =
"auto in function return";
2584 R
"cpp(// auto& in function return
2593 HI.Kind = index::SymbolKind::TypeAlias;
2594 HI.Definition =
"Bar";
2595 HI.Documentation =
"auto& in function return";
2598 R
"cpp(// auto* in function return
2607 HI.Kind = index::SymbolKind::TypeAlias;
2608 HI.Definition =
"Bar";
2609 HI.Documentation =
"auto* in function return";
2612 R
"cpp(// const auto& in function return
2614 const ^[[auto]]& test() {
2621 HI.Kind = index::SymbolKind::TypeAlias;
2622 HI.Definition =
"Bar";
2623 HI.Documentation =
"const auto& in function return";
2626 R
"cpp(// decltype(auto) in function return
2628 ^[[decltype]](auto) test() {
2633 HI.Name = "decltype";
2634 HI.Kind = index::SymbolKind::TypeAlias;
2635 HI.Definition =
"Bar";
2636 HI.Documentation =
"decltype(auto) in function return";
2639 R
"cpp(// decltype(auto) reference in function return
2640 ^[[decltype]](auto) test() {
2646 HI.Name = "decltype";
2647 HI.Kind = index::SymbolKind::TypeAlias;
2648 HI.Definition =
"int &";
2651 R
"cpp(// decltype lvalue reference
2654 ^[[decltype]](I) J = I;
2658 HI.Name = "decltype";
2659 HI.Kind = index::SymbolKind::TypeAlias;
2660 HI.Definition =
"int";
2663 R
"cpp(// decltype lvalue reference
2667 ^[[decltype]](K) J = I;
2671 HI.Name = "decltype";
2672 HI.Kind = index::SymbolKind::TypeAlias;
2673 HI.Definition =
"int &";
2676 R
"cpp(// decltype lvalue reference parenthesis
2679 ^[[decltype]]((I)) J = I;
2683 HI.Name = "decltype";
2684 HI.Kind = index::SymbolKind::TypeAlias;
2685 HI.Definition =
"int &";
2688 R
"cpp(// decltype rvalue reference
2691 ^[[decltype]](static_cast<int&&>(I)) J = static_cast<int&&>(I);
2695 HI.Name = "decltype";
2696 HI.Kind = index::SymbolKind::TypeAlias;
2697 HI.Definition =
"int &&";
2700 R
"cpp(// decltype rvalue reference function call
2704 ^[[decltype]](bar()) J = bar();
2708 HI.Name = "decltype";
2709 HI.Kind = index::SymbolKind::TypeAlias;
2710 HI.Definition =
"int &&";
2713 R
"cpp(// decltype of function with trailing return type.
2715 auto test() -> decltype(Bar()) {
2719 ^[[decltype]](test()) i = test();
2723 HI.Name = "decltype";
2724 HI.Kind = index::SymbolKind::TypeAlias;
2725 HI.Definition =
"Bar";
2727 "decltype of function with trailing return type.";
2730 R
"cpp(// decltype of var with decltype.
2734 ^[[decltype]](J) K = J;
2738 HI.Name = "decltype";
2739 HI.Kind = index::SymbolKind::TypeAlias;
2740 HI.Definition =
"int";
2743 R
"cpp(// decltype of dependent type
2744 template <typename T>
2746 using Y = ^[[decltype]](T::Z);
2750 HI.Name = "decltype";
2751 HI.Kind = index::SymbolKind::TypeAlias;
2752 HI.Definition =
"<dependent type>";
2755 R
"cpp(// More complicated structured types.
2757 ^[[auto]] (*foo)() = bar;
2761 HI.Kind = index::SymbolKind::TypeAlias;
2762 HI.Definition =
"int";
2765 R
"cpp(// Should not crash when evaluating the initializer.
2767 void test() { Test && [[te^st]] = {}; }
2771 HI.Kind = index::SymbolKind::Variable;
2772 HI.NamespaceScope =
"";
2773 HI.LocalScope =
"test::";
2774 HI.Type =
"Test &&";
2775 HI.Definition =
"Test &&test = {}";
2778 R
"cpp(// Shouldn't crash when evaluating the initializer.
2779 struct Bar {}; // error-ok
2780 struct Foo { void foo(Bar x = y); }
2781 void Foo::foo(Bar [[^x]]) {})cpp",
2784 HI.Kind = index::SymbolKind::Parameter;
2785 HI.NamespaceScope =
"";
2786 HI.LocalScope =
"Foo::foo::";
2788 HI.Definition =
"Bar x = <recovery - expr>()";
2791 R
"cpp(// auto on alias
2792 typedef int int_type;
2793 ^[[auto]] x = int_type();
2797 HI.Kind = index::SymbolKind::TypeAlias;
2798 HI.Definition =
"int_type // aka: int";
2801 R
"cpp(// auto on alias
2803 typedef cls cls_type;
2804 ^[[auto]] y = cls_type();
2808 HI.Kind = index::SymbolKind::TypeAlias;
2809 HI.Definition =
"cls_type // aka: cls";
2810 HI.Documentation =
"auto on alias";
2813 R
"cpp(// auto on alias
2816 ^[[auto]] z = templ<int>();
2820 HI.Kind = index::SymbolKind::TypeAlias;
2821 HI.Definition =
"templ<int>";
2822 HI.Documentation =
"auto on alias";
2825 R
"cpp(// Undeduced auto declaration
2826 template<typename T>
2833 HI.Kind = index::SymbolKind::TypeAlias;
2834 HI.Definition =
"T";
2837 R
"cpp(// Undeduced auto return type
2838 template<typename T>
2845 HI.Kind = index::SymbolKind::TypeAlias;
2846 HI.Definition =
"/* not deduced */";
2849 R
"cpp(// Template auto parameter
2850 template<[[a^uto]] T>
2858 HI.Kind = index::SymbolKind::TypeAlias;
2859 HI.Definition =
"/* not deduced */";
2862 R
"cpp(// Undeduced decltype(auto) return type
2863 template<typename T>
2864 ^[[decltype]](auto) foo() {
2869 HI.Name = "decltype";
2870 HI.Kind = index::SymbolKind::TypeAlias;
2871 HI.Definition =
"/* not deduced */";
2874 R
"cpp(// should not crash.
2875 template <class T> struct cls {
2879 auto test = cls<int>().[[m^ethod]]();
2882 HI.Definition = "int method()";
2883 HI.Kind = index::SymbolKind::InstanceMethod;
2884 HI.NamespaceScope =
"";
2885 HI.LocalScope =
"cls<int>::";
2887 HI.Parameters.emplace();
2888 HI.ReturnType =
"int";
2892 R
"cpp(// type of nested templates.
2893 template <class T> struct cls {};
2894 cls<cls<cls<int>>> [[fo^o]];
2897 HI.Definition = "cls<cls<cls<int>>> foo";
2898 HI.Kind = index::SymbolKind::Variable;
2899 HI.NamespaceScope =
"";
2901 HI.Type =
"cls<cls<cls<int>>>";
2904 R
"cpp(// type of nested templates.
2905 template <class T> struct cls {};
2906 [[cl^s]]<cls<cls<int>>> foo;
2909 HI.Definition = "template <> struct cls<cls<cls<int>>> {}";
2910 HI.Kind = index::SymbolKind::Struct;
2911 HI.NamespaceScope =
"";
2912 HI.Name =
"cls<cls<cls<int>>>";
2913 HI.Documentation =
"type of nested templates.";
2916 R
"cpp(// type with decltype
2918 decltype(a) [[b^]] = a;)cpp",
2920 HI.Definition = "decltype(a) b = a";
2921 HI.Kind = index::SymbolKind::Variable;
2922 HI.NamespaceScope =
"";
2927 R
"cpp(// type with decltype
2930 decltype(c) [[b^]] = a;)cpp",
2932 HI.Definition = "decltype(c) b = a";
2933 HI.Kind = index::SymbolKind::Variable;
2934 HI.NamespaceScope =
"";
2939 R
"cpp(// type with decltype
2941 const decltype(a) [[b^]] = a;)cpp",
2943 HI.Definition = "const decltype(a) b = a";
2944 HI.Kind = index::SymbolKind::Variable;
2945 HI.NamespaceScope =
"";
2950 R
"cpp(// type with decltype
2952 auto [[f^oo]](decltype(a) x) -> decltype(a) { return 0; })cpp",
2954 HI.Definition = "auto foo(decltype(a) x) -> decltype(a)";
2955 HI.Kind = index::SymbolKind::Function;
2956 HI.NamespaceScope =
"";
2960 HI.Type = {
"auto (decltype(a)) -> decltype(a)",
2961 "auto (int) -> int"};
2962 HI.ReturnType =
"int";
2963 HI.Parameters = {{{
"int"}, std::string(
"x"), std::nullopt}};
2966 R
"cpp(// sizeof expr
2968 (void)[[size^of]](char);
2971 HI.Name = "expression";
2972 HI.Type = {
"__size_t",
"unsigned long"};
2976 R
"cpp(// alignof expr
2978 (void)[[align^of]](char);
2981 HI.Name = "expression";
2982 HI.Type = {
"__size_t",
"unsigned long"};
2987 template <typename T = int>
2988 void foo(const T& = T()) {
2993 HI.Kind = index::SymbolKind::Function;
2994 HI.Type =
"void (const int &)";
2995 HI.ReturnType =
"void";
2997 {{
"const int &"}, std::nullopt, std::string(
"T()")}};
2998 HI.Definition =
"template <> void foo<int>(const int &)";
2999 HI.NamespaceScope =
"";
3002 R
"cpp(// should not crash
3010 HI.Kind = index::SymbolKind::Field;
3011 HI.LocalScope =
"ObjC::";
3012 HI.NamespaceScope =
"";
3013 HI.Definition =
"char data";
3019 @interface Interface
3020 @property(retain) [[MYOb^ject]] *x;
3024 HI.Name = "MYObject";
3025 HI.Kind = index::SymbolKind::Class;
3026 HI.NamespaceScope =
"";
3027 HI.Definition =
"@interface MYObject\n@end";
3033 @interface Interface
3034 - (void)doWith:([[MYOb^ject]] *)object;
3038 HI.Name = "MYObject";
3039 HI.Kind = index::SymbolKind::Class;
3040 HI.NamespaceScope =
"";
3041 HI.Definition =
"@interface MYObject\n@end";
3056 HI.Definition =
"ns::Foo *";
3059 R
"cpp(// this expr for template class
3061 template <typename T>
3071 HI.Definition =
"const ns::Foo<T> *";
3074 R
"cpp(// this expr for specialization class
3076 template <typename T> class Foo {};
3087 HI.Definition =
"ns::Foo<int> *";
3090 R
"cpp(// this expr for partial specialization struct
3092 template <typename T, typename F> struct Foo {};
3093 template <typename F>
3094 struct Foo<int, F> {
3103 HI.Definition =
"const ns::Foo<int, F> *";
3109 @interface MYObject (Private)
3110 @property(nonatomic, assign) int privateField;
3113 int someFunction() {
3114 MYObject *obj = [MYObject sharedInstance];
3115 return obj.[[private^Field]];
3119 HI.Name = "privateField";
3120 HI.Kind = index::SymbolKind::InstanceProperty;
3121 HI.LocalScope =
"MYObject(Private)::";
3122 HI.NamespaceScope =
"";
3123 HI.Definition =
"@property(nonatomic, assign, unsafe_unretained, "
3124 "readwrite) int privateField;";
3128 @protocol MYProtocol
3129 @property(nonatomic, assign) int prop1;
3132 int someFunction() {
3133 id<MYProtocol> obj = 0;
3134 return obj.[[pro^p1]];
3139 HI.Kind = index::SymbolKind::InstanceProperty;
3140 HI.LocalScope =
"MYProtocol::";
3141 HI.NamespaceScope =
"";
3142 HI.Definition =
"@property(nonatomic, assign, unsafe_unretained, "
3143 "readwrite) int prop1;";
3147 @protocol MYProtocol
3152 @interface MYObject (Ext) <[[MYProt^ocol]]>
3156 HI.Name = "MYProtocol";
3157 HI.Kind = index::SymbolKind::Protocol;
3158 HI.NamespaceScope =
"";
3159 HI.Definition =
"@protocol MYProtocol\n@end";
3165 @implementation Foo(Private)
3166 + (int)somePrivateMethod {
3167 int [[res^ult]] = 2;
3174 HI.Definition =
"int result = 2";
3175 HI.Kind = index::SymbolKind::Variable;
3177 HI.LocalScope =
"+[Foo(Private) somePrivateMethod]::";
3178 HI.NamespaceScope =
"";
3186 - (int)variadicArgMethod:(id)first, ... {
3187 int [[res^ult]] = 0;
3194 HI.Definition =
"int result = 0";
3195 HI.Kind = index::SymbolKind::Variable;
3197 HI.LocalScope =
"-[Foo variadicArgMethod:, ...]::";
3198 HI.NamespaceScope =
"";
3203 typedef struct MyRect {} MyRect;
3206 @property(nonatomic) MyRect frame;
3215 v.frame = [[foo^bar]]();
3220 HI.Kind = index::SymbolKind::Function;
3221 HI.NamespaceScope =
"";
3222 HI.Definition =
"MyRect foobar()";
3223 HI.Type = {
"MyRect ()",
"struct MyRect ()"};
3224 HI.ReturnType = {
"MyRect",
"struct MyRect"};
3225 HI.Parameters.emplace();
3228 void foo(int * __attribute__(([[non^null]], noescape)) );
3231 HI.Name = "nonnull";
3232 HI.Kind = index::SymbolKind::Unknown;
3233 HI.Definition =
"__attribute__((nonnull))";
3234 HI.Documentation = Attr::getDocumentation(attr::NonNull).str();
3239 struct strong_ordering {
3241 constexpr operator int() const { return n; }
3242 static const strong_ordering equal, greater, less;
3244 constexpr strong_ordering strong_ordering::equal = {0};
3245 constexpr strong_ordering strong_ordering::greater = {1};
3246 constexpr strong_ordering strong_ordering::less = {-1};
3253 auto operator<=>(const Foo&) const = default;
3256 bool x = Foo(1) [[!^=]] Foo(2);
3259 HI.Type = "bool (const Foo &) const noexcept";
3261 HI.Name =
"operator==";
3262 HI.Parameters = {{{
"const Foo &"}, std::nullopt, std::nullopt}};
3263 HI.ReturnType =
"bool";
3264 HI.Kind = index::SymbolKind::InstanceMethod;
3265 HI.LocalScope =
"Foo::";
3266 HI.NamespaceScope =
"";
3268 "bool operator==(const Foo &) const noexcept = default";
3269 HI.Documentation =
"";
3275 IndexSym.Documentation =
"comment from index";
3281 for (
const auto &Case : Cases) {
3282 SCOPED_TRACE(Case.Code);
3286 TU.ExtraArgs.push_back(
"-std=c++20");
3287 TU.ExtraArgs.push_back(
"-xobjective-c++");
3289 TU.ExtraArgs.push_back(
"-Wno-gnu-designator");
3292 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
3293 auto AST = TU.build();
3297 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(), Index.get());
3301 Case.ExpectedBuilder(Expected);
3304 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
3305 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
3306 EXPECT_EQ(H->Name, Expected.Name);
3307 EXPECT_EQ(H->Kind, Expected.Kind);
3308 EXPECT_EQ(H->Documentation, Expected.Documentation);
3309 EXPECT_EQ(H->Definition, Expected.Definition);
3310 EXPECT_EQ(H->Type, Expected.Type);
3311 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
3312 EXPECT_EQ(H->Parameters, Expected.Parameters);
3313 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
3314 EXPECT_EQ(H->SymRange, Expected.SymRange);
3315 EXPECT_EQ(H->Value, Expected.Value);
3322 const std::function<void(
HoverInfo &)> ExpectedBuilder;
3323 } Cases[] = {{R
"cpp(
3327 [](HoverInfo &HI) { HI.Provider = ""; }},
3332 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3337 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3342 [](HoverInfo &HI) { HI.Provider = ""; }},
3347 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3352 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3359 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3368 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3371 using namespace fo^o;
3373 [](HoverInfo &HI) { HI.Provider = ""; }},
3376 for (
const auto &Case : Cases) {
3378 SCOPED_TRACE(Code.code());
3382 TU.Code = Code.code();
3383 TU.AdditionalFiles[
"foo.h"] = guard(R
"cpp(
3386 Foo& operator+(const Foo, const Foo);
3388 TU.AdditionalFiles["all.h"] = guard(
"#include \"foo.h\"");
3390 auto AST = TU.build();
3391 auto H =
getHover(
AST, Code.point(), format::getLLVMStyle(),
nullptr);
3394 Case.ExpectedBuilder(Expected);
3396 EXPECT_EQ(H->Provider, Expected.Provider);
3403 HIFoo.Provider =
"\"foo.h\"";
3406 HIFooBar.
Name =
"foo";
3407 HIFooBar.Provider =
"<bar.h>";
3410 llvm::StringRef ExpectedMarkdown;
3411 } Cases[] = {{HIFoo,
"### `foo`\n\nprovided by `\"foo.h\"`"},
3412 {HIFooBar,
"### `foo`\n\nprovided by `<bar.h>`"}};
3414 for (
const auto &Case : Cases)
3421 const std::function<void(
HoverInfo &)> ExpectedBuilder;
3422 } Cases[] = {{R
"cpp(
3424 int fstBar = bar1();
3425 int another= bar1(0);
3426 int sndBar = bar2();
3431 HI.UsedSymbolNames = {"BAR",
"Bar",
"bar1",
"bar2"};
3435 std::vector<int> vec;
3437 [](HoverInfo &HI) { HI.UsedSymbolNames = {"vector"}; }}};
3438 for (
const auto &Case : Cases) {
3440 SCOPED_TRACE(Code.code());
3444 TU.Code = Code.code();
3445 TU.AdditionalFiles[
"bar.h"] = guard(R
"cpp(
3452 TU.AdditionalFiles["system/vector"] = guard(R
"cpp(
3458 TU.ExtraArgs.push_back("-isystem" +
testPath(
"system"));
3460 auto AST = TU.build();
3461 auto H =
getHover(
AST, Code.point(), format::getLLVMStyle(),
nullptr);
3464 Case.ExpectedBuilder(Expected);
3466 EXPECT_EQ(H->UsedSymbolNames, Expected.UsedSymbolNames);
3472 template <typename T> class X {};
3480 auto AST = TU.build();
3483 IndexSym.Documentation =
"comment from index";
3489 for (
const auto &P :
T.points()) {
3490 auto H =
getHover(
AST, P, format::getLLVMStyle(), Index.get());
3492 EXPECT_EQ(H->Documentation, IndexSym.Documentation);
3499 template <typename T> class X {};
3501 template <typename T> void bar() {}
3503 template <typename T> T baz;
3508 au^to T = ba^z<X<int>>;
3513 auto AST = TU.build();
3514 for (
const auto &P :
T.points()) {
3515 auto H =
getHover(
AST, P, format::getLLVMStyle(),
nullptr);
3517 EXPECT_EQ(H->Documentation,
"doc");
3524 template<typename T> T foo(T);
3526 // Setter variable heuristic might fail if the callexpr is broken.
3527 struct X { int Y; void [[^setY]](float) { Y = foo(undefined); } };)cpp");
3530 auto AST = TU.build();
3531 for (
const auto &P :
T.points())
3532 getHover(
AST, P, format::getLLVMStyle(),
nullptr);
3537 constexpr unsigned long value = -1; // wrap around
3538 void foo() { va^lue; }
3541 getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
3546 constexpr __int128_t value = -4;
3547 void foo() { va^lue; }
3551 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
3552 auto AST = TU.build();
3553 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
3555 EXPECT_EQ(H->Value,
"-4 (0xfffffffc)");
3561 template <typename T> class $doc1^X {};
3563 template <> class $doc2^X<int> {};
3565 template <typename T> class $doc3^X<T*> {};
3573 auto AST = TU.build();
3574 for (
const auto *Comment : {
"doc1",
"doc2",
"doc3"}) {
3575 for (
const auto &P :
T.points(Comment)) {
3576 auto H =
getHover(
AST, P, format::getLLVMStyle(),
nullptr);
3578 EXPECT_EQ(H->Documentation, Comment);
3585 const std::function<void(
HoverInfo &)> Builder;
3586 llvm::StringRef ExpectedMarkdownRender;
3587 llvm::StringRef ExpectedDoxygenRender;
3591 HI.Kind = index::SymbolKind::Unknown;
3599 HI.Kind = index::SymbolKind::NamespaceAlias;
3602 R
"(namespace-alias foo)",
3603 R"(### namespace-alias `foo`)",
3607 HI.Kind = index::SymbolKind::Class;
3609 HI.TemplateParameters = {
3610 {{"typename"}, std::string(
"T"), std::nullopt},
3611 {{
"typename"}, std::string(
"C"), std::string(
"bool")},
3613 HI.Documentation =
"documentation";
3615 "template <typename T, typename C = bool> class Foo {}";
3617 HI.NamespaceScope.emplace();
3625template <typename T, typename C = bool> class Foo {})",
3630template <typename T, typename C = bool> class Foo {}
3639### Template Parameters
3642- `typename C = bool`
3649 HI.Kind = index::SymbolKind::Function;
3651 HI.Type = {
"type",
"c_type"};
3652 HI.ReturnType = {
"ret_type",
"can_ret_type"};
3653 HI.Parameters.emplace();
3655 HI.Parameters->push_back(P);
3656 P.Type = {
"type",
"can_type"};
3657 HI.Parameters->push_back(P);
3659 HI.Parameters->push_back(P);
3660 P.Default =
"default";
3661 HI.Parameters->push_back(P);
3662 HI.NamespaceScope =
"ns::";
3663 HI.Definition =
"ret_type foo(params) {}";
3667 "→ ret_type (aka can_ret_type)\n\n"
3670 "- type (aka can_type)\n"
3671 "- type foo (aka can_type)\n"
3672 "- type foo = default (aka can_type)\n"
3674 "// In namespace ns\n"
3675 "ret_type foo(params) {}",
3681ret_type foo(params) {}
3688- `type (aka can_type)`
3689- `type foo (aka can_type)`
3690- `type foo = default (aka can_type)`
3695`ret_type (aka can_ret_type)`)",
3699 HI.Kind = index::SymbolKind::Field;
3700 HI.LocalScope = "test::Bar::";
3703 HI.Type = {
"type",
"can_type"};
3704 HI.Definition =
"def";
3712Type: type (aka can_type)
3718Size: 4 bytes (+4 bytes padding), alignment 4 bytes
3731Type: `type (aka can_type)`
3737Size: 4 bytes (+4 bytes padding), alignment 4 bytes)",
3741 HI.Kind = index::SymbolKind::Field;
3742 HI.LocalScope = "test::Bar::";
3745 HI.Type = {
"type",
"can_type"};
3746 HI.Definition =
"def";
3754Type: type (aka can_type)
3758Offset: 4 bytes and 3 bits
3760Size: 25 bits (+4 bits padding), alignment 8 bytes
3773Type: `type (aka can_type)`
3777Offset: 4 bytes and 3 bits
3779Size: 25 bits (+4 bits padding), alignment 8 bytes)",
3783 HI.Kind = index::SymbolKind::Field;
3784 HI.AccessSpecifier = "public";
3786 HI.LocalScope =
"test::Bar::";
3787 HI.Definition =
"def";
3803 HI.Definition = "size_t method()";
3804 HI.AccessSpecifier =
"protected";
3805 HI.Kind = index::SymbolKind::InstanceMethod;
3806 HI.NamespaceScope =
"";
3807 HI.LocalScope =
"cls<int>::";
3809 HI.Parameters.emplace();
3810 HI.ReturnType = {
"size_t",
"unsigned long"};
3811 HI.Type = {
"size_t ()",
"unsigned long ()"};
3813 R
"(instance-method method
3815→ size_t (aka unsigned long)
3818protected: size_t method())",
3819 R"(### instance-method
3824protected: size_t method()
3830`size_t (aka unsigned long)`)",
3834 HI.Definition = "cls(int a, int b = 5)";
3835 HI.AccessSpecifier =
"public";
3836 HI.Kind = index::SymbolKind::Constructor;
3837 HI.NamespaceScope =
"";
3838 HI.LocalScope =
"cls";
3840 HI.Parameters.emplace();
3841 HI.Parameters->emplace_back();
3842 HI.Parameters->back().Type =
"int";
3843 HI.Parameters->back().Name =
"a";
3844 HI.Parameters->emplace_back();
3845 HI.Parameters->back().Type =
"int";
3846 HI.Parameters->back().Name =
"b";
3847 HI.Parameters->back().Default =
"5";
3857public: cls(int a, int b = 5))",
3863public: cls(int a, int b = 5)
3874 HI.Kind = index::SymbolKind::Union;
3875 HI.AccessSpecifier = "private";
3877 HI.NamespaceScope =
"ns1::";
3878 HI.Definition =
"union foo {}";
3883private: union foo {})",
3889private: union foo {}
3894 HI.Kind = index::SymbolKind::Variable;
3896 HI.Definition =
"int foo = 3";
3897 HI.LocalScope =
"test::Bar::";
3900 HI.CalleeArgInfo.emplace();
3901 HI.CalleeArgInfo->Name =
"arg_a";
3902 HI.CalleeArgInfo->Type =
"int";
3903 HI.CalleeArgInfo->Default =
"7";
3933 HI.Kind = index::SymbolKind::Variable;
3935 HI.CalleeArgInfo.emplace();
3936 HI.CalleeArgInfo->Type =
"int";
3942 R"(### variable `foo`
3949 HI.Kind = index::SymbolKind::Variable;
3951 HI.Definition =
"int foo = 3";
3952 HI.LocalScope =
"test::Bar::";
3955 HI.CalleeArgInfo.emplace();
3956 HI.CalleeArgInfo->Name =
"arg_a";
3957 HI.CalleeArgInfo->Type =
"int";
3958 HI.CalleeArgInfo->Default =
"7";
3967Passed by reference as arg_a
3984Passed by reference as arg_a)",
3988 HI.Kind = index::SymbolKind::Variable;
3990 HI.Definition =
"int foo = 3";
3991 HI.LocalScope =
"test::Bar::";
3994 HI.CalleeArgInfo.emplace();
3995 HI.CalleeArgInfo->Name =
"arg_a";
3996 HI.CalleeArgInfo->Type = {
"alias_int",
"int"};
3997 HI.CalleeArgInfo->Default =
"7";
4006Passed as arg_a (converted to alias_int)
4023Passed as arg_a (converted to alias_int))",
4027 HI.Kind = index::SymbolKind::Macro;
4028 HI.Name = "PLUS_ONE";
4029 HI.Definition =
"#define PLUS_ONE(X) (X+1)\n\n"
4035#define PLUS_ONE(X) (X+1)
4043#define PLUS_ONE(X) (X+1)
4051 HI.Kind = index::SymbolKind::Variable;
4053 HI.Definition =
"int foo = 3";
4054 HI.LocalScope =
"test::Bar::";
4057 HI.CalleeArgInfo.emplace();
4058 HI.CalleeArgInfo->Name =
"arg_a";
4059 HI.CalleeArgInfo->Type =
"int";
4060 HI.CalleeArgInfo->Default =
"7";
4069Passed by const reference as arg_a (converted to int)
4086Passed by const reference as arg_a (converted to int))",
4090 HI.Name = "stdio.h";
4091 HI.Definition =
"/usr/include/stdio.h";
4092 HI.Kind = index::SymbolKind::IncludeDirective;
4096/usr/include/stdio.h)",
4099`/usr/include/stdio.h`)",
4104 HI.UsedSymbolNames = {
"Foo",
"Bar",
"Bar"};
4105 HI.Kind = index::SymbolKind::IncludeDirective;
4109provides Foo, Bar, Bar)",
4113provides `Foo`, `Bar`, `Bar`)",
4117 HI.UsedSymbolNames = {
"Foo",
"Bar",
"Baz",
"Foobar",
"Qux",
"Quux"};
4118 HI.Kind = index::SymbolKind::IncludeDirective;
4122provides Foo, Bar, Baz, Foobar, Qux and 1 more)",
4126provides `Foo`, `Bar`, `Baz`, `Foobar`, `Qux` and 1 more)"}};
4128 for (
const auto &C : Cases) {
4137 for (
const auto &C : Cases) {
4150 const std::function<void(
HoverInfo &)> Builder;
4151 llvm::StringRef ExpectedMarkdownRender;
4152 llvm::StringRef ExpectedDoxygenRender;
4155 HI.Kind = index::SymbolKind::Function;
4156 HI.Documentation =
"@brief brief doc\n\n"
4158 HI.Definition =
"void foo()";
4161 R
"(### function `foo`
4189 HI.Kind = index::SymbolKind::Function;
4190 HI.Documentation = "@brief brief doc\n\n"
4192 HI.Definition =
"int foo()";
4193 HI.ReturnType =
"int";
4196 R
"(### function `foo`
4231 HI.Kind = index::SymbolKind::Function;
4232 HI.Documentation = R"(@brief brief doc
4237As you see, notes are "inlined".
4238@warning this is a warning
4241@param a this is a param
4242@return it returns something
4243@retval 0 if successful
4244@retval 1 if failed)";
4245 HI.Definition = "int foo(int a)";
4246 HI.ReturnType =
"int";
4248 HI.Parameters.emplace();
4249 HI.Parameters->emplace_back();
4250 HI.Parameters->back().Type =
"int";
4251 HI.Parameters->back().Name =
"a";
4253 R
"(### function `foo`
4267As you see, notes are "inlined".
4268@warning this is a warning
4271@param a this is a param
4272@return it returns something
4273@retval 0 if successful
4295- `int a` - this is a param
4300`int` - it returns something
4302- `0` - if successful
4313As you see, notes are "inlined".
4318As well as warnings)"},
4320 HI.Kind = index::SymbolKind::Function;
4321 HI.Documentation = "@brief brief doc\n\n"
4322 "longer doc\n@param a this is a param\n@param b "
4323 "does not exist\n@return it returns something";
4324 HI.Definition =
"int foo(int a)";
4325 HI.ReturnType =
"int";
4327 HI.Parameters.emplace();
4328 HI.Parameters->emplace_back();
4329 HI.Parameters->back().Type =
"int";
4330 HI.Parameters->back().Name =
"a";
4332 R
"(### function `foo`
4344@param a this is a param
4345@param b does not exist
4346@return it returns something
4367- `int a` - this is a param
4372`int` - it returns something
4380 for (
const auto &C : Cases) {
4389 for (
const auto &C : Cases) {
4402 llvm::StringRef Documentation;
4403 llvm::StringRef ExpectedRenderEscapedMarkdown;
4404 llvm::StringRef ExpectedRenderMarkdown;
4405 llvm::StringRef ExpectedRenderPlainText;
4515 "Tests primality of `p`.",
4516 "Tests primality of `p`.",
4517 "Tests primality of `p`.",
4518 "Tests primality of `p`.",
4521 "'`' should not occur in `Code`",
4522 "'\\`' should not occur in `Code`",
4523 "'`' should not occur in `Code`",
4524 "'`' should not occur in `Code`",
4528 "\\`not\nparsed\\`",
4533 R
"(@brief this is a typical use case
4537 R"(@brief this is a typical use case
4541 R"(@brief this is a typical use case
4545 R"(@brief this is a typical use case
4551 for (
const auto &C : Cases) {
4552 markup::Document Output;
4555 EXPECT_EQ(Output.asEscapedMarkdown(),
C.ExpectedRenderEscapedMarkdown);
4556 EXPECT_EQ(Output.asMarkdown(),
C.ExpectedRenderMarkdown);
4557 EXPECT_EQ(Output.asPlainText(),
C.ExpectedRenderPlainText);
4565 HI.
Kind = index::SymbolKind::Variable;
4575 HI.
Kind = index::SymbolKind::Variable;
4578 HI.Definition =
"def";
4580 llvm::StringRef ExpectedMarkdown =
4581 "### variable `foo`\n"
4592 llvm::StringRef ExpectedDoxygenMarkdown =
4607 llvm::StringRef ExpectedPlaintext = R
"pt(variable foo
4618 struct strong_ordering {
4620 constexpr operator int() const { return n; }
4621 static const strong_ordering equal, greater, less;
4623 constexpr strong_ordering strong_ordering::equal = {0};
4624 constexpr strong_ordering strong_ordering::greater = {1};
4625 constexpr strong_ordering strong_ordering::less = {-1};
4628 template <typename T>
4631 friend auto operator<=>(S, S) = default;
4633 static_assert(S<void>() =^= S<void>());
4637 TU.ExtraArgs.push_back("-std=c++20");
4638 auto AST = TU.build();
4639 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4640 EXPECT_EQ(HI->Documentation,
"");
4647 auto baz = (Fo^o*)&bar;
4651 auto AST = TU.build();
4652 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4654 EXPECT_EQ(*HI->Value,
"&bar");
4657TEST(
Hover, FunctionParameterDefaulValueNotEvaluatedOnInvalidDecls) {
4659 const char *
const Code;
4660 const std::optional<std::string> HoverValue;
4663 // error-ok testing behavior on invalid decl
4665 void foo(Foo p^aram = nullptr);
4670 void foo(Foo *p^aram = nullptr);
4675 for (
const auto &C : Cases) {
4678 auto AST = TU.build();
4679 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4681 ASSERT_EQ(HI->Value,
C.HoverValue);
4696 TU.ExtraArgs.push_back(
"-std=c++17");
4697 auto AST = TU.build();
4698 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4706 #define A(x) x, x, x, x
4707 #define B(x) A(A(A(A(x))))
4708 int a^rr[] = {B(0)};
4712 auto AST = TU.build();
4713 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4716 EXPECT_EQ(H->Definition,
"int arr[]");
4719#if defined(__aarch64__)
4721#define PREDEFINEMACROS_TEST(x) DISABLED_##x
4723#define PREDEFINEMACROS_TEST(x) x
4728 using uintptr_t = __UINTPTR_TYPE__;
4729 enum Test : uintptr_t {};
4730 unsigned global_var;
4732 Test v^al = static_cast<Test>(reinterpret_cast<uintptr_t>(&global_var));
4737 TU.PredefineMacros = true;
4738 auto AST = TU.build();
4739 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4741 EXPECT_EQ(*HI->Value,
"&global_var");
4746 using uintptr_t = __UINTPTR_TYPE__;
4747 unsigned global_var;
4749 uintptr_t a^ddress = reinterpret_cast<uintptr_t>(&global_var);
4754 TU.PredefineMacros = true;
4755 auto AST = TU.build();
4756 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4758 EXPECT_EQ(*HI->Value,
"&global_var");
4763 template <bool X, typename T, typename F>
4764 struct cond { using type = T; };
4765 template <typename T, typename F>
4766 struct cond<false, T, F> { using type = F; };
4768 template <bool X, typename T, typename F>
4769 using type = typename cond<X, T, F>::type;
4772 using f^oo = type<true, int, double>;
4777 auto AST = TU.build();
4778 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4780 ASSERT_TRUE(H && H->Type);
4781 EXPECT_EQ(H->Type->Type,
"int");
4782 EXPECT_EQ(H->Definition,
"using foo = type<true, int, double>");
4786 llvm::StringRef PredefinedCXX = R
"cpp(
4788#define SizeOf sizeof
4789#define AlignOf alignof
4793using u64 = unsigned long long;
4794// calculate (a ** b) % p
4795constexpr u64 pow_with_mod(u64 a, u64 b, u64 p) {
4799 ret = (ret * a) % p;
4805#define last_n_digit(x, y, n) \
4806 pow_with_mod(x, y, pow_with_mod(10, n, 2147483647))
4807#define declare_struct(X, name, value) \
4809 constexpr auto name() { return value; } \
4811#define gnu_statement_expression(value) \
4813 declare_struct(Widget, getter, value); \
4814 Widget().getter(); \
4816#define define_lambda_begin(lambda, ...) \
4818#define define_lambda_end() }
4820#define left_bracket [
4821#define right_bracket ]
4822#define dg_left_bracket <:
4823#define dg_right_bracket :>
4824#define array_decl(type, name, size) type name left_bracket size right_bracket
4828 llvm::StringRef Code;
4829 const std::function<void(std::optional<HoverInfo>,
size_t )>
4837 [](std::optional<HoverInfo> HI, size_t) {
4838 EXPECT_EQ(HI->Value,
"42 (0x2a)");
4847 [](std::optional<HoverInfo> HI, size_t) {
4848 EXPECT_TRUE(HI->Value);
4849 EXPECT_TRUE(HI->Type);
4864 [](std::optional<HoverInfo> HI, size_t) {
4865 EXPECT_TRUE(HI->Value);
4866 EXPECT_TRUE(HI->Type);
4871 // 2**32 == 4294967296
4872 last_n_di^git(2, 32, 6);
4875 [](std::optional<HoverInfo> HI, size_t) {
4876 EXPECT_EQ(HI->Value,
"967296 (0xec280)");
4877 EXPECT_EQ(HI->Type,
"u64");
4882 gnu_statement_exp^ression(42);
4885 [](std::optional<HoverInfo> HI, size_t) {
4886 EXPECT_EQ(HI->Value,
"42 (0x2a)");
4887 EXPECT_EQ(HI->Type,
"int");
4895 [](std::optional<HoverInfo> HI, size_t) {
4896 EXPECT_EQ(HI->Value,
"2");
4897 EXPECT_EQ(HI->Type,
"int");
4905 [](std::optional<HoverInfo> HI, size_t) {
4906 EXPECT_FALSE(HI->Value) << HI->Value;
4907 EXPECT_FALSE(HI->Type) << HI->Type;
4915 [](std::optional<HoverInfo> HI, size_t) {
4916 EXPECT_EQ(HI->Value,
"2");
4917 EXPECT_EQ(HI->Type,
"int");
4922 arra^y_decl(int, vector, 10);
4923 vector left_b^racket 3 right_b^racket;
4924 vector dg_le^ft_bracket 3 dg_righ^t_bracket;
4927 [](std::optional<HoverInfo> HI,
size_t Id) {
4936 EXPECT_FALSE(HI->Type) << HI->Type;
4937 EXPECT_FALSE(HI->Value) << HI->Value;
4940 ASSERT_TRUE(
false) <<
"Unhandled id: " << Id;
4946 constexpr auto value = define_lamb^da_begin(lambda, int, char)
4947 // Check if the expansion range is right.
4948 return ^last_n_digit(10, 3, 3)^;
4949 define_lam^bda_end();
4952 [](std::optional<HoverInfo> HI,
size_t Id) {
4955 EXPECT_FALSE(HI->Value);
4959 EXPECT_EQ(HI->Value,
"0");
4966 EXPECT_FALSE(HI->Type) << HI->Type;
4967 EXPECT_FALSE(HI->Value) << HI->Value;
4970 ASSERT_TRUE(
false) <<
"Unhandled id: " << Id;
4979 for (
const auto &C : Cases) {
4981 (PredefinedCXX +
"void function() {\n" +
C.Code +
"}\n").str());
4983 TU.ExtraArgs.push_back(
"-std=c++17");
4984 auto AST = TU.build();
4985 for (
auto [Index,
Position] : llvm::enumerate(Code.points())) {
4992 #define alignof _Alignof
4994 al^ignof(struct { int x; char y[10]; });
4999 TU.Filename =
"TestTU.c";
5003 auto AST = TU.build();
5004 auto H =
getHover(
AST,
C.point(), format::getLLVMStyle(),
nullptr);
5007 EXPECT_TRUE(H->Value);
5008 EXPECT_TRUE(H->Type);
5012 const char *
const Code =
5014 #define C(A) A##A // Concatenate
5015 #define E(A) C(A) // Expand
5016 #define Z0032 00000000000000000000000000000000
5017 #define Z0064 E(Z0032)
5018 #define Z0128 E(Z0064)
5019 #define Z0256 E(Z0128)
5020 #define Z0512 E(Z0256)
5021 #define Z1024 E(Z0512)
5022 #define Z2048 E(Z1024)
5023 #define Z4096 E(Z2048) // 4096 zeroes
5024 int main() { return [[^Z4096]]; }
5028 uint32_t MacroContentsLimit;
5029 const std::string ExpectedDefinition;
5032 {2048,
"#define Z4096 E(Z2048)"},
5034 {8192, std::string(
"#define Z4096 E(Z2048)\n\n") +
5035 std::string(
"// Expands to\n") + std::string(4096,
'0')},
5037 for (
const auto &Case : Cases) {
5042 auto AST = TU.build();
5046 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
5049 EXPECT_EQ(H->Definition, Case.ExpectedDefinition);
5055 const char *
const Code;
5056 const std::function<void(
HoverInfo &)> ExpectedBuilder;
5057 std::string ExpectedRender;
5059 {R
"cpp(/// Function doc
5060 void foo(int [[^a]]);
5064 HI.Kind = index::SymbolKind::Parameter;
5065 HI.NamespaceScope =
"";
5066 HI.LocalScope =
"foo::";
5068 HI.Definition =
"int a";
5069 HI.Documentation =
"";
5071 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nType: `int`"},
5072 {R
"cpp(/// Function doc
5074 void foo(int [[^a]]);
5078 HI.Kind = index::SymbolKind::Parameter;
5079 HI.NamespaceScope =
"";
5080 HI.LocalScope =
"foo::";
5082 HI.Definition =
"int a";
5083 HI.Documentation =
"this is doc for a";
5085 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nthis is doc "
5086 "for a\n\n---\nType: `int`"},
5087 {R
"cpp(/// Function doc
5089 void foo(int [[^a]], int b);
5093 HI.Kind = index::SymbolKind::Parameter;
5094 HI.NamespaceScope =
"";
5095 HI.LocalScope =
"foo::";
5097 HI.Definition =
"int a";
5098 HI.Documentation =
"";
5100 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nType: `int`"},
5101 {R
"cpp(/// Function doc
5103 void foo(int a, int [[^b]]);
5107 HI.Kind = index::SymbolKind::Parameter;
5108 HI.NamespaceScope =
"";
5109 HI.LocalScope =
"foo::";
5111 HI.Definition =
"int b";
5112 HI.Documentation =
"this is doc for \\p b";
5114 "### param\n\n---\n```cpp\n// In foo\nint b\n```\n\n---\nthis is doc "
5115 "for `b`\n\n---\nType: `int`"},
5116 {R
"cpp(/// Function doc
5118 template <typename T>
5119 void foo(T a, T [[^b]]);
5123 HI.Kind = index::SymbolKind::Parameter;
5124 HI.NamespaceScope =
"";
5125 HI.LocalScope =
"foo::";
5127 HI.Definition =
"T b";
5128 HI.Documentation =
"this is doc for \\p b";
5130 "### param\n\n---\n```cpp\n// In foo\nT b\n```\n\n---\nthis is doc for "
5131 "`b`\n\n---\nType: `T`"},
5132 {R
"cpp(/// Function doc
5134 void foo(int a, int [[^b]]);
5138 HI.Kind = index::SymbolKind::Parameter;
5139 HI.NamespaceScope =
"";
5140 HI.LocalScope =
"foo::";
5142 HI.Definition =
"int b";
5144 "this is <b>doc</b> <html-tag attribute/> <another-html-tag "
5145 "attribute=\"value\">for</another-html-tag> \\p b";
5147 "### param\n\n---\n```cpp\n// In foo\nint b\n```\n\n---\nthis is "
5148 "\\<b>doc\\</b> \\<html-tag attribute/> \\<another-html-tag "
5149 "attribute=\"value\">for\\</another-html-tag> `b`\n\n---\nType: `int`"},
5154 IndexSym.Documentation =
"comment from index";
5160 for (
const auto &Case : Cases) {
5161 SCOPED_TRACE(Case.Code);
5165 auto AST = TU.build();
5170 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(), Index.get());
5174 Case.ExpectedBuilder(Expected);
5177 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
5178 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
5179 EXPECT_EQ(H->Name, Expected.Name);
5180 EXPECT_EQ(H->Kind, Expected.Kind);
5181 EXPECT_EQ(H->Documentation, Expected.Documentation);
5182 EXPECT_EQ(H->Definition, Expected.Definition);
5183 EXPECT_EQ(H->Type, Expected.Type);
5184 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
5185 EXPECT_EQ(H->Parameters, Expected.Parameters);
5186 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
5187 EXPECT_EQ(H->SymRange, Expected.SymRange);
5188 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.
struct clang::clangd::Config::@121122115314141033053005335347006075254233342165 Hover
Configures hover feature.
@ Markdown
Treat comments as Markdown.
@ Doxygen
Treat comments as doxygen.
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)