diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Sema.cpp | 28 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 36 |
2 files changed, 39 insertions, 25 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 778bf8c98a..f5c85ad99c 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -262,12 +262,12 @@ void Sema::ActOnEndOfTranslationUnit() { break; } - // Remove functions that turned out to be used. - UnusedStaticFuncs.erase(std::remove_if(UnusedStaticFuncs.begin(), - UnusedStaticFuncs.end(), - std::bind2nd(std::mem_fun(&FunctionDecl::isUsed), + // 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)), - UnusedStaticFuncs.end()); + UnusedFileScopedDecls.end()); if (!CompleteTranslationUnit) return; @@ -330,14 +330,16 @@ void Sema::ActOnEndOfTranslationUnit() { } - // Output warning for unused functions. - for (std::vector<FunctionDecl*>::iterator - F = UnusedStaticFuncs.begin(), - FEnd = UnusedStaticFuncs.end(); - F != FEnd; - ++F) - Diag((*F)->getLocation(), diag::warn_unused_function) << (*F)->getDeclName(); - + // Output warning for unused file scoped decls. + 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 + Diag((*I)->getLocation(), diag::warn_unused_variable) + << cast<VarDecl>(*I)->getDeclName(); + } } diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ea1cfa8f8a..e1f9c82fec 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -521,6 +521,26 @@ static void RemoveUsingDecls(LookupResult &R) { F.done(); } +static bool ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) { + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + // Warn for static, non-inlined function definitions that + // have not been used. + // FIXME: Also include static functions declared but not defined. + return (!FD->isInvalidDecl() + && !FD->isInlined() && FD->getLinkage() == InternalLinkage + && !FD->isUsed() && !FD->hasAttr<UnusedAttr>() + && !FD->hasAttr<ConstructorAttr>() + && !FD->hasAttr<DestructorAttr>()); + } + + return false; +} + +void Sema::MarkUnusedFileScopedDecl(const DeclaratorDecl *D) { + if (ShouldWarnIfUnusedFileScopedDecl(D)) + UnusedFileScopedDecls.push_back(D); +} + static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { if (D->isInvalidDecl()) return false; @@ -3618,17 +3638,9 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, if (FunctionTemplate) return FunctionTemplate; - - // Keep track of static, non-inlined function definitions that - // have not been used. We will warn later. - // FIXME: Also include static functions declared but not defined. - if (!NewFD->isInvalidDecl() && IsFunctionDefinition - && !NewFD->isInlined() && NewFD->getLinkage() == InternalLinkage - && !NewFD->isUsed() && !NewFD->hasAttr<UnusedAttr>() - && !NewFD->hasAttr<ConstructorAttr>() - && !NewFD->hasAttr<DestructorAttr>()) - UnusedStaticFuncs.push_back(NewFD); - + if (IsFunctionDefinition) + MarkUnusedFileScopedDecl(NewFD); + return NewFD; } @@ -4891,7 +4903,7 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg, // deletion in some later function. if (getDiagnostics().hasErrorOccurred()) ExprTemporaries.clear(); - + return D; } |