diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp --- a/clang-tools-extra/clangd/InlayHints.cpp +++ b/clang-tools-extra/clangd/InlayHints.cpp @@ -72,6 +72,23 @@ return true; } + bool VisitFunctionDecl(FunctionDecl *D) { + if (auto *AT = D->getReturnType()->getContainedAutoType()) { + QualType Deduced = AT->getDeducedType(); + if (!Deduced.isNull()) { + SourceRange R = D->getReturnTypeSourceRange(); + // For operator auto(), have to get location of `auto` a different way. + if (R.isInvalid() && isa(D)) { + R = D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); + } + addInlayHint(R, InlayHintKind::TypeHint, + ": " + D->getReturnType().getAsString(TypeHintPolicy)); + } + } + + return true; + } + bool VisitVarDecl(VarDecl *D) { // Do not show hints for the aggregate in a structured binding. // In the future, we may show hints for the individual bindings. diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp --- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp +++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp @@ -478,14 +478,32 @@ } TEST(TypeHints, ReturnTypeDeduction) { - // FIXME: Not handled yet. - // This test is currently here mostly because a naive implementation - // might have us print something not super helpful like the function type. - assertTypeHints(R"cpp( - auto func(int x) { - return x + 1; - } - )cpp"); + assertTypeHints( + R"cpp( + $ret1a[[auto]] f1(int x); // Hint forward declaration too + $ret1b[[auto]] f1(int x) { return x + 1; } + + // Include pointer operators in both location and hint + // (we could also go the other way). + int s; + $ret2[[auto&]] f2() { return s; } + + // Do not hint `auto` for trailing return type. + auto f3() -> int; + + // `auto` conversion operator + struct A { + operator $retConv[[auto]]() { return 42; } + }; + + // FIXME: Dependent types do not work yet. + template + struct S { + auto method() { return T(); } + }; + )cpp", + ExpectedHint{": int", "ret1a"}, ExpectedHint{": int", "ret1b"}, + ExpectedHint{": int &", "ret2"}, ExpectedHint{": int", "retConv"}); } TEST(TypeHints, DependentType) {