ilya-biryukov updated this revision to Diff 160536. ilya-biryukov marked an inline comment as done. ilya-biryukov added a comment.
- Use 'auto*' instead of 'auto' Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D50645 Files: clangd/CodeComplete.cpp unittests/clangd/CodeCompleteTests.cpp Index: unittests/clangd/CodeCompleteTests.cpp =================================================================== --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -1537,6 +1537,59 @@ 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 Index: clangd/CodeComplete.cpp =================================================================== --- clangd/CodeComplete.cpp +++ clangd/CodeComplete.cpp @@ -714,7 +714,15 @@ "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");
Index: unittests/clangd/CodeCompleteTests.cpp =================================================================== --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -1537,6 +1537,59 @@ 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 Index: clangd/CodeComplete.cpp =================================================================== --- clangd/CodeComplete.cpp +++ clangd/CodeComplete.cpp @@ -714,7 +714,15 @@ "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");
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits