diff --git a/clang-tools-extra/clangd/HeuristicResolver.h b/clang-tools-extra/clangd/HeuristicResolver.h --- a/clang-tools-extra/clangd/HeuristicResolver.h +++ b/clang-tools-extra/clangd/HeuristicResolver.h @@ -56,6 +56,8 @@ std::vector resolveReturnTypeOfCallExpr(const CallExpr *CE) const; std::vector + resolveCalleeOfCallExpr(const CallExpr *CE) const; + std::vector resolveUsingValueDecl(const UnresolvedUsingValueDecl *UUVD) const; std::vector resolveDependentNameType(const DependentNameType *DNT) const; @@ -87,6 +89,7 @@ // Try to heuristically resolve the type of a possibly-dependent expression // `E`. const Type *resolveExprToType(const Expr *E) const; + std::vector resolveExprToDecls(const Expr *E) const; // Given the type T of a dependent expression that appears of the LHS of a // "->", heuristically find a corresponding pointee type in whose scope we diff --git a/clang-tools-extra/clangd/HeuristicResolver.cpp b/clang-tools-extra/clangd/HeuristicResolver.cpp --- a/clang-tools-extra/clangd/HeuristicResolver.cpp +++ b/clang-tools-extra/clangd/HeuristicResolver.cpp @@ -130,6 +130,15 @@ return {}; } +std::vector +HeuristicResolver::resolveCalleeOfCallExpr(const CallExpr *CE) const { + if (const auto *ND = dyn_cast_or_null(CE->getCalleeDecl())) { + return {ND}; + } + + return resolveExprToDecls(CE->getCallee()); +} + std::vector HeuristicResolver::resolveUsingValueDecl( const UnresolvedUsingValueDecl *UUVD) const { return resolveDependentMember(UUVD->getQualifier()->getAsType(), @@ -163,18 +172,30 @@ return nullptr; } -const Type *HeuristicResolver::resolveExprToType(const Expr *E) const { +std::vector +HeuristicResolver::resolveExprToDecls(const Expr *E) const { if (const auto *ME = dyn_cast(E)) { - return resolveDeclsToType(resolveMemberExpr(ME)); + return resolveMemberExpr(ME); } if (const auto *RE = dyn_cast(E)) { - return resolveDeclsToType(resolveDeclRefExpr(RE)); + return resolveDeclRefExpr(RE); + } + if (const auto *OE = dyn_cast(E)) { + return {OE->decls_begin(), OE->decls_end()}; } if (const auto *CE = dyn_cast(E)) { - return resolveDeclsToType(resolveReturnTypeOfCallExpr(CE)); + return resolveReturnTypeOfCallExpr(CE); } if (const auto *ME = dyn_cast(E)) - return resolveDeclsToType({ME->getMemberDecl()}); + return {ME->getMemberDecl()}; + + return {}; +} + +const Type *HeuristicResolver::resolveExprToType(const Expr *E) const { + std::vector Decls = resolveExprToDecls(E); + if (!Decls.empty()) + return resolveDeclsToType(Decls); return E->getType().getTypePtr(); } 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 @@ -20,7 +20,8 @@ class InlayHintVisitor : public RecursiveASTVisitor { public: InlayHintVisitor(std::vector &Results, ParsedAST &AST) - : Results(Results), AST(AST.getASTContext()) {} + : Results(Results), AST(AST.getASTContext()), + Resolver(AST.getHeuristicResolver()) {} bool VisitCXXConstructExpr(CXXConstructExpr *E) { // Weed out constructor calls that don't look like a function call with @@ -45,9 +46,18 @@ if (isa(E) || isa(E)) return true; - processCall(E->getRParenLoc(), - dyn_cast_or_null(E->getCalleeDecl()), - {E->getArgs(), E->getNumArgs()}); + auto CalleeDecls = Resolver->resolveCalleeOfCallExpr(E); + if (CalleeDecls.empty()) + return true; + const FunctionDecl *Callee = nullptr; + if (const auto *FD = dyn_cast(CalleeDecls[0])) + Callee = FD; + else if (const auto *FTD = dyn_cast(CalleeDecls[0])) + Callee = FTD->getTemplatedDecl(); + if (!Callee) + return true; + + processCall(E->getRParenLoc(), Callee, {E->getArgs(), E->getNumArgs()}); return true; } @@ -251,6 +261,7 @@ std::vector &Results; ASTContext * + const HeuristicResolver *Resolver; }; std::vector inlayHints(ParsedAST &AST) { 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 @@ -256,7 +256,8 @@ foo($param[[par]]); } }; - )cpp"); + )cpp", + ExpectedHint{"param: ", "param"}); } TEST(ParameterHints, VariadicFunction) {