kadircet created this revision.
kadircet added reviewers: hokein, sammccall.
Herald added subscribers: cfe-commits, usaxena95, arphaman, jkorous, MaskRay, 
ilya-biryukov.
Herald added a project: clang.

Fixes https://github.com/clangd/clangd/issues/263


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73344

Files:
  clang-tools-extra/clangd/Hover.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp


Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -556,15 +556,22 @@
           }},
       {
           R"cpp(
+          // comment
           template <typename T> class Foo {};
-          Foo<int>* bar();
+          // comment2
+          template <typename T> class Foo<T*> {};
           void foo() {
-            [[^auto]] *x = bar();
+            [[Fo^o]]<int*> *x = nullptr;
           }
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "Foo<int>";
+            HI.Name = "Foo<int *>";
             HI.Kind = index::SymbolKind::Class;
+            HI.NamespaceScope = "";
+            HI.Definition = "template <> class Foo<int *>";
+            // FIXME: Maybe force instantiation to make use of real template
+            // pattern.
+            HI.Documentation = "comment";
           }},
   };
   for (const auto &Case : Cases) {
Index: clang-tools-extra/clangd/Hover.cpp
===================================================================
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -26,6 +26,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/Type.h"
+#include "clang/Basic/Specifiers.h"
 #include "clang/Index/IndexSymbol.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
@@ -205,11 +206,18 @@
 // Returns the decl that should be used for querying comments, either from 
index
 // or AST.
 const NamedDecl *getDeclForComment(const NamedDecl *D) {
-  if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
-    if (const auto *TIP = CTSD->getTemplateInstantiationPattern())
+  if (const auto *TSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+    // We might get a non-instantiated decl, e.g.
+    // template <typename T> struct X {};
+    // X^<int>* x;
+    // Fallback to primary template in such cases.
+    if (TSD->getTemplateSpecializationKind() == TSK_Undeclared)
+      return TSD->getSpecializedTemplate();
+    if (const auto *TIP = TSD->getTemplateInstantiationPattern())
       return TIP;
-  if (const auto *VTSD = llvm::dyn_cast<VarTemplateSpecializationDecl>(D))
-    if (const auto *TIP = VTSD->getTemplateInstantiationPattern())
+  }
+  if (const auto *TSD = llvm::dyn_cast<VarTemplateSpecializationDecl>(D))
+    if (const auto *TIP = TSD->getTemplateInstantiationPattern())
       return TIP;
   if (const auto *FD = D->getAsFunction())
     if (const auto *TIP = FD->getTemplateInstantiationPattern())


Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -556,15 +556,22 @@
           }},
       {
           R"cpp(
+          // comment
           template <typename T> class Foo {};
-          Foo<int>* bar();
+          // comment2
+          template <typename T> class Foo<T*> {};
           void foo() {
-            [[^auto]] *x = bar();
+            [[Fo^o]]<int*> *x = nullptr;
           }
           )cpp",
           [](HoverInfo &HI) {
-            HI.Name = "Foo<int>";
+            HI.Name = "Foo<int *>";
             HI.Kind = index::SymbolKind::Class;
+            HI.NamespaceScope = "";
+            HI.Definition = "template <> class Foo<int *>";
+            // FIXME: Maybe force instantiation to make use of real template
+            // pattern.
+            HI.Documentation = "comment";
           }},
   };
   for (const auto &Case : Cases) {
Index: clang-tools-extra/clangd/Hover.cpp
===================================================================
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -26,6 +26,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/Type.h"
+#include "clang/Basic/Specifiers.h"
 #include "clang/Index/IndexSymbol.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
@@ -205,11 +206,18 @@
 // Returns the decl that should be used for querying comments, either from index
 // or AST.
 const NamedDecl *getDeclForComment(const NamedDecl *D) {
-  if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
-    if (const auto *TIP = CTSD->getTemplateInstantiationPattern())
+  if (const auto *TSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+    // We might get a non-instantiated decl, e.g.
+    // template <typename T> struct X {};
+    // X^<int>* x;
+    // Fallback to primary template in such cases.
+    if (TSD->getTemplateSpecializationKind() == TSK_Undeclared)
+      return TSD->getSpecializedTemplate();
+    if (const auto *TIP = TSD->getTemplateInstantiationPattern())
       return TIP;
-  if (const auto *VTSD = llvm::dyn_cast<VarTemplateSpecializationDecl>(D))
-    if (const auto *TIP = VTSD->getTemplateInstantiationPattern())
+  }
+  if (const auto *TSD = llvm::dyn_cast<VarTemplateSpecializationDecl>(D))
+    if (const auto *TIP = TSD->getTemplateInstantiationPattern())
       return TIP;
   if (const auto *FD = D->getAsFunction())
     if (const auto *TIP = FD->getTemplateInstantiationPattern())
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to