aboutsummaryrefslogtreecommitdiff
path: root/clang-tools-extra
diff options
context:
space:
mode:
authorkadir çetinkaya <kadircet@google.com>2024-02-29 10:37:00 +0100
committerGitHub <noreply@github.com>2024-02-29 10:37:00 +0100
commitbd595d54219e434acce2c05e97440847d30b5240 (patch)
tree8861cdbd5391a457080965301531703c2799a7c3 /clang-tools-extra
parent53bd411e5144937acec45080697957bf5b22de54 (diff)
downloadllvm-bd595d54219e434acce2c05e97440847d30b5240.zip
llvm-bd595d54219e434acce2c05e97440847d30b5240.tar.gz
llvm-bd595d54219e434acce2c05e97440847d30b5240.tar.bz2
[include-cleaner] Generate references from explicit functiontemplate specializations (#83392)
Diffstat (limited to 'clang-tools-extra')
-rw-r--r--clang-tools-extra/include-cleaner/lib/WalkAST.cpp5
-rw-r--r--clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp10
2 files changed, 9 insertions, 6 deletions
diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 277e6ec5..878067a 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -228,6 +228,11 @@ public:
// Mark declaration from definition as it needs type-checking.
if (FD->isThisDeclarationADefinition())
report(FD->getLocation(), FD);
+ // Explicit specializaiton/instantiations of a function template requires
+ // primary template.
+ if (clang::isTemplateExplicitInstantiationOrSpecialization(
+ FD->getTemplateSpecializationKind()))
+ report(FD->getLocation(), FD->getPrimaryTemplate());
return true;
}
bool VisitVarDecl(VarDecl *VD) {
diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
index e238dc3..5dc8815 100644
--- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -229,13 +229,9 @@ TEST(WalkAST, FunctionTemplates) {
EXPECT_THAT(testWalk("template<typename T> void foo(T) {}",
"template void ^foo<int>(int);"),
ElementsAre());
- // FIXME: Report specialized template as used from explicit specializations.
- EXPECT_THAT(testWalk("template<typename T> void foo(T);",
+ EXPECT_THAT(testWalk("template<typename T> void $explicit^foo(T);",
"template<> void ^foo<int>(int);"),
- ElementsAre());
- EXPECT_THAT(testWalk("template<typename T> void foo(T) {}",
- "template<typename T> void ^foo(T*) {}"),
- ElementsAre());
+ ElementsAre(Decl::FunctionTemplate));
// Implicit instantiations references most relevant template.
EXPECT_THAT(testWalk(R"cpp(
@@ -510,6 +506,8 @@ TEST(WalkAST, Functions) {
// Definition uses declaration, not the other way around.
testWalk("void $explicit^foo();", "void ^foo() {}");
testWalk("void foo() {}", "void ^foo();");
+ testWalk("template <typename> void $explicit^foo();",
+ "template <typename> void ^foo() {}");
// Unresolved calls marks all the overloads.
testWalk("void $ambiguous^foo(int); void $ambiguous^foo(char);",