aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Ridge <zeratul976@hotmail.com>2019-12-05 16:29:59 -0500
committerNathan Ridge <zeratul976@hotmail.com>2019-12-08 00:40:45 -0500
commite8716a6df7abad68b6cf81c437a2e0524e88f3ad (patch)
tree590102f6d8fbb0aa839bd6d7571ef9d4203057f7
parentc49194969430f0ee817498a7000a979a7a0ded03 (diff)
downloadllvm-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.cpp20
-rw-r--r--clang-tools-extra/clangd/unittests/XRefsTests.cpp17
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;