void UnusedUsingDeclsCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(usingDecl(isExpansionInMainFile()).bind("using"), this);
- Finder->addMatcher(recordType(hasDeclaration(namedDecl().bind("used"))),
- this);
+ auto DeclMatcher = hasDeclaration(namedDecl().bind("used"));
+ Finder->addMatcher(loc(recordType(DeclMatcher)), this);
+ Finder->addMatcher(loc(templateSpecializationType(DeclMatcher)), this);
}
void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
Using->shadow_begin()->getTargetDecl()->getCanonicalDecl();
// FIXME: Handle other target types.
- if (!isa<RecordDecl>(TargetDecl))
+ if (!isa<RecordDecl>(TargetDecl) && !isa<ClassTemplateDecl>(TargetDecl))
return;
FoundDecls[TargetDecl] = Using;
// 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")) {
+ if (const auto *Specialization =
+ dyn_cast<ClassTemplateSpecializationDecl>(Used))
+ Used = Specialization->getSpecializedTemplate();
auto I = FoundDecls.find(Used->getCanonicalDecl());
if (I != FoundDecls.end())
I->second = nullptr;
class C;
class D;
class D { public: static int i; };
+template <typename T> class E {};
+template <typename T> class F {};
}
// ----- Using declarations -----
using n::B;
using n::C;
using n::D;
+using n::E; // E
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'E' is unused
+// CHECK-FIXES: {{^}}// E
+using n::F;
// ----- Usages -----
void f(B b);
void g() {
vector<C> data;
D::i = 1;
+ F<int> f;
}