diff options
author | Nathan Ridge <zeratul976@hotmail.com> | 2019-12-05 16:29:59 -0500 |
---|---|---|
committer | Nathan Ridge <zeratul976@hotmail.com> | 2019-12-08 00:40:45 -0500 |
commit | e8716a6df7abad68b6cf81c437a2e0524e88f3ad (patch) | |
tree | 590102f6d8fbb0aa839bd6d7571ef9d4203057f7 | |
parent | c49194969430f0ee817498a7000a979a7a0ded03 (diff) | |
download | llvm-e8716a6df7abad68b6cf81c437a2e0524e88f3ad.zip llvm-e8716a6df7abad68b6cf81c437a2e0524e88f3ad.tar.gz llvm-e8716a6df7abad68b6cf81c437a2e0524e88f3ad.tar.bz2 |
[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
-rw-r--r-- | clang-tools-extra/clangd/XRefs.cpp | 20 | ||||
-rw-r--r-- | clang-tools-extra/clangd/unittests/XRefsTests.cpp | 17 |
2 files changed, 32 insertions, 5 deletions
diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp index 157faf3..cf5cc4e 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, // different 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 b611506..ee23522 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; |