hokein updated this revision to Diff 218423.
hokein added a comment.
minor fix
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D66945/new/
https://reviews.llvm.org/D66945
Files:
clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
clang-tools-extra/test/clang-tidy/misc-unused-using-decls.cpp
Index: clang-tools-extra/test/clang-tidy/misc-unused-using-decls.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/misc-unused-using-decls.cpp
+++ clang-tools-extra/test/clang-tidy/misc-unused-using-decls.cpp
@@ -31,6 +31,8 @@
template <int T> class P {};
const int Constant = 0;
+template <typename T> class Q {};
+
class Base {
public:
void f();
@@ -169,6 +171,8 @@
using n::Constant;
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'Constant' is unused
+using n::Q;
+
// ----- Usages -----
void f(B b);
void g() {
@@ -202,3 +206,8 @@
template <int T>
void i(n::P<T>* t) {}
template void i(n::P<Constant>* t);
+
+template <typename T, template <typename> class U> class Bar {};
+// We used to report Q unsued, because we only checked the first template
+// argument.
+Bar<int, Q> *bar;
Index: clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
+++ clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
@@ -17,6 +17,29 @@
namespace tidy {
namespace misc {
+namespace {
+// FIXME: Move ASTMatcher library.
+AST_POLYMORPHIC_MATCHER_P(
+ forEachTemplateArgument,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
+ TemplateSpecializationType, FunctionDecl),
+ clang::ast_matchers::internal::Matcher<TemplateArgument>, InnerMatcher) {
+ ArrayRef<TemplateArgument> TemplateArgs =
+ clang::ast_matchers::internal::getTemplateSpecializationArgs(Node);
+ clang::ast_matchers::internal::BoundNodesTreeBuilder Result;
+ bool Matched = false;
+ for (const auto &Arg : TemplateArgs) {
+ clang::ast_matchers::internal::BoundNodesTreeBuilder ArgBuilder(*Builder);
+ if (InnerMatcher.matches(Arg, Finder, &ArgBuilder)) {
+ Matched = true;
+ Result.addMatch(ArgBuilder);
+ }
+ }
+ *Builder = std::move(Result);
+ return Matched;
+}
+} // namespace
+
// A function that helps to tell whether a TargetDecl in a UsingDecl will be
// checked. Only variable, function, function template, class template, class,
// enum declaration and enum constant declaration are considered.
@@ -37,11 +60,10 @@
Finder->addMatcher(callExpr(callee(unresolvedLookupExpr().bind("used"))),
this);
Finder->addMatcher(
- callExpr(hasDeclaration(functionDecl(hasAnyTemplateArgument(
- anyOf(refersToTemplate(templateName().bind("used")),
- refersToDeclaration(functionDecl().bind("used"))))))),
+ callExpr(hasDeclaration(functionDecl(
+ forEachTemplateArgument(templateArgument().bind("used"))))),
this);
- Finder->addMatcher(loc(templateSpecializationType(hasAnyTemplateArgument(
+ Finder->addMatcher(loc(templateSpecializationType(forEachTemplateArgument(
templateArgument().bind("used")))),
this);
}
@@ -85,47 +107,43 @@
// corresponding using declaration has been found.
// FIXME: This currently doesn't look at whether the type reference is
// actually found with the help of the using declaration.
- if (const auto *Used = Result.Nodes.getNodeAs<NamedDecl>("used")) {
+ auto RemoveNamedDecl = [&](const NamedDecl *Used) {
+ removeFromFoundDecls(Used);
+ // Also remove variants of Used.
if (const auto *FD = dyn_cast<FunctionDecl>(Used)) {
removeFromFoundDecls(FD->getPrimaryTemplate());
} else if (const auto *Specialization =
dyn_cast<ClassTemplateSpecializationDecl>(Used)) {
- Used = Specialization->getSpecializedTemplate();
+ removeFromFoundDecls(Specialization->getSpecializedTemplate());
+ } else if (const auto *FD = dyn_cast<FunctionDecl>(Used)) {
+ if (const auto *FDT = FD->getPrimaryTemplate())
+ removeFromFoundDecls(FDT);
+ } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(Used)) {
+ if (const auto *ET = ECD->getType()->getAs<EnumType>())
+ removeFromFoundDecls(ET->getDecl());
}
- removeFromFoundDecls(Used);
+ };
+ if (const auto *Used = Result.Nodes.getNodeAs<NamedDecl>("used")) {
+ RemoveNamedDecl(Used);
return;
}
if (const auto *Used = Result.Nodes.getNodeAs<TemplateArgument>("used")) {
- // FIXME: Support non-type template parameters.
if (Used->getKind() == TemplateArgument::Template) {
if (const auto *TD = Used->getAsTemplate().getAsTemplateDecl())
removeFromFoundDecls(TD);
} else if (Used->getKind() == TemplateArgument::Type) {
if (auto *RD = Used->getAsType()->getAsCXXRecordDecl())
removeFromFoundDecls(RD);
+ } else if (Used->getKind() == TemplateArgument::Declaration) {
+ RemoveNamedDecl(Used->getAsDecl());
}
return;
}
- if (const auto *Used = Result.Nodes.getNodeAs<TemplateName>("used")) {
- removeFromFoundDecls(Used->getAsTemplateDecl());
- return;
- }
-
if (const auto *DRE = Result.Nodes.getNodeAs<DeclRefExpr>("used")) {
- if (const auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
- if (const auto *FDT = FD->getPrimaryTemplate())
- removeFromFoundDecls(FDT);
- else
- removeFromFoundDecls(FD);
- } else if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
- removeFromFoundDecls(VD);
- } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
- removeFromFoundDecls(ECD);
- if (const auto *ET = ECD->getType()->getAs<EnumType>())
- removeFromFoundDecls(ET->getDecl());
- }
+ RemoveNamedDecl(DRE->getDecl());
+ return;
}
// Check the uninstantiated template function usage.
if (const auto *ULE = Result.Nodes.getNodeAs<UnresolvedLookupExpr>("used")) {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits