diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2014-06-27 15:25:46 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2014-06-27 15:27:39 +0200 |
commit | e48a2339600d12d43148bbdb9a47770ae9bc94e3 (patch) | |
tree | dcaa8b52ed44f0b6c22b02c29910cea6b1ea46a3 /compilerplugins | |
parent | libgltf: use WHITESPACE (diff) | |
download | core-e48a2339600d12d43148bbdb9a47770ae9bc94e3.tar.gz core-e48a2339600d12d43148bbdb9a47770ae9bc94e3.zip |
loplugin:unreffun: also warn about redundant redeclarations
Change-Id: I9a812220b58cf6da00d854e65794f7c673ab239d
Diffstat (limited to 'compilerplugins')
-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() |