diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp --- a/clang-tools-extra/clangd/XRefs.cpp +++ b/clang-tools-extra/clangd/XRefs.cpp @@ -22,6 +22,7 @@ #include "index/SymbolLocation.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" +#include "clang/AST/Attrs.inc" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" @@ -277,7 +278,9 @@ for (const NamedDecl *D : getDeclAtPosition(AST, SourceLoc, Relations)) { // Special case: void foo() ^override: jump to the overridden method. if (const auto *CMD = llvm::dyn_cast(D)) { - const auto *Attr = D->getAttr(); + const InheritableAttr* Attr = D->getAttr(); + if (!Attr) + Attr = D->getAttr(); const syntax::Token *Tok = spelledIdentifierTouching(SourceLoc, AST.getTokens()); if (Attr && Tok && diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp --- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -452,6 +452,11 @@ class X : Y { void a() ^override {} }; )cpp", + R"cpp(// Final specifier jumps to overridden method + class Y { virtual void $decl[[a]]() = 0; }; + class X : Y { void a() ^final {} }; + )cpp", + R"cpp(// Heuristic resolution of dependent method template struct S {