aboutsummaryrefslogtreecommitdiff
path: root/clang-tools-extra
diff options
context:
space:
mode:
authorkadir çetinkaya <kadircet@google.com>2024-02-23 11:48:04 +0100
committerGitHub <noreply@github.com>2024-02-23 11:48:04 +0100
commit9dfb8430509619a4e9d36fd00a11b83a2d5d0c3c (patch)
tree998ada3660958c30f057d6772eef8fefbb8b6385 /clang-tools-extra
parentde04b7d44edbfe8c2357cc291f8806575e6e93f2 (diff)
downloadllvm-9dfb8430509619a4e9d36fd00a11b83a2d5d0c3c.zip
llvm-9dfb8430509619a4e9d36fd00a11b83a2d5d0c3c.tar.gz
llvm-9dfb8430509619a4e9d36fd00a11b83a2d5d0c3c.tar.bz2
[include-cleaner] Use FoundDecl only for using-shadow-decls (#82615)
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.cpp34
2 files changed, 24 insertions, 15 deletions
diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 6c4d9b7..277e6ec5 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -128,6 +128,11 @@ public:
bool VisitDeclRefExpr(DeclRefExpr *DRE) {
auto *FD = DRE->getFoundDecl();
+ // Prefer the underlying decl if FoundDecl isn't a shadow decl, e.g:
+ // - For templates, found-decl is always primary template, but we want the
+ // specializaiton itself.
+ if (!llvm::isa<UsingShadowDecl>(FD))
+ FD = DRE->getDecl();
// For refs to non-meber-like decls, use the found decl.
// For member-like decls, we should have a reference from the qualifier to
// the container decl instead, which is preferred as it'll handle
diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
index 0be5db3..e238dc3 100644
--- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -200,24 +200,26 @@ TEST(WalkAST, VarTemplates) {
EXPECT_THAT(testWalk(R"cpp(
template <typename T> T $explicit^Foo = 0;)cpp",
"int z = ^Foo<int>;"),
- ElementsAre(Decl::VarTemplate));
+ ElementsAre(Decl::VarTemplateSpecialization));
EXPECT_THAT(testWalk(R"cpp(
- template<typename T> T $explicit^Foo = 0;
- template<> int Foo<int> = 1;)cpp",
+ template<typename T> T Foo = 0;
+ template<> int $explicit^Foo<int> = 1;)cpp",
"int x = ^Foo<int>;"),
- ElementsAre(Decl::VarTemplate));
+ ElementsAre(Decl::VarTemplateSpecialization));
// FIXME: This points at implicit specialization, instead we should point to
// explicit partial specializaiton pattern.
EXPECT_THAT(testWalk(R"cpp(
- template<typename T> T $explicit^Foo = 0;
- template<typename T> T* Foo<T*> = nullptr;)cpp",
+ template<typename T> T Foo = 0;
+ template<typename T> T* $explicit^Foo<T*> = nullptr;)cpp",
"int *x = ^Foo<int *>;"),
- ElementsAre(Decl::VarTemplate));
+ ElementsAre(Decl::VarTemplateSpecialization));
+ // Implicit specializations through explicit instantiations has source
+ // locations pointing at the primary template.
EXPECT_THAT(testWalk(R"cpp(
template<typename T> T $explicit^Foo = 0;
template int Foo<int>;)cpp",
"int x = ^Foo<int>;"),
- ElementsAre(Decl::VarTemplate));
+ ElementsAre(Decl::VarTemplateSpecialization));
}
TEST(WalkAST, FunctionTemplates) {
// Explicit instantiation and (partial) specialization references primary
@@ -239,18 +241,19 @@ TEST(WalkAST, FunctionTemplates) {
EXPECT_THAT(testWalk(R"cpp(
template <typename T> void $explicit^foo() {})cpp",
"auto x = []{ ^foo<int>(); };"),
- ElementsAre(Decl::FunctionTemplate));
- // FIXME: DeclRefExpr points at primary template, not the specialization.
+ ElementsAre(Decl::Function));
EXPECT_THAT(testWalk(R"cpp(
- template<typename T> void $explicit^foo() {}
- template<> void foo<int>(){})cpp",
+ template<typename T> void foo() {}
+ template<> void $explicit^foo<int>(){})cpp",
"auto x = []{ ^foo<int>(); };"),
- ElementsAre(Decl::FunctionTemplate));
+ ElementsAre(Decl::Function));
+ // The decl is actually the specialization, but explicit instantations point
+ // at the primary template.
EXPECT_THAT(testWalk(R"cpp(
template<typename T> void $explicit^foo() {};
template void foo<int>();)cpp",
"auto x = [] { ^foo<int>(); };"),
- ElementsAre(Decl::FunctionTemplate));
+ ElementsAre(Decl::Function));
}
TEST(WalkAST, TemplateSpecializationsFromUsingDecl) {
// Class templates
@@ -548,7 +551,8 @@ TEST(WalkAST, Concepts) {
testWalk(Concept, "template<typename T> void func() requires ^Foo<T> {}");
testWalk(Concept, "void func(^Foo auto x) {}");
// FIXME: Foo should be explicitly referenced.
- testWalk("template<typename T> concept Foo = true;", "void func() { ^Foo auto x = 1; }");
+ testWalk("template<typename T> concept Foo = true;",
+ "void func() { ^Foo auto x = 1; }");
}
TEST(WalkAST, FriendDecl) {