Author: Haojian Wu Date: 2020-08-07T11:39:49+02:00 New Revision: a70161808bcd6560e268aecf90138ff68f41fe54
URL: https://github.com/llvm/llvm-project/commit/a70161808bcd6560e268aecf90138ff68f41fe54 DIFF: https://github.com/llvm/llvm-project/commit/a70161808bcd6560e268aecf90138ff68f41fe54.diff LOG: [clangd] Include the underlying decls in go-to-definition. Fixes https://github.com/clangd/clangd/issues/277 Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D74054 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 26653aa409d7..b61ff4979320 100644 --- a/clang-tools-extra/clangd/XRefs.cpp +++ b/clang-tools-extra/clangd/XRefs.cpp @@ -290,6 +290,18 @@ locateASTReferent(SourceLocation CurLoc, const syntax::Token *TouchedIdentifier, } } + // Give the underlying decl if navigation is triggered on a non-renaming + // alias. + if (llvm::isa<UsingDecl>(D)) { + // FIXME: address more complicated cases. TargetDecl(... Underlying) gives + // all overload candidates, we only want the targeted one if the cursor is + // on an using-alias usage, workround it with getDeclAtPosition. + llvm::for_each( + getDeclAtPosition(AST, CurLoc, DeclRelation::Underlying, NodeKind), + [&](const NamedDecl *UD) { AddResultDecl(UD); }); + continue; + } + // Otherwise the target declaration is the right one. AddResultDecl(D); } diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp index c9c115fd19d8..686ba023a282 100644 --- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -47,6 +47,11 @@ using ::testing::UnorderedElementsAreArray; MATCHER_P2(FileRange, File, Range, "") { return Location{URIForFile::canonicalize(File, testRoot()), Range} == arg; } +MATCHER(DeclRange, "") { + const LocatedSymbol &Sym = ::testing::get<0>(arg); + const Range &Range = ::testing::get<1>(arg); + return Sym.PreferredDeclaration.range == Range; +} // Extracts ranges from an annotated example, and constructs a matcher for a // highlight set. Ranges should be named $read/$write as appropriate. @@ -945,15 +950,77 @@ TEST(LocateSymbol, TextualDependent) { Sym("uniqueMethodName", Header.range("BarLoc"), llvm::None))); } -TEST(LocateSymbol, TemplateTypedefs) { - auto T = Annotations(R"cpp( - template <class T> struct function {}; - template <class T> using callback = function<T()>; +TEST(LocateSymbol, Alias) { + const char *Tests[] = { + R"cpp( + template <class T> struct function {}; + template <class T> using [[callback]] = function<T()>; - c^allback<int> foo; - )cpp"); - auto AST = TestTU::withCode(T.code()).build(); - EXPECT_THAT(locateSymbolAt(AST, T.point()), ElementsAre(Sym("callback"))); + c^allback<int> foo; + )cpp", + + // triggered on non-definition of a renaming alias: should not give any + // underlying decls. + R"cpp( + class Foo {}; + typedef Foo [[Bar]]; + + B^ar b; + )cpp", + R"cpp( + class Foo {}; + using [[Bar]] = Foo; // definition + Ba^r b; + )cpp", + + // triggered on the underlying decl of a renaming alias. + R"cpp( + class [[Foo]]; + using Bar = Fo^o; + )cpp", + + // triggered on definition of a non-renaming alias: should give underlying + // decls. + R"cpp( + namespace ns { class [[Foo]] {}; } + using ns::F^oo; + )cpp", + + R"cpp( + namespace ns { int [[x]](char); int [[x]](double); } + using ns::^x; + )cpp", + + R"cpp( + namespace ns { int [[x]](char); int x(double); } + using ns::x; + int y = ^x('a'); + )cpp", + + R"cpp( + namespace ns { class [[Foo]] {}; } + using ns::Foo; + F^oo f; + )cpp", + + // other cases that don't matter much. + R"cpp( + class Foo {}; + typedef Foo [[Ba^r]]; + )cpp", + R"cpp( + class Foo {}; + using [[B^ar]] = Foo; + )cpp", + }; + + for (const auto* Case : Tests) { + SCOPED_TRACE(Case); + auto T = Annotations(Case); + auto AST = TestTU::withCode(T.code()).build(); + EXPECT_THAT(locateSymbolAt(AST, T.point()), + ::testing::UnorderedPointwise(DeclRange(), T.ranges())); + } } TEST(LocateSymbol, RelPathsInCompileCommand) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits