[clang-tools-extra] r339665 - [clangd] Show non-instantiated decls in signatureHelp

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 14 02:36:32 PDT 2018


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




More information about the cfe-commits mailing list