Re: [PATCH] D20429: [clang-tidy] Handle using-decls with more than one shadow decl.

2016-05-20 Thread Haojian Wu via cfe-commits
hokein added inline comments.


Comment at: clang-tidy/misc/UnusedUsingDeclsCheck.cpp:59
@@ -59,1 +58,3 @@
 /*SkipTrailingWhitespaceAndNewLine=*/true));
+for (const auto It : Using->shadows()) {
+  const auto *TargetDecl = It->getTargetDecl()->getCanonicalDecl();

alexfh wrote:
> hokein wrote:
> > alexfh wrote:
> > > It's not iterator, so `It` is a confusing name. Something along the lines 
> > > of `Shadow` or `UsingShadow` should be better.
> > Actually, the `Using->shadows()` returns an iterator range, but I'm fine 
> > renaming it here.
> Sure, it returns a `llvm::iterator_range`, which is just a 
> range adaptor for a pair of iterators. It's not a "collection of iterators", 
> it's a "collection, defined by a pair of iterators". If you iterate over it 
> using a range-based for loop, you get whatever is pointed by the iterators, 
> not iterators.
I see it now. Thanks for the explanations :-).


Repository:
  rL LLVM

http://reviews.llvm.org/D20429



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20429: [clang-tidy] Handle using-decls with more than one shadow decl.

2016-05-20 Thread Alexander Kornienko via cfe-commits
alexfh added inline comments.


Comment at: clang-tidy/misc/UnusedUsingDeclsCheck.cpp:59
@@ -59,1 +58,3 @@
 /*SkipTrailingWhitespaceAndNewLine=*/true));
+for (const auto It : Using->shadows()) {
+  const auto *TargetDecl = It->getTargetDecl()->getCanonicalDecl();

hokein wrote:
> alexfh wrote:
> > It's not iterator, so `It` is a confusing name. Something along the lines 
> > of `Shadow` or `UsingShadow` should be better.
> Actually, the `Using->shadows()` returns an iterator range, but I'm fine 
> renaming it here.
Sure, it returns a `llvm::iterator_range`, which is just a 
range adaptor for a pair of iterators. It's not a "collection of iterators", 
it's a "collection, defined by a pair of iterators". If you iterate over it 
using a range-based for loop, you get whatever is pointed by the iterators, not 
iterators.


Repository:
  rL LLVM

http://reviews.llvm.org/D20429



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20429: [clang-tidy] Handle using-decls with more than one shadow decl.

2016-05-20 Thread Haojian Wu via cfe-commits
This revision was automatically updated to reflect the committed changes.
hokein marked an inline comment as done.
Closed by commit rL270191: [clang-tidy] Handle using-decls with more than one 
shadow decl. (authored by hokein).

Changed prior to commit:
  http://reviews.llvm.org/D20429?vs=57904&id=57906#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D20429

Files:
  clang-tools-extra/trunk/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
  clang-tools-extra/trunk/clang-tidy/misc/UnusedUsingDeclsCheck.h
  clang-tools-extra/trunk/test/clang-tidy/misc-unused-using-decls.cpp

Index: clang-tools-extra/trunk/clang-tidy/misc/UnusedUsingDeclsCheck.h
===
--- clang-tools-extra/trunk/clang-tidy/misc/UnusedUsingDeclsCheck.h
+++ clang-tools-extra/trunk/clang-tidy/misc/UnusedUsingDeclsCheck.h
@@ -11,7 +11,8 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_USING_DECLS_H
 
 #include "../ClangTidy.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include 
 
 namespace clang {
 namespace tidy {
@@ -32,8 +33,16 @@
 private:
   void removeFromFoundDecls(const Decl *D);
 
-  llvm::DenseMap FoundDecls;
-  llvm::DenseMap FoundRanges;
+  struct UsingDeclContext {
+explicit UsingDeclContext(const UsingDecl *FoundUsingDecl)
+: FoundUsingDecl(FoundUsingDecl), IsUsed(false) {}
+llvm::SmallPtrSet UsingTargetDecls;
+const UsingDecl *FoundUsingDecl;
+CharSourceRange UsingDeclRange;
+bool IsUsed;
+  };
+
+  std::vector Contexts;
 };
 
 } // namespace misc
Index: clang-tools-extra/trunk/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
@@ -18,6 +18,25 @@
 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(TargetDecl->getDeclContext()))
