[clang-tidy] Ignore function context in misc-unused-using-decls.
Summary: Make the check's behavior more correct when handling using-decls in multiple scopes. Reviewers: alexfh Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D20909 llvm-svn: 271632
This commit is contained in:
parent
5e3d314488
commit
d80c7c4808
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue