zyounan created this revision. zyounan added a reviewer: nridge. Herald added subscribers: kadircet, arphaman. Herald added a project: All. zyounan requested review of this revision. Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov. Herald added a project: clang-tools-extra.
Closes https://github.com/clangd/clangd/issues/1742 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D158926 Files: clang-tools-extra/clangd/InlayHints.cpp clang-tools-extra/clangd/unittests/InlayHintTests.cpp
Index: clang-tools-extra/clangd/unittests/InlayHintTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/InlayHintTests.cpp +++ clang-tools-extra/clangd/unittests/InlayHintTests.cpp @@ -89,7 +89,7 @@ ExpectedHints... Expected) { Annotations Source(AnnotatedSource); TestTU TU = TestTU::withCode(Source.code()); - TU.ExtraArgs.push_back("-std=c++20"); + TU.ExtraArgs.push_back("-std=c++23"); TU.HeaderCode = HeaderContent; auto AST = TU.build(); @@ -807,6 +807,42 @@ )cpp"); } +TEST(ParameterHints, FunctionCallOperator) { + assertParameterHints(R"cpp( + struct W { + void operator()(int x); + }; + struct S : W { + using W::operator(); + static void operator()(int x, int y); + }; + void bar() { + auto l1 = [](int x) {}; + auto l2 = [](int x) static {}; + + S s; + s($1[[1]]); + s.operator()($2[[1]]); + s.operator()($3[[1]], $4[[2]]); + S::operator()($5[[1]], $6[[2]]); + + l1($7[[1]]); + l1.operator()($8[[1]]); + l2($9[[1]]); + l2.operator()($10[[1]]); + + void (*ptr)(int a, int b) = &S::operator(); + ptr($11[[1]], $12[[2]]); + } + )cpp", + ExpectedHint{"x: ", "1"}, ExpectedHint{"x: ", "2"}, + ExpectedHint{"x: ", "3"}, ExpectedHint{"y: ", "4"}, + ExpectedHint{"x: ", "5"}, ExpectedHint{"y: ", "6"}, + ExpectedHint{"x: ", "7"}, ExpectedHint{"x: ", "8"}, + ExpectedHint{"x: ", "9"}, ExpectedHint{"x: ", "10"}, + ExpectedHint{"a: ", "11"}, ExpectedHint{"b: ", "12"}); +} + TEST(ParameterHints, Macros) { // Handling of macros depends on where the call's argument list comes from. Index: clang-tools-extra/clangd/InlayHints.cpp =================================================================== --- clang-tools-extra/clangd/InlayHints.cpp +++ clang-tools-extra/clangd/InlayHints.cpp @@ -586,11 +586,13 @@ if (!Cfg.InlayHints.Parameters) return true; - // Do not show parameter hints for operator calls written using operator - // syntax or user-defined literals. (Among other reasons, the resulting + bool IsFunctor = isFunctionObjectCallExpr(E); + // Do not show parameter hints for user-defined literals or + // operator calls except for operator(). (Among other reasons, the resulting // hints can look awkward, e.g. the expression can itself be a function // argument and then we'd get two hints side by side). - if (isa<CXXOperatorCallExpr>(E) || isa<UserDefinedLiteral>(E)) + if ((isa<CXXOperatorCallExpr>(E) && !IsFunctor) || + isa<UserDefinedLiteral>(E)) return true; auto CalleeDecls = Resolver->resolveCalleeOfCallExpr(E); @@ -607,7 +609,22 @@ else return true; - processCall(Callee, {E->getArgs(), E->getNumArgs()}); + // N4868 [over.call.object]p3 says, + // The argument list submitted to overload resolution consists of the + // argument expressions present in the function call syntax preceded by the + // implied object argument (E). + // + // However, we don't have the implied object argument for static + // operator() per clang::Sema::BuildCallToObjectOfClassType. + llvm::ArrayRef<const Expr *> Args = {E->getArgs(), E->getNumArgs()}; + if (IsFunctor) + // We don't have the implied object argument through + // a function pointer either. + if (const CXXMethodDecl *Method = + dyn_cast_or_null<CXXMethodDecl>(Callee.Decl); + Method && Method->isInstance()) + Args = Args.drop_front(1); + processCall(Callee, Args); return true; } @@ -1202,6 +1219,12 @@ return Range{HintStart, HintEnd}; } + bool isFunctionObjectCallExpr(CallExpr *E) const noexcept { + if (auto *CallExpr = dyn_cast<CXXOperatorCallExpr>(E)) + return CallExpr->getOperator() == OverloadedOperatorKind::OO_Call; + return false; + } + std::vector<InlayHint> &Results; ASTContext &AST; const syntax::TokenBuffer &Tokens;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits