Author: ibiryukov Date: Tue Aug 14 02:36:32 2018 New Revision: 339665 URL: http://llvm.org/viewvc/llvm-project?rev=339665&view=rev Log: [clangd] Show non-instantiated decls in signatureHelp
Summary: To avoid producing very verbose output in substitutions involving typedefs, e.g. T -> std::vector<std::string>::iterator gets turned into an unreadable mess when printed out for libstdc++, result contains internal types (std::__Vector_iterator<...>) and expanded well-defined typedefs (std::basic_string<char>). Until we improve the presentation code in clang, going with non-instantiated decls looks like a better UX trade-off. Reviewers: hokein, ioeric, kadircet Reviewed By: hokein Subscribers: MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D50645 Modified: clang-tools-extra/trunk/clangd/CodeComplete.cpp clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Modified: clang-tools-extra/trunk/clangd/CodeComplete.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.cpp?rev=339665&r1=339664&r2=339665&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/CodeComplete.cpp (original) +++ clang-tools-extra/trunk/clangd/CodeComplete.cpp Tue Aug 14 02:36:32 2018 @@ -714,7 +714,15 @@ public: "too many arguments"); SigHelp.activeParameter = static_cast<int>(CurrentArg); for (unsigned I = 0; I < NumCandidates; ++I) { - const auto &Candidate = Candidates[I]; + OverloadCandidate Candidate = Candidates[I]; + // We want to avoid showing instantiated signatures, because they may be + // long in some cases (e.g. when 'T' is substituted with 'std::string', we + // would get 'std::basic_string<char>'). + if (auto *Func = Candidate.getFunction()) { + if (auto *Pattern = Func->getTemplateInstantiationPattern()) + Candidate = OverloadCandidate(Pattern); + } + const auto *CCS = Candidate.CreateSignatureString( CurrentArg, S, *Allocator, CCTUInfo, true); assert(CCS && "Expected the CodeCompletionString to be non-null"); Modified: clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp?rev=339665&r1=339664&r2=339665&view=diff ============================================================================== --- clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp (original) +++ clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Tue Aug 14 02:36:32 2018 @@ -1537,6 +1537,59 @@ TEST(SignatureHelpTest, OverloadsOrderin EXPECT_EQ(0, Results.activeParameter); } +TEST(SignatureHelpTest, InstantiatedSignatures) { + EXPECT_THAT(signatures(R"cpp( + template <class T> + void foo(T, T, T); + + int main() { + foo<int>(^); + } + )cpp") + .signatures, + ElementsAre(Sig("foo(T, T, T) -> void", {"T", "T", "T"}))); + + EXPECT_THAT(signatures(R"cpp( + template <class T> + void foo(T, T, T); + + int main() { + foo(10, ^); + })cpp") + .signatures, + ElementsAre(Sig("foo(T, T, T) -> void", {"T", "T", "T"}))); + + EXPECT_THAT(signatures(R"cpp( + template <class ...T> + void foo(T...); + + int main() { + foo<int>(^); + } + )cpp") + .signatures, + ElementsAre(Sig("foo(T...) -> void", {"T..."}))); + + // It is debatable whether we should substitute the outer template parameter + // ('T') in that case. Currently we don't substitute it in signature help, but + // do substitute in code complete. + // FIXME: make code complete and signature help consistent, figure out which + // way is better. + EXPECT_THAT(signatures(R"cpp( + template <class T> + struct X { + template <class U> + void foo(T, U); + }; + + int main() { + X<int>().foo<double>(^) + } + )cpp") + .signatures, + ElementsAre(Sig("foo(T, U) -> void", {"T", "U"}))); +} + } // namespace } // namespace clangd } // namespace clang _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits