summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp19
-rw-r--r--clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.h6
-rw-r--r--clang-tools-extra/test/clang-tidy/misc-unused-using-decls.cpp21
3 files changed, 40 insertions, 6 deletions
diff --git a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
index 7cb203c0e5e..7499190d5c3 100644
--- a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
@@ -41,11 +41,17 @@ void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *Using = Result.Nodes.getNodeAs<UsingDecl>("using")) {
// Ignores using-declarations defined in macros.
if (Using->getLocation().isMacroID())
- return ;
+ return;
// Ignores using-declarations defined in class definition.
if (isa<CXXRecordDecl>(Using->getDeclContext()))
- return ;
+ return;
+
+ // FIXME: We ignore using-decls defined in function definitions at the
+ // moment because of false positives caused by ADL and different function
+ // scopes.
+ if (isa<FunctionDecl>(Using->getDeclContext()))
+ return;
UsingDeclContext Context(Using);
Context.UsingDeclRange = CharSourceRange::getCharRange(
@@ -97,11 +103,14 @@ void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
}
void UnusedUsingDeclsCheck::removeFromFoundDecls(const Decl *D) {
+ // FIXME: Currently, we don't handle the using-decls being used in different
+ // scopes (such as different namespaces, different functions). Instead of
+ // giving an incorrect message, we mark all of them as used.
+ //
+ // FIXME: Use a more efficient way to find a matching context.
for (auto &Context : Contexts) {
- if (Context.UsingTargetDecls.count(D->getCanonicalDecl()) > 0) {
+ if (Context.UsingTargetDecls.count(D->getCanonicalDecl()) > 0)
Context.IsUsed = true;
- break;
- }
}
}
diff --git a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.h b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.h
index 6a240392de0..2a41a8f63f9 100644
--- a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.h
@@ -36,9 +36,15 @@ private:
struct UsingDeclContext {
explicit UsingDeclContext(const UsingDecl *FoundUsingDecl)
: FoundUsingDecl(FoundUsingDecl), IsUsed(false) {}
+ // A set saves all UsingShadowDecls introduced by a UsingDecl. A UsingDecl
+ // can introduce multiple UsingShadowDecls in some cases (such as
+ // overloaded functions).
llvm::SmallPtrSet<const Decl *, 4> UsingTargetDecls;
+ // The original UsingDecl.
const UsingDecl *FoundUsingDecl;
+ // The source range of the UsingDecl.
CharSourceRange UsingDeclRange;
+ // Whether the UsingDecl is used.
bool IsUsed;
};
diff --git a/clang-tools-extra/test/clang-tidy/misc-unused-using-decls.cpp b/clang-tools-extra/test/clang-tidy/misc-unused-using-decls.cpp
index 92977cc048d..4d6b33252f1 100644
--- a/clang-tools-extra/test/clang-tidy/misc-unused-using-decls.cpp
+++ b/clang-tools-extra/test/clang-tidy/misc-unused-using-decls.cpp
@@ -17,6 +17,8 @@ class I {
static int ii;
};
template <typename T> class J {};
+class G;
+class H;
class Base {
public:
@@ -99,6 +101,24 @@ DEFINE_INT(test);
USING_FUNC
#undef USING_FUNC
+namespace N1 {
+// n::G is used in namespace N2.
+// Currently, the check doesn't support multiple scopes. All the relevant
+// using-decls will be marked as used once we see an usage even the usage is in
+// other scope.
+using n::G;
+}
+
+namespace N2 {
+using n::G;
+void f(G g);
+}
+
+void IgnoreFunctionScope() {
+// Using-decls defined in function scope will be ignored.
+using n::H;
+}
+
// ----- Usages -----
void f(B b);
void g() {
@@ -112,4 +132,3 @@ void g() {
UsedTemplateFunc<int>();
cout << endl;
}
-
OpenPOWER on IntegriCloud