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 {}
3460**Template Parameters:**
3463- `typename C = bool`
3473 HI.Kind = index::SymbolKind::Function;
3475 HI.Type = {
"type",
"c_type"};
3476 HI.ReturnType = {
"ret_type",
"can_ret_type"};
3477 HI.Parameters.emplace();
3479 HI.Parameters->push_back(P);
3480 P.Type = {
"type",
"can_type"};
3481 HI.Parameters->push_back(P);
3483 HI.Parameters->push_back(P);
3484 P.Default =
"default";
3485 HI.Parameters->push_back(P);
3486 HI.NamespaceScope =
"ns::";
3487 HI.Definition =
"ret_type foo(params) {}";
3491 "→ ret_type (aka can_ret_type)\n\n"
3494 "- type (aka can_type)\n"
3495 "- type foo (aka can_type)\n"
3496 "- type foo = default (aka can_type)\n"
3498 "// In namespace ns\n"
3499 "ret_type foo(params) {}",
3505ret_type foo(params) {}
3512- `type (aka can_type)`
3513- `type foo (aka can_type)`
3514- `type foo = default (aka can_type)`
3519`ret_type (aka can_ret_type)`)",
3523 HI.Kind = index::SymbolKind::Field;
3524 HI.LocalScope = "test::Bar::";
3527 HI.Type = {
"type",
"can_type"};
3528 HI.Definition =
"def";
3536Type: type (aka can_type)
3542Size: 4 bytes (+4 bytes padding), alignment 4 bytes
3555Type: `type (aka can_type)`
3561Size: 4 bytes (+4 bytes padding), alignment 4 bytes)",
3565 HI.Kind = index::SymbolKind::Field;
3566 HI.LocalScope = "test::Bar::";
3569 HI.Type = {
"type",
"can_type"};
3570 HI.Definition =
"def";
3578Type: type (aka can_type)
3582Offset: 4 bytes and 3 bits
3584Size: 25 bits (+4 bits padding), alignment 8 bytes
3597Type: `type (aka can_type)`
3601Offset: 4 bytes and 3 bits
3603Size: 25 bits (+4 bits padding), alignment 8 bytes)",
3607 HI.Kind = index::SymbolKind::Field;
3608 HI.AccessSpecifier = "public";
3610 HI.LocalScope =
"test::Bar::";
3611 HI.Definition =
"def";
3627 HI.Definition = "size_t method()";
3628 HI.AccessSpecifier =
"protected";
3629 HI.Kind = index::SymbolKind::InstanceMethod;
3630 HI.NamespaceScope =
"";
3631 HI.LocalScope =
"cls<int>::";
3633 HI.Parameters.emplace();
3634 HI.ReturnType = {
"size_t",
"unsigned long"};
3635 HI.Type = {
"size_t ()",
"unsigned long ()"};
3637 R
"(instance-method method
3639→ size_t (aka unsigned long)
3642protected: size_t method())",
3643 R"(### instance-method
3648protected: size_t method()
3654`size_t (aka unsigned long)`)",
3658 HI.Definition = "cls(int a, int b = 5)";
3659 HI.AccessSpecifier =
"public";
3660 HI.Kind = index::SymbolKind::Constructor;
3661 HI.NamespaceScope =
"";
3662 HI.LocalScope =
"cls";
3664 HI.Parameters.emplace();
3665 HI.Parameters->emplace_back();
3666 HI.Parameters->back().Type =
"int";
3667 HI.Parameters->back().Name =
"a";
3668 HI.Parameters->emplace_back();
3669 HI.Parameters->back().Type =
"int";
3670 HI.Parameters->back().Name =
"b";
3671 HI.Parameters->back().Default =
"5";
3681public: cls(int a, int b = 5))",
3687public: cls(int a, int b = 5)
3698 HI.Kind = index::SymbolKind::Union;
3699 HI.AccessSpecifier = "private";
3701 HI.NamespaceScope =
"ns1::";
3702 HI.Definition =
"union foo {}";
3707private: union foo {})",
3713private: union foo {}
3718 HI.Kind = index::SymbolKind::Variable;
3720 HI.Definition =
"int foo = 3";
3721 HI.LocalScope =
"test::Bar::";
3724 HI.CalleeArgInfo.emplace();
3725 HI.CalleeArgInfo->Name =
"arg_a";
3726 HI.CalleeArgInfo->Type =
"int";
3727 HI.CalleeArgInfo->Default =
"7";
3757 HI.Kind = index::SymbolKind::Variable;
3759 HI.CalleeArgInfo.emplace();
3760 HI.CalleeArgInfo->Type =
"int";
3766 R"(### variable `foo`
3773 HI.Kind = index::SymbolKind::Variable;
3775 HI.Definition =
"int foo = 3";
3776 HI.LocalScope =
"test::Bar::";
3779 HI.CalleeArgInfo.emplace();
3780 HI.CalleeArgInfo->Name =
"arg_a";
3781 HI.CalleeArgInfo->Type =
"int";
3782 HI.CalleeArgInfo->Default =
"7";
3791Passed by reference as arg_a
3808Passed by reference as arg_a)",
3812 HI.Kind = index::SymbolKind::Variable;
3814 HI.Definition =
"int foo = 3";
3815 HI.LocalScope =
"test::Bar::";
3818 HI.CalleeArgInfo.emplace();
3819 HI.CalleeArgInfo->Name =
"arg_a";
3820 HI.CalleeArgInfo->Type = {
"alias_int",
"int"};
3821 HI.CalleeArgInfo->Default =
"7";
3830Passed as arg_a (converted to alias_int)
3847Passed as arg_a (converted to alias_int))",
3851 HI.Kind = index::SymbolKind::Macro;
3852 HI.Name = "PLUS_ONE";
3853 HI.Definition =
"#define PLUS_ONE(X) (X+1)\n\n"
3859#define PLUS_ONE(X) (X+1)
3867#define PLUS_ONE(X) (X+1)
3875 HI.Kind = index::SymbolKind::Variable;
3877 HI.Definition =
"int foo = 3";
3878 HI.LocalScope =
"test::Bar::";
3881 HI.CalleeArgInfo.emplace();
3882 HI.CalleeArgInfo->Name =
"arg_a";
3883 HI.CalleeArgInfo->Type =
"int";
3884 HI.CalleeArgInfo->Default =
"7";
3893Passed by const reference as arg_a (converted to int)
3910Passed by const reference as arg_a (converted to int))",
3914 HI.Name = "stdio.h";
3915 HI.Definition =
"/usr/include/stdio.h";
3916 HI.Kind = index::SymbolKind::IncludeDirective;
3920/usr/include/stdio.h)",
3923`/usr/include/stdio.h`)",
3928 HI.UsedSymbolNames = {
"Foo",
"Bar",
"Bar"};
3929 HI.Kind = index::SymbolKind::IncludeDirective;
3933provides Foo, Bar, Bar)",
3937provides `Foo`, `Bar`, `Bar`)",
3941 HI.UsedSymbolNames = {
"Foo",
"Bar",
"Baz",
"Foobar",
"Qux",
"Quux"};
3942 HI.Kind = index::SymbolKind::IncludeDirective;
3946provides Foo, Bar, Baz, Foobar, Qux and 1 more)",
3950provides `Foo`, `Bar`, `Baz`, `Foobar`, `Qux` and 1 more)"}};
3952 for (
const auto &C : Cases) {
3961 for (
const auto &C : Cases) {
3974 const std::function<void(
HoverInfo &)> Builder;
3975 llvm::StringRef ExpectedMarkdownRender;
3976 llvm::StringRef ExpectedDoxygenRender;
3979 HI.Kind = index::SymbolKind::Function;
3980 HI.Documentation =
"@brief brief doc\n\n"
3982 HI.Definition =
"void foo()";
3985 R
"(### function `foo`
4009 HI.Kind = index::SymbolKind::Function;
4010 HI.Documentation = "@brief brief doc\n\n"
4012 HI.Definition =
"int foo()";
4013 HI.ReturnType =
"int";
4016 R
"(### function `foo`
4047 HI.Kind = index::SymbolKind::Function;
4048 HI.Documentation = "@brief brief doc\n\n"
4049 "longer doc\n@param a this is a param\n@return it "
4050 "returns something";
4051 HI.Definition =
"int foo(int a)";
4052 HI.ReturnType =
"int";
4054 HI.Parameters.emplace();
4055 HI.Parameters->emplace_back();
4056 HI.Parameters->back().Type =
"int";
4057 HI.Parameters->back().Name =
"a";
4059 R
"(### function `foo`
4071@param a this is a param
4072@return it returns something
4091- `int a` - this is a param
4096`int` - it returns something
4101 HI.Kind = index::SymbolKind::Function;
4102 HI.Documentation = "@brief brief doc\n\n"
4103 "longer doc\n@param a this is a param\n@param b "
4104 "does not exist\n@return it returns something";
4105 HI.Definition =
"int foo(int a)";
4106 HI.ReturnType =
"int";
4108 HI.Parameters.emplace();
4109 HI.Parameters->emplace_back();
4110 HI.Parameters->back().Type =
"int";
4111 HI.Parameters->back().Name =
"a";
4113 R
"(### function `foo`
4125@param a this is a param
4126@param b does not exist
4127@return it returns something
4146- `int a` - this is a param
4151`int` - it returns something
4157 for (
const auto &C : Cases) {
4166 for (
const auto &C : Cases) {
4179 llvm::StringRef Documentation;
4180 llvm::StringRef ExpectedRenderEscapedMarkdown;
4181 llvm::StringRef ExpectedRenderMarkdown;
4182 llvm::StringRef ExpectedRenderPlainText;
4292 "Tests primality of `p`.",
4293 "Tests primality of `p`.",
4294 "Tests primality of `p`.",
4295 "Tests primality of `p`.",
4298 "'`' should not occur in `Code`",
4299 "'\\`' should not occur in `Code`",
4300 "'`' should not occur in `Code`",
4301 "'`' should not occur in `Code`",
4305 "\\`not\nparsed\\`",
4310 for (
const auto &C : Cases) {
4311 markup::Document Output;
4314 EXPECT_EQ(Output.asEscapedMarkdown(),
C.ExpectedRenderEscapedMarkdown);
4315 EXPECT_EQ(Output.asMarkdown(),
C.ExpectedRenderMarkdown);
4316 EXPECT_EQ(Output.asPlainText(),
C.ExpectedRenderPlainText);
4324 HI.
Kind = index::SymbolKind::Variable;
4334 HI.
Kind = index::SymbolKind::Variable;
4337 HI.Definition =
"def";
4339 llvm::StringRef ExpectedMarkdown =
4340 "### variable `foo`\n"
4351 llvm::StringRef ExpectedDoxygenMarkdown =
4366 llvm::StringRef ExpectedPlaintext = R
"pt(variable foo
4377 struct strong_ordering {
4379 constexpr operator int() const { return n; }
4380 static const strong_ordering equal, greater, less;
4382 constexpr strong_ordering strong_ordering::equal = {0};
4383 constexpr strong_ordering strong_ordering::greater = {1};
4384 constexpr strong_ordering strong_ordering::less = {-1};
4387 template <typename T>
4390 friend auto operator<=>(S, S) = default;
4392 static_assert(S<void>() =^= S<void>());
4396 TU.ExtraArgs.push_back("-std=c++20");
4397 auto AST = TU.build();
4398 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4399 EXPECT_EQ(HI->Documentation,
"");
4406 auto baz = (Fo^o*)&bar;
4410 auto AST = TU.build();
4411 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4413 EXPECT_EQ(*HI->Value,
"&bar");
4416TEST(
Hover, FunctionParameterDefaulValueNotEvaluatedOnInvalidDecls) {
4418 const char *
const Code;
4419 const std::optional<std::string> HoverValue;
4422 // error-ok testing behavior on invalid decl
4424 void foo(Foo p^aram = nullptr);
4429 void foo(Foo *p^aram = nullptr);
4434 for (
const auto &C : Cases) {
4437 auto AST = TU.build();
4438 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4440 ASSERT_EQ(HI->Value,
C.HoverValue);
4455 TU.ExtraArgs.push_back(
"-std=c++17");
4456 auto AST = TU.build();
4457 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4465 #define A(x) x, x, x, x
4466 #define B(x) A(A(A(A(x))))
4467 int a^rr[] = {B(0)};
4471 auto AST = TU.build();
4472 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4475 EXPECT_EQ(H->Definition,
"int arr[]");
4478#if defined(__aarch64__)
4480#define PREDEFINEMACROS_TEST(x) DISABLED_##x
4482#define PREDEFINEMACROS_TEST(x) x
4487 using uintptr_t = __UINTPTR_TYPE__;
4488 enum Test : uintptr_t {};
4489 unsigned global_var;
4491 Test v^al = static_cast<Test>(reinterpret_cast<uintptr_t>(&global_var));
4496 TU.PredefineMacros = true;
4497 auto AST = TU.build();
4498 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4500 EXPECT_EQ(*HI->Value,
"&global_var");
4505 using uintptr_t = __UINTPTR_TYPE__;
4506 unsigned global_var;
4508 uintptr_t a^ddress = reinterpret_cast<uintptr_t>(&global_var);
4513 TU.PredefineMacros = true;
4514 auto AST = TU.build();
4515 auto HI =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4517 EXPECT_EQ(*HI->Value,
"&global_var");
4522 template <bool X, typename T, typename F>
4523 struct cond { using type = T; };
4524 template <typename T, typename F>
4525 struct cond<false, T, F> { using type = F; };
4527 template <bool X, typename T, typename F>
4528 using type = typename cond<X, T, F>::type;
4531 using f^oo = type<true, int, double>;
4536 auto AST = TU.build();
4537 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4539 ASSERT_TRUE(H && H->Type);
4540 EXPECT_EQ(H->Type->Type,
"int");
4541 EXPECT_EQ(H->Definition,
"using foo = type<true, int, double>");
4545 llvm::StringRef PredefinedCXX = R
"cpp(
4547#define SizeOf sizeof
4548#define AlignOf alignof
4552using u64 = unsigned long long;
4553// calculate (a ** b) % p
4554constexpr u64 pow_with_mod(u64 a, u64 b, u64 p) {
4558 ret = (ret * a) % p;
4564#define last_n_digit(x, y, n) \
4565 pow_with_mod(x, y, pow_with_mod(10, n, 2147483647))
4566#define declare_struct(X, name, value) \
4568 constexpr auto name() { return value; } \
4570#define gnu_statement_expression(value) \
4572 declare_struct(Widget, getter, value); \
4573 Widget().getter(); \
4575#define define_lambda_begin(lambda, ...) \
4577#define define_lambda_end() }
4579#define left_bracket [
4580#define right_bracket ]
4581#define dg_left_bracket <:
4582#define dg_right_bracket :>
4583#define array_decl(type, name, size) type name left_bracket size right_bracket
4587 llvm::StringRef Code;
4588 const std::function<void(std::optional<HoverInfo>,
size_t )>
4596 [](std::optional<HoverInfo> HI, size_t) {
4597 EXPECT_EQ(HI->Value,
"42 (0x2a)");
4606 [](std::optional<HoverInfo> HI, size_t) {
4607 EXPECT_TRUE(HI->Value);
4608 EXPECT_TRUE(HI->Type);
4623 [](std::optional<HoverInfo> HI, size_t) {
4624 EXPECT_TRUE(HI->Value);
4625 EXPECT_TRUE(HI->Type);
4630 // 2**32 == 4294967296
4631 last_n_di^git(2, 32, 6);
4634 [](std::optional<HoverInfo> HI, size_t) {
4635 EXPECT_EQ(HI->Value,
"967296 (0xec280)");
4636 EXPECT_EQ(HI->Type,
"u64");
4641 gnu_statement_exp^ression(42);
4644 [](std::optional<HoverInfo> HI, size_t) {
4645 EXPECT_EQ(HI->Value,
"42 (0x2a)");
4646 EXPECT_EQ(HI->Type,
"int");
4654 [](std::optional<HoverInfo> HI, size_t) {
4655 EXPECT_EQ(HI->Value,
"2");
4656 EXPECT_EQ(HI->Type,
"int");
4664 [](std::optional<HoverInfo> HI, size_t) {
4665 EXPECT_FALSE(HI->Value) << HI->Value;
4666 EXPECT_FALSE(HI->Type) << HI->Type;
4674 [](std::optional<HoverInfo> HI, size_t) {
4675 EXPECT_EQ(HI->Value,
"2");
4676 EXPECT_EQ(HI->Type,
"int");
4681 arra^y_decl(int, vector, 10);
4682 vector left_b^racket 3 right_b^racket;
4683 vector dg_le^ft_bracket 3 dg_righ^t_bracket;
4686 [](std::optional<HoverInfo> HI,
size_t Id) {
4695 EXPECT_FALSE(HI->Type) << HI->Type;
4696 EXPECT_FALSE(HI->Value) << HI->Value;
4699 ASSERT_TRUE(
false) <<
"Unhandled id: " << Id;
4705 constexpr auto value = define_lamb^da_begin(lambda, int, char)
4706 // Check if the expansion range is right.
4707 return ^last_n_digit(10, 3, 3)^;
4708 define_lam^bda_end();
4711 [](std::optional<HoverInfo> HI,
size_t Id) {
4714 EXPECT_FALSE(HI->Value);
4718 EXPECT_EQ(HI->Value,
"0");
4725 EXPECT_FALSE(HI->Type) << HI->Type;
4726 EXPECT_FALSE(HI->Value) << HI->Value;
4729 ASSERT_TRUE(
false) <<
"Unhandled id: " << Id;
4738 for (
const auto &C : Cases) {
4740 (PredefinedCXX +
"void function() {\n" +
C.Code +
"}\n").str());
4742 TU.ExtraArgs.push_back(
"-std=c++17");
4743 auto AST = TU.build();
4744 for (
auto [Index,
Position] : llvm::enumerate(Code.points())) {
4751 #define alignof _Alignof
4753 al^ignof(struct { int x; char y[10]; });
4758 TU.Filename =
"TestTU.c";
4762 auto AST = TU.build();
4763 auto H =
getHover(
AST,
C.point(), format::getLLVMStyle(),
nullptr);
4766 EXPECT_TRUE(H->Value);
4767 EXPECT_TRUE(H->Type);
4771 const char *
const Code =
4773 #define C(A) A##A // Concatenate
4774 #define E(A) C(A) // Expand
4775 #define Z0032 00000000000000000000000000000000
4776 #define Z0064 E(Z0032)
4777 #define Z0128 E(Z0064)
4778 #define Z0256 E(Z0128)
4779 #define Z0512 E(Z0256)
4780 #define Z1024 E(Z0512)
4781 #define Z2048 E(Z1024)
4782 #define Z4096 E(Z2048) // 4096 zeroes
4783 int main() { return [[^Z4096]]; }
4787 uint32_t MacroContentsLimit;
4788 const std::string ExpectedDefinition;
4791 {2048,
"#define Z4096 E(Z2048)"},
4793 {8192, std::string(
"#define Z4096 E(Z2048)\n\n") +
4794 std::string(
"// Expands to\n") + std::string(4096,
'0')},
4796 for (
const auto &Case : Cases) {
4801 auto AST = TU.build();
4805 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(),
nullptr);
4808 EXPECT_EQ(H->Definition, Case.ExpectedDefinition);
4814 const char *
const Code;
4815 const std::function<void(
HoverInfo &)> ExpectedBuilder;
4816 std::string ExpectedRender;
4818 {R
"cpp(/// Function doc
4819 void foo(int [[^a]]);
4823 HI.Kind = index::SymbolKind::Parameter;
4824 HI.NamespaceScope =
"";
4825 HI.LocalScope =
"foo::";
4827 HI.Definition =
"int a";
4828 HI.Documentation =
"";
4830 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nType: `int`"},
4831 {R
"cpp(/// Function doc
4833 void foo(int [[^a]]);
4837 HI.Kind = index::SymbolKind::Parameter;
4838 HI.NamespaceScope =
"";
4839 HI.LocalScope =
"foo::";
4841 HI.Definition =
"int a";
4842 HI.Documentation =
"this is doc for a";
4844 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nthis is doc "
4845 "for a\n\n---\nType: `int`"},
4846 {R
"cpp(/// Function doc
4848 void foo(int [[^a]], int b);
4852 HI.Kind = index::SymbolKind::Parameter;
4853 HI.NamespaceScope =
"";
4854 HI.LocalScope =
"foo::";
4856 HI.Definition =
"int a";
4857 HI.Documentation =
"";
4859 "### param\n\n---\n```cpp\n// In foo\nint a\n```\n\n---\nType: `int`"},
4860 {R
"cpp(/// Function doc
4862 void foo(int a, int [[^b]]);
4866 HI.Kind = index::SymbolKind::Parameter;
4867 HI.NamespaceScope =
"";
4868 HI.LocalScope =
"foo::";
4870 HI.Definition =
"int b";
4871 HI.Documentation =
"this is doc for \\p b";
4873 "### param\n\n---\n```cpp\n// In foo\nint b\n```\n\n---\nthis is doc "
4874 "for `b`\n\n---\nType: `int`"},
4875 {R
"cpp(/// Function doc
4877 template <typename T>
4878 void foo(T a, T [[^b]]);
4882 HI.Kind = index::SymbolKind::Parameter;
4883 HI.NamespaceScope =
"";
4884 HI.LocalScope =
"foo::";
4886 HI.Definition =
"T b";
4887 HI.Documentation =
"this is doc for \\p b";
4889 "### param\n\n---\n```cpp\n// In foo\nT b\n```\n\n---\nthis is doc for "
4890 "`b`\n\n---\nType: `T`"},
4891 {R
"cpp(/// Function doc
4893 void foo(int a, int [[^b]]);
4897 HI.Kind = index::SymbolKind::Parameter;
4898 HI.NamespaceScope =
"";
4899 HI.LocalScope =
"foo::";
4901 HI.Definition =
"int b";
4903 "this is <b>doc</b> <html-tag attribute/> <another-html-tag "
4904 "attribute=\"value\">for</another-html-tag> \\p b";
4906 "### param\n\n---\n```cpp\n// In foo\nint b\n```\n\n---\nthis is "
4907 "\\<b>doc\\</b> \\<html-tag attribute/> \\<another-html-tag "
4908 "attribute=\"value\">for\\</another-html-tag> `b`\n\n---\nType: `int`"},
4913 IndexSym.Documentation =
"comment from index";
4919 for (
const auto &Case : Cases) {
4920 SCOPED_TRACE(Case.Code);
4924 auto AST = TU.build();
4929 auto H =
getHover(
AST,
T.point(), format::getLLVMStyle(), Index.get());
4933 Case.ExpectedBuilder(Expected);
4936 EXPECT_EQ(H->NamespaceScope, Expected.NamespaceScope);
4937 EXPECT_EQ(H->LocalScope, Expected.LocalScope);
4938 EXPECT_EQ(H->Name, Expected.Name);
4939 EXPECT_EQ(H->Kind, Expected.Kind);
4940 EXPECT_EQ(H->Documentation, Expected.Documentation);
4941 EXPECT_EQ(H->Definition, Expected.Definition);
4942 EXPECT_EQ(H->Type, Expected.Type);
4943 EXPECT_EQ(H->ReturnType, Expected.ReturnType);
4944 EXPECT_EQ(H->Parameters, Expected.Parameters);
4945 EXPECT_EQ(H->TemplateParameters, Expected.TemplateParameters);
4946 EXPECT_EQ(H->SymRange, Expected.SymRange);
4947 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)