diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -586,6 +586,13 @@ } void VisitNamedDecl(const NamedDecl *ND) { + // We choose to ignore {Class, Function, Var, TypeAlias}TemplateDecls. As + // as their underlying decls, covering the same range, will be visited. + if (llvm::isa(ND) || + llvm::isa(ND) || + llvm::isa(ND) || + llvm::isa(ND)) + return; // FIXME: decide on how to surface destructors when we need them. if (llvm::isa(ND)) return; diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -741,21 +741,17 @@ {R"cpp( namespace foo { template - class $1^$2^Bar { - ~$3^Bar(); - void $4^f($5^Bar); + class $1^Bar { + ~$2^Bar(); + void $3^f($4^Bar); }; } )cpp", "0: targets = {foo::Bar::T}, decl\n" - // FIXME: avoid the 2 duplicated foo::Bar references below, the first - // one comes from ClassTemplateDecl; the second comes from the - // underlying CXXRecordDecl. "1: targets = {foo::Bar}, decl\n" - "2: targets = {foo::Bar}, decl\n" - "3: targets = {foo::Bar}\n" - "4: targets = {foo::Bar::f}, decl\n" - "5: targets = {foo::Bar}\n"}, + "2: targets = {foo::Bar}\n" + "3: targets = {foo::Bar::f}, decl\n" + "4: targets = {foo::Bar}\n"}, // MemberExpr should know their using declaration. {R"cpp( struct X { void func(int); }; @@ -1055,7 +1051,47 @@ } )cpp", "0: targets = {Test}\n" - "1: targets = {a}, decl\n"}}; + "1: targets = {a}, decl\n"}, + // Templates + {R"cpp( + namespace foo { + template + class $1^Bar {}; + } + )cpp", + "0: targets = {foo::Bar::T}, decl\n" + "1: targets = {foo::Bar}, decl\n"}, + // Templates + {R"cpp( + namespace foo { + template + void $1^func(); + } + )cpp", + "0: targets = {T}, decl\n" + "1: targets = {foo::func}, decl\n"}, + // Templates + {R"cpp( + namespace foo { + template + $1^T $2^x; + } + )cpp", + "0: targets = {foo::T}, decl\n" + "1: targets = {foo::T}\n" + "2: targets = {foo::x}, decl\n"}, + // Templates + {R"cpp( + template class vector {}; + namespace foo { + template + using $1^V = $2^vector<$3^T>; + } + )cpp", + "0: targets = {foo::T}, decl\n" + "1: targets = {foo::V}, decl\n" + "2: targets = {vector}\n" + "3: targets = {foo::T}\n"}}; for (const auto &C : Cases) { llvm::StringRef ExpectedCode = C.first;