16#include "llvm/ADT/StringRef.h"
17#include "llvm/Support/ScopedPrinter.h"
18#include "llvm/Support/raw_ostream.h"
19#include "gmock/gmock.h"
20#include "gtest/gtest.h"
36using ::testing::ElementsAre;
37using ::testing::IsEmpty;
40 std::vector<InlayHint> Result;
42 if (Hint.kind ==
Kind)
43 Result.push_back(Hint);
55 friend llvm::raw_ostream &
operator<<(llvm::raw_ostream &Stream,
56 const ExpectedHint &Hint) {
57 return Stream << Hint.Label <<
"@$" << Hint.RangeName;
62 llvm::StringRef ExpectedView(
Expected.Label);
63 std::string ResultLabel = arg.joinLabels();
64 if (ResultLabel != ExpectedView.trim(
" ") ||
65 arg.paddingLeft != ExpectedView.starts_with(
" ") ||
66 arg.paddingRight != ExpectedView.ends_with(
" ")) {
67 *result_listener <<
"label is '" << ResultLabel <<
"'";
70 if (arg.range != Code.range(
Expected.RangeName)) {
71 *result_listener <<
"range is " << llvm::to_string(arg.range) <<
" but $"
73 << llvm::to_string(Code.range(
Expected.RangeName));
81Config noHintsConfig() {
83 C.InlayHints.Parameters =
false;
84 C.InlayHints.DeducedTypes =
false;
85 C.InlayHints.Designators =
false;
86 C.InlayHints.BlockEnd =
false;
87 C.InlayHints.DefaultArguments =
false;
91template <
typename... ExpectedHints>
93 llvm::StringRef HeaderContent,
95 Annotations Source(AnnotatedSource);
97 TU.ExtraArgs.push_back(
"-std=c++23");
98 TU.HeaderCode = HeaderContent;
99 auto AST = TU.build();
101 EXPECT_THAT(hintsOfKind(
AST,
Kind),
102 ElementsAre(HintMatcher(
Expected, Source)...));
105 WithContextValue WithCfg(
Config::Key, noHintsConfig());
109template <
typename... ExpectedHints>
112 return assertHintsWithHeader(
Kind, AnnotatedSource,
"",
117template <
typename...
T>
void ignore(T &&...) {}
119template <
typename... ExpectedHints>
120void assertParameterHints(llvm::StringRef AnnotatedSource,
126template <
typename... ExpectedHints>
127void assertTypeHints(llvm::StringRef AnnotatedSource,
133template <
typename... ExpectedHints>
134void assertDesignatorHints(llvm::StringRef AnnotatedSource,
138 WithContextValue WithCfg(
Config::Key, std::move(Cfg));
142template <
typename... ExpectedHints>
143void assertBlockEndHints(llvm::StringRef AnnotatedSource,
147 WithContextValue WithCfg(
Config::Key, std::move(Cfg));
151TEST(ParameterHints, Smoke) {
152 assertParameterHints(R
"cpp(
158 ExpectedHint{"param: ",
"param"});
161TEST(ParameterHints, NoName) {
163 assertParameterHints(R
"cpp(
171TEST(ParameterHints, NoNameConstReference) {
173 assertParameterHints(R
"cpp(
174 void foo(const int&);
181TEST(ParameterHints, NoNameReference) {
183 assertParameterHints(R
"cpp(
190 ExpectedHint{"&: ",
"param"});
193TEST(ParameterHints, NoNameRValueReference) {
195 assertParameterHints(R
"cpp(
203TEST(ParameterHints, NoNameVariadicDeclaration) {
205 assertParameterHints(R
"cpp(
206 template <typename... Args>
207 void foo(Args&& ...);
214TEST(ParameterHints, NoNameVariadicForwarded) {
217 assertParameterHints(R
"cpp(
218 namespace std { template <typename T> T&& forward(T&); }
220 template <typename... Args>
221 void bar(Args&&... args) { return foo(std::forward<Args>(args)...); }
228TEST(ParameterHints, NoNameVariadicPlain) {
230 assertParameterHints(R
"cpp(
232 template <typename... Args>
233 void bar(Args&&... args) { return foo(args...); }
240TEST(ParameterHints, NameInDefinition) {
242 assertParameterHints(R
"cpp(
247 void foo(int param) {};
249 ExpectedHint{"param: ",
"param"});
252TEST(ParameterHints, NamePartiallyInDefinition) {
254 assertParameterHints(R
"cpp(
255 void foo(int, int b);
257 foo($param1[[42]], $param2[[42]]);
259 void foo(int a, int) {};
261 ExpectedHint{"a: ",
"param1"},
262 ExpectedHint{
"b: ",
"param2"});
265TEST(ParameterHints, NameInDefinitionVariadic) {
267 assertParameterHints(R
"cpp(
269 template <typename... Args>
270 void bar(Args... args) {
274 bar($param1[[42]], $param2[[42]]);
276 void foo(int a, int b) {};
278 ExpectedHint{"a: ",
"param1"},
279 ExpectedHint{
"b: ",
"param2"});
282TEST(ParameterHints, NameMismatch) {
284 assertParameterHints(R
"cpp(
289 void foo(int bad) {};
291 ExpectedHint{"good: ",
"good"});
294TEST(ParameterHints, NameConstReference) {
296 assertParameterHints(R
"cpp(
297 void foo(const int& param);
302 ExpectedHint{"param: ",
"param"});
305TEST(ParameterHints, NameTypeAliasConstReference) {
307 assertParameterHints(R
"cpp(
308 using alias = const int&;
309 void foo(alias param);
315 ExpectedHint{"param: ",
"param"});
318TEST(ParameterHints, NameReference) {
320 assertParameterHints(R
"cpp(
321 void foo(int& param);
327 ExpectedHint{"¶m: ",
"param"});
330TEST(ParameterHints, NameTypeAliasReference) {
332 assertParameterHints(R
"cpp(
334 void foo(alias param);
340 ExpectedHint{"¶m: ",
"param"});
343TEST(ParameterHints, NameRValueReference) {
345 assertParameterHints(R
"cpp(
346 void foo(int&& param);
351 ExpectedHint{"param: ",
"param"});
354TEST(ParameterHints, VariadicForwardedConstructor) {
357 assertParameterHints(R
"cpp(
358 namespace std { template <typename T> T&& forward(T&); }
359 struct S { S(int a); };
360 template <typename T, typename... Args>
361 T bar(Args&&... args) { return T{std::forward<Args>(args)...}; }
367 ExpectedHint{"a: ",
"param"});
370TEST(ParameterHints, VariadicPlainConstructor) {
372 assertParameterHints(R
"cpp(
373 struct S { S(int a); };
374 template <typename T, typename... Args>
375 T bar(Args&&... args) { return T{args...}; }
381 ExpectedHint{"a: ",
"param"});
384TEST(ParameterHints, VariadicForwardedNewConstructor) {
387 assertParameterHints(R
"cpp(
388 namespace std { template <typename T> T&& forward(T&); }
389 struct S { S(int a); };
390 template <typename T, typename... Args>
391 T* bar(Args&&... args) { return new T{std::forward<Args>(args)...}; }
397 ExpectedHint{"a: ",
"param"});
400TEST(ParameterHints, VariadicPlainNewConstructor) {
402 assertParameterHints(R
"cpp(
403 struct S { S(int a); };
404 template <typename T, typename... Args>
405 T* bar(Args&&... args) { return new T{args...}; }
411 ExpectedHint{"a: ",
"param"});
414TEST(ParameterHints, VariadicForwarded) {
417 assertParameterHints(R
"cpp(
418 namespace std { template <typename T> T&& forward(T&); }
420 template <typename... Args>
421 void bar(Args&&... args) { return foo(std::forward<Args>(args)...); }
427 ExpectedHint{"a: ",
"param"});
430TEST(ParameterHints, VariadicPlain) {
432 assertParameterHints(R
"cpp(
434 template <typename... Args>
435 void bar(Args&&... args) { return foo(args...); }
440 ExpectedHint{"a: ",
"param"});
443TEST(ParameterHints, VariadicPlainWithPackFirst) {
446 assertParameterHints(R
"cpp(
448 template <typename... Args, typename Arg>
449 void bar(Arg, Args&&... args) { return foo(args...); }
451 bar(1, $param[[42]]);
454 ExpectedHint{"a: ",
"param"});
457TEST(ParameterHints, VariadicSplitTwolevel) {
461 assertParameterHints(R
"cpp(
462 namespace std { template <typename T> T&& forward(T&); }
463 void baz(int, int b, double);
464 template <typename... Args>
465 void foo(int a, Args&&... args) {
466 return baz(1, std::forward<Args>(args)..., 1.0);
468 template <typename... Args>
469 void bar(Args&&... args) { return foo(std::forward<Args>(args)...); }
471 bar($param1[[32]], $param2[[42]]);
474 ExpectedHint{"a: ",
"param1"},
475 ExpectedHint{
"b: ",
"param2"});
478TEST(ParameterHints, VariadicNameFromSpecialization) {
481 assertParameterHints(R
"cpp(
483 template <typename... Args>
484 void bar(Args... args) {
488 void bar<int>(int b);
493 ExpectedHint{"b: ",
"param"});
496TEST(ParameterHints, VariadicNameFromSpecializationRecursive) {
499 assertParameterHints(R
"cpp(
501 template <typename... Args>
502 void foo(Args... args) {
505 template <typename... Args>
506 void bar(Args... args) {
510 void foo<int>(int b);
515 ExpectedHint{"b: ",
"param"});
518TEST(ParameterHints, VariadicOverloaded) {
522 assertParameterHints(
524 namespace std { template <typename T> T&& forward(T&); }
525 void baz(int b, int c);
526 void baz(int bb, int cc, int dd);
527 template <typename... Args>
528 void foo(int a, Args&&... args) {
529 return baz(std::forward<Args>(args)...);
531 template <typename... Args>
532 void bar(Args&&... args) { return foo(std::forward<Args>(args)...); }
534 bar($param1[[32]], $param2[[42]], $param3[[52]]);
535 bar($param4[[1]], $param5[[2]], $param6[[3]], $param7[[4]]);
538 ExpectedHint{"a: ",
"param1"}, ExpectedHint{
"b: ",
"param2"},
539 ExpectedHint{
"c: ",
"param3"}, ExpectedHint{
"a: ",
"param4"},
540 ExpectedHint{
"bb: ",
"param5"}, ExpectedHint{
"cc: ",
"param6"},
541 ExpectedHint{
"dd: ",
"param7"});
544TEST(ParameterHints, VariadicRecursive) {
546 assertParameterHints(
550 template <typename Head, typename... Tail>
551 void foo(Head head, Tail... tail) {
555 template <typename... Args>
556 void bar(Args... args) {
566TEST(ParameterHints, VariadicVarargs) {
568 assertParameterHints(R
"cpp(
569 void foo(int fixed, ...);
570 template <typename... Args>
571 void bar(Args&&... args) {
576 bar($fixed[[41]], 42, 43);
581TEST(ParameterHints, VariadicTwolevelUnresolved) {
583 assertParameterHints(R
"cpp(
584 template <typename... Args>
585 void foo(int fixed, Args&& ... args);
586 template <typename... Args>
587 void bar(Args&&... args) {
592 bar($fixed[[41]], 42, 43);
595 ExpectedHint{"fixed: ",
"fixed"});
598TEST(ParameterHints, VariadicTwoCalls) {
600 assertParameterHints(
602 void f1(int a, int b);
603 void f2(int c, int d);
607 template <typename... Args>
608 void foo(Args... args) {
617 foo($param1[[1]], $param2[[2]]);
620 ExpectedHint{"a: ",
"param1"}, ExpectedHint{
"b: ",
"param2"});
623TEST(ParameterHints, VariadicInfinite) {
625 assertParameterHints(
627 template <typename... Args>
630 template <typename... Args>
631 void bar(Args... args) {
635 template <typename... Args>
636 void foo(Args... args) {
646TEST(ParameterHints, VariadicDuplicatePack) {
648 assertParameterHints(
650 void foo(int a, int b, int c, int);
652 template <typename... Args>
653 void bar(int, Args... args, int d) {
657 template <typename... Args>
658 void baz(Args... args, Args... args2) {
659 bar<Args..., int>(1, args..., args2...);
663 baz<int, int>($p1[[1]], $p2[[2]], $p3[[3]], $p4[[4]]);
666 ExpectedHint{"a: ",
"p1"}, ExpectedHint{
"b: ",
"p2"},
667 ExpectedHint{
"c: ",
"p3"}, ExpectedHint{
"d: ",
"p4"});
670TEST(ParameterHints, VariadicEmplace) {
673 assertParameterHints(
675 namespace std { template <typename T> T&& forward(T&); }
676 using size_t = decltype(sizeof(0));
677 void *operator new(size_t, void *);
683 template <typename T>
685 template <typename T, typename... Args>
686 void construct(T* ptr, Args&&... args) {
687 ::new ((void*)ptr) T{std::forward<Args>(args)...};
690 template <typename T>
692 template <typename... Args>
693 void emplace(Args&&... args) {
695 auto ptr = a.template allocate<T>();
696 a.construct(ptr, std::forward<Args>(args)...);
701 c.emplace($param1[[1]]);
702 c.emplace($param2[[2]], $param3[[3]]);
705 ExpectedHint{"A: ",
"param1"}, ExpectedHint{
"B: ",
"param2"},
706 ExpectedHint{
"C: ",
"param3"});
709TEST(ParameterHints, VariadicReferenceHint) {
710 assertParameterHints(R
"cpp(
712 template <typename... Args>
713 void bar(Args... args) { return foo(args...); }
722TEST(ParameterHints, VariadicReferenceHintForwardingRef) {
723 assertParameterHints(R"cpp(
725 template <typename... Args>
726 void bar(Args&&... args) { return foo(args...); }
733 ExpectedHint{"&: ",
"param"});
736TEST(ParameterHints, VariadicReferenceHintForwardingRefStdForward) {
737 assertParameterHints(R
"cpp(
738 namespace std { template <typename T> T&& forward(T&); }
740 template <typename... Args>
741 void bar(Args&&... args) { return foo(std::forward<Args>(args)...); }
747 ExpectedHint{"&: ",
"param"});
750TEST(ParameterHints, VariadicNoReferenceHintForwardingRefStdForward) {
751 assertParameterHints(R
"cpp(
752 namespace std { template <typename T> T&& forward(T&); }
754 template <typename... Args>
755 void bar(Args&&... args) { return foo(std::forward<Args>(args)...); }
764TEST(ParameterHints, VariadicNoReferenceHintUnresolvedForward) {
765 assertParameterHints(R"cpp(
766 template <typename... Args>
767 void foo(Args&&... args);
775TEST(ParameterHints, MatchingNameVariadicForwarded) {
778 assertParameterHints(R
"cpp(
779 namespace std { template <typename T> T&& forward(T&); }
781 template <typename... Args>
782 void bar(Args&&... args) { return foo(std::forward<Args>(args)...); }
790TEST(ParameterHints, MatchingNameVariadicPlain) {
792 assertParameterHints(R
"cpp(
794 template <typename... Args>
795 void bar(Args&&... args) { return foo(args...); }
805 assertParameterHints(R
"cpp(
807 void operator+(S lhs, S rhs);
815TEST(ParameterHints, FunctionCallOperator) {
816 assertParameterHints(R"cpp(
818 void operator()(int x);
822 static void operator()(int x, int y);
825 auto l1 = [](int x) {};
826 auto l2 = [](int x) static {};
830 s.operator()($2[[1]]);
831 s.operator()($3[[1]], $4[[2]]);
832 S::operator()($5[[1]], $6[[2]]);
835 l1.operator()($8[[1]]);
837 l2.operator()($10[[1]]);
839 void (*ptr)(int a, int b) = &S::operator();
840 ptr($11[[1]], $12[[2]]);
843 ExpectedHint{"x: ",
"1"}, ExpectedHint{
"x: ",
"2"},
844 ExpectedHint{
"x: ",
"3"}, ExpectedHint{
"y: ",
"4"},
845 ExpectedHint{
"x: ",
"5"}, ExpectedHint{
"y: ",
"6"},
846 ExpectedHint{
"x: ",
"7"}, ExpectedHint{
"x: ",
"8"},
847 ExpectedHint{
"x: ",
"9"}, ExpectedHint{
"x: ",
"10"},
848 ExpectedHint{
"a: ",
"11"}, ExpectedHint{
"b: ",
"12"});
851TEST(ParameterHints, DeducingThis) {
852 assertParameterHints(R
"cpp(
854 template <typename This>
855 auto operator()(this This &&Self, int Param) {
859 auto function(this auto &Self, int Param) {
866 s.function($2[[42]]);
868 auto lambda = [](this auto &Self, char C) -> void {
874 ExpectedHint{"Param: ",
"1"},
875 ExpectedHint{
"Param: ",
"2"},
876 ExpectedHint{
"Param: ",
"3"}, ExpectedHint{
"C: ",
"4"});
879TEST(ParameterHints, Macros) {
884 assertParameterHints(R
"cpp(
886 #define ExpandsToCall() foo(42)
894 assertParameterHints(R
"cpp(
896 void foo(double param);
901 ExpectedHint{"param: ",
"param"});
904 assertParameterHints(R
"cpp(
906 #define ASSERT(expr) if (!expr) abort()
909 ASSERT(foo($param[[42]]) == 0);
912 ExpectedHint{"param: ",
"param"});
915 assertParameterHints(R
"cpp(
916 void foo(double x, double y);
917 #define CONSTANTS 3.14, 2.72
924TEST(ParameterHints, ConstructorParens) {
925 assertParameterHints(R"cpp(
933 ExpectedHint{"param: ",
"param"});
936TEST(ParameterHints, ConstructorBraces) {
937 assertParameterHints(R
"cpp(
945 ExpectedHint{"param: ",
"param"});
948TEST(ParameterHints, ConstructorStdInitList) {
950 assertParameterHints(R
"cpp(
952 template <typename E> class initializer_list { const E *a, *b; };
955 S(std::initializer_list<int> param);
963TEST(ParameterHints, MemberInit) {
964 assertParameterHints(R"cpp(
970 T() : member($param[[42]]) {}
973 ExpectedHint{"param: ",
"param"});
976TEST(ParameterHints, ImplicitConstructor) {
977 assertParameterHints(R
"cpp(
983 // Do not show hint for implicit constructor call in argument.
985 // Do not show hint for implicit constructor call in return.
991TEST(ParameterHints, FunctionPointer) {
992 assertParameterHints(
994 void (*f1)(int param);
995 void (__stdcall *f2)(int param);
996 using f3_t = void(*)(int param);
998 using f4_t = void(__stdcall *)(int param);
1007 ExpectedHint{"param: ",
"f1"}, ExpectedHint{
"param: ",
"f2"},
1008 ExpectedHint{
"param: ",
"f3"}, ExpectedHint{
"param: ",
"f4"});
1011TEST(ParameterHints, ArgMatchesParam) {
1012 assertParameterHints(R
"cpp(
1013 void foo(int param);
1015 static const int param = 42;
1019 // Do not show redundant "param: param".
1021 // But show it if the argument is qualified.
1022 foo($param[[S::param]]);
1027 // Do not show "param: param" for member-expr.
1032 ExpectedHint{"param: ",
"param"});
1035TEST(ParameterHints, ArgMatchesParamReference) {
1036 assertParameterHints(R
"cpp(
1037 void foo(int& param);
1038 void foo2(const int& param);
1041 // show reference hint on mutable reference
1042 foo($param[[param]]);
1043 // but not on const reference
1047 ExpectedHint{"&: ",
"param"});
1050TEST(ParameterHints, LeadingUnderscore) {
1051 assertParameterHints(R
"cpp(
1052 void foo(int p1, int _p2, int __p3);
1054 foo($p1[[41]], $p2[[42]], $p3[[43]]);
1057 ExpectedHint{"p1: ",
"p1"}, ExpectedHint{
"p2: ",
"p2"},
1058 ExpectedHint{
"p3: ",
"p3"});
1061TEST(ParameterHints, DependentCalls) {
1062 assertParameterHints(R
"cpp(
1063 template <typename T>
1064 void nonmember(T par1);
1066 template <typename T>
1068 void member(T par2);
1069 static void static_member(T par3);
1072 void overload(int anInt);
1073 void overload(double aDouble);
1075 template <typename T>
1077 void bar(A<T> a, T t) {
1078 nonmember($par1[[t]]);
1079 a.member($par2[[t]]);
1080 A<T>::static_member($par3[[t]]);
1081 // We don't want to arbitrarily pick between
1082 // "anInt" or "aDouble", so just show no hint.
1087 ExpectedHint{"par1: ",
"par1"},
1088 ExpectedHint{
"par2: ",
"par2"},
1089 ExpectedHint{
"par3: ",
"par3"});
1092TEST(ParameterHints, VariadicFunction) {
1093 assertParameterHints(R
"cpp(
1094 template <typename... T>
1095 void foo(int fixed, T... variadic);
1098 foo($fixed[[41]], 42, 43);
1101 ExpectedHint{"fixed: ",
"fixed"});
1104TEST(ParameterHints, VarargsFunction) {
1105 assertParameterHints(R
"cpp(
1106 void foo(int fixed, ...);
1109 foo($fixed[[41]], 42, 43);
1112 ExpectedHint{"fixed: ",
"fixed"});
1115TEST(ParameterHints, CopyOrMoveConstructor) {
1117 assertParameterHints(R
"cpp(
1131TEST(ParameterHints, AggregateInit) {
1134 assertParameterHints(R
"cpp(
1145TEST(ParameterHints, UserDefinedLiteral) {
1147 assertParameterHints(R
"cpp(
1148 long double operator"" _w(long double param);
1155TEST(ParameterHints, ParamNameComment) {
1158 assertParameterHints(R
"cpp(
1159 void foo(int param);
1162 foo( /* param = */ 42);
1166 foo(/*param=*/Z(a));
1167 foo($macro[[Z(a)]]);
1168 foo(/* the answer */$param[[42]]);
1171 ExpectedHint{"param: ",
"macro"},
1172 ExpectedHint{
"param: ",
"param"});
1175TEST(ParameterHints, SetterFunctions) {
1176 assertParameterHints(R
"cpp(
1178 void setParent(S* parent);
1179 void set_parent(S* parent);
1180 void setTimeout(int timeoutMillis);
1181 void setTimeoutMillis(int timeout_millis);
1185 // Parameter name matches setter name - omit hint.
1186 s.setParent(nullptr);
1187 // Support snake_case
1188 s.set_parent(nullptr);
1189 // Parameter name may contain extra info - show hint.
1190 s.setTimeout($timeoutMillis[[120]]);
1191 // FIXME: Ideally we'd want to omit this.
1192 s.setTimeoutMillis($timeout_millis[[120]]);
1195 ExpectedHint{"timeoutMillis: ",
"timeoutMillis"},
1196 ExpectedHint{
"timeout_millis: ",
"timeout_millis"});
1199TEST(ParameterHints, BuiltinFunctions) {
1201 assertParameterHints(R
"cpp(
1202 namespace std { template <typename T> T&& forward(T&); }
1210TEST(ParameterHints, IncludeAtNonGlobalScope) {
1211 Annotations FooInc(R"cpp(
1212 void bar() { foo(42); }
1214 Annotations FooCC(R"cpp(
1216 void foo(int param);
1221 TestWorkspace Workspace;
1222 Workspace.addSource("foo.inc", FooInc.code());
1223 Workspace.addMainFile(
"foo.cc", FooCC.code());
1225 auto AST = Workspace.openFile(
"foo.cc");
1226 ASSERT_TRUE(
bool(
AST));
1232TEST(TypeHints, Smoke) {
1233 assertTypeHints(R
"cpp(
1234 auto $waldo[[waldo]] = 42;
1236 ExpectedHint{": int",
"waldo"});
1239TEST(TypeHints, Decorations) {
1240 assertTypeHints(R
"cpp(
1242 auto* $var1[[var1]] = &x;
1243 auto&& $var2[[var2]] = x;
1244 const auto& $var3[[var3]] = x;
1246 ExpectedHint{": int *",
"var1"},
1247 ExpectedHint{
": int &",
"var2"},
1248 ExpectedHint{
": const int &",
"var3"});
1251TEST(TypeHints, DecltypeAuto) {
1252 assertTypeHints(R
"cpp(
1255 decltype(auto) $z[[z]] = y;
1257 ExpectedHint{": int &",
"z"});
1260TEST(TypeHints, NoQualifiers) {
1261 assertTypeHints(R
"cpp(
1266 auto $x[[x]] = foo();
1269 template <typename T>
1272 S2::Inner<int> bar();
1273 auto $y[[y]] = bar();
1277 ExpectedHint{": S1",
"x"},
1284 ExpectedHint{
": S2::Inner<int>",
"y"});
1287TEST(TypeHints, Lambda) {
1290 assertTypeHints(R
"cpp(
1293 auto $L[[L]] = [cap, $init[[init]] = 1 + 1](int a$ret[[)]] {
1294 return a + cap + init;
1298 ExpectedHint{": (lambda)",
"L"},
1299 ExpectedHint{
": int",
"init"}, ExpectedHint{
"-> int",
"ret"});
1303 assertTypeHints(
"auto $L[[x]] = <:$ret[[:>]]{return 42;};",
1304 ExpectedHint{
": (lambda)",
"L"},
1305 ExpectedHint{
"-> int",
"ret"});
1311TEST(TypeHints, StructuredBindings_PublicStruct) {
1312 assertTypeHints(R
"cpp(
1313 // Struct with public fields.
1319 auto [$x[[x]], $y[[y]]] = foo();
1321 ExpectedHint{": int",
"x"}, ExpectedHint{
": int",
"y"});
1324TEST(TypeHints, StructuredBindings_Array) {
1325 assertTypeHints(R
"cpp(
1327 auto [$x[[x]], $y[[y]]] = arr;
1329 ExpectedHint{": int",
"x"}, ExpectedHint{
": int",
"y"});
1332TEST(TypeHints, StructuredBindings_TupleLike) {
1333 assertTypeHints(R
"cpp(
1340 template <typename T>
1341 struct tuple_size {};
1343 struct tuple_size<IntPair> {
1344 constexpr static unsigned value = 2;
1346 template <unsigned I, typename T>
1347 struct tuple_element {};
1348 template <unsigned I>
1349 struct tuple_element<I, IntPair> {
1353 template <unsigned I>
1354 int get(const IntPair& p) {
1355 if constexpr (I == 0) {
1357 } else if constexpr (I == 1) {
1362 auto [$x[[x]], $y[[y]]] = bar();
1364 ExpectedHint{": int",
"x"}, ExpectedHint{
": int",
"y"});
1367TEST(TypeHints, StructuredBindings_NoInitializer) {
1368 assertTypeHints(R
"cpp(
1369 // No initializer (ill-formed).
1370 // Do not show useless "NULL TYPE" hint.
1371 auto [x, y]; /*error-ok*/
1375TEST(TypeHints, InvalidType) {
1376 assertTypeHints(R"cpp(
1377 auto x = (unknown_type)42; /*error-ok*/
1378 auto *y = (unknown_ptr)nullptr;
1382TEST(TypeHints, ReturnTypeDeduction) {
1385 auto f1(int x$ret1a[[)]]; // Hint forward declaration too
1386 auto f1(int x$ret1b[[)]] { return x + 1; }
1388 // Include pointer operators in hint
1390 auto& f2($ret2[[)]] { return s; }
1392 // Do not hint `auto` for trailing return type.
1395 // Do not hint when a trailing return type is specified.
1396 auto f4() -> auto* { return "foo"; }
1398 auto f5($noreturn[[)]] {}
1400 // `auto` conversion operator
1402 operator auto($retConv[[)]] { return 42; }
1405 // FIXME: Dependent types do not work yet.
1406 template <typename T>
1408 auto method() { return T(); }
1411 ExpectedHint{"-> int",
"ret1a"}, ExpectedHint{
"-> int",
"ret1b"},
1412 ExpectedHint{
"-> int &",
"ret2"}, ExpectedHint{
"-> void",
"noreturn"},
1413 ExpectedHint{
"-> int",
"retConv"});
1416TEST(TypeHints, DependentType) {
1417 assertTypeHints(R
"cpp(
1418 template <typename T>
1420 // The hint would just be "auto" and we can't do any better.
1421 auto var1 = arg.method();
1422 // FIXME: It would be nice to show "T" as the hint.
1423 auto $var2[[var2]] = arg;
1426 template <typename T>
1433TEST(TypeHints, LongTypeName) {
1434 assertTypeHints(R"cpp(
1435 template <typename, typename, typename>
1437 struct MultipleWords {};
1438 A<MultipleWords, MultipleWords, MultipleWords> foo();
1439 // Omit type hint past a certain length (currently 32)
1445 WithContextValue WithCfg(Config::Key, std::move(Cfg));
1449 template <typename, typename, typename>
1451 struct MultipleWords {};
1452 A<MultipleWords, MultipleWords, MultipleWords> foo();
1453 // Should have type hint with TypeNameLimit = 0
1454 auto $var[[var]] = foo();
1456 ExpectedHint{": A<MultipleWords, MultipleWords, MultipleWords>",
"var"});
1459TEST(TypeHints, DefaultTemplateArgs) {
1460 assertTypeHints(R
"cpp(
1461 template <typename, typename = int>
1464 auto $var[[var]] = foo();
1466 auto [$binding[[value]]] = bar;
1468 ExpectedHint{": A<float>",
"var"},
1469 ExpectedHint{
": A<float>",
"binding"});
1472TEST(DefaultArguments, Smoke) {
1481 WithContextValue WithCfg(
Config::Key, std::move(Cfg));
1483 const auto *Code = R
"cpp(
1484 int foo(int A = 4) { return A; }
1485 int bar(int A, int B = 1, bool C = foo($default1[[)]]) { return A; }
1486 int A = bar($explicit[[2]]$default2[[)]];
1488 void baz(int = 5) { if (false) baz($unnamed[[)]]; };
1492 ExpectedHint{"A: 4",
"default1",
Left},
1493 ExpectedHint{
", B: 1, C: foo()",
"default2",
Left},
1494 ExpectedHint{
"5",
"unnamed",
Left});
1497 ExpectedHint{
"A: ",
"explicit",
Left});
1500TEST(DefaultArguments, WithoutParameterNames) {
1508 WithContextValue WithCfg(
Config::Key, std::move(Cfg));
1510 const auto *Code = R
"cpp(
1516 Foo(int, Baz baz = //
1517 Baz{$abbreviated[[}]]
1524 Foo foo1(1$paren[[)]];
1525 Foo foo2{2$brace1[[}]];
1526 Foo foo3 = {3$brace2[[}]];
1527 auto foo4 = Foo{4$brace3[[}]];
1532 ExpectedHint{"...",
"abbreviated",
Left},
1533 ExpectedHint{
", Baz{}",
"paren",
Left},
1534 ExpectedHint{
", Baz{}",
"brace1",
Left},
1535 ExpectedHint{
", Baz{}",
"brace2",
Left},
1536 ExpectedHint{
", Baz{}",
"brace3",
Left});
1541TEST(TypeHints, Deduplication) {
1542 assertTypeHints(R
"cpp(
1543 template <typename T>
1545 auto $var[[var]] = 42;
1547 template void foo<int>();
1548 template void foo<float>();
1550 ExpectedHint{": int",
"var"});
1553TEST(TypeHints, SinglyInstantiatedTemplate) {
1554 assertTypeHints(R
"cpp(
1555 auto $lambda[[x]] = [](auto *$param[[y]], auto) { return 42; };
1556 int m = x("foo", 3);
1558 ExpectedHint{": (lambda)",
"lambda"},
1559 ExpectedHint{
": const char *",
"param"});
1562 assertTypeHints(R
"cpp(
1563 int x(auto $a[[a]], auto... b, auto c) { return 42; }
1564 int m = x<void*, char, float>(nullptr, 'c', 2.0, 2);
1566 ExpectedHint{": void *",
"a"});
1569TEST(TypeHints, Aliased) {
1573 TU.ExtraArgs.push_back(
"-xc");
1574 auto AST = TU.build();
1579TEST(TypeHints, CallingConvention) {
1582 std::string Code = R
"cpp(
1588 TU.ExtraArgs.push_back("--target=x86_64-w64-mingw32");
1589 TU.PredefineMacros =
true;
1590 auto AST = TU.build();
1595TEST(TypeHints, Decltype) {
1596 assertTypeHints(R
"cpp(
1597 $a[[decltype(0)]] a;
1598 $b[[decltype(a)]] b;
1599 const $c[[decltype(0)]] &c = b;
1601 // Don't show for dependent type
1603 constexpr decltype(T{}) d;
1605 $e[[decltype(0)]] e();
1606 auto f() -> $f[[decltype(0)]];
1608 template <class, class> struct Foo;
1609 using G = Foo<$g[[decltype(0)]], float>;
1611 auto $h[[h]] = $i[[decltype(0)]]{};
1617 ExpectedHint{": int",
"a"}, ExpectedHint{
": int",
"b"},
1618 ExpectedHint{
": int",
"c"}, ExpectedHint{
": int",
"e"},
1619 ExpectedHint{
": int",
"f"}, ExpectedHint{
": int",
"g"},
1620 ExpectedHint{
": int",
"h"}, ExpectedHint{
": int",
"i"});
1623TEST(TypeHints, SubstTemplateParameterAliases) {
1624 llvm::StringRef Header = R
"cpp(
1625 template <class T> struct allocator {};
1627 template <class T, class A>
1628 struct vector_base {
1632 template <class T, class A>
1633 struct internal_iterator_type_template_we_dont_expect {};
1635 struct my_iterator {};
1637 template <class T, class A = allocator<T>>
1638 struct vector : vector_base<T, A> {
1639 using base = vector_base<T, A>;
1640 typedef T value_type;
1641 typedef base::pointer pointer;
1642 using allocator_type = A;
1643 using size_type = int;
1644 using iterator = internal_iterator_type_template_we_dont_expect<T, A>;
1645 using non_template_iterator = my_iterator;
1647 value_type& operator[](int index) { return elements[index]; }
1648 const value_type& at(int index) const { return elements[index]; }
1649 pointer data() { return &elements[0]; }
1650 allocator_type get_allocator() { return A(); }
1651 size_type size() const { return 10; }
1652 iterator begin() { return iterator(); }
1653 non_template_iterator end() { return non_template_iterator(); }
1659 llvm::StringRef VectorIntPtr = R"cpp(
1660 vector<int *> array;
1661 auto $no_modifier[[x]] = array[3];
1662 auto* $ptr_modifier[[ptr]] = &array[3];
1663 auto& $ref_modifier[[ref]] = array[3];
1664 auto& $at[[immutable]] = array.at(3);
1666 auto $data[[data]] = array.data();
1667 auto $allocator[[alloc]] = array.get_allocator();
1668 auto $size[[size]] = array.size();
1669 auto $begin[[begin]] = array.begin();
1670 auto $end[[end]] = array.end();
1673 assertHintsWithHeader(
1675 ExpectedHint{": int *",
"no_modifier"},
1676 ExpectedHint{
": int **",
"ptr_modifier"},
1677 ExpectedHint{
": int *&",
"ref_modifier"},
1678 ExpectedHint{
": int *const &",
"at"}, ExpectedHint{
": int **",
"data"},
1679 ExpectedHint{
": allocator<int *>",
"allocator"},
1680 ExpectedHint{
": size_type",
"size"}, ExpectedHint{
": iterator",
"begin"},
1681 ExpectedHint{
": non_template_iterator",
"end"});
1683 llvm::StringRef VectorInt = R
"cpp(
1685 auto $no_modifier[[by_value]] = array[3];
1686 auto* $ptr_modifier[[ptr]] = &array[3];
1687 auto& $ref_modifier[[ref]] = array[3];
1688 auto& $at[[immutable]] = array.at(3);
1690 auto $data[[data]] = array.data();
1691 auto $allocator[[alloc]] = array.get_allocator();
1692 auto $size[[size]] = array.size();
1693 auto $begin[[begin]] = array.begin();
1694 auto $end[[end]] = array.end();
1697 assertHintsWithHeader(
1699 ExpectedHint{": int",
"no_modifier"},
1700 ExpectedHint{
": int *",
"ptr_modifier"},
1701 ExpectedHint{
": int &",
"ref_modifier"},
1702 ExpectedHint{
": const int &",
"at"}, ExpectedHint{
": int *",
"data"},
1703 ExpectedHint{
": allocator<int>",
"allocator"},
1704 ExpectedHint{
": size_type",
"size"}, ExpectedHint{
": iterator",
"begin"},
1705 ExpectedHint{
": non_template_iterator",
"end"});
1708 // If the type alias is not of substituted template parameter type,
1709 // do not show desugared type.
1710 using VeryLongLongTypeName = my_iterator;
1711 using Short = VeryLongLongTypeName;
1713 auto $short_name[[my_value]] = Short();
1715 // Same applies with templates.
1716 template <typename T, typename A>
1717 using basic_static_vector = vector<T, A>;
1718 template <typename T>
1719 using static_vector = basic_static_vector<T, allocator<T>>;
1721 auto $vector_name[[vec]] = static_vector<int>();
1725 ExpectedHint{": Short",
"short_name"},
1726 ExpectedHint{
": static_vector<int>",
"vector_name"});
1729TEST(DesignatorHints, Basic) {
1730 assertDesignatorHints(R
"cpp(
1731 struct S { int x, y, z; };
1732 S s {$x[[1]], $y[[2+2]]};
1734 int x[] = {$0[[0]], $1[[1]]};
1736 ExpectedHint{".x=",
"x"}, ExpectedHint{
".y=",
"y"},
1737 ExpectedHint{
"[0]=",
"0"}, ExpectedHint{
"[1]=",
"1"});
1740TEST(DesignatorHints, Nested) {
1741 assertDesignatorHints(R
"cpp(
1742 struct Inner { int x, y; };
1743 struct Outer { Inner a, b; };
1744 Outer o{ $a[[{ $x[[1]], $y[[2]] }]], $bx[[3]] };
1746 ExpectedHint{".a=",
"a"}, ExpectedHint{
".x=",
"x"},
1747 ExpectedHint{
".y=",
"y"}, ExpectedHint{
".b.x=",
"bx"});
1750TEST(DesignatorHints, AnonymousRecord) {
1751 assertDesignatorHints(R
"cpp(
1763 ExpectedHint{".x.y=",
"xy"});
1766TEST(DesignatorHints, Suppression) {
1767 assertDesignatorHints(R
"cpp(
1768 struct Point { int a, b, c, d, e, f, g, h; };
1769 Point p{/*a=*/1, .c=2, /* .d = */3, $e[[4]]};
1771 ExpectedHint{".e=",
"e"});
1774TEST(DesignatorHints, StdArray) {
1777 assertDesignatorHints(R
"cpp(
1778 template <typename T, int N> struct Array { T __elements[N]; };
1779 Array<int, 2> x = {$0[[0]], $1[[1]]};
1781 ExpectedHint{"[0]=",
"0"}, ExpectedHint{
"[1]=",
"1"});
1784TEST(DesignatorHints, OnlyAggregateInit) {
1785 assertDesignatorHints(R
"cpp(
1786 struct Copyable { int x; } c;
1789 struct Constructible { Constructible(int x); };
1790 Constructible x{42};
1794TEST(DesignatorHints, NoCrash) {
1795 assertDesignatorHints(R
"cpp(
1798 struct Foo {int a; int b;};
1800 Foo f{A(), $b[[1]]};
1803 ExpectedHint{".b=",
"b"});
1806TEST(InlayHints, RestrictRange) {
1807 Annotations Code(R
"cpp(
1815 ElementsAre(labelIs(
": int"), labelIs(
": char")));
1818TEST(ParameterHints, PseudoObjectExpr) {
1819 Annotations Code(R
"cpp(
1821 __declspec(property(get=GetX, put=PutX)) int x[];
1822 int GetX(int y, int z) { return 42 + y; }
1825 // This is a PseudoObjectExpression whose syntactic form is a binary
1827 void Work(int y) { x = y; } // Not `x = y: y`.
1830 int printf(const char *Format, ...);
1834 __builtin_dump_struct(&s, printf); // Not `Format: __builtin_dump_struct()`
1835 printf($Param[["Hello, %d"]], 42); // Normal calls are not affected.
1836 // This builds a PseudoObjectExpr, but here it's useful for showing the
1837 // arguments from the semantic form.
1838 return s.x[ $one[[1]] ][ $two[[2]] ]; // `x[y: 1][z: 2]`
1842 TU.ExtraArgs.push_back(
"-fms-extensions");
1843 auto AST = TU.build();
1845 ElementsAre(HintMatcher(ExpectedHint{
"Format: ",
"Param"}, Code),
1846 HintMatcher(ExpectedHint{
"y: ",
"one"}, Code),
1847 HintMatcher(ExpectedHint{
"z: ",
"two"}, Code)));
1850TEST(ParameterHints, ArgPacksAndConstructors) {
1851 assertParameterHints(
1853 struct Foo{ Foo(); Foo(int x); };
1854 void foo(Foo a, int b);
1855 template <typename... Args>
1856 void bar(Args... args) {
1859 template <typename... Args>
1860 void baz(Args... args) { foo($param1[[Foo{args...}]], $param2[[1]]); }
1862 template <typename... Args>
1863 void bax(Args... args) { foo($param3[[{args...}]], args...); }
1866 bar($param4[[Foo{}]], $param5[[42]]);
1867 bar($param6[[42]], $param7[[42]]);
1872 ExpectedHint{"a: ",
"param1"}, ExpectedHint{
"b: ",
"param2"},
1873 ExpectedHint{
"a: ",
"param3"}, ExpectedHint{
"a: ",
"param4"},
1874 ExpectedHint{
"b: ",
"param5"}, ExpectedHint{
"a: ",
"param6"},
1875 ExpectedHint{
"b: ",
"param7"}, ExpectedHint{
"x: ",
"param8"},
1876 ExpectedHint{
"b: ",
"param9"});
1879TEST(ParameterHints, DoesntExpandAllArgs) {
1880 assertParameterHints(
1882 void foo(int x, int y);
1883 int id(int a, int b, int c);
1884 template <typename... Args>
1885 void bar(Args... args) {
1886 foo(id($param1[[args]], $param2[[1]], $param3[[args]])...);
1889 bar(1, 2); // FIXME: We could have `bar(a: 1, a: 2)` here.
1892 ExpectedHint{"a: ",
"param1"}, ExpectedHint{
"b: ",
"param2"},
1893 ExpectedHint{
"c: ",
"param3"});
1896TEST(BlockEndHints, Functions) {
1897 assertBlockEndHints(R
"cpp(
1904 // No hint for lambda for now
1911 // No hint because this isn't a definition
1915 bool operator==(S, S) {
1919 ExpectedHint{" // foo",
"foo"},
1920 ExpectedHint{
" // bar",
"bar"},
1921 ExpectedHint{
" // operator==",
"opEqual"});
1924TEST(BlockEndHints, Methods) {
1925 assertBlockEndHints(R
"cpp(
1927 // No hint because there's no function body
1936 // No hint because this isn't a definition
1939 template <typename T>
1943 // No hint because this isn't a definition
1944 template <typename T>
1947 Test operator+(int) const {
1951 operator bool() const {
1955 // No hint because there's no function body
1956 operator int() const = delete;
1959 void Test::method2() {
1962 template <typename T>
1963 void Test::method4() {
1966 ExpectedHint{" // ~Test",
"dtor"},
1967 ExpectedHint{
" // method1",
"method1"},
1968 ExpectedHint{
" // method3",
"method3"},
1969 ExpectedHint{
" // operator+",
"opIdentity"},
1970 ExpectedHint{
" // operator bool",
"opBool"},
1971 ExpectedHint{
" // Test::method2",
"method2"},
1972 ExpectedHint{
" // Test::method4",
"method4"});
1975TEST(BlockEndHints, Namespaces) {
1976 assertBlockEndHints(
1986 ExpectedHint{" // namespace",
"anon"},
1987 ExpectedHint{
" // namespace ns",
"ns"});
1990TEST(BlockEndHints, Types) {
1991 assertBlockEndHints(
2008 ExpectedHint{" // struct S",
"S"}, ExpectedHint{
" // class C",
"C"},
2009 ExpectedHint{
" // union U",
"U"}, ExpectedHint{
" // enum E1",
"E1"},
2010 ExpectedHint{
" // enum class E2",
"E2"});
2013TEST(BlockEndHints, If) {
2014 assertBlockEndHints(
2016 void foo(bool cond) {
2037 if (auto X = cond) {
2040 if (int i = 0; i > 10) {
2044 ExpectedHint{" // if cond",
"simple"},
2045 ExpectedHint{
" // if cond",
"ifelse"}, ExpectedHint{
" // if",
"elseif"},
2046 ExpectedHint{
" // if !cond",
"inner"},
2047 ExpectedHint{
" // if cond",
"outer"}, ExpectedHint{
" // if X",
"init"},
2048 ExpectedHint{
" // if i > 10",
"init_cond"});
2051TEST(BlockEndHints, Loops) {
2052 assertBlockEndHints(
2067 for (int I = 0; I < 10; ++I) {
2075 ExpectedHint{" // while true",
"while"},
2076 ExpectedHint{
" // for true",
"forcond"},
2077 ExpectedHint{
" // for I",
"forvar"},
2078 ExpectedHint{
" // for V",
"foreach"});
2081TEST(BlockEndHints, Switch) {
2082 assertBlockEndHints(
2090 ExpectedHint{" // switch I",
"switch"});
2093TEST(BlockEndHints, PrintLiterals) {
2094 assertBlockEndHints(
2100 while ("foo but this time it is very long") {
2113 ExpectedHint{" // while \"foo\"",
"string"},
2114 ExpectedHint{
" // while \"foo but...\"",
"string_long"},
2115 ExpectedHint{
" // while true",
"boolean"},
2116 ExpectedHint{
" // while 1",
"integer"},
2117 ExpectedHint{
" // while 1.5",
"float"});
2120TEST(BlockEndHints, PrintRefs) {
2121 assertBlockEndHints(
2135 while (ns::func()) {
2138 while (ns::S{}.Field) {
2141 while (ns::S{}.method()) {
2145 ExpectedHint{" // while Var",
"var"},
2146 ExpectedHint{
" // while func",
"func"},
2147 ExpectedHint{
" // while Field",
"field"},
2148 ExpectedHint{
" // while method",
"method"});
2151TEST(BlockEndHints, PrintConversions) {
2152 assertBlockEndHints(
2157 explicit operator bool();
2161 $convert_primitive[[}]]
2167 $construct_class[[}]]
2170 ExpectedHint{" // while float",
"convert_primitive"},
2171 ExpectedHint{
" // while S",
"convert_class"},
2172 ExpectedHint{
" // while S",
"construct_class"});
2175TEST(BlockEndHints, PrintOperators) {
2177 void foo(Integer I) {
2196 while((I + I) < (I + I)){
2197 $binary_complex[[}]]
2202 auto AssertExpectedHints = [&](llvm::StringRef Code) {
2203 assertBlockEndHints(Code, ExpectedHint{
" // while ++I",
"preinc"},
2204 ExpectedHint{
" // while I++",
"postinc"},
2205 ExpectedHint{
" // while",
"unary_complex"},
2206 ExpectedHint{
" // while I < 0",
"compare"},
2207 ExpectedHint{
" // while ... < I",
"lhs_complex"},
2208 ExpectedHint{
" // while I < ...",
"rhs_complex"},
2209 ExpectedHint{
" // while",
"binary_complex"});
2213 AssertExpectedHints(
"using Integer = int;" +
AnnotatedCode);
2215 AssertExpectedHints(R
"cpp(
2217 explicit operator bool();
2218 Integer operator++();
2219 Integer operator++(int);
2220 Integer operator+(Integer);
2221 Integer operator+();
2222 bool operator<(Integer);
2223 bool operator<(int);
2228TEST(BlockEndHints, TrailingSemicolon) {
2229 assertBlockEndHints(R"cpp(
2230 // The hint is placed after the trailing ';'
2234 // The hint is always placed in the same line with the closing '}'.
2235 // So in this case where ';' is missing, it is attached to '}'.
2241 // No hint because only one trailing ';' is allowed
2245 // No hint because trailing ';' is only allowed for class/struct/union/enum
2249 // Rare case, but yes we'll have a hint here.
2256 ExpectedHint{" // struct S1",
"S1"},
2257 ExpectedHint{
" // struct S2",
"S2"},
2258 ExpectedHint{
" // struct",
"anon"});
2261TEST(BlockEndHints, TrailingText) {
2262 assertBlockEndHints(R
"cpp(
2266 // No hint for S2 because of the trailing comment
2268 }; /* Put anything here */
2271 // No hint for S4 because of the trailing source code
2275 // No hint for ns because of the trailing comment
2279 ExpectedHint{" // struct S1",
"S1"},
2280 ExpectedHint{
" // struct S3",
"S3"});
2284 assertBlockEndHints(R
"cpp(
2285 #define DECL_STRUCT(NAME) struct NAME {
2291 // No hint because we require a '}'
2295 ExpectedHint{" // struct S1",
"S1"});
2298TEST(BlockEndHints, PointerToMemberFunction) {
2300 assertBlockEndHints(R
"cpp(
2302 using Predicate = bool(A::*)();
2303 void foo(A* a, Predicate p) {
2308 ExpectedHint{" // if",
"ptrmem"});
std::string AnnotatedCode
std::vector< const char * > Expected
MATCHER_P2(hasFlag, Flag, Path, "")
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
TEST(BackgroundQueueTest, Priority)
InlayHintKind
Inlay hint kinds.
@ BlockEnd
A hint after function, type or namespace definition, indicating the defined symbol name of the defini...
@ DefaultArgument
An inlay hint that is for a default argument.
@ Parameter
An inlay hint that is for a parameter.
@ Type
An inlay hint that for a type annotation.
@ Designator
A hint before an element of an aggregate braced initializer list, indicating what it is initializing.
std::vector< InlayHint > inlayHints(ParsedAST &AST, std::optional< Range > RestrictRange)
Compute and return inlay hints for a file.
@ TypeAlias
The path from one type to the other involves desugaring type aliases.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static clangd::Key< Config > Key
Context key which can be used to set the current Config.
struct clang::clangd::Config::@8 InlayHints
std::string joinLabels() const
Join the label[].value together.
Range range
The range of source code to which the hint applies.
static TestTU withCode(llvm::StringRef Code)