summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
diff options
context:
space:
mode:
authorHaojian Wu <hokein@google.com>2016-05-20 08:34:32 +0000
committerHaojian Wu <hokein@google.com>2016-05-20 08:34:32 +0000
commit1cea6e553117b25eb1a97e6b95508591af5da63e (patch)
treeaa825c420cea0dad0679dc20687a68ceff7ca509 /clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
parent86f1f4ca7724471cc027f31d777b8457c23ecebc (diff)
downloadbcm5719-llvm-1cea6e553117b25eb1a97e6b95508591af5da63e.tar.gz
bcm5719-llvm-1cea6e553117b25eb1a97e6b95508591af5da63e.zip
[clang-tidy] Handle using-decls with more than one shadow decl.
Reviewers: alexfh Subscribers: cfe-commits, djasper Differential Revision: http://reviews.llvm.org/D20429 llvm-svn: 270191
Diffstat (limited to 'clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp73
1 files changed, 41 insertions, 32 deletions
diff --git a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
index 1fe8f3cdfc0..1785886e291 100644
--- a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
@@ -18,6 +18,25 @@ namespace clang {
namespace tidy {
namespace misc {
+// A function that helps to tell whether a TargetDecl will be checked.
+// We only check a TargetDecl if :
+// * The corresponding UsingDecl is not defined in macros or in class
+// definitions.
+// * Only variable, function and class types are considered.
+static bool ShouldCheckDecl(const Decl *TargetDecl) {
+ // Ignores using-declarations defined in macros.
+ if (TargetDecl->getLocation().isMacroID())
+ return false;
+
+ // Ignores using-declarations defined in class definition.
+ if (isa<CXXRecordDecl>(TargetDecl->getDeclContext()))
+ return false;
+
+ return isa<RecordDecl>(TargetDecl) || isa<ClassTemplateDecl>(TargetDecl) ||
+ isa<FunctionDecl>(TargetDecl) || isa<VarDecl>(TargetDecl) ||
+ isa<FunctionTemplateDecl>(TargetDecl);
+}
+
void UnusedUsingDeclsCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(usingDecl(isExpansionInMainFile()).bind("using"), this);
auto DeclMatcher = hasDeclaration(namedDecl().bind("used"));
@@ -30,33 +49,20 @@ void UnusedUsingDeclsCheck::registerMatchers(MatchFinder *Finder) {
void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *Using = Result.Nodes.getNodeAs<UsingDecl>("using")) {
- // FIXME: Implement the correct behavior for using declarations with more
- // than one shadow.
- if (Using->shadow_size() != 1)
- return;
- const auto *TargetDecl =
- Using->shadow_begin()->getTargetDecl()->getCanonicalDecl();
-
- // Ignores using-declarations defined in macros.
- if (TargetDecl->getLocation().isMacroID())
- return;
-
- // Ignores using-declarations defined in class definition.
- if (isa<CXXRecordDecl>(TargetDecl->getDeclContext()))
- return;
-
- if (!isa<RecordDecl>(TargetDecl) && !isa<ClassTemplateDecl>(TargetDecl) &&
- !isa<FunctionDecl>(TargetDecl) && !isa<VarDecl>(TargetDecl) &&
- !isa<FunctionTemplateDecl>(TargetDecl))
- return;
-
- FoundDecls[TargetDecl] = Using;
- FoundRanges[TargetDecl] = CharSourceRange::getCharRange(
+ UsingDeclContext Context(Using);
+ Context.UsingDeclRange = CharSourceRange::getCharRange(
Using->getLocStart(),
Lexer::findLocationAfterToken(
Using->getLocEnd(), tok::semi, *Result.SourceManager,
Result.Context->getLangOpts(),
/*SkipTrailingWhitespaceAndNewLine=*/true));
+ for (const auto *UsingShadow : Using->shadows()) {
+ const auto *TargetDecl = UsingShadow->getTargetDecl()->getCanonicalDecl();
+ if (ShouldCheckDecl(TargetDecl))
+ Context.UsingTargetDecls.insert(TargetDecl);
+ }
+ if (!Context.UsingTargetDecls.empty())
+ Contexts.push_back(Context);
return;
}
@@ -93,20 +99,23 @@ void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
}
void UnusedUsingDeclsCheck::removeFromFoundDecls(const Decl *D) {
- auto I = FoundDecls.find(D->getCanonicalDecl());
- if (I != FoundDecls.end())
- I->second = nullptr;
+ for (auto &Context : Contexts) {
+ if (Context.UsingTargetDecls.count(D->getCanonicalDecl()) > 0) {
+ Context.IsUsed = true;
+ break;
+ }
+ }
}
void UnusedUsingDeclsCheck::onEndOfTranslationUnit() {
- for (const auto &FoundDecl : FoundDecls) {
- if (FoundDecl.second == nullptr)
- continue;
- diag(FoundDecl.second->getLocation(), "using decl %0 is unused")
- << FoundDecl.second
- << FixItHint::CreateRemoval(FoundRanges[FoundDecl.first]);
+ for (const auto &Context : Contexts) {
+ if (!Context.IsUsed) {
+ diag(Context.FoundUsingDecl->getLocation(), "using decl %0 is unused")
+ << Context.FoundUsingDecl
+ << FixItHint::CreateRemoval(Context.UsingDeclRange);
+ }
}
- FoundDecls.clear();
+ Contexts.clear();
}
} // namespace misc
OpenPOWER on IntegriCloud