Skip to content

Commit e8716a6

Browse files
[clangd] Navigation from definition of template specialization to primary template
Fixes clangd/clangd#212. Reviewers: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D71090
1 parent c491949 commit e8716a6

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

clang-tools-extra/clangd/XRefs.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,10 @@ std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos,
191191

192192
// Macros are simple: there's no declaration/definition distinction.
193193
// As a consequence, there's no need to look them up in the index either.
194-
SourceLocation MaybeMacroLocation = SM.getMacroArgExpandedLocation(
194+
SourceLocation IdentStartLoc = SM.getMacroArgExpandedLocation(
195195
getBeginningOfIdentifier(Pos, AST.getSourceManager(), AST.getLangOpts()));
196196
std::vector<LocatedSymbol> Result;
197-
if (auto M = locateMacroAt(MaybeMacroLocation, AST.getPreprocessor())) {
197+
if (auto M = locateMacroAt(IdentStartLoc, AST.getPreprocessor())) {
198198
if (auto Loc = makeLocation(AST.getASTContext(),
199199
M->Info->getDefinitionLoc(), *MainFilePath)) {
200200
LocatedSymbol Macro;
@@ -234,6 +234,18 @@ std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos,
234234
for (const Decl *D : getDeclAtPosition(AST, SourceLoc, Relations)) {
235235
const Decl *Def = getDefinition(D);
236236
const Decl *Preferred = Def ? Def : D;
237+
238+
// If we're at the point of declaration of a template specialization,
239+
// it's more useful to navigate to the template declaration.
240+
if (SM.getMacroArgExpandedLocation(Preferred->getLocation()) ==
241+
IdentStartLoc) {
242+
if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Preferred)) {
243+
D = CTSD->getSpecializedTemplate();
244+
Def = getDefinition(D);
245+
Preferred = Def ? Def : D;
246+
}
247+
}
248+
237249
auto Loc = makeLocation(AST.getASTContext(),
238250
spellingLocIfSpelled(findName(Preferred), SM),
239251
*MainFilePath);
@@ -373,8 +385,8 @@ std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
373385
// different kinds, deduplicate them.
374386
std::vector<DocumentHighlight> Result;
375387
for (const auto &Ref : References) {
376-
if (auto Range = getTokenRange(AST.getSourceManager(),
377-
AST.getLangOpts(), Ref.Loc)) {
388+
if (auto Range =
389+
getTokenRange(AST.getSourceManager(), AST.getLangOpts(), Ref.Loc)) {
378390
DocumentHighlight DH;
379391
DH.range = *Range;
380392
if (Ref.Role & index::SymbolRoleSet(index::SymbolRole::Write))

clang-tools-extra/clangd/unittests/XRefsTests.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,22 @@ TEST(LocateSymbol, All) {
450450
+^+x;
451451
}
452452
)cpp",
453-
};
453+
454+
R"cpp(// Declaration of explicit template specialization
455+
template <typename T>
456+
struct $decl[[Foo]] {};
457+
458+
template <>
459+
struct Fo^o<int> {};
460+
)cpp",
461+
462+
R"cpp(// Declaration of partial template specialization
463+
template <typename T>
464+
struct $decl[[Foo]] {};
465+
466+
template <typename T>
467+
struct Fo^o<T*> {};
468+
)cpp"};
454469
for (const char *Test : Tests) {
455470
Annotations T(Test);
456471
llvm::Optional<Range> WantDecl;

0 commit comments

Comments
 (0)