summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorVassil Vassilev <v.g.vassilev@gmail.com>2017-05-09 11:25:41 +0000
committerVassil Vassilev <v.g.vassilev@gmail.com>2017-05-09 11:25:41 +0000
commit64e1e1ea0a2758ac1e7667a52ef18dd9623a63c9 (patch)
tree18d7dd839deca6b99643a49f245d25da6c42a04d /clang/lib
parent5a741dd8a6bcb97151c8ba4bc74118ecb019929b (diff)
downloadbcm5719-llvm-64e1e1ea0a2758ac1e7667a52ef18dd9623a63c9.tar.gz
bcm5719-llvm-64e1e1ea0a2758ac1e7667a52ef18dd9623a63c9.zip
Reland "Warn about unused static file scope function template declarations."
This patch reinstates r299930, reverted in r299956, as a separate diagnostic option (-Wunused-template). llvm-svn: 302518
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/Sema.cpp32
-rw-r--r--clang/lib/Sema/SemaDecl.cpp9
2 files changed, 31 insertions, 10 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 2f493fa5fbe..ca1d27e9505 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -477,6 +477,13 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
return true;
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ // If this is a function template and none of its specializations is used,
+ // we should warn.
+ if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate())
+ for (const auto *Spec : Template->specializations())
+ if (ShouldRemoveFromUnused(SemaRef, Spec))
+ return true;
+
// UnusedFileScopedDecls stores the first declaration.
// The declaration may have become definition so check again.
const FunctionDecl *DeclToCheck;
@@ -500,6 +507,13 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
VD->isUsableInConstantExpressions(SemaRef->Context))
return true;
+ if (VarTemplateDecl *Template = VD->getDescribedVarTemplate())
+ // If this is a variable template and none of its specializations is used,
+ // we should warn.
+ for (const auto *Spec : Template->specializations())
+ if (ShouldRemoveFromUnused(SemaRef, Spec))
+ return true;
+
// UnusedFileScopedDecls stores the first declaration.
// The declaration may have become definition so check again.
const VarDecl *DeclToCheck = VD->getDefinition();
@@ -905,10 +919,14 @@ void Sema::ActOnEndOfTranslationUnit() {
<< /*function*/0 << DiagD->getDeclName();
}
} else {
- Diag(DiagD->getLocation(),
- isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function
- : diag::warn_unused_function)
- << DiagD->getDeclName();
+ if (FD->getDescribedFunctionTemplate())
+ Diag(DiagD->getLocation(), diag::warn_unused_template)
+ << /*function*/0 << DiagD->getDeclName();
+ else
+ Diag(DiagD->getLocation(),
+ isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function
+ : diag::warn_unused_function)
+ << DiagD->getDeclName();
}
} else {
const VarDecl *DiagD = cast<VarDecl>(*I)->getDefinition();
@@ -924,7 +942,11 @@ void Sema::ActOnEndOfTranslationUnit() {
Diag(DiagD->getLocation(), diag::warn_unused_const_variable)
<< DiagD->getDeclName();
} else {
- Diag(DiagD->getLocation(), diag::warn_unused_variable)
+ if (DiagD->getDescribedVarTemplate())
+ Diag(DiagD->getLocation(), diag::warn_unused_template)
+ << /*variable*/1 << DiagD->getDeclName();
+ else
+ Diag(DiagD->getLocation(), diag::warn_unused_variable)
<< DiagD->getDeclName();
}
}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 2612023f59d..2d15c75f48f 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8923,6 +8923,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (FunctionTemplate) {
if (NewFD->isInvalidDecl())
FunctionTemplate->setInvalidDecl();
+ MarkUnusedFileScopedDecl(NewFD);
return FunctionTemplate;
}
}
@@ -11023,8 +11024,7 @@ static bool hasDependentAlignment(VarDecl *VD) {
/// FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform
/// any semantic actions necessary after any initializer has been attached.
-void
-Sema::FinalizeDeclaration(Decl *ThisDecl) {
+void Sema::FinalizeDeclaration(Decl *ThisDecl) {
// Note that we are no longer parsing the initializer for this declaration.
ParsingInitForAutoVars.erase(ThisDecl);
@@ -11189,9 +11189,8 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
if (DC->getRedeclContext()->isFileContext() && VD->isExternallyVisible())
AddPushedVisibilityAttribute(VD);
- // FIXME: Warn on unused templates.
- if (VD->isFileVarDecl() && !VD->getDescribedVarTemplate() &&
- !isa<VarTemplatePartialSpecializationDecl>(VD))
+ // FIXME: Warn on unused var template partial specializations.
+ if (VD->isFileVarDecl() && !isa<VarTemplatePartialSpecializationDecl>(VD))
MarkUnusedFileScopedDecl(VD);
// Now we have parsed the initializer and can update the table of magic
OpenPOWER on IntegriCloud