+return false;
+
+  return isa(TargetDecl) || isa(TargetDecl) ||
+ isa(TargetDecl) || isa(TargetDecl) ||
+ isa(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::check(const MatchFinder::MatchResult &Result) {
   if (const auto *Using = Result.Nodes.getNodeAs("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(TargetDecl->getDeclContext()))
-  return;
-
-if (!isa(TargetDecl) && !isa(TargetDecl) &&
-!isa(TargetDecl) && !isa(TargetDecl) &&
-!isa(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::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")
-<< 

Re: [PATCH] D20429: [clang-tidy] Handle using-decls with more than one shadow decl.

2016-05-20 Thread Haojian Wu via cfe-commits
hokein marked 2 inline comments as done.


Comment at: clang-tidy/misc/UnusedUsingDeclsCheck.cpp:59
@@ -59,1 +58,3 @@
 /*SkipTrailingWhitespaceAndNewLine=*/true));
+for (const auto It : Using->shadows()) {
+  const auto *TargetDecl = It->getTargetDecl()->getCanonicalDecl();

alexfh wrote:
> It's not iterator, so `It` is a confusing name. Something along the lines of 
> `Shadow` or `UsingShadow` should be better.
Actually, the `Using->shadows()` returns an iterator range, but I'm fine 
renaming it here.


http://reviews.llvm.org/D20429



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20429: [clang-tidy] Handle using-decls with more than one shadow decl.

2016-05-20 Thread Haojian Wu via cfe-commits
hokein updated this revision to Diff 57904.
hokein added a comment.

Address more comments.


http://reviews.llvm.org/D20429

Files:
  clang-tidy/misc/UnusedUsingDeclsCheck.cpp
  clang-tidy/misc/UnusedUsingDeclsCheck.h
  test/clang-tidy/misc-unused-using-decls.cpp

Index: test/clang-tidy/misc-unused-using-decls.cpp
===
--- test/clang-tidy/misc-unused-using-decls.cpp
+++ test/clang-tidy/misc-unused-using-decls.cpp
@@ -31,6 +31,8 @@
 template  int UsedTemplateFunc() { return 1; }
 template  int UnusedTemplateFunc() { return 1; }
 template  int UsedInTemplateFunc() { return 1; }
+void OverloadFunc(int);
+void OverloadFunc(double);
 
 class ostream {
 public:
@@ -79,6 +81,10 @@
   UsedInTemplateFunc();
 }
 
+using n::OverloadFunc; // OverloadFunc
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'OverloadFunc' is unused
+// CHECK-FIXES: {{^}}// OverloadFunc
+
 #define DEFINE_INT(name)\
   namespace INT {   \
   static const int _##name = 1; \
Index: clang-tidy/misc/UnusedUsingDeclsCheck.h
===
--- clang-tidy/misc/UnusedUsingDeclsCheck.h
+++ clang-tidy/misc/UnusedUsingDeclsCheck.h
@@ -11,7 +11,8 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_USING_DECLS_H
 
 #include "../ClangTidy.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include 
 
 namespace clang {
 namespace tidy {
@@ -32,8 +33,16 @@
 private:
   void removeFromFoundDecls(const Decl *D);
 
-  llvm::DenseMap FoundDecls;
-  llvm::DenseMap FoundRanges;
+  struct UsingDeclContext {
+explicit UsingDeclContext(const UsingDecl *FoundUsingDecl)
+: FoundUsingDecl(FoundUsingDecl), IsUsed(false) {}
+llvm::SmallPtrSet UsingTargetDecls;
+const UsingDecl *FoundUsingDecl;
+CharSourceRange UsingDeclRange;
+bool IsUsed;
+  };
+
+  std::vector Contexts;
 };
 
 } // namespace misc
Index: clang-tidy/misc/UnusedUsingDeclsCheck.cpp
===
--- clang-tidy/misc/UnusedUsingDeclsCheck.cpp
+++ clang-tidy/misc/UnusedUsingDeclsCheck.cpp
@@ -18,6 +18,25 @@
 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(TargetDecl->getDeclContext()))
+return false;
+
+  return isa(TargetDecl) || isa(TargetDecl) ||
+ isa(TargetDecl) || isa(TargetDecl) ||
+ isa(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::check(const MatchFinder::MatchResult &Result) {
   if (const auto *Using = Result.Nodes.getNodeAs("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(TargetDecl->getDeclContext()))
-  return;
-
-if (!isa(TargetDecl) && !isa(TargetDecl) &&
-!isa(TargetDecl) && !isa(TargetDecl) &&
-!isa(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::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->getCa

Re: [PATCH] D20429: [clang-tidy] Handle using-decls with more than one shadow decl.

2016-05-19 Thread Alexander Kornienko via cfe-commits
alexfh accepted this revision.
alexfh added a comment.
This revision is now accepted and ready to land.

LG with a couple of nits.



Comment at: clang-tidy/misc/UnusedUsingDeclsCheck.cpp:22
@@ +21,3 @@
+// 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

`ShouldCheckDecl` might convey the idea better.


Comment at: clang-tidy/misc/UnusedUsingDeclsCheck.cpp:59
@@ -59,1 +58,3 @@
 /*SkipTrailingWhitespaceAndNewLine=*/true));
+for (const auto It : Using->shadows()) {
+  const auto *TargetDecl = It->getTargetDecl()->getCanonicalDecl();

It's not iterator, so `It` is a confusing name. Something along the lines of 
`Shadow` or `UsingShadow` should be better.


http://reviews.llvm.org/D20429



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20429: [clang-tidy] Handle using-decls with more than one shadow decl.

2016-05-19 Thread Haojian Wu via cfe-commits
hokein marked an inline comment as done.


Comment at: clang-tidy/misc/UnusedUsingDeclsCheck.cpp:22
@@ +21,3 @@
+namespace {
+bool IsValidDecl(const Decl *TargetDecl) {
+  // Ignores using-declarations defined in macros.

alexfh wrote:
> This method assumes a rather non-trivial definition of "valid". Please add a 
> comment what exactly this method does.
> 
> Also, static is preferred to anonymous namespaces for functions in LLVM style 
> (http://llvm.org/docs/CodingStandards.html#anonymous-namespaces):
> | ... make anonymous namespaces as small as possible, and only use them for 
> class declarations. ...
I have renamed to `IsCheckable`, but it doesn't make more sense here. Do you 
have better suggestion on the function name? 


Comment at: test/clang-tidy/misc-unused-using-decls.cpp:86
@@ +85,3 @@
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'OverloadFunc' is 
unused
+// CHECK-FIXES: {{^}}// OverloadFunc
+

Will do it in a follow-up.


http://reviews.llvm.org/D20429



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20429: [clang-tidy] Handle using-decls with more than one shadow decl.

2016-05-19 Thread Haojian Wu via cfe-commits
hokein updated this revision to Diff 57790.
hokein added a comment.

Forgot a comments.


http://reviews.llvm.org/D20429

Files:
  clang-tidy/misc/UnusedUsingDeclsCheck.cpp
  clang-tidy/misc/UnusedUsingDeclsCheck.h
  test/clang-tidy/misc-unused-using-decls.cpp

Index: test/clang-tidy/misc-unused-using-decls.cpp
===
--- test/clang-tidy/misc-unused-using-decls.cpp
+++ test/clang-tidy/misc-unused-using-decls.cpp
@@ -31,6 +31,8 @@
 template  int UsedTemplateFunc() { return 1; }
 template  int UnusedTemplateFunc() { return 1; }
 template  int UsedInTemplateFunc() { return 1; }
+void OverloadFunc(int);
+void OverloadFunc(double);
 
 class ostream {
 public:
@@ -79,6 +81,10 @@
   UsedInTemplateFunc();
 }
 
+using n::OverloadFunc; // OverloadFunc
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'OverloadFunc' is unused
+// CHECK-FIXES: {{^}}// OverloadFunc
+
 #define DEFINE_INT(name)\
   namespace INT {   \
   static const int _##name = 1; \
Index: clang-tidy/misc/UnusedUsingDeclsCheck.h
===
--- clang-tidy/misc/UnusedUsingDeclsCheck.h
+++ clang-tidy/misc/UnusedUsingDeclsCheck.h
@@ -11,7 +11,8 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_USING_DECLS_H
 
 #include "../ClangTidy.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include 
 
 namespace clang {
 namespace tidy {
@@ -32,8 +33,16 @@
 private:
   void removeFromFoundDecls(const Decl *D);
 
-  llvm::DenseMap FoundDecls;
-  llvm::DenseMap FoundRanges;
+  struct UsingDeclContext {
+explicit UsingDeclContext(const UsingDecl *FoundUsingDecl)
+: FoundUsingDecl(FoundUsingDecl), IsUsed(false) {}
+llvm::SmallPtrSet UsingTargetDecls;
+const UsingDecl *FoundUsingDecl;
+CharSourceRange UsingDeclRange;
+bool IsUsed;
+  };
+
+  std::vector Contexts;
 };
 
 } // namespace misc
Index: clang-tidy/misc/UnusedUsingDeclsCheck.cpp
===
--- clang-tidy/misc/UnusedUsingDeclsCheck.cpp
+++ clang-tidy/misc/UnusedUsingDeclsCheck.cpp
@@ -18,6 +18,25 @@
 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 IsCheckable(const Decl *TargetDecl) {
+  // Ignores using-declarations defined in macros.
+  if (TargetDecl->getLocation().isMacroID())
+return false;
+
+  // Ignores using-declarations defined in class definition.
+  if (isa(TargetDecl->getDeclContext()))
+return false;
+
+  return isa(TargetDecl) || isa(TargetDecl) ||
+ isa(TargetDecl) || isa(TargetDecl) ||
+ isa(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::check(const MatchFinder::MatchResult &Result) {
   if (const auto *Using = Result.Nodes.getNodeAs("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(TargetDecl->getDeclContext()))
-  return;
-
-if (!isa(TargetDecl) && !isa(TargetDecl) &&
-!isa(TargetDecl) && !isa(TargetDecl) &&
-!isa(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 It : Using->shadows()) {
+  const auto *TargetDecl = It->getTargetDecl()->getCanonicalDecl();
+  if (IsCheckable(TargetDecl))
+Context.UsingTargetDecls.insert(TargetDecl);
+}
+if (!Context.UsingTargetDecls.empty())
+  Contexts.push_back(Context);
 return;
   }
 
@@ -93,20 +99,23 @@
 }
 
 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) {
+  Co

Re: [PATCH] D20429: [clang-tidy] Handle using-decls with more than one shadow decl.

2016-05-19 Thread Haojian Wu via cfe-commits
hokein updated this revision to Diff 57785.
hokein marked 4 inline comments as done.
hokein added a comment.

Address comments.


http://reviews.llvm.org/D20429

Files:
  clang-tidy/misc/UnusedUsingDeclsCheck.cpp
  clang-tidy/misc/UnusedUsingDeclsCheck.h
  test/clang-tidy/misc-unused-using-decls.cpp

Index: test/clang-tidy/misc-unused-using-decls.cpp
===
--- test/clang-tidy/misc-unused-using-decls.cpp
+++ test/clang-tidy/misc-unused-using-decls.cpp
@@ -31,6 +31,8 @@
 template  int UsedTemplateFunc() { return 1; }
 template  int UnusedTemplateFunc() { return 1; }
 template  int UsedInTemplateFunc() { return 1; }
+void OverloadFunc(int);
+void OverloadFunc(double);
 
 class ostream {
 public:
@@ -79,6 +81,10 @@
   UsedInTemplateFunc();
 }
 
+using n::OverloadFunc; // OverloadFunc
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'OverloadFunc' is unused
+// CHECK-FIXES: {{^}}// OverloadFunc
+
 #define DEFINE_INT(name)\
   namespace INT {   \
   static const int _##name = 1; \
Index: clang-tidy/misc/UnusedUsingDeclsCheck.h
===
--- clang-tidy/misc/UnusedUsingDeclsCheck.h
+++ clang-tidy/misc/UnusedUsingDeclsCheck.h
@@ -11,7 +11,8 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_USING_DECLS_H
 
 #include "../ClangTidy.h"
-#include "llvm/ADT/DenseMap.h"
+#include 
+#include 
 
 namespace clang {
 namespace tidy {
@@ -32,8 +33,16 @@
 private:
   void removeFromFoundDecls(const Decl *D);
 
-  llvm::DenseMap FoundDecls;
-  llvm::DenseMap FoundRanges;
+  struct UsingDeclContext {
+explicit UsingDeclContext(const UsingDecl *FoundUsingDecl)
+: FoundUsingDecl(FoundUsingDecl), IsUsed(false) {}
+std::set UsingTargetDecls;
+const UsingDecl *FoundUsingDecl;
+CharSourceRange UsingDeclRange;
+bool IsUsed;
+  };
+
+  std::vector Contexts;
 };
 
 } // namespace misc
Index: clang-tidy/misc/UnusedUsingDeclsCheck.cpp
===
--- clang-tidy/misc/UnusedUsingDeclsCheck.cpp
+++ clang-tidy/misc/UnusedUsingDeclsCheck.cpp
@@ -18,6 +18,25 @@
 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 IsCheckable(const Decl *TargetDecl) {
+  // Ignores using-declarations defined in macros.
+  if (TargetDecl->getLocation().isMacroID())
+return false;
+
+  // Ignores using-declarations defined in class definition.
+  if (isa(TargetDecl->getDeclContext()))
+return false;
+
+  return isa(TargetDecl) || isa(TargetDecl) ||
+ isa(TargetDecl) || isa(TargetDecl) ||
+ isa(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::check(const MatchFinder::MatchResult &Result) {
   if (const auto *Using = Result.Nodes.getNodeAs("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(TargetDecl->getDeclContext()))
-  return;
-
-if (!isa(TargetDecl) && !isa(TargetDecl) &&
-!isa(TargetDecl) && !isa(TargetDecl) &&
-!isa(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 It : Using->shadows()) {
+  const auto *TargetDecl = It->getTargetDecl()->getCanonicalDecl();
+  if (IsCheckable(TargetDecl))
+Context.UsingTargetDecls.insert(TargetDecl);
+}
+if (!Context.UsingTargetDecls.empty())
+  Contexts.push_back(Context);
 return;
   }
 
@@ -93,20 +99,23 @@
 }
 
 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) {
+ 

Re: [PATCH] D20429: [clang-tidy] Handle using-decls with more than one shadow decl.

2016-05-19 Thread Alexander Kornienko via cfe-commits
alexfh requested changes to this revision.
This revision now requires changes to proceed.


Comment at: clang-tidy/misc/UnusedUsingDeclsCheck.cpp:22
@@ +21,3 @@
+namespace {
+bool IsValidDecl(const Decl *TargetDecl) {
+  // Ignores using-declarations defined in macros.

This method assumes a rather non-trivial definition of "valid". Please add a 
comment what exactly this method does.

Also, static is preferred to anonymous namespaces for functions in LLVM style 
(http://llvm.org/docs/CodingStandards.html#anonymous-namespaces):
| ... make anonymous namespaces as small as possible, and only use them for 
class declarations. ...


Comment at: clang-tidy/misc/UnusedUsingDeclsCheck.cpp:29
@@ +28,3 @@
+  if (isa(TargetDecl->getDeclContext())) {
+llvm::errs() << "context\n";
+return false;

Debug output?


Comment at: clang-tidy/misc/UnusedUsingDeclsCheck.cpp:102
@@ +101,3 @@
+  for (auto &Context : Contexts) {
+if (Context.UsingTargetDecls.find(D->getCanonicalDecl()) !=
+Context.UsingTargetDecls.end()) {

.count() for sets is as effective, but results in clearer code.


Comment at: clang-tidy/misc/UnusedUsingDeclsCheck.h:39
@@ +38,3 @@
+: FoundUsingDecl(FoundUsingDecl), IsUsed(false) {}
+std::set UsingTargetDecls;
+const UsingDecl *FoundUsingDecl;

`SmallPtrSet` should be more efficient here.


Comment at: test/clang-tidy/misc-unused-using-decls.cpp:86
@@ +85,3 @@
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'OverloadFunc' is 
unused
+// CHECK-FIXES: {{^}}// OverloadFunc
+

Not for this patch, but it makes sense to remove trailing comments on deleted 
lines.


http://reviews.llvm.org/D20429



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D20429: [clang-tidy] Handle using-decls with more than one shadow decl.

2016-05-19 Thread Haojian Wu via cfe-commits
hokein created this revision.
hokein added a reviewer: alexfh.
hokein added subscribers: djasper, cfe-commits.

http://reviews.llvm.org/D20429

Files:
  clang-tidy/misc/UnusedUsingDeclsCheck.cpp
  clang-tidy/misc/UnusedUsingDeclsCheck.h
  test/clang-tidy/misc-unused-using-decls.cpp

Index: test/clang-tidy/misc-unused-using-decls.cpp
===
--- test/clang-tidy/misc-unused-using-decls.cpp
+++ test/clang-tidy/misc-unused-using-decls.cpp
@@ -31,6 +31,8 @@
 template  int UsedTemplateFunc() { return 1; }
 template  int UnusedTemplateFunc() { return 1; }
 template  int UsedInTemplateFunc() { return 1; }
+void OverloadFunc(int);
+void OverloadFunc(double);
 
 class ostream {
 public:
@@ -79,6 +81,10 @@
   UsedInTemplateFunc();
 }
 
+using n::OverloadFunc; // OverloadFunc
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'OverloadFunc' is unused
+// CHECK-FIXES: {{^}}// OverloadFunc
+
 #define DEFINE_INT(name)\
   namespace INT {   \
   static const int _##name = 1; \
Index: clang-tidy/misc/UnusedUsingDeclsCheck.h
===
--- clang-tidy/misc/UnusedUsingDeclsCheck.h
+++ clang-tidy/misc/UnusedUsingDeclsCheck.h
@@ -11,7 +11,8 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_UNUSED_USING_DECLS_H
 
 #include "../ClangTidy.h"
-#include "llvm/ADT/DenseMap.h"
+#include 
+#include 
 
 namespace clang {
 namespace tidy {
@@ -32,8 +33,16 @@
 private:
   void removeFromFoundDecls(const Decl *D);
 
-  llvm::DenseMap FoundDecls;
-  llvm::DenseMap FoundRanges;
+  struct UsingDeclContext {
+explicit UsingDeclContext(const UsingDecl *FoundUsingDecl)
+: FoundUsingDecl(FoundUsingDecl), IsUsed(false) {}
+std::set UsingTargetDecls;
+const UsingDecl *FoundUsingDecl;
+CharSourceRange UsingDeclRange;
+bool IsUsed;
+  };
+
+  std::vector Contexts;
 };
 
 } // namespace misc
Index: clang-tidy/misc/UnusedUsingDeclsCheck.cpp
===
--- clang-tidy/misc/UnusedUsingDeclsCheck.cpp
+++ clang-tidy/misc/UnusedUsingDeclsCheck.cpp
@@ -18,6 +18,24 @@
 namespace tidy {
 namespace misc {
 
+namespace {
+bool IsValidDecl(const Decl *TargetDecl) {
+  // Ignores using-declarations defined in macros.
+  if (TargetDecl->getLocation().isMacroID())
+return false;
+
+  // Ignores using-declarations defined in class definition.
+  if (isa(TargetDecl->getDeclContext())) {
+llvm::errs() << "context\n";
+return false;
+  }
+
+  return isa(TargetDecl) || isa(TargetDecl) ||
+ isa(TargetDecl) || isa(TargetDecl) ||
+ isa(TargetDecl);
+}
+} // namespace
+
 void UnusedUsingDeclsCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(usingDecl(isExpansionInMainFile()).bind("using"), this);
   auto DeclMatcher = hasDeclaration(namedDecl().bind("used"));
@@ -30,33 +48,20 @@
 
 void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
   if (const auto *Using = Result.Nodes.getNodeAs("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(TargetDecl->getDeclContext()))
-  return;
-
-if (!isa(TargetDecl) && !isa(TargetDecl) &&
-!isa(TargetDecl) && !isa(TargetDecl) &&
-!isa(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 It : Using->shadows()) {
+  const auto *TargetDecl = It->getTargetDecl()->getCanonicalDecl();
+  if (IsValidDecl(TargetDecl))
+Context.UsingTargetDecls.insert(TargetDecl);
+}
+if (!Context.UsingTargetDecls.empty())
+  Contexts.push_back(Context);
 return;
   }
 
@@ -93,20 +98,24 @@
 }
 
 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.find(D->getCanonicalDecl()) !=
+Context.UsingTargetDecls.end()) {
+  Context.IsUsed = true;
+  break;
+}
+  }
 }
 
 void UnusedUsingDeclsCheck::onEndOfTranslationUnit() {
-  for (const auto &FoundDecl : FoundDecls) {
-if (FoundDecl.sec