diff options
Diffstat (limited to 'compilerplugins/clang/unreffun.cxx')
-rw-r--r-- | compilerplugins/clang/unreffun.cxx | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/compilerplugins/clang/unreffun.cxx b/compilerplugins/clang/unreffun.cxx index 8c726e3d0845..3b9c616414b3 100644 --- a/compilerplugins/clang/unreffun.cxx +++ b/compilerplugins/clang/unreffun.cxx @@ -45,6 +45,19 @@ bool hasCLanguageLinkageType(FunctionDecl const * decl) { return false; } +bool isFriendDecl(Decl const * decl) { + return decl->getFriendObjectKind() != Decl::FOK_None; +} + +Decl const * getPreviousNonFriendDecl(Decl const * decl) { + for (;;) { + decl = decl->getPreviousDecl(); + if (decl == nullptr || !isFriendDecl(decl)) { + return decl; + } + } +} + class UnrefFun: public RecursiveASTVisitor<UnrefFun>, public loplugin::Plugin { public: explicit UnrefFun(InstantiationData const & data): Plugin(data) {} @@ -69,6 +82,26 @@ bool UnrefFun::VisitFunctionDecl(FunctionDecl const * decl) { return true; } + if (!(decl->isThisDeclarationADefinition() || isFriendDecl(decl) + || decl->isFunctionTemplateSpecialization())) + { + Decl const * prev = getPreviousNonFriendDecl(decl); + if (prev != nullptr/* && prev != decl->getPrimaryTemplate()*/) { + report( + DiagnosticsEngine::Warning, + "redundant function%0 redeclaration", decl->getLocation()) + << ((decl->getTemplatedKind() + == FunctionDecl::TK_FunctionTemplate) + ? " template" : "") + << decl->getSourceRange(); + report( + DiagnosticsEngine::Note, "previous declaration is here", + prev->getLocation()) + << prev->getSourceRange(); + return true; + } + } + FunctionDecl const * canon = decl->getCanonicalDecl(); //TODO: is that the first? if (canon->isDeleted() || canon->isReferenced() |