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