diff options
| author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-08-13 18:42:29 +0000 |
|---|---|---|
| committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-08-13 18:42:29 +0000 |
| commit | 540bc01f500e353d3233edb799b1b5d868633c48 (patch) | |
| tree | 1d84c58136922739a7fe41e2443c10da8e781630 /clang/lib/Sema/Sema.cpp | |
| parent | 35672e78523162ab292962ce5aec3f512ee5cf8a (diff) | |
| download | bcm5719-llvm-540bc01f500e353d3233edb799b1b5d868633c48.tar.gz bcm5719-llvm-540bc01f500e353d3233edb799b1b5d868633c48.zip | |
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
llvm-svn: 111026
Diffstat (limited to 'clang/lib/Sema/Sema.cpp')
| -rw-r--r-- | clang/lib/Sema/Sema.cpp | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index f5c85ad99cd..76e059138e6 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/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(); } |

