aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/DeclBase.cpp12
-rw-r--r--lib/Sema/Sema.cpp26
-rw-r--r--lib/Sema/SemaExpr.cpp2
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp4
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp1
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp2
6 files changed, 40 insertions, 7 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 673b718ba0..41a0361425 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -242,6 +242,18 @@ bool Decl::isUsed(bool CheckUsedAttr) const {
return false;
}
+bool Decl::isReferenced() const {
+ if (Referenced)
+ return true;
+
+ // Check redeclarations.
+ for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I)
+ if (I->Referenced)
+ return true;
+
+ return false;
+}
+
/// \brief Determine the availability of the given declaration based on
/// the target platform.
///
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index a83722d824..403cf6246c 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -473,16 +473,30 @@ void Sema::ActOnEndOfTranslationUnit() {
DiagD = FD;
if (DiagD->isDeleted())
continue; // Deleted functions are supposed to be unused.
- Diag(DiagD->getLocation(),
- isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function
- : diag::warn_unused_function)
- << DiagD->getDeclName();
+ if (DiagD->isReferenced()) {
+ if (isa<CXXMethodDecl>(DiagD))
+ Diag(DiagD->getLocation(), diag::warn_unneeded_member_function)
+ << DiagD->getDeclName();
+ else
+ Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl)
+ << /*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();
if (!DiagD)
DiagD = cast<VarDecl>(*I);
- Diag(DiagD->getLocation(), diag::warn_unused_variable)
- << DiagD->getDeclName();
+ if (DiagD->isReferenced()) {
+ Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl)
+ << /*variable*/1 << DiagD->getDeclName();
+ } else {
+ Diag(DiagD->getLocation(), diag::warn_unused_variable)
+ << DiagD->getDeclName();
+ }
}
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 9415673a77..8eb0177046 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -9885,6 +9885,8 @@ Sema::PopExpressionEvaluationContext() {
void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
assert(D && "No declaration?");
+ D->setReferenced();
+
if (D->isUsed(false))
return;
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 3fe5fd5c95..0ff7ff4d40 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -298,8 +298,10 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
Var->setAccess(D->getAccess());
- if (!D->isStaticDataMember())
+ if (!D->isStaticDataMember()) {
Var->setUsed(D->isUsed(false));
+ Var->setReferenced(D->isReferenced());
+ }
// FIXME: In theory, we could have a previous declaration for variables that
// are not static data members.
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 5b4a64eeb5..889ef7324c 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -214,6 +214,7 @@ void ASTDeclReader::VisitDecl(Decl *D) {
}
D->setImplicit(Record[Idx++]);
D->setUsed(Record[Idx++]);
+ D->setReferenced(Record[Idx++]);
D->setAccess((AccessSpecifier)Record[Idx++]);
D->setPCHLevel(Record[Idx++] + (F.Type <= ASTReader::PCH));
}
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 1306ffda6d..b3b55f584a 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -141,6 +141,7 @@ void ASTDeclWriter::VisitDecl(Decl *D) {
Writer.WriteAttributes(D->getAttrs(), Record);
Record.push_back(D->isImplicit());
Record.push_back(D->isUsed(false));
+ Record.push_back(D->isReferenced());
Record.push_back(D->getAccess());
Record.push_back(D->getPCHLevel());
}
@@ -1133,6 +1134,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
+ Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
Abv->Add(BitCodeAbbrevOp(0)); // PCH level