Skip to content

Commit 769eb0d

Browse files
committedMay 9, 2016
Support variables and functions types in misc-unused-using-decls.
Summary: Fix PR27429. Reviewers: djasper Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D20018 llvm-svn: 268917
1 parent 484983f commit 769eb0d

File tree

3 files changed

+80
-5
lines changed

3 files changed

+80
-5
lines changed
 

‎clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp

+27-5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ void UnusedUsingDeclsCheck::registerMatchers(MatchFinder *Finder) {
2323
auto DeclMatcher = hasDeclaration(namedDecl().bind("used"));
2424
Finder->addMatcher(loc(recordType(DeclMatcher)), this);
2525
Finder->addMatcher(loc(templateSpecializationType(DeclMatcher)), this);
26+
Finder->addMatcher(declRefExpr().bind("used"), this);
2627
}
2728

2829
void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
@@ -34,8 +35,13 @@ void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
3435
const auto *TargetDecl =
3536
Using->shadow_begin()->getTargetDecl()->getCanonicalDecl();
3637

37-
// FIXME: Handle other target types.
38-
if (!isa<RecordDecl>(TargetDecl) && !isa<ClassTemplateDecl>(TargetDecl))
38+
// Ignores using-declarations defined in class definition.
39+
if (isa<CXXRecordDecl>(TargetDecl->getDeclContext()))
40+
return;
41+
42+
if (!isa<RecordDecl>(TargetDecl) && !isa<ClassTemplateDecl>(TargetDecl) &&
43+
!isa<FunctionDecl>(TargetDecl) && !isa<VarDecl>(TargetDecl) &&
44+
!isa<FunctionTemplateDecl>(TargetDecl))
3945
return;
4046

4147
FoundDecls[TargetDecl] = Using;
@@ -57,10 +63,26 @@ void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
5763
if (const auto *Specialization =
5864
dyn_cast<ClassTemplateSpecializationDecl>(Used))
5965
Used = Specialization->getSpecializedTemplate();
60-
auto I = FoundDecls.find(Used->getCanonicalDecl());
61-
if (I != FoundDecls.end())
62-
I->second = nullptr;
66+
removeFromFoundDecls(Used);
67+
return;
6368
}
69+
70+
if (const auto *DRE = Result.Nodes.getNodeAs<DeclRefExpr>("used")) {
71+
if (const auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
72+
if (const auto *FDT = FD->getPrimaryTemplate())
73+
removeFromFoundDecls(FDT);
74+
else
75+
removeFromFoundDecls(FD);
76+
} else if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
77+
removeFromFoundDecls(VD);
78+
}
79+
}
80+
}
81+
82+
void UnusedUsingDeclsCheck::removeFromFoundDecls(const Decl *D) {
83+
auto I = FoundDecls.find(D->getCanonicalDecl());
84+
if (I != FoundDecls.end())
85+
I->second = nullptr;
6486
}
6587

6688
void UnusedUsingDeclsCheck::onEndOfTranslationUnit() {

‎clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.h

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class UnusedUsingDeclsCheck : public ClangTidyCheck {
3030
void onEndOfTranslationUnit() override;
3131

3232
private:
33+
void removeFromFoundDecls(const Decl *D);
34+
3335
llvm::DenseMap<const Decl*, const UsingDecl*> FoundDecls;
3436
llvm::DenseMap<const Decl*, CharSourceRange> FoundRanges;
3537
};

‎clang-tools-extra/test/clang-tidy/misc-unused-using-decls.cpp

+51
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,32 @@ class D;
1010
class D { public: static int i; };
1111
template <typename T> class E {};
1212
template <typename T> class F {};
13+
class G { public: static void func() {} };
14+
class H { public: static int i; };
15+
class I {
16+
public:
17+
static int ii;
18+
};
19+
20+
class Base {
21+
public:
22+
void f();
23+
};
24+
25+
D UsedInstance;
26+
D UnusedInstance;
27+
28+
int UsedFunc() { return 1; }
29+
int UnusedFunc() { return 1; }
30+
template <typename T> int UsedTemplateFunc() { return 1; }
31+
template <typename T> int UnusedTemplateFunc() { return 1; }
32+
33+
class ostream {
34+
public:
35+
ostream &operator<<(ostream &(*PF)(ostream &));
36+
};
37+
extern ostream cout;
38+
ostream &endl(ostream &os);
1339
}
1440

1541
// ----- Using declarations -----
@@ -24,12 +50,37 @@ using n::E; // E
2450
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'E' is unused
2551
// CHECK-FIXES: {{^}}// E
2652
using n::F;
53+
using n::G;
54+
using n::H;
55+
using n::I;
56+
int I::ii = 1;
57+
class Derived : public n::Base {
58+
public:
59+
using Base::f;
60+
};
61+
using n::UsedInstance;
62+
using n::UsedFunc;
63+
using n::UsedTemplateFunc;
64+
using n::UnusedInstance; // UnusedInstance
65+
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'UnusedInstance' is unused
66+
// CHECK-FIXES: {{^}}// UnusedInstance
67+
using n::UnusedFunc; // UnusedFunc
68+
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'UnusedFunc' is unused
69+
// CHECK-FIXES: {{^}}// UnusedFunc
70+
using n::cout;
71+
using n::endl;
2772

2873
// ----- Usages -----
2974
void f(B b);
3075
void g() {
3176
vector<C> data;
3277
D::i = 1;
3378
F<int> f;
79+
void (*func)() = &G::func;
80+
int *i = &H::i;
81+
UsedInstance.i;
82+
UsedFunc();
83+
UsedTemplateFunc<int>();
84+
cout << endl;
3485
}
3586

0 commit comments

Comments
 (0)
Please sign in to comment.