Skip to content

Commit bd595d5

Browse files
authored
[include-cleaner] Generate references from explicit functiontemplate specializations (#83392)
1 parent 53bd411 commit bd595d5

File tree

2 files changed

+9
-6
lines changed

2 files changed

+9
-6
lines changed

clang-tools-extra/include-cleaner/lib/WalkAST.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
228228
// Mark declaration from definition as it needs type-checking.
229229
if (FD->isThisDeclarationADefinition())
230230
report(FD->getLocation(), FD);
231+
// Explicit specializaiton/instantiations of a function template requires
232+
// primary template.
233+
if (clang::isTemplateExplicitInstantiationOrSpecialization(
234+
FD->getTemplateSpecializationKind()))
235+
report(FD->getLocation(), FD->getPrimaryTemplate());
231236
return true;
232237
}
233238
bool VisitVarDecl(VarDecl *VD) {

clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -229,13 +229,9 @@ TEST(WalkAST, FunctionTemplates) {
229229
EXPECT_THAT(testWalk("template<typename T> void foo(T) {}",
230230
"template void ^foo<int>(int);"),
231231
ElementsAre());
232-
// FIXME: Report specialized template as used from explicit specializations.
233-
EXPECT_THAT(testWalk("template<typename T> void foo(T);",
232+
EXPECT_THAT(testWalk("template<typename T> void $explicit^foo(T);",
234233
"template<> void ^foo<int>(int);"),
235-
ElementsAre());
236-
EXPECT_THAT(testWalk("template<typename T> void foo(T) {}",
237-
"template<typename T> void ^foo(T*) {}"),
238-
ElementsAre());
234+
ElementsAre(Decl::FunctionTemplate));
239235

240236
// Implicit instantiations references most relevant template.
241237
EXPECT_THAT(testWalk(R"cpp(
@@ -510,6 +506,8 @@ TEST(WalkAST, Functions) {
510506
// Definition uses declaration, not the other way around.
511507
testWalk("void $explicit^foo();", "void ^foo() {}");
512508
testWalk("void foo() {}", "void ^foo();");
509+
testWalk("template <typename> void $explicit^foo();",
510+
"template <typename> void ^foo() {}");
513511

514512
// Unresolved calls marks all the overloads.
515513
testWalk("void $ambiguous^foo(int); void $ambiguous^foo(char);",

0 commit comments

Comments
 (0)