-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[include-cleaner] Mark RecordDecls referenced in UsingDecls as explicit #106430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang-tools-extra Author: kadir çetinkaya (kadircet) ChangesWe were reporting ambigious references from using declarations as user Hence this patch returns an explicit reference to record decls and Full diff: https://github.com/llvm/llvm-project/pull/106430.diff 2 Files Affected:
diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 598484d09712e5..5e6b862caf0d6c 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -203,7 +203,7 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
bool VisitUsingDecl(UsingDecl *UD) {
for (const auto *Shadow : UD->shadows()) {
auto *TD = Shadow->getTargetDecl();
- auto IsUsed = TD->isUsed() || TD->isReferenced();
+ auto IsUsed = TD->isUsed() || TD->isReferenced() || !TD->getAsFunction();
report(UD->getLocation(), TD,
IsUsed ? RefType::Explicit : RefType::Ambiguous);
diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
index 6c8eacbff1cea3..9286758cab081c 100644
--- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -255,7 +255,7 @@ TEST(WalkAST, TemplateSpecializationsFromUsingDecl) {
// Class templates
testWalk(R"cpp(
namespace ns {
-template<class T> class $ambiguous^Z {}; // primary template
+template<class T> class $explicit^Z {}; // primary template
template<class T> class $ambiguous^Z<T*> {}; // partial specialization
template<> class $ambiguous^Z<int> {}; // full specialization
}
@@ -265,7 +265,7 @@ template<> class $ambiguous^Z<int> {}; // full specialization
// Var templates
testWalk(R"cpp(
namespace ns {
-template<class T> T $ambiguous^foo; // primary template
+template<class T> T $explicit^foo; // primary template
template<class T> T $ambiguous^foo<T*>; // partial specialization
template<> int* $ambiguous^foo<int>; // full specialization
}
@@ -335,7 +335,12 @@ TEST(WalkAST, Using) {
testWalk(R"cpp(
namespace ns {
template<class T>
- class $ambiguous^Y {};
+ class $explicit^Y {};
+ })cpp",
+ "using ns::^Y;");
+ testWalk(R"cpp(
+ namespace ns {
+ class $explicit^Y {};
})cpp",
"using ns::^Y;");
testWalk(R"cpp(
|
@@ -203,7 +203,7 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> { | |||
bool VisitUsingDecl(UsingDecl *UD) { | |||
for (const auto *Shadow : UD->shadows()) { | |||
auto *TD = Shadow->getTargetDecl(); | |||
auto IsUsed = TD->isUsed() || TD->isReferenced(); | |||
auto IsUsed = TD->isUsed() || TD->isReferenced() || !TD->getAsFunction(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: the name IsUsed
no longer reflects its purpose. Consider renaming it to something more suitable or inlining it.
Additionally, it would be helpful to add comments to document the intention behind this code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I was actually thinking that usedness
is still the right concept here, spelling of the type name in the using declaration is enough to trigger that use for records.
I added comments also along those lines, LMK if it still doesn't resonate with you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The connection between usedness and !TD->getAsFunction()
wasn’t immediately obvious to me. With the newly-added comment, it's much clearer now, everything looks good, thanks.
We were reporting ambigious references from using declarations as user can be depending on different overloads of a function just because they are visible in the TU. This doesn't apply to records, or primary templates as declaration being referenced in such cases is unambigious, the ambiguity applies to specializations though. Hence this patch returns an explicit reference to record decls and primary templates of those.
8969498
to
9a96724
Compare
@@ -203,7 +203,7 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> { | |||
bool VisitUsingDecl(UsingDecl *UD) { | |||
for (const auto *Shadow : UD->shadows()) { | |||
auto *TD = Shadow->getTargetDecl(); | |||
auto IsUsed = TD->isUsed() || TD->isReferenced(); | |||
auto IsUsed = TD->isUsed() || TD->isReferenced() || !TD->getAsFunction(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The connection between usedness and !TD->getAsFunction()
wasn’t immediately obvious to me. With the newly-added comment, it's much clearer now, everything looks good, thanks.
We were reporting ambigious references from using declarations as user
can be depending on different overloads of a function just because they
are visible in the TU.
This doesn't apply to records, or primary templates as declaration being
referenced in such cases is unambigious, the ambiguity applies to
specializations though.
Hence this patch returns an explicit reference to record decls and
primary templates of those.