diff options
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index cf6f20f60a..a37d25a143 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -523,15 +523,17 @@ static void RemoveUsingDecls(LookupResult &R) { bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { assert(D); + if (D->isInvalidDecl() || D->isUsed() || D->hasAttr<UnusedAttr>()) return false; - if (D->getLinkage() == ExternalLinkage) - return false; // Ignore class templates. - if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) - if (MD->getParent()->getDescribedClassTemplate()) - return false; + if (D->getDeclContext()->isDependentContext()) + return false; + + // We warn for unused decls internal to the translation unit. + if (D->getLinkage() == ExternalLinkage) + return false; if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { if (FD->isThisDeclarationADefinition()) @@ -539,6 +541,10 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { return true; } + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) + if (VD->isFileVarDecl()) + return !Context.DeclMustBeEmitted(VD); + return false; } @@ -552,6 +558,12 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { return; // First should already be in the vector. } + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { + const VarDecl *First = VD->getFirstDeclaration(); + if (VD != First && ShouldWarnIfUnusedFileScopedDecl(First)) + return; // First should already be in the vector. + } + if (ShouldWarnIfUnusedFileScopedDecl(D)) UnusedFileScopedDecls.push_back(D); } @@ -2758,6 +2770,8 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, if (NewVD->getLinkage() == ExternalLinkage && !DC->isRecord()) AddPushedVisibilityAttribute(NewVD); + MarkUnusedFileScopedDecl(NewVD); + return NewVD; } |