Skip to content

Commit 4b88198

Browse files
committed
Ensure class templates are handled correctly
1 parent cce4abe commit 4b88198

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

clang-tools-extra/clangd/HeaderSourceSwitch.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ std::vector<const Decl *> getIndexableLocalDecls(ParsedAST &AST) {
147147
for (auto *D : Scope->decls())
148148
TraverseDecl(D);
149149
}
150+
// ClassTemplateDecl does not inherit from DeclContext
151+
if (auto *Scope = llvm::dyn_cast<ClassTemplateDecl>(ND)) {
152+
for (auto *D : Scope->getTemplatedDecl()->decls())
153+
TraverseDecl(D);
154+
}
150155
}
151156
if (llvm::isa<NamespaceDecl>(D))
152157
return; // namespace is indexable, but we're not interested.

clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,48 @@ TEST(HeaderSourceSwitchTest, FromImplHeaderToHeader) {
379379
Index.get()));
380380
}
381381
}
382+
383+
TEST(HeaderSourceSwitchTest, FromHeaderToImplHeaderClassTemplate) {
384+
// build a proper index, which contains symbols:
385+
// A_Sym1, declared in TestTU.h, defined in a_ext.h
386+
// B_Sym[1-2], declared in TestTU.h, defined in b_ext.h
387+
SymbolSlab::Builder AllSymbols;
388+
TestTU Testing;
389+
Testing.Filename = "a.cpp";
390+
Testing.Code = R"cpp(void f() {}
391+
void g(){})cpp";
392+
Testing.HeaderFilename = "TestTU.h";
393+
Testing.HeaderCode = R"cpp(void f();
394+
void g();
395+
template<typename T> struct S
396+
{
397+
void a();
398+
void b();
399+
void c();
400+
};)cpp";
401+
for (auto &Sym : Testing.headerSymbols())
402+
AllSymbols.insert(Sym);
403+
404+
Testing.Filename = "b_ext.h";
405+
Testing.Code =
406+
R"cpp(template<typename T> void S<T>::a(){}
407+
template<typename T> void S<T>::b(){}
408+
template<typename T> void S<T>::c(){})cpp";
409+
Testing.ExtraArgs.push_back("-xc++-header"); // inform clang this is a header.
410+
411+
for (auto &Sym : Testing.headerSymbols())
412+
AllSymbols.insert(Sym);
413+
auto Index = MemIndex::build(std::move(AllSymbols).build(), {}, {});
414+
415+
TestTU TU = TestTU::withCode(Testing.HeaderCode);
416+
TU.Filename = "TestTU.h";
417+
TU.ExtraArgs.push_back("-xc++-header"); // inform clang this is a header.
418+
auto HeaderAST = TU.build();
419+
EXPECT_EQ(testPath("b_ext.h"),
420+
getCorrespondingHeaderOrSource(testPath(TU.Filename), HeaderAST,
421+
Index.get()));
422+
}
423+
382424
TEST(HeaderSourceSwitchTest, FromSourceToHeader) {
383425
// build a proper index, which contains symbols:
384426
// A_Sym1, declared in a.h, defined in TestTU.cpp

0 commit comments

Comments
 (0)