aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/Sema.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-08-13 18:42:29 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-08-13 18:42:29 +0000
commitf6d1d43d68016e975f22264343631a55b9701495 (patch)
tree8134cf05aa51a7c95f4f0530fa6773aa6dc62744 /lib/Sema/Sema.cpp
parent49b96d1a382ae9f31456166f1a734d3f7f30b992 (diff)
Expand the unused warnings for functions. Warn for:
-static function declarations -functions in anonymous namespace -class methods in anonymous namespace -class method specializations in anonymous namespace -function specializations in anonymous namespace git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111026 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/Sema.cpp')
-rw-r--r--lib/Sema/Sema.cpp36
1 files changed, 29 insertions, 7 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index f5c85ad99c..76e059138e 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -235,6 +235,24 @@ void Sema::DeleteExpr(ExprTy *E) {
void Sema::DeleteStmt(StmtTy *S) {
}
+/// \brief Used to prune the decls of Sema's UnusedFileScopedDecls vector.
+static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
+ if (D->isUsed())
+ return true;
+
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ // For functions, UnusedFileScopedDecls stores the first declaration.
+ // Later redecls may add new information resulting in not having to warn,
+ // so check again.
+ const FunctionDecl *DeclToCheck;
+ if (!FD->hasBody(DeclToCheck))
+ DeclToCheck = FD->getMostRecentDeclaration();
+ if (DeclToCheck != FD)
+ return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
+ }
+ return false;
+}
+
/// ActOnEndOfTranslationUnit - This is called at the very end of the
/// translation unit when EOF is reached and all but the top-level scope is
/// popped.
@@ -263,10 +281,10 @@ void Sema::ActOnEndOfTranslationUnit() {
}
// Remove file scoped decls that turned out to be used.
- UnusedFileScopedDecls.erase(std::remove_if(UnusedFileScopedDecls.begin(),
- UnusedFileScopedDecls.end(),
- std::bind2nd(std::mem_fun(&DeclaratorDecl::isUsed),
- true)),
+ UnusedFileScopedDecls.erase(std::remove_if(UnusedFileScopedDecls.begin(),
+ UnusedFileScopedDecls.end(),
+ std::bind1st(std::ptr_fun(ShouldRemoveFromUnused),
+ this)),
UnusedFileScopedDecls.end());
if (!CompleteTranslationUnit)
@@ -334,9 +352,13 @@ void Sema::ActOnEndOfTranslationUnit() {
for (std::vector<const DeclaratorDecl*>::iterator
I = UnusedFileScopedDecls.begin(),
E = UnusedFileScopedDecls.end(); I != E; ++I) {
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I))
- Diag(FD->getLocation(), diag::warn_unused_function) << FD->getDeclName();
- else
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
+ const FunctionDecl *DiagD;
+ if (!FD->hasBody(DiagD))
+ DiagD = FD;
+ Diag(DiagD->getLocation(), diag::warn_unused_function)
+ << DiagD->getDeclName();
+ } else
Diag((*I)->getLocation(), diag::warn_unused_variable)
<< cast<VarDecl>(*I)->getDeclName();
}