[clang-tools-extra] e8716a6 - [clangd] Navigation from definition of template specialization to primary template

Nathan Ridge via cfe-commits cfe-commits at lists.llvm.org
Sat Dec 7 21:41:01 PST 2019


Author: Nathan Ridge
Date: 2019-12-08T00:40:45-05:00
New Revision: e8716a6df7abad68b6cf81c437a2e0524e88f3ad

URL: https://github.com/llvm/llvm-project/commit/e8716a6df7abad68b6cf81c437a2e0524e88f3ad
DIFF: https://github.com/llvm/llvm-project/commit/e8716a6df7abad68b6cf81c437a2e0524e88f3ad.diff

LOG: [clangd] Navigation from definition of template specialization to primary template

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

Reviewers: sammccall

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D71090

Added: 
    

Modified: 
    clang-tools-extra/clangd/XRefs.cpp
    clang-tools-extra/clangd/unittests/XRefsTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
index 157faf37ea1e..cf5cc4eb273e 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -191,10 +191,10 @@ std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos,
 
   // Macros are simple: there's no declaration/definition distinction.
   // As a consequence, there's no need to look them up in the index either.
-  SourceLocation MaybeMacroLocation = SM.getMacroArgExpandedLocation(
+  SourceLocation IdentStartLoc = SM.getMacroArgExpandedLocation(
       getBeginningOfIdentifier(Pos, AST.getSourceManager(), AST.getLangOpts()));
   std::vector<LocatedSymbol> Result;
-  if (auto M = locateMacroAt(MaybeMacroLocation, AST.getPreprocessor())) {
+  if (auto M = locateMacroAt(IdentStartLoc, AST.getPreprocessor())) {
     if (auto Loc = makeLocation(AST.getASTContext(),
                                 M->Info->getDefinitionLoc(), *MainFilePath)) {
       LocatedSymbol Macro;
@@ -234,6 +234,18 @@ std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos,
   for (const Decl *D : getDeclAtPosition(AST, SourceLoc, Relations)) {
     const Decl *Def = getDefinition(D);
     const Decl *Preferred = Def ? Def : D;
+
+    // If we're at the point of declaration of a template specialization,
+    // it's more useful to navigate to the template declaration.
+    if (SM.getMacroArgExpandedLocation(Preferred->getLocation()) ==
+        IdentStartLoc) {
+      if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Preferred)) {
+        D = CTSD->getSpecializedTemplate();
+        Def = getDefinition(D);
+        Preferred = Def ? Def : D;
+      }
+    }
+
     auto Loc = makeLocation(AST.getASTContext(),
                             spellingLocIfSpelled(findName(Preferred), SM),
                             *MainFilePath);
@@ -373,8 +385,8 @@ std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
   // 
diff erent kinds, deduplicate them.
   std::vector<DocumentHighlight> Result;
   for (const auto &Ref : References) {
-    if (auto Range = getTokenRange(AST.getSourceManager(),
-                                   AST.getLangOpts(), Ref.Loc)) {
+    if (auto Range =
+            getTokenRange(AST.getSourceManager(), AST.getLangOpts(), Ref.Loc)) {
       DocumentHighlight DH;
       DH.range = *Range;
       if (Ref.Role & index::SymbolRoleSet(index::SymbolRole::Write))

diff  --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp
index b6115065d1b7..ee23522d109a 100644
--- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -450,7 +450,22 @@ TEST(LocateSymbol, All) {
           +^+x;
         }
       )cpp",
-  };
+
+      R"cpp(// Declaration of explicit template specialization
+        template <typename T>
+        struct $decl[[Foo]] {};
+
+        template <>
+        struct Fo^o<int> {};
+      )cpp",
+
+      R"cpp(// Declaration of partial template specialization
+        template <typename T>
+        struct $decl[[Foo]] {};
+
+        template <typename T>
+        struct Fo^o<T*> {};
+      )cpp"};
   for (const char *Test : Tests) {
     Annotations T(Test);
     llvm::Optional<Range> WantDecl;


        


More information about the cfe-commits mailing list