[clang-tidy] Fix a template function false positive in misc-unused-using-decls check.

Summary: Ignore warning uninstantiated template function usages.

Reviewers: djasper, alexfh

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D20326

git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@269906 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Haojian Wu 2016-05-18 11:49:34 +00:00
Родитель 296bbc1e5a
Коммит 1ba2168830
2 изменённых файлов: 25 добавлений и 0 удалений

Просмотреть файл

@ -10,6 +10,7 @@
#include "UnusedUsingDeclsCheck.h" #include "UnusedUsingDeclsCheck.h"
#include "clang/AST/ASTContext.h" #include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/Lex/Lexer.h" #include "clang/Lex/Lexer.h"
using namespace clang::ast_matchers; using namespace clang::ast_matchers;
@ -18,12 +19,20 @@ namespace clang {
namespace tidy { namespace tidy {
namespace misc { namespace misc {
namespace {
// FIXME: Move this node matcher to ASTMatcher.
const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr>
unresolvedLookupExpr;
}
void UnusedUsingDeclsCheck::registerMatchers(MatchFinder *Finder) { void UnusedUsingDeclsCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(usingDecl(isExpansionInMainFile()).bind("using"), this); Finder->addMatcher(usingDecl(isExpansionInMainFile()).bind("using"), this);
auto DeclMatcher = hasDeclaration(namedDecl().bind("used")); auto DeclMatcher = hasDeclaration(namedDecl().bind("used"));
Finder->addMatcher(loc(recordType(DeclMatcher)), this); Finder->addMatcher(loc(recordType(DeclMatcher)), this);
Finder->addMatcher(loc(templateSpecializationType(DeclMatcher)), this); Finder->addMatcher(loc(templateSpecializationType(DeclMatcher)), this);
Finder->addMatcher(declRefExpr().bind("used"), this); Finder->addMatcher(declRefExpr().bind("used"), this);
Finder->addMatcher(callExpr(callee(unresolvedLookupExpr().bind("used"))),
this);
} }
void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) { void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
@ -81,6 +90,13 @@ void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
removeFromFoundDecls(VD); removeFromFoundDecls(VD);
} }
} }
// Check the uninstantiated template function usage.
if (const auto *ULE = Result.Nodes.getNodeAs<UnresolvedLookupExpr>("used")) {
for (const NamedDecl* ND : ULE->decls()) {
if (const auto *USD = dyn_cast<UsingShadowDecl>(ND))
removeFromFoundDecls(USD->getTargetDecl()->getCanonicalDecl());
}
}
} }
void UnusedUsingDeclsCheck::removeFromFoundDecls(const Decl *D) { void UnusedUsingDeclsCheck::removeFromFoundDecls(const Decl *D) {

Просмотреть файл

@ -16,6 +16,7 @@ class I {
public: public:
static int ii; static int ii;
}; };
template <typename T> class J {};
class Base { class Base {
public: public:
@ -29,6 +30,7 @@ int UsedFunc() { return 1; }
int UnusedFunc() { return 1; } int UnusedFunc() { return 1; }
template <typename T> int UsedTemplateFunc() { return 1; } template <typename T> int UsedTemplateFunc() { return 1; }
template <typename T> int UnusedTemplateFunc() { return 1; } template <typename T> int UnusedTemplateFunc() { return 1; }
template <typename T> int UsedInTemplateFunc() { return 1; }
class ostream { class ostream {
public: public:
@ -70,6 +72,13 @@ using n::UnusedFunc; // UnusedFunc
using n::cout; using n::cout;
using n::endl; using n::endl;
using n::UsedInTemplateFunc;
using n::J;
template <typename T> void Callee() {
J<T> j;
UsedInTemplateFunc<T>();
}
#define DEFINE_INT(name) \ #define DEFINE_INT(name) \
namespace INT { \ namespace INT { \
static const int _##name = 1; \ static const int _##name = 1; \