diff options
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; } - |

