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 @@ -1863,6 +1863,26 @@ Vector x2; Vector y; )cpp", + R"cpp(// Dependent code + template void $decl[[foo]](T t); + template void bar(T t) { [[foo]](t); } // foo in bar is uninstantiated. + void baz(int x) { [[f^oo]](x); } + )cpp", + R"cpp( + namespace ns { + struct S{}; + void $decl[[foo]](S s); + } // namespace ns + template void foo(T t); + // FIXME: Maybe report this foo as a ref to ns::foo (because of ADL) + // when bar is instantiated? + template void bar(T t) { foo(t); } + void baz(int x) { + ns::S s; + bar(s); + [[f^oo]](s); + } + )cpp", }; for (const char *Test : Tests) checkFindRefs(Test); diff --git a/clang/lib/Index/IndexBody.cpp b/clang/lib/Index/IndexBody.cpp --- a/clang/lib/Index/IndexBody.cpp +++ b/clang/lib/Index/IndexBody.cpp @@ -466,6 +466,15 @@ } return true; } + + bool VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { + SmallVector Relations; + SymbolRoleSet Roles = getRolesForRef(E, Relations); + for (auto *D : E->decls()) + IndexCtx.handleReference(D, E->getNameLoc(), Parent, ParentDC, Roles, + Relations, E); + return true; + } }; } // anonymous namespace diff --git a/clang/test/Index/Core/index-dependent-source.cpp b/clang/test/Index/Core/index-dependent-source.cpp --- a/clang/test/Index/Core/index-dependent-source.cpp +++ b/clang/test/Index/Core/index-dependent-source.cpp @@ -224,3 +224,10 @@ // CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T@UsingD | | Ref,RelCont | rel: 1 using UsingD::foo; }; + +template void foo(); +// CHECK: [[@LINE-1]]:28 | function/C | foo | c:@FT@>1#Tfoo#v# | | Decl | rel: 0 +template void bar() { + foo(); +// CHECK: [[@LINE-1]]:3 | function/C | foo | c:@FT@>1#Tfoo#v# | | Ref,Call,RelCall,RelCont | rel: 1 +}