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 namespace ns1 { namespace ns2 {
68 HI.NamespaceScope =
"ns1::ns2::";
70 HI.Kind = index::SymbolKind::Function;
71 HI.Documentation =
"Best foo ever.";
72 HI.Definition =
"void foo()";
73 HI.ReturnType =
"void";
75 HI.Parameters.emplace();
79 namespace ns1 { namespace ns2 {
87 HI.NamespaceScope = "ns1::ns2::";
88 HI.LocalScope =
"Foo::";
90 HI.Kind = index::SymbolKind::Field;
91 HI.Definition =
"char bar";
97 HI.AccessSpecifier =
"private";
107 HI.NamespaceScope = "";
108 HI.LocalScope =
"Foo::";
110 HI.Kind = index::SymbolKind::Field;
111 HI.Definition =
"char bar";
116 HI.AccessSpecifier =
"public";
126 HI.NamespaceScope = "";
127 HI.LocalScope =
"Foo::";
129 HI.Kind = index::SymbolKind::Field;
130 HI.Definition =
"int x : 1";
135 HI.AccessSpecifier =
"public";
139 namespace ns1 { namespace ns2 {
148 HI.NamespaceScope = "ns1::ns2::";
149 HI.LocalScope =
"Foo::foo::";
151 HI.Kind = index::SymbolKind::Variable;
152 HI.Definition =
"int bar";
162 HI.Name = "__func__";
163 HI.Kind = index::SymbolKind::Variable;
165 "Name of the current function (predefined variable)";
166 HI.Value =
"\"foo\"";
167 HI.Type =
"const char[4]";
171 template<int> void foo() {
176 HI.Name = "__func__";
177 HI.Kind = index::SymbolKind::Variable;
179 "Name of the current function (predefined variable)";
180 HI.Type =
"const char[]";
184 namespace ns1 { namespace {
191 HI.NamespaceScope = "ns1::";
192 HI.LocalScope =
"(anonymous struct)::";
194 HI.Kind = index::SymbolKind::Field;
195 HI.Definition =
"char bar";
200 HI.AccessSpecifier =
"public";
207 HI.NamespaceScope = "";
209 HI.Kind = index::SymbolKind::Struct;
210 HI.Definition =
"struct X {}";
216 template <typename T, class... Ts> class Foo { public: Foo(int); };
217 Foo<int, char, bool> [[fo^o]] = Foo<int, char, bool>(5);
220 HI.NamespaceScope = "";
222 HI.Kind = index::SymbolKind::Variable;
223 HI.Definition =
"Foo<int, char, bool> foo = Foo<int, char, bool>(5)";
224 HI.Type =
"Foo<int, char, bool>";
228 template <typename T> class vector{};
229 [[vec^tor]]<int> foo;
232 HI.NamespaceScope = "";
233 HI.Name =
"vector<int>";
234 HI.Kind = index::SymbolKind::Class;
235 HI.Definition =
"template <> class vector<int> {}";
239 template <template<typename, bool...> class C,
243 class... Ts> class Foo final {};
244 template <template<typename, bool...> class T>
248 HI.NamespaceScope = "";
250 HI.Kind = index::SymbolKind::Class;
252 R
"cpp(template <template <typename, bool...> class C, typename = char, int = 0,
253 bool Q = false, class... Ts>
254class Foo final {})cpp";
255 HI.TemplateParameters = {
256 {{"template <typename, bool...> class"},
259 {{
"typename"}, std::nullopt, std::string(
"char")},
260 {{
"int"}, std::nullopt, std::string(
"0")},
261 {{
"bool"}, std::string(
"Q"), std::string(
"false")},
262 {{
"class..."}, std::string(
"Ts"), std::nullopt},
267 template <template<typename, bool...> class C,
271 class... Ts> void foo();
272 template<typename, bool...> class Foo;
279 HI.NamespaceScope = "";
281 HI.Kind = index::SymbolKind::Function;
282 HI.Definition =
"template <> void foo<Foo, char, 0, false, <>>()";
283 HI.ReturnType =
"void";
285 HI.Parameters.emplace();
289 template<typename, bool...> class Foo {};
290 Foo<bool, true, false> foo(int, bool T = false);
297 HI.NamespaceScope = "";
299 HI.Kind = index::SymbolKind::Function;
300 HI.Definition =
"Foo<bool, true, false> foo(int, bool T = false)";
301 HI.ReturnType =
"Foo<bool, true, false>";
302 HI.Type =
"Foo<bool, true, false> (int, bool)";
304 {{
"int"}, std::nullopt, std::nullopt},
305 {{
"bool"}, std::string(
"T"), std::string(
"false")},
311 auto lamb = [](int T, bool B) -> bool { return T && B; };
317 HI.NamespaceScope = "";
318 HI.LocalScope =
"foo::";
320 HI.Kind = index::SymbolKind::Variable;
321 HI.Definition =
"auto *c = &b";
322 HI.Type =
"(lambda) **";
323 HI.ReturnType =
"bool";
325 {{
"int"}, std::string(
"T"), std::nullopt},
326 {{
"bool"}, std::string(
"B"), std::nullopt},
332 auto lamb = [](int T, bool B) -> bool { return T && B; };
333 void foo(decltype(lamb)& bar) {
338 HI.NamespaceScope = "";
339 HI.LocalScope =
"foo::";
341 HI.Kind = index::SymbolKind::Parameter;
342 HI.Definition =
"decltype(lamb) &bar";
343 HI.Type = {
"decltype(lamb) &",
"(lambda) &"};
344 HI.ReturnType =
"bool";
346 {{
"int"}, std::string(
"T"), std::nullopt},
347 {{
"bool"}, std::string(
"B"), std::nullopt},
353 auto lamb = [](int T, bool B) -> bool { return T && B; };
354 void foo(decltype(lamb) bar) {
359 HI.NamespaceScope = "";
360 HI.LocalScope =
"foo::";
362 HI.Kind = index::SymbolKind::Parameter;
363 HI.Definition =
"decltype(lamb) bar";
364 HI.Type =
"class (lambda)";
365 HI.ReturnType =
"bool";
367 {{
"int"}, std::string(
"T"), std::nullopt},
368 {{
"bool"}, std::string(
"B"), std::nullopt},
377 auto lamb = [&bar](int T, bool B) -> bool { return T && B && bar; };
378 bool res = [[lam^b]](bar, false);
382 HI.NamespaceScope = "";
383 HI.LocalScope =
"foo::";
385 HI.Kind = index::SymbolKind::Variable;
386 HI.Definition =
"auto lamb = [&bar](int T, bool B) -> bool {}";
387 HI.Type =
"class (lambda)";
388 HI.ReturnType =
"bool";
390 {{
"int"}, std::string(
"T"), std::nullopt},
391 {{
"bool"}, std::string(
"B"), std::nullopt},
398 auto lamb = []{int [[te^st]];};
402 HI.NamespaceScope = "";
403 HI.LocalScope =
"foo::(anonymous class)::operator()::";
405 HI.Kind = index::SymbolKind::Variable;
406 HI.Definition =
"int test";
411 template <typename T> class X;
412 template <typename T> class [[^X]]<T*> {};
416 HI.NamespaceScope =
"";
417 HI.Kind = index::SymbolKind::Class;
418 HI.Definition =
"template <typename T> class X<T *> {}";
422 template<typename, typename=void> struct X;
423 template<typename T> struct X<T*>{ [[^X]](); };
426 HI.NamespaceScope = "";
428 HI.LocalScope =
"X<T *>::";
429 HI.Kind = index::SymbolKind::Constructor;
430 HI.Definition =
"X()";
431 HI.Parameters.emplace();
432 HI.AccessSpecifier =
"public";
434 {
"class X { [[^~]]X(); };",
436 HI.NamespaceScope =
"";
438 HI.LocalScope =
"X::";
439 HI.Kind = index::SymbolKind::Destructor;
440 HI.Definition =
"~X()";
441 HI.Parameters.emplace();
442 HI.AccessSpecifier =
"private";
444 {
"class X { [[op^erator]] int(); };",
446 HI.NamespaceScope =
"";
447 HI.Name =
"operator int";
448 HI.LocalScope =
"X::";
449 HI.Kind = index::SymbolKind::ConversionFunction;
450 HI.Definition =
"operator int()";
451 HI.Parameters.emplace();
452 HI.AccessSpecifier =
"private";
454 {
"class X { operator [[^X]](); };",
456 HI.NamespaceScope =
"";
458 HI.Kind = index::SymbolKind::Class;
459 HI.Definition =
"class X {}";
465 struct S { int x; float y; };
466 [[au^to]] [x, y] = S();
471 HI.Kind = index::SymbolKind::TypeAlias;
483 HI.Kind = index::SymbolKind::TypeAlias;
488 template <class T> concept F = true;
493 HI.Kind = index::SymbolKind::TypeAlias;
494 HI.Definition =
"int";
497 template <class T> concept F = true;
501 HI.NamespaceScope = "";
503 HI.Kind = index::SymbolKind::Concept;
504 HI.Definition =
"template <class T>\nconcept F = true";
509 [[au^to]] lamb = []{};
514 HI.Kind = index::SymbolKind::TypeAlias;
515 HI.Definition =
"class(lambda)";
519 template<typename T> class Foo{};
521 [[au^to]] x = Foo<int>();
526 HI.Kind = index::SymbolKind::TypeAlias;
527 HI.Definition =
"Foo<int>";
531 template<typename T> class Foo{};
532 template<> class Foo<int>{};
534 [[au^to]] x = Foo<int>();
539 HI.Kind = index::SymbolKind::TypeAlias;
540 HI.Definition =
"Foo<int>";
544 template<class T> concept Fooable = true;
545 template<[[Foo^able]] T>
549 HI.NamespaceScope = "";
551 HI.Kind = index::SymbolKind::Concept;
552 HI.Definition =
"template <class T>\nconcept Fooable = true";
555 template<class T> concept Fooable = true;
556 template<Fooable [[T^T]]>
562 HI.AccessSpecifier =
"public";
563 HI.NamespaceScope =
"";
564 HI.LocalScope =
"bar::";
565 HI.Kind = index::SymbolKind::TemplateTypeParm;
566 HI.Definition =
"Fooable TT";
569 template<class T> concept Fooable = true;
570 void bar([[Foo^able]] auto t) {}
573 HI.NamespaceScope = "";
575 HI.Kind = index::SymbolKind::Concept;
576 HI.Definition =
"template <class T>\nconcept Fooable = true";
580 template<class T> concept Fooable = true;
581 auto X = [[Fooa^ble]]<int>;
584 HI.NamespaceScope = "";
586 HI.Kind = index::SymbolKind::Concept;
587 HI.Definition =
"template <class T>\nconcept Fooable = true";
598 HI.Kind = index::SymbolKind::Macro;
599 HI.Definition =
"#define MACRO";
609 HI.Kind = index::SymbolKind::Macro;
610 HI.Value =
"41 (0x29)";
612 HI.Definition =
"#define MACRO 41\n\n"
620 #define MACRO(x,y,z) void foo(x, y, z)
621 [[MAC^RO]](int, double d, bool z = false);
625 HI.Kind = index::SymbolKind::Macro;
626 HI.Definition =
"#define MACRO(x, y, z) void foo(x, y, z)\n\n"
628 "void foo(int, double d, bool z = false)";
633 #define STRINGIFY_AUX(s) #s
634 #define STRINGIFY(s) STRINGIFY_AUX(s)
635 #define DECL_STR(NAME, VALUE) const char *v_##NAME = STRINGIFY(VALUE)
638 [[DECL^_STR]](foo, FOO);
641 HI.Name = "DECL_STR";
642 HI.Kind = index::SymbolKind::Macro;
644 HI.Definition =
"#define DECL_STR(NAME, VALUE) const char *v_##NAME = "
645 "STRINGIFY(VALUE)\n\n"
647 "const char *v_foo = \"41\"";
652 constexpr int add(int a, int b) { return a + b; }
653 int [[b^ar]] = add(1, 2);
657 HI.Definition =
"int bar = add(1, 2)";
658 HI.Kind = index::SymbolKind::Variable;
660 HI.NamespaceScope =
"";
664 int [[b^ar]] = sizeof(char);
668 HI.Definition =
"int bar = sizeof(char)";
669 HI.Kind = index::SymbolKind::Variable;
671 HI.NamespaceScope =
"";
675 template<int a, int b> struct Add {
676 static constexpr int result = a + b;
678 int [[ba^r]] = Add<1, 2>::result;
682 HI.Definition =
"int bar = Add<1, 2>::result";
683 HI.Kind = index::SymbolKind::Variable;
685 HI.NamespaceScope =
"";
689 enum Color { RED = -123, GREEN = 5, };
690 Color x = [[GR^EEN]];
694 HI.NamespaceScope =
"";
695 HI.LocalScope =
"Color::";
696 HI.Definition =
"GREEN = 5";
697 HI.Kind = index::SymbolKind::EnumConstant;
698 HI.Type =
"enum Color";
702 enum Color { RED = -123, GREEN = 5, };
708 HI.NamespaceScope =
"";
709 HI.Definition =
"Color x = RED";
710 HI.Kind = index::SymbolKind::Variable;
712 HI.Value =
"RED (0xffffff85)";
715 template<int a, int b> struct Add {
716 static constexpr int result = a + b;
718 int bar = Add<1, 2>::[[resu^lt]];
722 HI.Definition =
"static constexpr int result = a + b";
723 HI.Kind = index::SymbolKind::StaticProperty;
724 HI.Type =
"const int";
725 HI.NamespaceScope =
"";
726 HI.LocalScope =
"Add<1, 2>::";
728 HI.AccessSpecifier =
"public";
732 constexpr my_int answer() { return 40 + 2; }
733 int x = [[ans^wer]]();
737 HI.Definition =
"constexpr my_int answer()";
738 HI.Kind = index::SymbolKind::Function;
739 HI.Type = {
"my_int ()",
"int ()"};
740 HI.ReturnType = {
"my_int",
"int"};
741 HI.Parameters.emplace();
742 HI.NamespaceScope =
"";
743 HI.Value =
"42 (0x2a)";
746 const char *[[ba^r]] = "1234";
750 HI.Definition =
"const char *bar = \"1234\"";
751 HI.Kind = index::SymbolKind::Variable;
752 HI.Type =
"const char *";
753 HI.NamespaceScope =
"";
754 HI.Value =
"&\"1234\"[0]";
756 {R
"cpp(// Should not crash
757 template <typename T>
762 template <typename A>
763 void boom(int name) {
764 new Tmpl<A>([[na^me]]);
768 HI.Definition =
"int name";
769 HI.Kind = index::SymbolKind::Parameter;
771 HI.NamespaceScope =
"";
772 HI.LocalScope =
"boom::";
775 R
"cpp(// Should not print inline or anon namespaces.
777 inline namespace in_ns {
781 inline namespace in_ns2 {
790 ns::a::b::[[F^oo]] x;
796 HI.Kind = index::SymbolKind::Class;
797 HI.NamespaceScope =
"ns::a::b::";
798 HI.Definition =
"class Foo {}";
802 template <typename T> class Foo {};
805 [[^auto]] x = Foo<X>();
810 HI.Kind = index::SymbolKind::TypeAlias;
811 HI.Definition =
"Foo<X>";
815 // comment from primary
816 template <typename T> class Foo {};
817 // comment from specialization
818 template <typename T> class Foo<T*> {};
820 [[Fo^o]]<int*> *x = nullptr;
824 HI.Name = "Foo<int *>";
825 HI.Kind = index::SymbolKind::Class;
826 HI.NamespaceScope =
"";
827 HI.Definition =
"template <> class Foo<int *>";
830 HI.Documentation =
"comment from primary";
834 template <typename [[^T]] = int> void foo();
838 HI.Kind = index::SymbolKind::TemplateTypeParm;
839 HI.NamespaceScope =
"";
840 HI.Definition =
"typename T = int";
841 HI.LocalScope =
"foo::";
842 HI.Type =
"typename";
843 HI.AccessSpecifier =
"public";
847 template <template<typename> class [[^T]]> void foo();
851 HI.Kind = index::SymbolKind::TemplateTemplateParm;
852 HI.NamespaceScope =
"";
853 HI.Definition =
"template <typename> class T";
854 HI.LocalScope =
"foo::";
855 HI.Type =
"template <typename> class";
856 HI.AccessSpecifier =
"public";
860 template <int [[^T]] = 5> void foo();
864 HI.Kind = index::SymbolKind::NonTypeTemplateParm;
865 HI.NamespaceScope =
"";
866 HI.Definition =
"int T = 5";
867 HI.LocalScope =
"foo::";
869 HI.AccessSpecifier =
"public";
874 struct X { int Y; float [[^y]]() { return Y; } };
878 HI.Kind = index::SymbolKind::InstanceMethod;
879 HI.NamespaceScope =
"";
880 HI.Definition =
"float y()";
881 HI.LocalScope =
"X::";
882 HI.Documentation =
"Trivial accessor for `Y`.";
883 HI.Type =
"float ()";
884 HI.ReturnType =
"float";
885 HI.Parameters.emplace();
886 HI.AccessSpecifier =
"public";
890 struct X { int Y; void [[^setY]](float v) { Y = v; } };
894 HI.Kind = index::SymbolKind::InstanceMethod;
895 HI.NamespaceScope =
"";
896 HI.Definition =
"void setY(float v)";
897 HI.LocalScope =
"X::";
898 HI.Documentation =
"Trivial setter for `Y`.";
899 HI.Type =
"void (float)";
900 HI.ReturnType =
"void";
901 HI.Parameters.emplace();
902 HI.Parameters->emplace_back();
903 HI.Parameters->back().Type =
"float";
904 HI.Parameters->back().Name =
"v";
905 HI.AccessSpecifier =
"public";
909 struct X { int Y; X& [[^setY]](float v) { Y = v; return *this; } };
913 HI.Kind = index::SymbolKind::InstanceMethod;
914 HI.NamespaceScope =
"";
915 HI.Definition =
"X &setY(float v)";
916 HI.LocalScope =
"X::";
917 HI.Documentation =
"Trivial setter for `Y`.";
918 HI.Type =
"X &(float)";
919 HI.ReturnType =
"X &";
920 HI.Parameters.emplace();
921 HI.Parameters->emplace_back();
922 HI.Parameters->back().Type =
"float";
923 HI.Parameters->back().Name =
"v";
924 HI.AccessSpecifier =
"public";
928 namespace std { template<typename T> T&& move(T&& t); }
929 struct X { int Y; void [[^setY]](float v) { Y = std::move(v); } };
933 HI.Kind = index::SymbolKind::InstanceMethod;
934 HI.NamespaceScope =
"";
935 HI.Definition =
"void setY(float v)";
936 HI.LocalScope =
"X::";
937 HI.Documentation =
"Trivial setter for `Y`.";
938 HI.Type =
"void (float)";
939 HI.ReturnType =
"void";
940 HI.Parameters.emplace();
941 HI.Parameters->emplace_back();
942 HI.Parameters->back().Type =
"float";
943 HI.Parameters->back().Name =
"v";
944 HI.AccessSpecifier =
"public";
948 struct X { int x = 2; };
953 HI.Kind = index::SymbolKind::Variable;
954 HI.NamespaceScope =
"";
955 HI.Definition =
"X x";
959 R
"cpp(auto [^[[x]]] = 1; /*error-ok*/)cpp",
962 HI.Kind = index::SymbolKind::Variable;
963 HI.NamespaceScope =
"";
965 HI.Type =
"NULL TYPE";
967 HI.AccessSpecifier =
"public";
971 Unknown [[^abc]] = invalid;
976 HI.Kind = index::SymbolKind::Variable;
977 HI.NamespaceScope =
"";
978 HI.Definition =
"int abc";
980 HI.AccessSpecifier =
"public";
984 void fun(int arg_a, int &arg_b) {};
992 HI.Kind = index::SymbolKind::Variable;
993 HI.NamespaceScope =
"";
994 HI.Definition =
"int b = 2";
995 HI.LocalScope =
"code::";
998 HI.CalleeArgInfo.emplace();
999 HI.CalleeArgInfo->Name =
"arg_b";
1000 HI.CalleeArgInfo->Type =
"int &";
1006 explicit Foo(int arg_a) {}
1008 template<class T, class... Args>
1009 T make(Args&&... args)
1016 auto foo = make<Foo>([[^a]]);
1021 HI.Kind = index::SymbolKind::Variable;
1022 HI.NamespaceScope =
"";
1023 HI.Definition =
"int a = 1";
1024 HI.LocalScope =
"code::";
1027 HI.CalleeArgInfo.emplace();
1028 HI.CalleeArgInfo->Name =
"arg_a";
1029 HI.CalleeArgInfo->Type =
"int";
1034 void foobar(const float &arg);
1042 HI.Kind = index::SymbolKind::Variable;
1043 HI.NamespaceScope =
"";
1044 HI.Definition =
"int a = 0";
1045 HI.LocalScope =
"main::";
1048 HI.CalleeArgInfo.emplace();
1049 HI.CalleeArgInfo->Name =
"arg";
1050 HI.CalleeArgInfo->Type =
"const float &";
1056 explicit Foo(const float& arg) {}
1065 HI.Kind = index::SymbolKind::Variable;
1066 HI.NamespaceScope =
"";
1067 HI.Definition =
"int a = 0";
1068 HI.LocalScope =
"main::";
1071 HI.CalleeArgInfo.emplace();
1072 HI.CalleeArgInfo->Name =
"arg";
1073 HI.CalleeArgInfo->Type =
"const float &";
1078 void fun(int arg_a, const int &arg_b) {};
1085 HI.Name = "literal";
1086 HI.Kind = index::SymbolKind::Unknown;
1087 HI.CalleeArgInfo.emplace();
1088 HI.CalleeArgInfo->Name =
"arg_b";
1089 HI.CalleeArgInfo->Type =
"const int &";
1094 void fun(int arg_a, const int &arg_b) {};
1101 HI.Name = "expression";
1102 HI.Kind = index::SymbolKind::Unknown;
1105 HI.CalleeArgInfo.emplace();
1106 HI.CalleeArgInfo->Name =
"arg_b";
1107 HI.CalleeArgInfo->Type =
"const int &";
1112 int add(int lhs, int rhs);
1118 HI.Name = "expression";
1119 HI.Kind = index::SymbolKind::Unknown;
1122 HI.CalleeArgInfo.emplace();
1123 HI.CalleeArgInfo->Name =
"lhs";
1124 HI.CalleeArgInfo->Type =
"int";
1129 void foobar(const float &arg);
1135 HI.Name = "literal";
1136 HI.Kind = index::SymbolKind::Unknown;
1137 HI.CalleeArgInfo.emplace();
1138 HI.CalleeArgInfo->Name =
"arg";
1139 HI.CalleeArgInfo->Type =
"const float &";
1146 void fun(int arg_a = 3, int arg_b = 4) {}
1156 HI.Kind = index::SymbolKind::Variable;
1157 HI.NamespaceScope =
"";
1158 HI.Definition =
"int a = 1";
1159 HI.LocalScope =
"code::";
1162 HI.CalleeArgInfo.emplace();
1163 HI.CalleeArgInfo->Name =
"arg_a";
1164 HI.CalleeArgInfo->Type =
"int";
1165 HI.CalleeArgInfo->Default =
"3";
1181 HI.Kind = index::SymbolKind::Variable;
1182 HI.NamespaceScope =
"";
1183 HI.Definition =
"const int x = 0";
1184 HI.LocalScope =
"bar::";
1186 HI.Type =
"const int";
1187 HI.CalleeArgInfo.emplace();
1188 HI.CalleeArgInfo->Type =
"Foo";
1199 HI.Kind = index::SymbolKind::Field;
1200 HI.NamespaceScope =
"";
1201 HI.Definition =
"int xx";
1202 HI.LocalScope =
"Foo::";
1204 HI.AccessSpecifier =
"public";
1214 HI.Kind = index::SymbolKind::Field;
1215 HI.NamespaceScope =
"";
1216 HI.Definition =
"int yy";
1217 HI.LocalScope =
"Foo::";
1219 HI.AccessSpecifier =
"public";
1226 constexpr Foo k2 = {
1227 ^[[{]]1} // FIXME: why the hover range is 1 character?
1231 HI.Name = "expression";
1232 HI.Kind = index::SymbolKind::Unknown;
1233 HI.Type =
"int[10]";
1240 template <int Size> m_int ^[[arr]][Size];
1244 HI.Kind = index::SymbolKind::Variable;
1245 HI.Type = {
"m_int[Size]",
"int[Size]"};
1246 HI.NamespaceScope =
"";
1247 HI.Definition =
"template <int Size> m_int arr[Size]";
1248 HI.TemplateParameters = {{{
"int"}, {
"Size"}, std::nullopt}};
1254 template <int Size> m_int arr[Size];
1256 template <> m_int ^[[arr]]<4>[4];
1260 HI.Kind = index::SymbolKind::Variable;
1261 HI.Type = {
"m_int[4]",
"int[4]"};
1262 HI.NamespaceScope =
"";
1263 HI.Definition =
"m_int arr[4]";
1267 template<typename T>
1273 TestHover<int>::Type ^[[a]];
1278 HI.NamespaceScope =
"";
1279 HI.LocalScope =
"code::";
1280 HI.Definition =
"TestHover<int>::Type a";
1281 HI.Kind = index::SymbolKind::Variable;
1282 HI.Type = {
"TestHover<int>::Type",
"int"};
1286 template<typename T>
1287 void ^[[foo]](T arg) {}
1291 HI.Kind = index::SymbolKind::Function;
1292 HI.NamespaceScope =
"";
1293 HI.Definition =
"template <typename T> void foo(T arg)";
1294 HI.Type =
"void (T)";
1295 HI.ReturnType =
"void";
1296 HI.Parameters = {{{
"T"}, std::string(
"arg"), std::nullopt}};
1297 HI.TemplateParameters = {
1298 {{
"typename"}, std::string(
"T"), std::nullopt}};
1302 template<typename T>
1303 using ^[[alias]] = T;
1307 HI.NamespaceScope =
"";
1309 HI.Kind = index::SymbolKind::TypeAlias;
1310 HI.Definition =
"template <typename T> using alias = T";
1312 HI.TemplateParameters = {
1313 {{
"typename"}, std::string(
"T"), std::nullopt}};
1317 template<typename T>
1320 template<typename T>
1321 using ^[[AA]] = A<T>;
1325 HI.NamespaceScope =
"";
1327 HI.Kind = index::SymbolKind::TypeAlias;
1328 HI.Definition =
"template <typename T> using AA = A<T>";
1329 HI.Type = {
"A<T>",
"T"};
1330 HI.TemplateParameters = {
1331 {{
"typename"}, std::string(
"T"), std::nullopt}};
1341 HI.NamespaceScope =
"";
1343 HI.Kind = index::SymbolKind::Variable;
1344 HI.Definition =
"m_int arr[10]";
1345 HI.Type = {
"m_int[10]",
"int[10]"};
1351 extern m_int ^[[arr]][];
1355 HI.NamespaceScope =
"";
1357 HI.Kind = index::SymbolKind::Variable;
1358 HI.Definition =
"extern m_int arr[]";
1359 HI.Type = {
"m_int[]",
"int[]"};
1367 m_int ^[[arr]][Size];
1372 HI.NamespaceScope =
"";
1373 HI.LocalScope =
"Test<Size>::";
1374 HI.AccessSpecifier =
"public";
1375 HI.Kind = index::SymbolKind::Field;
1376 HI.Definition =
"m_int arr[Size]";
1377 HI.Type = {
"m_int[Size]",
"int[Size]"};
1388 HI.NamespaceScope = "";
1389 HI.LocalScope =
"Foo::";
1391 HI.Kind = index::SymbolKind::Field;
1392 HI.Definition =
"char y : 1";
1398 HI.AccessSpecifier =
"public";
1400 for (
const auto &Case : Cases) {
1401 SCOPED_TRACE(Case.Code);
1405 TU.ExtraArgs.push_back(
"-std=c++20");
1408 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
1409 auto AST = TU.build();
1414 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
1418 Case.ExpectedBuilder(Expected);
1420 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
1421 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
1422 EXPECT_EQ(H->Name, Expected.Name);
1423 EXPECT_EQ(H->Kind, Expected.Kind);
1424 EXPECT_EQ(H->Documentation, Expected.Documentation);
1425 EXPECT_EQ(H->Definition, Expected.Definition);
1426 EXPECT_EQ(H->Type, Expected.Type);
1427 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
1428 EXPECT_EQ(H->Parameters, Expected.Parameters);
1429 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
1430 EXPECT_EQ(H->SymRange, Expected.SymRange);
1431 EXPECT_EQ(H->Value, Expected.Value);
1432 EXPECT_EQ(H->Size, Expected.Size);
1433 EXPECT_EQ(H->Offset, Expected.Offset);
1434 EXPECT_EQ(H->Align, Expected.Align);
1435 EXPECT_EQ(H->AccessSpecifier, Expected.AccessSpecifier);
1436 EXPECT_EQ(H->CalleeArgInfo, Expected.CalleeArgInfo);
1437 EXPECT_EQ(H->CallPassType, Expected.CallPassType);
1443 const char *
const Code;
1444 const std::string ClangLanguageFlag;
1445 const char *
const ExpectedDefinitionLanguage;
1446 } Cases[] = {{R
"cpp(
1447 void [[some^Global]]() {}
1451 void [[some^Global]]() {}
1453 "-xobjective-c++",
"objective-cpp"},
1455 void [[some^Global]]() {}
1457 "-xobjective-c",
"objective-c"}};
1458 for (
const auto &Case : Cases) {
1459 SCOPED_TRACE(Case.Code);
1463 if (!Case.ClangLanguageFlag.empty())
1464 TU.ExtraArgs.push_back(Case.ClangLanguageFlag);
1465 auto AST = TU.build();
1467 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
1470 EXPECT_STREQ(H->DefinitionLanguage, Case.ExpectedDefinitionLanguage);
1475 const llvm::StringRef CodePrefix = R
"cpp(
1477class Derived : public Base {};
1481 CustomClass(const Base &x) {}
1482 CustomClass(int &x) {}
1483 CustomClass(float x) {}
1484 CustomClass(int x, int y) {}
1487void int_by_ref(int &x) {}
1488void int_by_const_ref(const int &x) {}
1489void int_by_value(int x) {}
1490void base_by_ref(Base &x) {}
1491void base_by_const_ref(const Base &x) {}
1492void base_by_value(Base x) {}
1493void float_by_value(float x) {}
1494void custom_by_value(CustomClass x) {}
1498 int &int_ref = int_x;
1499 const int &int_const_ref = int_x;
1501 const Base &base_const_ref = base;
1505 const llvm::StringRef CodeSuffix =
"}";
1508 const char *
const Code;
1513 {
"int_by_value([[^int_x]]);", PassMode::Value,
false},
1514 {
"int_by_value([[^123]]);", PassMode::Value,
false},
1515 {
"int_by_ref([[^int_x]]);", PassMode::Ref,
false},
1516 {
"int_by_const_ref([[^int_x]]);", PassMode::ConstRef,
false},
1517 {
"int_by_const_ref([[^123]]);", PassMode::ConstRef,
false},
1518 {
"int_by_value([[^int_ref]]);", PassMode::Value,
false},
1519 {
"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef,
false},
1520 {
"int_by_const_ref([[^int_ref]]);", PassMode::ConstRef,
false},
1521 {
"int_by_const_ref([[^int_const_ref]]);", PassMode::ConstRef,
false},
1523 {
"base_by_ref([[^base]]);", PassMode::Ref,
false},
1524 {
"base_by_const_ref([[^base]]);", PassMode::ConstRef,
false},
1525 {
"base_by_const_ref([[^base_const_ref]]);", PassMode::ConstRef,
false},
1526 {
"base_by_value([[^base]]);", PassMode::Value,
false},
1527 {
"base_by_value([[^base_const_ref]]);", PassMode::Value,
false},
1528 {
"base_by_ref([[^derived]]);", PassMode::Ref,
false},
1529 {
"base_by_const_ref([[^derived]]);", PassMode::ConstRef,
false},
1530 {
"base_by_value([[^derived]]);", PassMode::Value,
false},
1532 {
"CustomClass c1([[^base]]);", PassMode::ConstRef,
false},
1533 {
"auto c2 = new CustomClass([[^base]]);", PassMode::ConstRef,
false},
1534 {
"CustomClass c3([[^int_x]]);", PassMode::Ref,
false},
1535 {
"CustomClass c3(int_x, [[^int_x]]);", PassMode::Value,
false},
1537 {
"float_by_value([[^int_x]]);", PassMode::Value,
true},
1538 {
"float_by_value([[^int_ref]]);", PassMode::Value,
true},
1539 {
"float_by_value([[^int_const_ref]]);", PassMode::Value,
true},
1540 {
"float_by_value([[^123.0f]]);", PassMode::Value,
false},
1541 {
"float_by_value([[^123]]);", PassMode::Value,
true},
1542 {
"custom_by_value([[^int_x]]);", PassMode::Ref,
true},
1543 {
"custom_by_value([[^float_x]]);", PassMode::Value,
true},
1544 {
"custom_by_value([[^base]]);", PassMode::ConstRef,
true},
1546 for (
const auto &Test : Tests) {
1547 SCOPED_TRACE(Test.Code);
1549 const auto Code = (CodePrefix + Test.Code + CodeSuffix).str();
1552 TU.ExtraArgs.push_back(
"-std=c++17");
1553 auto AST = TU.build();
1554 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
1556 EXPECT_EQ(H->CallPassType->PassBy, Test.PassBy);
1557 EXPECT_EQ(H->CallPassType->Converted, Test.Converted);
1562 llvm::StringRef Tests[] = {
1566 "decltype(au^to) x = 0;",
1568 R
"cpp(// Lambda auto parameter
1569 auto lamb = [](a^uto){};
1571 R"cpp(// non-named decls don't get hover. Don't crash!
1572 ^static_assert(1, "");
1574 R"cpp(// non-evaluatable expr
1575 template <typename T> void foo() {
1576 (void)[[size^of]](T);
1578 R"cpp(// should not crash on invalid semantic form of init-list-expr.
1584 constexpr Foo s = ^{
1590 "auto x = ^(int){42};",
1594 "auto x = ^nullptr;",
1597 for (
const auto &Test : Tests) {
1602 TU.ExtraArgs.push_back(
"-std=c++17");
1603 auto AST = TU.build();
1604 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
1611 const char *
const Code;
1612 const std::function<void(
HoverInfo &)> ExpectedBuilder;
1614 {
"auto x = [['^A']]; // character literal",
1616 HI.Name =
"expression";
1618 HI.Value =
"65 (0x41)";
1620 {
"auto s = ^[[\"Hello, world!\"]]; // string literal",
1622 HI.Name =
"string-literal";
1624 HI.Type =
"const char[14]";
1627 R
"cpp(// Local variable
1631 int test1 = bonjour;
1635 HI.Name = "bonjour";
1636 HI.Kind = index::SymbolKind::Variable;
1637 HI.NamespaceScope =
"";
1638 HI.LocalScope =
"main::";
1640 HI.Definition =
"int bonjour";
1643 R
"cpp(// Local variable in method
1652 HI.Name = "bonjour";
1653 HI.Kind = index::SymbolKind::Variable;
1654 HI.NamespaceScope =
"";
1655 HI.LocalScope =
"s::method::";
1657 HI.Definition =
"int bonjour";
1665 ns1::[[My^Class]]* Params;
1669 HI.Name = "MyClass";
1670 HI.Kind = index::SymbolKind::Struct;
1671 HI.NamespaceScope =
"ns1::";
1672 HI.Definition =
"struct MyClass {}";
1680 ns1::[[My^Class]]* Params;
1684 HI.Name = "MyClass";
1685 HI.Kind = index::SymbolKind::Class;
1686 HI.NamespaceScope =
"ns1::";
1687 HI.Definition =
"class MyClass {}";
1692 union MyUnion { int x; int y; };
1695 ns1::[[My^Union]] Params;
1699 HI.Name = "MyUnion";
1700 HI.Kind = index::SymbolKind::Union;
1701 HI.NamespaceScope =
"ns1::";
1702 HI.Definition =
"union MyUnion {}";
1705 R
"cpp(// Function definition via pointer
1708 auto *X = &^[[foo]];
1713 HI.Kind = index::SymbolKind::Function;
1714 HI.NamespaceScope =
"";
1715 HI.Type =
"void (int)";
1716 HI.Definition =
"void foo(int)";
1717 HI.Documentation =
"Function definition via pointer";
1718 HI.ReturnType =
"void";
1720 {{
"int"}, std::nullopt, std::nullopt},
1724 R
"cpp(// Function declaration via call
1727 return ^[[foo]](42);
1732 HI.Kind = index::SymbolKind::Function;
1733 HI.NamespaceScope =
"";
1734 HI.Type =
"int (int)";
1735 HI.Definition =
"int foo(int)";
1736 HI.Documentation =
"Function declaration via call";
1737 HI.ReturnType =
"int";
1739 {{
"int"}, std::nullopt, std::nullopt},
1744 struct Foo { int x; };
1752 HI.Kind = index::SymbolKind::Field;
1753 HI.NamespaceScope =
"";
1754 HI.LocalScope =
"Foo::";
1756 HI.Definition =
"int x";
1759 R
"cpp(// Field with initialization
1760 struct Foo { int x = 5; };
1768 HI.Kind = index::SymbolKind::Field;
1769 HI.NamespaceScope =
"";
1770 HI.LocalScope =
"Foo::";
1772 HI.Definition =
"int x = 5";
1775 R
"cpp(// Static field
1776 struct Foo { static int x; };
1783 HI.Kind = index::SymbolKind::StaticProperty;
1784 HI.NamespaceScope =
"";
1785 HI.LocalScope =
"Foo::";
1787 HI.Definition =
"static int x";
1790 R
"cpp(// Field, member initializer
1793 Foo() : ^[[x]](0) {}
1798 HI.Kind = index::SymbolKind::Field;
1799 HI.NamespaceScope =
"";
1800 HI.LocalScope =
"Foo::";
1802 HI.Definition =
"int x";
1805 R
"cpp(// Field, GNU old-style field designator
1806 struct Foo { int x; };
1808 Foo bar = { ^[[x]] : 1 };
1813 HI.Kind = index::SymbolKind::Field;
1814 HI.NamespaceScope =
"";
1815 HI.LocalScope =
"Foo::";
1817 HI.Definition =
"int x";
1822 R
"cpp(// Field, field designator
1823 struct Foo { int x; int y; };
1825 Foo bar = { .^[[x]] = 2, .y = 2 };
1830 HI.Kind = index::SymbolKind::Field;
1831 HI.NamespaceScope =
"";
1832 HI.LocalScope =
"Foo::";
1834 HI.Definition =
"int x";
1837 R
"cpp(// Method call
1838 struct Foo { int x(); };
1846 HI.Kind = index::SymbolKind::InstanceMethod;
1847 HI.NamespaceScope =
"";
1848 HI.LocalScope =
"Foo::";
1850 HI.Definition =
"int x()";
1851 HI.ReturnType =
"int";
1852 HI.Parameters = std::vector<HoverInfo::Param>{};
1855 R
"cpp(// Static method call
1856 struct Foo { static int x(); };
1863 HI.Kind = index::SymbolKind::StaticMethod;
1864 HI.NamespaceScope =
"";
1865 HI.LocalScope =
"Foo::";
1867 HI.Definition =
"static int x()";
1868 HI.ReturnType =
"int";
1869 HI.Parameters = std::vector<HoverInfo::Param>{};
1880 HI.Kind = index::SymbolKind::TypeAlias;
1881 HI.NamespaceScope =
"";
1882 HI.Definition =
"typedef int Foo";
1884 HI.Documentation =
"Typedef";
1887 R
"cpp(// Typedef with embedded definition
1888 typedef struct Bar {} Foo;
1895 HI.Kind = index::SymbolKind::TypeAlias;
1896 HI.NamespaceScope =
"";
1897 HI.Definition =
"typedef struct Bar Foo";
1898 HI.Type =
"struct Bar";
1899 HI.Documentation =
"Typedef with embedded definition";
1904 struct Foo { static void bar(); };
1906 int main() { ^[[ns]]::Foo::bar(); }
1910 HI.Kind = index::SymbolKind::Namespace;
1911 HI.NamespaceScope =
"";
1912 HI.Definition =
"namespace ns {}";
1915 R
"cpp(// Anonymous namespace
1919 } // anonymous namespace
1921 int main() { ns::[[f^oo]]++; }
1925 HI.Kind = index::SymbolKind::Variable;
1926 HI.NamespaceScope =
"ns::";
1928 HI.Definition =
"int foo";
1931 R
"cpp(// Function definition via using declaration
1942 HI.Kind = index::SymbolKind::Function;
1943 HI.NamespaceScope =
"ns::";
1944 HI.Type =
"void ()";
1945 HI.Definition =
"void foo()";
1946 HI.Documentation =
"";
1947 HI.ReturnType =
"void";
1948 HI.Parameters = std::vector<HoverInfo::Param>{};
1951 R
"cpp( // using declaration and two possible function declarations
1952 namespace ns { void foo(int); void foo(char); }
1954 template <typename T> void bar() { [[f^oo]](T{}); }
1958 HI.Kind = index::SymbolKind::Using;
1959 HI.NamespaceScope =
"";
1960 HI.Definition =
"using ns::foo";
1965 int main() { return ^[[MACRO]]; }
1971 HI.Kind = index::SymbolKind::Macro;
1972 HI.Definition =
"#define MACRO 0\n\n"
1979 #define MACRO2 ^[[MACRO]]
1983 HI.Kind = index::SymbolKind::Macro;
1984 HI.Definition =
"#define MACRO 0";
1993 int main() ^[[MACRO]]
1997 HI.Kind = index::SymbolKind::Macro;
1999 R
"cpp(#define MACRO \
2010 R"cpp(// Forward class declaration
2017 HI.Kind = index::SymbolKind::Class;
2018 HI.NamespaceScope =
"";
2019 HI.Definition =
"class Foo {}";
2020 HI.Documentation =
"Forward class declaration";
2023 R
"cpp(// Function declaration
2025 void g() { [[f^oo]](); }
2030 HI.Kind = index::SymbolKind::Function;
2031 HI.NamespaceScope =
"";
2032 HI.Type =
"void ()";
2033 HI.Definition =
"void foo()";
2034 HI.Documentation =
"Function declaration";
2035 HI.ReturnType =
"void";
2036 HI.Parameters = std::vector<HoverInfo::Param>{};
2039 R
"cpp(// Enum declaration
2044 [[Hel^lo]] hello = ONE;
2049 HI.Kind = index::SymbolKind::Enum;
2050 HI.NamespaceScope =
"";
2051 HI.Definition =
"enum Hello {}";
2052 HI.Documentation =
"Enum declaration";
2060 Hello hello = [[O^NE]];
2065 HI.Kind = index::SymbolKind::EnumConstant;
2066 HI.NamespaceScope =
"";
2067 HI.LocalScope =
"Hello::";
2068 HI.Type =
"enum Hello";
2069 HI.Definition =
"ONE";
2073 R
"cpp(// C++20's using enum
2079 Hello hello = [[O^NE]];
2084 HI.Kind = index::SymbolKind::EnumConstant;
2085 HI.NamespaceScope =
"";
2086 HI.LocalScope =
"Hello::";
2087 HI.Type =
"enum Hello";
2088 HI.Definition =
"ONE";
2092 R
"cpp(// Enumerator in anonymous enum
2097 int hello = [[O^NE]];
2102 HI.Kind = index::SymbolKind::EnumConstant;
2103 HI.NamespaceScope =
"";
2106 HI.Type =
"enum (unnamed)";
2107 HI.Definition =
"ONE";
2111 R
"cpp(// Global variable
2112 static int hey = 10;
2119 HI.Kind = index::SymbolKind::Variable;
2120 HI.NamespaceScope =
"";
2122 HI.Definition =
"static int hey = 10";
2123 HI.Documentation =
"Global variable";
2125 HI.Value =
"10 (0xa)";
2128 R
"cpp(// Global variable in namespace
2130 static long long hey = -36637162602497;
2138 HI.Kind = index::SymbolKind::Variable;
2139 HI.NamespaceScope =
"ns1::";
2140 HI.Type =
"long long";
2141 HI.Definition =
"static long long hey = -36637162602497";
2142 HI.Value =
"-36637162602497 (0xffffdeadbeefffff)";
2145 R
"cpp(// Field in anonymous struct
2155 HI.Kind = index::SymbolKind::Field;
2156 HI.NamespaceScope =
"";
2157 HI.LocalScope =
"(anonymous struct)::";
2159 HI.Definition =
"int hello";
2162 R
"cpp(// Templated function
2163 template <typename T>
2167 void g() { auto x = [[f^oo]]<int>(); }
2171 HI.Kind = index::SymbolKind::Function;
2172 HI.NamespaceScope =
"";
2174 HI.Definition =
"template <> int foo<int>()";
2175 HI.Documentation =
"Templated function";
2176 HI.ReturnType =
"int";
2177 HI.Parameters = std::vector<HoverInfo::Param>{};
2182 R
"cpp(// Anonymous union
2188 void g() { struct outer o; o.v.[[d^ef]]++; }
2192 HI.Kind = index::SymbolKind::Field;
2193 HI.NamespaceScope =
"";
2194 HI.LocalScope =
"outer::(anonymous union)::";
2196 HI.Definition =
"int def";
2199 R
"cpp(// documentation from index
2200 int nextSymbolIsAForwardDeclFromIndexWithNoLocalDocs;
2202 void g() { [[ind^exSymbol]](); }
2205 HI.Name = "indexSymbol";
2206 HI.Kind = index::SymbolKind::Function;
2207 HI.NamespaceScope =
"";
2208 HI.Type =
"void ()";
2209 HI.Definition =
"void indexSymbol()";
2210 HI.ReturnType =
"void";
2211 HI.Parameters = std::vector<HoverInfo::Param>{};
2212 HI.Documentation =
"comment from index";
2215 R
"cpp(// Simple initialization with auto
2222 HI.Kind = index::SymbolKind::TypeAlias;
2223 HI.Definition =
"int";
2226 R
"cpp(// Simple initialization with const auto
2228 const ^[[auto]] i = 1;
2233 HI.Kind = index::SymbolKind::TypeAlias;
2234 HI.Definition =
"int";
2237 R
"cpp(// Simple initialization with const auto&
2239 const ^[[auto]]& i = 1;
2244 HI.Kind = index::SymbolKind::TypeAlias;
2245 HI.Definition =
"int";
2248 R
"cpp(// Simple initialization with auto&
2256 HI.Kind = index::SymbolKind::TypeAlias;
2257 HI.Definition =
"int";
2260 R
"cpp(// Simple initialization with auto*
2268 HI.Kind = index::SymbolKind::TypeAlias;
2269 HI.Definition =
"int";
2272 R
"cpp(// Simple initialization with auto from pointer
2280 HI.Kind = index::SymbolKind::TypeAlias;
2281 HI.Definition =
"int *";
2284 R
"cpp(// Auto with initializer list.
2288 class initializer_list { const _E *a, *b; };
2291 ^[[auto]] i = {1,2};
2296 HI.Kind = index::SymbolKind::TypeAlias;
2297 HI.Definition =
"std::initializer_list<int>";
2300 R
"cpp(// User defined conversion to auto
2302 operator ^[[auto]]() const { return 10; }
2307 HI.Kind = index::SymbolKind::TypeAlias;
2308 HI.Definition =
"int";
2311 R
"cpp(// Simple initialization with decltype(auto)
2313 ^[[decltype]](auto) i = 1;
2317 HI.Name = "decltype";
2318 HI.Kind = index::SymbolKind::TypeAlias;
2319 HI.Definition =
"int";
2322 R
"cpp(// Simple initialization with const decltype(auto)
2325 ^[[decltype]](auto) i = j;
2329 HI.Name = "decltype";
2330 HI.Kind = index::SymbolKind::TypeAlias;
2331 HI.Definition =
"const int";
2334 R
"cpp(// Simple initialization with const& decltype(auto)
2338 ^[[decltype]](auto) i = j;
2342 HI.Name = "decltype";
2343 HI.Kind = index::SymbolKind::TypeAlias;
2344 HI.Definition =
"const int &";
2347 R
"cpp(// Simple initialization with & decltype(auto)
2351 ^[[decltype]](auto) i = j;
2355 HI.Name = "decltype";
2356 HI.Kind = index::SymbolKind::TypeAlias;
2357 HI.Definition =
"int &";
2360 R
"cpp(// simple trailing return type
2361 ^[[auto]] main() -> int {
2367 HI.Kind = index::SymbolKind::TypeAlias;
2368 HI.Definition =
"int";
2371 R
"cpp(// auto function return with trailing type
2373 ^[[auto]] test() -> decltype(Bar()) {
2379 HI.Kind = index::SymbolKind::TypeAlias;
2380 HI.Definition =
"Bar";
2381 HI.Documentation =
"auto function return with trailing type";
2384 R
"cpp(// trailing return type
2386 auto test() -> ^[[decltype]](Bar()) {
2391 HI.Name = "decltype";
2392 HI.Kind = index::SymbolKind::TypeAlias;
2393 HI.Definition =
"Bar";
2394 HI.Documentation =
"trailing return type";
2397 R
"cpp(// auto in function return
2405 HI.Kind = index::SymbolKind::TypeAlias;
2406 HI.Definition =
"Bar";
2407 HI.Documentation =
"auto in function return";
2410 R
"cpp(// auto& in function return
2419 HI.Kind = index::SymbolKind::TypeAlias;
2420 HI.Definition =
"Bar";
2421 HI.Documentation =
"auto& in function return";
2424 R
"cpp(// auto* in function return
2433 HI.Kind = index::SymbolKind::TypeAlias;
2434 HI.Definition =
"Bar";
2435 HI.Documentation =
"auto* in function return";
2438 R
"cpp(// const auto& in function return
2440 const ^[[auto]]& test() {
2447 HI.Kind = index::SymbolKind::TypeAlias;
2448 HI.Definition =
"Bar";
2449 HI.Documentation =
"const auto& in function return";
2452 R
"cpp(// decltype(auto) in function return
2454 ^[[decltype]](auto) test() {
2459 HI.Name = "decltype";
2460 HI.Kind = index::SymbolKind::TypeAlias;
2461 HI.Definition =
"Bar";
2462 HI.Documentation =
"decltype(auto) in function return";
2465 R
"cpp(// decltype(auto) reference in function return
2466 ^[[decltype]](auto) test() {
2472 HI.Name = "decltype";
2473 HI.Kind = index::SymbolKind::TypeAlias;
2474 HI.Definition =
"int &";
2477 R
"cpp(// decltype lvalue reference
2480 ^[[decltype]](I) J = I;
2484 HI.Name = "decltype";
2485 HI.Kind = index::SymbolKind::TypeAlias;
2486 HI.Definition =
"int";
2489 R
"cpp(// decltype lvalue reference
2493 ^[[decltype]](K) J = I;
2497 HI.Name = "decltype";
2498 HI.Kind = index::SymbolKind::TypeAlias;
2499 HI.Definition =
"int &";
2502 R
"cpp(// decltype lvalue reference parenthesis
2505 ^[[decltype]]((I)) J = I;
2509 HI.Name = "decltype";
2510 HI.Kind = index::SymbolKind::TypeAlias;
2511 HI.Definition =
"int &";
2514 R
"cpp(// decltype rvalue reference
2517 ^[[decltype]](static_cast<int&&>(I)) J = static_cast<int&&>(I);
2521 HI.Name = "decltype";
2522 HI.Kind = index::SymbolKind::TypeAlias;
2523 HI.Definition =
"int &&";
2526 R
"cpp(// decltype rvalue reference function call
2530 ^[[decltype]](bar()) J = bar();
2534 HI.Name = "decltype";
2535 HI.Kind = index::SymbolKind::TypeAlias;
2536 HI.Definition =
"int &&";
2539 R
"cpp(// decltype of function with trailing return type.
2541 auto test() -> decltype(Bar()) {
2545 ^[[decltype]](test()) i = test();
2549 HI.Name = "decltype";
2550 HI.Kind = index::SymbolKind::TypeAlias;
2551 HI.Definition =
"Bar";
2553 "decltype of function with trailing return type.";
2556 R
"cpp(// decltype of var with decltype.
2560 ^[[decltype]](J) K = J;
2564 HI.Name = "decltype";
2565 HI.Kind = index::SymbolKind::TypeAlias;
2566 HI.Definition =
"int";
2569 R
"cpp(// decltype of dependent type
2570 template <typename T>
2572 using Y = ^[[decltype]](T::Z);
2576 HI.Name = "decltype";
2577 HI.Kind = index::SymbolKind::TypeAlias;
2578 HI.Definition =
"<dependent type>";
2581 R
"cpp(// More complicated structured types.
2583 ^[[auto]] (*foo)() = bar;
2587 HI.Kind = index::SymbolKind::TypeAlias;
2588 HI.Definition =
"int";
2591 R
"cpp(// Should not crash when evaluating the initializer.
2593 void test() { Test && [[te^st]] = {}; }
2597 HI.Kind = index::SymbolKind::Variable;
2598 HI.NamespaceScope =
"";
2599 HI.LocalScope =
"test::";
2600 HI.Type =
"Test &&";
2601 HI.Definition =
"Test &&test = {}";
2604 R
"cpp(// Shouldn't crash when evaluating the initializer.
2605 struct Bar {}; // error-ok
2606 struct Foo { void foo(Bar x = y); }
2607 void Foo::foo(Bar [[^x]]) {})cpp",
2610 HI.Kind = index::SymbolKind::Parameter;
2611 HI.NamespaceScope =
"";
2612 HI.LocalScope =
"Foo::foo::";
2614 HI.Definition =
"Bar x = <recovery - expr>()";
2617 R
"cpp(// auto on alias
2618 typedef int int_type;
2619 ^[[auto]] x = int_type();
2623 HI.Kind = index::SymbolKind::TypeAlias;
2624 HI.Definition =
"int_type // aka: int";
2627 R
"cpp(// auto on alias
2629 typedef cls cls_type;
2630 ^[[auto]] y = cls_type();
2634 HI.Kind = index::SymbolKind::TypeAlias;
2635 HI.Definition =
"cls_type // aka: cls";
2636 HI.Documentation =
"auto on alias";
2639 R
"cpp(// auto on alias
2642 ^[[auto]] z = templ<int>();
2646 HI.Kind = index::SymbolKind::TypeAlias;
2647 HI.Definition =
"templ<int>";
2648 HI.Documentation =
"auto on alias";
2651 R
"cpp(// Undeduced auto declaration
2652 template<typename T>
2659 HI.Kind = index::SymbolKind::TypeAlias;
2660 HI.Definition =
"T";
2663 R
"cpp(// Undeduced auto return type
2664 template<typename T>
2671 HI.Kind = index::SymbolKind::TypeAlias;
2672 HI.Definition =
"/* not deduced */";
2675 R
"cpp(// Template auto parameter
2676 template<[[a^uto]] T>
2684 HI.Kind = index::SymbolKind::TypeAlias;
2685 HI.Definition =
"/* not deduced */";
2688 R
"cpp(// Undeduced decltype(auto) return type
2689 template<typename T>
2690 ^[[decltype]](auto) foo() {
2695 HI.Name = "decltype";
2696 HI.Kind = index::SymbolKind::TypeAlias;
2697 HI.Definition =
"/* not deduced */";
2700 R
"cpp(// should not crash.
2701 template <class T> struct cls {
2705 auto test = cls<int>().[[m^ethod]]();
2708 HI.Definition = "int method()";
2709 HI.Kind = index::SymbolKind::InstanceMethod;
2710 HI.NamespaceScope =
"";
2711 HI.LocalScope =
"cls<int>::";
2713 HI.Parameters.emplace();
2714 HI.ReturnType =
"int";
2718 R
"cpp(// type of nested templates.
2719 template <class T> struct cls {};
2720 cls<cls<cls<int>>> [[fo^o]];
2723 HI.Definition = "cls<cls<cls<int>>> foo";
2724 HI.Kind = index::SymbolKind::Variable;
2725 HI.NamespaceScope =
"";
2727 HI.Type =
"cls<cls<cls<int>>>";
2730 R
"cpp(// type of nested templates.
2731 template <class T> struct cls {};
2732 [[cl^s]]<cls<cls<int>>> foo;
2735 HI.Definition = "template <> struct cls<cls<cls<int>>> {}";
2736 HI.Kind = index::SymbolKind::Struct;
2737 HI.NamespaceScope =
"";
2738 HI.Name =
"cls<cls<cls<int>>>";
2739 HI.Documentation =
"type of nested templates.";
2742 R
"cpp(// type with decltype
2744 decltype(a) [[b^]] = a;)cpp",
2746 HI.Definition = "decltype(a) b = a";
2747 HI.Kind = index::SymbolKind::Variable;
2748 HI.NamespaceScope =
"";
2753 R
"cpp(// type with decltype
2756 decltype(c) [[b^]] = a;)cpp",
2758 HI.Definition = "decltype(c) b = a";
2759 HI.Kind = index::SymbolKind::Variable;
2760 HI.NamespaceScope =
"";
2765 R
"cpp(// type with decltype
2767 const decltype(a) [[b^]] = a;)cpp",
2769 HI.Definition = "const decltype(a) b = a";
2770 HI.Kind = index::SymbolKind::Variable;
2771 HI.NamespaceScope =
"";
2776 R
"cpp(// type with decltype
2778 auto [[f^oo]](decltype(a) x) -> decltype(a) { return 0; })cpp",
2780 HI.Definition = "auto foo(decltype(a) x) -> decltype(a)";
2781 HI.Kind = index::SymbolKind::Function;
2782 HI.NamespaceScope =
"";
2786 HI.Type = {
"auto (decltype(a)) -> decltype(a)",
2787 "auto (int) -> int"};
2788 HI.ReturnType =
"int";
2789 HI.Parameters = {{{
"int"}, std::string(
"x"), std::nullopt}};
2792 R
"cpp(// sizeof expr
2794 (void)[[size^of]](char);
2797 HI.Name = "expression";
2798 HI.Type = {
"__size_t",
"unsigned long"};
2802 R
"cpp(// alignof expr
2804 (void)[[align^of]](char);
2807 HI.Name = "expression";
2808 HI.Type = {
"__size_t",
"unsigned long"};
2813 template <typename T = int>
2814 void foo(const T& = T()) {
2819 HI.Kind = index::SymbolKind::Function;
2820 HI.Type =
"void (const int &)";
2821 HI.ReturnType =
"void";
2823 {{
"const int &"}, std::nullopt, std::string(
"T()")}};
2824 HI.Definition =
"template <> void foo<int>(const int &)";
2825 HI.NamespaceScope =
"";
2828 R
"cpp(// should not crash
2836 HI.Kind = index::SymbolKind::Field;
2837 HI.LocalScope =
"ObjC::";
2838 HI.NamespaceScope =
"";
2839 HI.Definition =
"char data";
2845 @interface Interface
2846 @property(retain) [[MYOb^ject]] *x;
2850 HI.Name = "MYObject";
2851 HI.Kind = index::SymbolKind::Class;
2852 HI.NamespaceScope =
"";
2853 HI.Definition =
"@interface MYObject\n@end";
2859 @interface Interface
2860 - (void)doWith:([[MYOb^ject]] *)object;
2864 HI.Name = "MYObject";
2865 HI.Kind = index::SymbolKind::Class;
2866 HI.NamespaceScope =
"";
2867 HI.Definition =
"@interface MYObject\n@end";
2882 HI.Definition =
"ns::Foo *";
2885 R
"cpp(// this expr for template class
2887 template <typename T>
2897 HI.Definition =
"const ns::Foo<T> *";
2900 R
"cpp(// this expr for specialization class
2902 template <typename T> class Foo {};
2913 HI.Definition =
"ns::Foo<int> *";
2916 R
"cpp(// this expr for partial specialization struct
2918 template <typename T, typename F> struct Foo {};
2919 template <typename F>
2920 struct Foo<int, F> {
2929 HI.Definition =
"const ns::Foo<int, F> *";
2935 @interface MYObject (Private)
2936 @property(nonatomic, assign) int privateField;
2939 int someFunction() {
2940 MYObject *obj = [MYObject sharedInstance];
2941 return obj.[[private^Field]];
2945 HI.Name = "privateField";
2946 HI.Kind = index::SymbolKind::InstanceProperty;
2947 HI.LocalScope =
"MYObject(Private)::";
2948 HI.NamespaceScope =
"";
2949 HI.Definition =
"@property(nonatomic, assign, unsafe_unretained, "
2950 "readwrite) int privateField;";
2954 @protocol MYProtocol
2955 @property(nonatomic, assign) int prop1;
2958 int someFunction() {
2959 id<MYProtocol> obj = 0;
2960 return obj.[[pro^p1]];
2965 HI.Kind = index::SymbolKind::InstanceProperty;
2966 HI.LocalScope =
"MYProtocol::";
2967 HI.NamespaceScope =
"";
2968 HI.Definition =
"@property(nonatomic, assign, unsafe_unretained, "
2969 "readwrite) int prop1;";
2973 @protocol MYProtocol
2978 @interface MYObject (Ext) <[[MYProt^ocol]]>
2982 HI.Name = "MYProtocol";
2983 HI.Kind = index::SymbolKind::Protocol;
2984 HI.NamespaceScope =
"";
2985 HI.Definition =
"@protocol MYProtocol\n@end";
2991 @implementation Foo(Private)
2992 + (int)somePrivateMethod {
2993 int [[res^ult]] = 2;
3000 HI.Definition =
"int result = 2";
3001 HI.Kind = index::SymbolKind::Variable;
3003 HI.LocalScope =
"+[Foo(Private) somePrivateMethod]::";
3004 HI.NamespaceScope =
"";
3012 - (int)variadicArgMethod:(id)first, ... {
3013 int [[res^ult]] = 0;
3020 HI.Definition =
"int result = 0";
3021 HI.Kind = index::SymbolKind::Variable;
3023 HI.LocalScope =
"-[Foo variadicArgMethod:, ...]::";
3024 HI.NamespaceScope =
"";
3029 typedef struct MyRect {} MyRect;
3032 @property(nonatomic) MyRect frame;
3041 v.frame = [[foo^bar]]();
3046 HI.Kind = index::SymbolKind::Function;
3047 HI.NamespaceScope =
"";
3048 HI.Definition =
"MyRect foobar()";
3049 HI.Type = {
"MyRect ()",
"struct MyRect ()"};
3050 HI.ReturnType = {
"MyRect",
"struct MyRect"};
3051 HI.Parameters.emplace();
3054 void foo(int * __attribute__(([[non^null]], noescape)) );
3057 HI.Name = "nonnull";
3058 HI.Kind = index::SymbolKind::Unknown;
3059 HI.Definition =
"__attribute__((nonnull))";
3060 HI.Documentation = Attr::getDocumentation(attr::NonNull).str();
3065 struct strong_ordering {
3067 constexpr operator int() const { return n; }
3068 static const strong_ordering equal, greater, less;
3070 constexpr strong_ordering strong_ordering::equal = {0};
3071 constexpr strong_ordering strong_ordering::greater = {1};
3072 constexpr strong_ordering strong_ordering::less = {-1};
3079 auto operator<=>(const Foo&) const = default;
3082 bool x = Foo(1) [[!^=]] Foo(2);
3085 HI.Type = "bool (const Foo &) const noexcept";
3087 HI.Name =
"operator==";
3088 HI.Parameters = {{{
"const Foo &"}, std::nullopt, std::nullopt}};
3089 HI.ReturnType =
"bool";
3090 HI.Kind = index::SymbolKind::InstanceMethod;
3091 HI.LocalScope =
"Foo::";
3092 HI.NamespaceScope =
"";
3094 "bool operator==(const Foo &) const noexcept = default";
3095 HI.Documentation =
"";
3101 IndexSym.Documentation =
"comment from index";
3107 for (
const auto &Case : Cases) {
3108 SCOPED_TRACE(Case.Code);
3112 TU.ExtraArgs.push_back(
"-std=c++20");
3113 TU.ExtraArgs.push_back(
"-xobjective-c++");
3115 TU.ExtraArgs.push_back(
"-Wno-gnu-designator");
3118 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
3119 auto AST = TU.build();
3123 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(), Index.get());
3127 Case.ExpectedBuilder(Expected);
3130 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
3131 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
3132 EXPECT_EQ(H->Name, Expected.Name);
3133 EXPECT_EQ(H->Kind, Expected.Kind);
3134 EXPECT_EQ(H->Documentation, Expected.Documentation);
3135 EXPECT_EQ(H->Definition, Expected.Definition);
3136 EXPECT_EQ(H->Type, Expected.Type);
3137 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
3138 EXPECT_EQ(H->Parameters, Expected.Parameters);
3139 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
3140 EXPECT_EQ(H->SymRange, Expected.SymRange);
3141 EXPECT_EQ(H->Value, Expected.Value);
3148 const std::function<void(
HoverInfo &)> ExpectedBuilder;
3149 } Cases[] = {{R
"cpp(
3153 [](HoverInfo &HI) { HI.Provider = ""; }},
3158 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3163 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3168 [](HoverInfo &HI) { HI.Provider = ""; }},
3173 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3178 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3185 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3194 [](HoverInfo &HI) { HI.Provider = "\"foo.h\""; }},
3197 using namespace fo^o;
3199 [](HoverInfo &HI) { HI.Provider = ""; }},
3202 for (
const auto &Case : Cases) {
3204 SCOPED_TRACE(Code.code());
3208 TU.Code = Code.code();
3209 TU.AdditionalFiles[
"foo.h"] = guard(R
"cpp(
3212 Foo& operator+(const Foo, const Foo);
3214 TU.AdditionalFiles["all.h"] = guard(
"#include \"foo.h\"");
3216 auto AST = TU.build();
3217 auto H =
getHover(
AST, Code.point(), format::getLLVMStyle(),
nullptr);
3220 Case.ExpectedBuilder(Expected);
3222 EXPECT_EQ(H->Provider, Expected.Provider);
3229 HIFoo.Provider =
"\"foo.h\"";
3232 HIFooBar.
Name =
"foo";
3233 HIFooBar.Provider =
"<bar.h>";
3236 llvm::StringRef ExpectedMarkdown;
3237 } Cases[] = {{HIFoo,
"### `foo`\n\nprovided by `\"foo.h\"`"},
3238 {HIFooBar,
"### `foo`\n\nprovided by `<bar.h>`"}};
3240 for (
const auto &Case : Cases)
3247 const std::function<void(
HoverInfo &)> ExpectedBuilder;
3248 } Cases[] = {{R
"cpp(
3250 int fstBar = bar1();
3251 int another= bar1(0);
3252 int sndBar = bar2();
3257 HI.UsedSymbolNames = {"BAR",
"Bar",
"bar1",
"bar2"};
3261 std::vector<int> vec;
3263 [](HoverInfo &HI) { HI.UsedSymbolNames = {"vector"}; }}};
3264 for (
const auto &Case : Cases) {
3266 SCOPED_TRACE(Code.code());
3270 TU.Code = Code.code();
3271 TU.AdditionalFiles[
"bar.h"] = guard(R
"cpp(
3278 TU.AdditionalFiles["system/vector"] = guard(R
"cpp(
3284 TU.ExtraArgs.push_back("-isystem" +
testPath(
"system"));
3286 auto AST = TU.build();
3287 auto H =
getHover(
AST, Code.point(), format::getLLVMStyle(),
nullptr);
3290 Case.ExpectedBuilder(Expected);
3292 EXPECT_EQ(H->UsedSymbolNames, Expected.UsedSymbolNames);
3298 template <typename T> class X {};
3306 auto AST = TU.build();
3309 IndexSym.Documentation =
"comment from index";
3315 for (
const auto &P :
T.points()) {
3316 auto H =
getHover(
AST, P, format::getLLVMStyle(), Index.get());
3318 EXPECT_EQ(H->Documentation, IndexSym.Documentation);
3325 template <typename T> class X {};
3327 template <typename T> void bar() {}
3329 template <typename T> T baz;
3334 au^to T = ba^z<X<int>>;
3339 auto AST = TU.build();
3340 for (
const auto &P :
T.points()) {
3341 auto H =
getHover(
AST, P, format::getLLVMStyle(),
nullptr);
3343 EXPECT_EQ(H->Documentation,
"doc");
3350 template<typename T> T foo(T);
3352 // Setter variable heuristic might fail if the callexpr is broken.
3353 struct X { int Y; void [[^setY]](float) { Y = foo(undefined); } };)cpp");
3356 auto AST = TU.build();
3357 for (
const auto &P :
T.points())
3358 getHover(
AST, P, format::getLLVMStyle(),
nullptr);
3363 constexpr unsigned long value = -1; // wrap around
3364 void foo() { va^lue; }
3367 getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
3372 constexpr __int128_t value = -4;
3373 void foo() { va^lue; }
3377 TU.ExtraArgs.push_back(
"--target=x86_64-pc-linux-gnu");
3378 auto AST = TU.build();
3379 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
3381 EXPECT_EQ(H->Value,
"-4 (0xfffffffc)");
3387 template <typename T> class $doc1^X {};
3389 template <> class $doc2^X<int> {};
3391 template <typename T> class $doc3^X<T*> {};
3399 auto AST = TU.build();
3400 for (
const auto *Comment : {
"doc1",
"doc2",
"doc3"}) {
3401 for (
const auto &P :
T.points(Comment)) {
3402 auto H =
getHover(
AST, P, format::getLLVMStyle(),
nullptr);
3404 EXPECT_EQ(H->Documentation, Comment);
3411 const std::function<void(
HoverInfo &)> Builder;
3412 llvm::StringRef ExpectedMarkdownRender;
3413 llvm::StringRef ExpectedDoxygenRender;
3417 HI.Kind = index::SymbolKind::Unknown;
3425 HI.Kind = index::SymbolKind::NamespaceAlias;
3428 R
"(namespace-alias foo)",
3429 R"(### namespace-alias `foo`)",
3433 HI.Kind = index::SymbolKind::Class;
3435 HI.TemplateParameters = {
3436 {{"typename"}, std::string(
"T"), std::nullopt},
3437 {{
"typename"}, std::string(
"C"), std::string(
"bool")},
3439 HI.Documentation =
"documentation";
3441 "template <typename T, typename C = bool> class Foo {}";
3443 HI.NamespaceScope.emplace();
3451template <typename T, typename C = bool> class Foo {})",
3456template <typename T, typename C = bool> class Foo {}
3465### Template Parameters
3468- `typename C = bool`
3475 HI.Kind = index::SymbolKind::Function;
3477 HI.Type = {
"type",
"c_type"};
3478 HI.ReturnType = {
"ret_type",
"can_ret_type"};
3479 HI.Parameters.emplace();
3481 HI.Parameters->push_back(P);
3482 P.Type = {
"type",
"can_type"};
3483 HI.Parameters->push_back(P);
3485 HI.Parameters->push_back(P);
3486 P.Default =
"default";
3487 HI.Parameters->push_back(P);
3488 HI.NamespaceScope =
"ns::";
3489 HI.Definition =
"ret_type foo(params) {}";
3493 "→ ret_type (aka can_ret_type)\n\n"
3496 "- type (aka can_type)\n"
3497 "- type foo (aka can_type)\n"
3498 "- type foo = default (aka can_type)\n"
3500 "// In namespace ns\n"
3501 "ret_type foo(params) {}",
3507ret_type foo(params) {}
3514- `type (aka can_type)`
3515- `type foo (aka can_type)`
3516- `type foo = default (aka can_type)`
3521`ret_type (aka can_ret_type)`)",
3525 HI.Kind = index::SymbolKind::Field;
3526 HI.LocalScope = "test::Bar::";
3529 HI.Type = {
"type",
"can_type"};
3530 HI.Definition =
"def";
3538Type: type (aka can_type)
3544Size: 4 bytes (+4 bytes padding), alignment 4 bytes
3557Type: `type (aka can_type)`
3563Size: 4 bytes (+4 bytes padding), alignment 4 bytes)",
3567 HI.Kind = index::SymbolKind::Field;
3568 HI.LocalScope = "test::Bar::";
3571 HI.Type = {
"type",
"can_type"};
3572 HI.Definition =
"def";
3580Type: type (aka can_type)
3584Offset: 4 bytes and 3 bits
3586Size: 25 bits (+4 bits padding), alignment 8 bytes
3599Type: `type (aka can_type)`
3603Offset: 4 bytes and 3 bits
3605Size: 25 bits (+4 bits padding), alignment 8 bytes)",
3609 HI.Kind = index::SymbolKind::Field;
3610 HI.AccessSpecifier = "public";
3612 HI.LocalScope =
"test::Bar::";
3613 HI.Definition =
"def";
3629 HI.Definition = "size_t method()";
3630 HI.AccessSpecifier =
"protected";
3631 HI.Kind = index::SymbolKind::InstanceMethod;
3632 HI.NamespaceScope =
"";
3633 HI.LocalScope =
"cls<int>::";
3635 HI.Parameters.emplace();
3636 HI.ReturnType = {
"size_t",
"unsigned long"};
3637 HI.Type = {
"size_t ()",
"unsigned long ()"};
3639 R
"(instance-method method
3641→ size_t (aka unsigned long)
3644protected: size_t method())",
3645 R"(### instance-method
3650protected: size_t method()
3656`size_t (aka unsigned long)`)",
3660 HI.Definition = "cls(int a, int b = 5)";
3661 HI.AccessSpecifier =
"public";
3662 HI.Kind = index::SymbolKind::Constructor;
3663 HI.NamespaceScope =
"";
3664 HI.LocalScope =
"cls";
3666 HI.Parameters.emplace();
3667 HI.Parameters->emplace_back();
3668 HI.Parameters->back().Type =
"int";
3669 HI.Parameters->back().Name =
"a";
3670 HI.Parameters->emplace_back();
3671 HI.Parameters->back().Type =
"int";
3672 HI.Parameters->back().Name =
"b";
3673 HI.Parameters->back().Default =
"5";
3683public: cls(int a, int b = 5))",
3689public: cls(int a, int b = 5)
3700 HI.Kind = index::SymbolKind::Union;
3701 HI.AccessSpecifier = "private";
3703 HI.NamespaceScope =
"ns1::";
3704 HI.Definition =
"union foo {}";
3709private: union foo {})",
3715private: union foo {}
3720 HI.Kind = index::SymbolKind::Variable;
3722 HI.Definition =
"int foo = 3";
3723 HI.LocalScope =
"test::Bar::";
3726 HI.CalleeArgInfo.emplace();
3727 HI.CalleeArgInfo->Name =
"arg_a";
3728 HI.CalleeArgInfo->Type =
"int";
3729 HI.CalleeArgInfo->Default =
"7";
3759 HI.Kind = index::SymbolKind::Variable;
3761 HI.CalleeArgInfo.emplace();
3762 HI.CalleeArgInfo->Type =
"int";
3768 R"(### variable `foo`
3775 HI.Kind = index::SymbolKind::Variable;
3777 HI.Definition =
"int foo = 3";
3778 HI.LocalScope =
"test::Bar::";
3781 HI.CalleeArgInfo.emplace();
3782 HI.CalleeArgInfo->Name =
"arg_a";
3783 HI.CalleeArgInfo->Type =
"int";
3784 HI.CalleeArgInfo->Default =
"7";
3793Passed by reference as arg_a
3810Passed by reference as arg_a)",
3814 HI.Kind = index::SymbolKind::Variable;
3816 HI.Definition =
"int foo = 3";
3817 HI.LocalScope =
"test::Bar::";
3820 HI.CalleeArgInfo.emplace();
3821 HI.CalleeArgInfo->Name =
"arg_a";
3822 HI.CalleeArgInfo->Type = {
"alias_int",
"int"};
3823 HI.CalleeArgInfo->Default =
"7";
3832Passed as arg_a (converted to alias_int)
3849Passed as arg_a (converted to alias_int))",
3853 HI.Kind = index::SymbolKind::Macro;
3854 HI.Name = "PLUS_ONE";
3855 HI.Definition =
"#define PLUS_ONE(X) (X+1)\n\n"
3861#define PLUS_ONE(X) (X+1)
3869#define PLUS_ONE(X) (X+1)
3877 HI.Kind = index::SymbolKind::Variable;
3879 HI.Definition =
"int foo = 3";
3880 HI.LocalScope =
"test::Bar::";
3883 HI.CalleeArgInfo.emplace();
3884 HI.CalleeArgInfo->Name =
"arg_a";
3885 HI.CalleeArgInfo->Type =
"int";
3886 HI.CalleeArgInfo->Default =
"7";
3895Passed by const reference as arg_a (converted to int)
3912Passed by const reference as arg_a (converted to int))",
3916 HI.Name = "stdio.h";
3917 HI.Definition =
"/usr/include/stdio.h";
3918 HI.Kind = index::SymbolKind::IncludeDirective;
3922/usr/include/stdio.h)",
3925`/usr/include/stdio.h`)",
3930 HI.UsedSymbolNames = {
"Foo",
"Bar",
"Bar"};
3931 HI.Kind = index::SymbolKind::IncludeDirective;
3935provides Foo, Bar, Bar)",
3939provides `Foo`, `Bar`, `Bar`)",
3943 HI.UsedSymbolNames = {
"Foo",
"Bar",
"Baz",
"Foobar",
"Qux",
"Quux"};
3944 HI.Kind = index::SymbolKind::IncludeDirective;
3948provides Foo, Bar, Baz, Foobar, Qux and 1 more)",
3952provides `Foo`, `Bar`, `Baz`, `Foobar`, `Qux` and 1 more)"}};
3954 for (
const auto &C : Cases) {
3963 for (
const auto &C : Cases) {
3976 const std::function<void(
HoverInfo &)> Builder;
3977 llvm::StringRef ExpectedMarkdownRender;
3978 llvm::StringRef ExpectedDoxygenRender;
3981 HI.Kind = index::SymbolKind::Function;
3982 HI.Documentation =
"@brief brief doc\n\n"
3984 HI.Definition =
"void foo()";
3987 R
"(### function `foo`
4015 HI.Kind = index::SymbolKind::Function;
4016 HI.Documentation = "@brief brief doc\n\n"
4018 HI.Definition =
"int foo()";
4019 HI.ReturnType =
"int";
4022 R
"(### function `foo`
4057 HI.Kind = index::SymbolKind::Function;
4058 HI.Documentation = R"(@brief brief doc
4063As you see, notes are "inlined".
4064@warning this is a warning
4067@param a this is a param
4068@return it returns something
4069@retval 0 if successful
4070@retval 1 if failed)";
4071 HI.Definition = "int foo(int a)";
4072 HI.ReturnType =
"int";
4074 HI.Parameters.emplace();
4075 HI.Parameters->emplace_back();
4076 HI.Parameters->back().Type =
"int";
4077 HI.Parameters->back().Name =
"a";
4079 R
"(### function `foo`
4093As you see, notes are "inlined".
4094@warning this is a warning
4097@param a this is a param
4098@return it returns something
4099@retval 0 if successful
4121- `int a` - this is a param
4126`int` - it returns something
4128- `0` - if successful
4139As you see, notes are "inlined".
4144As well as warnings)"},
4146 HI.Kind = index::SymbolKind::Function;
4147 HI.Documentation = "@brief brief doc\n\n"
4148 "longer doc\n@param a this is a param\n@param b "
4149 "does not exist\n@return it returns something";
4150 HI.Definition =
"int foo(int a)";
4151 HI.ReturnType =
"int";
4153 HI.Parameters.emplace();
4154 HI.Parameters->emplace_back();
4155 HI.Parameters->back().Type =
"int";
4156 HI.Parameters->back().Name =
"a";
4158 R
"(### function `foo`
4170@param a this is a param
4171@param b does not exist
4172@return it returns something
4193- `int a` - this is a param
4198`int` - it returns something
4206 for (
const auto &C : Cases) {
4215 for (
const auto &C : Cases) {
4228 llvm::StringRef Documentation;
4229 llvm::StringRef ExpectedRenderEscapedMarkdown;
4230 llvm::StringRef ExpectedRenderMarkdown;
4231 llvm::StringRef ExpectedRenderPlainText;
4341 "Tests primality of `p`.",
4342 "Tests primality of `p`.",
4343 "Tests primality of `p`.",
4344 "Tests primality of `p`.",
4347 "'`' should not occur in `Code`",
4348 "'\\`' should not occur in `Code`",
4349 "'`' should not occur in `Code`",
4350 "'`' should not occur in `Code`",
4354 "\\`not\nparsed\\`",
4359 for (
const auto &C : Cases) {
4360 markup::Document Output;
4363 EXPECT_EQ(Output.asEscapedMarkdown(),
C.ExpectedRenderEscapedMarkdown);
4364 EXPECT_EQ(Output.asMarkdown(),
C.ExpectedRenderMarkdown);
4365 EXPECT_EQ(Output.asPlainText(),
C.ExpectedRenderPlainText);
4373 HI.
Kind = index::SymbolKind::Variable;
4383 HI.
Kind = index::SymbolKind::Variable;
4386 HI.Definition =
"def";
4388 llvm::StringRef ExpectedMarkdown =
4389 "### variable `foo`\n"
4400 llvm::StringRef ExpectedDoxygenMarkdown =
4415 llvm::StringRef ExpectedPlaintext = R
"pt(variable foo
4426 struct strong_ordering {
4428 constexpr operator int() const { return n; }
4429 static const strong_ordering equal, greater, less;
4431 constexpr strong_ordering strong_ordering::equal = {0};
4432 constexpr strong_ordering strong_ordering::greater = {1};
4433 constexpr strong_ordering strong_ordering::less = {-1};
4436 template <typename T>
4439 friend auto operator<=>(S, S) = default;
4441 static_assert(S<void>() =^= S<void>());
4445 TU.ExtraArgs.push_back("-std=c++20");
4446 auto AST = TU.build();
4447 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4448 EXPECT_EQ(HI->Documentation,
"");
4455 auto baz = (Fo^o*)&bar;
4459 auto AST = TU.build();
4460 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4462 EXPECT_EQ(*HI->Value,
"&bar");
4465TEST(
Hover, FunctionParameterDefaulValueNotEvaluatedOnInvalidDecls) {
4467 const char *
const Code;
4468 const std::optional<std::string> HoverValue;
4471 // error-ok testing behavior on invalid decl
4473 void foo(Foo p^aram = nullptr);
4478 void foo(Foo *p^aram = nullptr);
4483 for (
const auto &C : Cases) {
4486 auto AST = TU.build();
4487 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4489 ASSERT_EQ(HI->Value,
C.HoverValue);
4504 TU.ExtraArgs.push_back(
"-std=c++17");
4505 auto AST = TU.build();
4506 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4514 #define A(x) x, x, x, x
4515 #define B(x) A(A(A(A(x))))
4516 int a^rr[] = {B(0)};
4520 auto AST = TU.build();
4521 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4524 EXPECT_EQ(H->Definition,
"int arr[]");
4527#if defined(__aarch64__)
4529#define PREDEFINEMACROS_TEST(x) DISABLED_##x
4531#define PREDEFINEMACROS_TEST(x) x
4536 using uintptr_t = __UINTPTR_TYPE__;
4537 enum Test : uintptr_t {};
4538 unsigned global_var;
4540 Test v^al = static_cast<Test>(reinterpret_cast<uintptr_t>(&global_var));
4545 TU.PredefineMacros = true;
4546 auto AST = TU.build();
4547 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4549 EXPECT_EQ(*HI->Value,
"&global_var");
4554 using uintptr_t = __UINTPTR_TYPE__;
4555 unsigned global_var;
4557 uintptr_t a^ddress = reinterpret_cast<uintptr_t>(&global_var);
4562 TU.PredefineMacros = true;
4563 auto AST = TU.build();
4564 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4566 EXPECT_EQ(*HI->Value,
"&global_var");
4571 template <bool X, typename T, typename F>
4572 struct cond { using type = T; };
4573 template <typename T, typename F>
4574 struct cond<false, T, F> { using type = F; };
4576 template <bool X, typename T, typename F>
4577 using type = typename cond<X, T, F>::type;
4580 using f^oo = type<true, int, double>;
4585 auto AST = TU.build();
4586 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4588 ASSERT_TRUE(H && H->Type);
4589 EXPECT_EQ(H->Type->Type,
"int");
4590 EXPECT_EQ(H->Definition,
"using foo = type<true, int, double>");
4594 llvm::StringRef PredefinedCXX = R
"cpp(
4596#define SizeOf sizeof
4597#define AlignOf alignof
4601using u64 = unsigned long long;
4602// calculate (a ** b) % p
4603constexpr u64 pow_with_mod(u64 a, u64 b, u64 p) {
4607 ret = (ret * a) % p;
4613#define last_n_digit(x, y, n) \
4614 pow_with_mod(x, y, pow_with_mod(10, n, 2147483647))
4615#define declare_struct(X, name, value) \
4617 constexpr auto name() { return value; } \
4619#define gnu_statement_expression(value) \
4621 declare_struct(Widget, getter, value); \
4622 Widget().getter(); \
4624#define define_lambda_begin(lambda, ...) \
4626#define define_lambda_end() }
4628#define left_bracket [
4629#define right_bracket ]
4630#define dg_left_bracket <:
4631#define dg_right_bracket :>
4632#define array_decl(type, name, size) type name left_bracket size right_bracket
4636 llvm::StringRef Code;
4637 const std::function<void(std::optional<HoverInfo>,
size_t )>
4645 [](std::optional<HoverInfo> HI, size_t) {
4646 EXPECT_EQ(HI->Value,
"42 (0x2a)");
4655 [](std::optional<HoverInfo> HI, size_t) {
4656 EXPECT_TRUE(HI->Value);
4657 EXPECT_TRUE(HI->Type);
4672 [](std::optional<HoverInfo> HI, size_t) {
4673 EXPECT_TRUE(HI->Value);
4674 EXPECT_TRUE(HI->Type);
4679 // 2**32 == 4294967296
4680 last_n_di^git(2, 32, 6);
4683 [](std::optional<HoverInfo> HI, size_t) {
4684 EXPECT_EQ(HI->Value,
"967296 (0xec280)");
4685 EXPECT_EQ(HI->Type,
"u64");
4690 gnu_statement_exp^ression(42);
4693 [](std::optional<HoverInfo> HI, size_t) {
4694 EXPECT_EQ(HI->Value,
"42 (0x2a)");
4695 EXPECT_EQ(HI->Type,
"int");
4703 [](std::optional<HoverInfo> HI, size_t) {
4704 EXPECT_EQ(HI->Value,
"2");
4705 EXPECT_EQ(HI->Type,
"int");
4713 [](std::optional<HoverInfo> HI, size_t) {
4714 EXPECT_FALSE(HI->Value) << HI->Value;
4715 EXPECT_FALSE(HI->Type) << HI->Type;
4723 [](std::optional<HoverInfo> HI, size_t) {
4724 EXPECT_EQ(HI->Value,
"2");
4725 EXPECT_EQ(HI->Type,
"int");
4730 arra^y_decl(int, vector, 10);
4731 vector left_b^racket 3 right_b^racket;
4732 vector dg_le^ft_bracket 3 dg_righ^t_bracket;
4735 [](std::optional<HoverInfo> HI,
size_t Id) {
4744 EXPECT_FALSE(HI->Type) << HI->Type;
4745 EXPECT_FALSE(HI->Value) << HI->Value;
4748 ASSERT_TRUE(
false) <<
"Unhandled id: " << Id;
4754 constexpr auto value = define_lamb^da_begin(lambda, int, char)
4755 // Check if the expansion range is right.
4756 return ^last_n_digit(10, 3, 3)^;
4757 define_lam^bda_end();
4760 [](std::optional<HoverInfo> HI,
size_t Id) {
4763 EXPECT_FALSE(HI->Value);
4767 EXPECT_EQ(HI->Value,
"0");
4774 EXPECT_FALSE(HI->Type) << HI->Type;
4775 EXPECT_FALSE(HI->Value) << HI->Value;
4778 ASSERT_TRUE(
false) <<
"Unhandled id: " << Id;
4787 for (
const auto &C : Cases) {
4789 (PredefinedCXX +
"void function() {\n" +
C.Code +
"}\n").str());
4791 TU.ExtraArgs.push_back(
"-std=c++17");
4792 auto AST = TU.build();
4793 for (
auto [Index,
Position] : llvm::enumerate(Code.points())) {
4800 #define alignof _Alignof
4802 al^ignof(struct { int x; char y[10]; });
4807 TU.Filename =
"TestTU.c";
4811 auto AST = TU.build();
4812 auto H =
getHover(
AST,
C.point(), format::getLLVMStyle(),
nullptr);
4815 EXPECT_TRUE(H->Value);
4816 EXPECT_TRUE(H->Type);
4820 const char *
const Code =
4822 #define C(A) A##A // Concatenate
4823 #define E(A) C(A) // Expand
4824 #define Z0032 00000000000000000000000000000000
4825 #define Z0064 E(Z0032)
4826 #define Z0128 E(Z0064)
4827 #define Z0256 E(Z0128)
4828 #define Z0512 E(Z0256)
4829 #define Z1024 E(Z0512)
4830 #define Z2048 E(Z1024)
4831 #define Z4096 E(Z2048) // 4096 zeroes
4832 int main() { return [[^Z4096]]; }
4836 uint32_t MacroContentsLimit;
4837 const std::string ExpectedDefinition;
4840 {2048,
"#define Z4096 E(Z2048)"},
4842 {8192, std::string(
"#define Z4096 E(Z2048)\n\n") +
4843 std::string(
"// Expands to\n") + std::string(4096,
'0')},
4845 for (
const auto &Case : Cases) {
4850 auto AST = TU.build();
4854 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4857 EXPECT_EQ(H->Definition, Case.ExpectedDefinition);
4863 const char *
const Code;
4864 const std::function<void(
HoverInfo &)> ExpectedBuilder;
4865 std::string ExpectedRender;
4867 {R
"cpp(/// Function doc
4868 void foo(int [[^a]]);
4872 HI.Kind = index::SymbolKind::Parameter;
4873 HI.NamespaceScope =
"";
4874 HI.LocalScope =
"foo::";
4876 HI.Definition =
"int a";
4877 HI.Documentation =
"";
4879 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nType: `int`"},
4880 {R
"cpp(/// Function doc
4882 void foo(int [[^a]]);
4886 HI.Kind = index::SymbolKind::Parameter;
4887 HI.NamespaceScope =
"";
4888 HI.LocalScope =
"foo::";
4890 HI.Definition =
"int a";
4891 HI.Documentation =
"this is doc for a";
4893 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nthis is doc "
4894 "for a\n\n---\nType: `int`"},
4895 {R
"cpp(/// Function doc
4897 void foo(int [[^a]], int b);
4901 HI.Kind = index::SymbolKind::Parameter;
4902 HI.NamespaceScope =
"";
4903 HI.LocalScope =
"foo::";
4905 HI.Definition =
"int a";
4906 HI.Documentation =
"";
4908 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nType: `int`"},
4909 {R
"cpp(/// Function doc
4911 void foo(int a, int [[^b]]);
4915 HI.Kind = index::SymbolKind::Parameter;
4916 HI.NamespaceScope =
"";
4917 HI.LocalScope =
"foo::";
4919 HI.Definition =
"int b";
4920 HI.Documentation =
"this is doc for \\p b";
4922 "### param\n\n---\n```cpp\n// In foo\nint b\n```\n\n---\nthis is doc "
4923 "for `b`\n\n---\nType: `int`"},
4924 {R
"cpp(/// Function doc
4926 template <typename T>
4927 void foo(T a, T [[^b]]);
4931 HI.Kind = index::SymbolKind::Parameter;
4932 HI.NamespaceScope =
"";
4933 HI.LocalScope =
"foo::";
4935 HI.Definition =
"T b";
4936 HI.Documentation =
"this is doc for \\p b";
4938 "### param\n\n---\n```cpp\n// In foo\nT b\n```\n\n---\nthis is doc for "
4939 "`b`\n\n---\nType: `T`"},
4940 {R
"cpp(/// Function doc
4942 void foo(int a, int [[^b]]);
4946 HI.Kind = index::SymbolKind::Parameter;
4947 HI.NamespaceScope =
"";
4948 HI.LocalScope =
"foo::";
4950 HI.Definition =
"int b";
4952 "this is <b>doc</b> <html-tag attribute/> <another-html-tag "
4953 "attribute=\"value\">for</another-html-tag> \\p b";
4955 "### param\n\n---\n```cpp\n// In foo\nint b\n```\n\n---\nthis is "
4956 "\\<b>doc\\</b> \\<html-tag attribute/> \\<another-html-tag "
4957 "attribute=\"value\">for\\</another-html-tag> `b`\n\n---\nType: `int`"},
4962 IndexSym.Documentation =
"comment from index";
4968 for (
const auto &Case : Cases) {
4969 SCOPED_TRACE(Case.Code);
4973 auto AST = TU.build();
4978 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(), Index.get());
4982 Case.ExpectedBuilder(Expected);
4985 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
4986 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
4987 EXPECT_EQ(H->Name, Expected.Name);
4988 EXPECT_EQ(H->Kind, Expected.Kind);
4989 EXPECT_EQ(H->Documentation, Expected.Documentation);
4990 EXPECT_EQ(H->Definition, Expected.Definition);
4991 EXPECT_EQ(H->Type, Expected.Type);
4992 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
4993 EXPECT_EQ(H->Parameters, Expected.Parameters);
4994 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
4995 EXPECT_EQ(H->SymRange, Expected.SymRange);
4996 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::ProBoundsAvoidUncheckedContainerAccess 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)