Author: Sam McCall Date: 2020-10-28T20:17:35+01:00 New Revision: 0e94836989a12e11b4717f01099e34dbc0ff25d4
URL: https://github.com/llvm/llvm-project/commit/0e94836989a12e11b4717f01099e34dbc0ff25d4 DIFF: https://github.com/llvm/llvm-project/commit/0e94836989a12e11b4717f01099e34dbc0ff25d4.diff LOG: [clangd] Go-to-definition from non-renaming alias is unambiguous. It's not helpful to show the alias itself as an option. This fixes a regression accepted in f24649b77d856157c64841457dcc4f70530d607c. Differential Revision: https://reviews.llvm.org/D89238 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 0ec62d76c104..02dbd3ee9278 100644 --- a/clang-tools-extra/clangd/XRefs.cpp +++ b/clang-tools-extra/clangd/XRefs.cpp @@ -171,22 +171,33 @@ SymbolLocation getPreferredLocation(const Location &ASTLoc, return Merged.CanonicalDeclaration; } +std::vector<std::pair<const NamedDecl *, DeclRelationSet>> +getDeclAtPositionWithRelations(ParsedAST &AST, SourceLocation Pos, + DeclRelationSet Relations, + ASTNodeKind *NodeKind = nullptr) { + unsigned Offset = AST.getSourceManager().getDecomposedSpellingLoc(Pos).second; + std::vector<std::pair<const NamedDecl *, DeclRelationSet>> Result; + auto ResultFromTree = [&](SelectionTree ST) { + if (const SelectionTree::Node *N = ST.commonAncestor()) { + if (NodeKind) + *NodeKind = N->ASTNode.getNodeKind(); + llvm::copy_if(allTargetDecls(N->ASTNode), std::back_inserter(Result), + [&](auto &Entry) { return !(Entry.second & ~Relations); }); + } + return !Result.empty(); + }; + SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), Offset, + Offset, ResultFromTree); + return Result; +} + std::vector<const NamedDecl *> getDeclAtPosition(ParsedAST &AST, SourceLocation Pos, DeclRelationSet Relations, ASTNodeKind *NodeKind = nullptr) { - unsigned Offset = AST.getSourceManager().getDecomposedSpellingLoc(Pos).second; std::vector<const NamedDecl *> Result; - SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), Offset, - Offset, [&](SelectionTree ST) { - if (const SelectionTree::Node *N = - ST.commonAncestor()) { - if (NodeKind) - *NodeKind = N->ASTNode.getNodeKind(); - llvm::copy(targetDecl(N->ASTNode, Relations), - std::back_inserter(Result)); - } - return !Result.empty(); - }); + for (auto &Entry : + getDeclAtPositionWithRelations(AST, Pos, Relations, NodeKind)) + Result.push_back(Entry.first); return Result; } @@ -316,8 +327,10 @@ locateASTReferent(SourceLocation CurLoc, const syntax::Token *TouchedIdentifier, // Emit all symbol locations (declaration or definition) from AST. DeclRelationSet Relations = DeclRelation::TemplatePattern | DeclRelation::Alias; - for (const NamedDecl *D : - getDeclAtPosition(AST, CurLoc, Relations, NodeKind)) { + auto Candidates = + getDeclAtPositionWithRelations(AST, CurLoc, Relations, NodeKind); + for (const auto &E : Candidates) { + const NamedDecl *D = E.first; // Special case: void foo() ^override: jump to the overridden method. if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(D)) { const InheritableAttr *Attr = D->getAttr<OverrideAttr>(); @@ -333,6 +346,18 @@ locateASTReferent(SourceLocation CurLoc, const syntax::Token *TouchedIdentifier, } } + // Special case: the cursor is on an alias, prefer other results. + // This targets "using ns::^Foo", where the target is more interesting. + // This does not trigger on renaming aliases: + // `using Foo = ^Bar` already targets Bar via a TypeLoc + // `using ^Foo = Bar` has no other results, as Underlying is filtered. + if (E.second & DeclRelation::Alias && Candidates.size() > 1 && + // beginLoc/endLoc are a token range, so rewind the identifier we're in. + SM.isPointWithin(TouchedIdentifier ? TouchedIdentifier->location() + : CurLoc, + D->getBeginLoc(), D->getEndLoc())) + continue; + // Special case: the point of declaration of a template specialization, // it's more useful to navigate to the template declaration. if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) { diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp index 9f77db39a3e4..efca92fd0e9f 100644 --- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -1118,13 +1118,12 @@ TEST(LocateSymbol, Alias) { // decls. R"cpp( namespace ns { class [[Foo]] {}; } - // FIXME: don't return the using decl if it touches the cursor position. - using ns::[[F^oo]]; + using ns::F^oo; )cpp", R"cpp( namespace ns { int [[x]](char); int [[x]](double); } - using ns::[[^x]]; + using ns::^x; )cpp", R"cpp( @@ -1157,7 +1156,7 @@ TEST(LocateSymbol, Alias) { }; template <typename T> struct Derived : Base<T> { - using Base<T>::[[w^aldo]]; + using Base<T>::w^aldo; }; )cpp", }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits