diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-08-13 18:42:17 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-08-13 18:42:17 +0000 |
commit | 35672e78523162ab292962ce5aec3f512ee5cf8a (patch) | |
tree | 3fc477ff544140ebd4fe96a5b0fa46005c823a99 | |
parent | 5cd66587988e8fc858ca1c32f7cb295966fd824d (diff) | |
download | bcm5719-llvm-35672e78523162ab292962ce5aec3f512ee5cf8a.tar.gz bcm5719-llvm-35672e78523162ab292962ce5aec3f512ee5cf8a.zip |
Change Sema's UnusedStaticFuncs to UnusedFileScopedDecls to allow also keeping track of unused file scoped variables.
This is only preparation, currently only static function definitions are tracked, as before.
llvm-svn: 111025
-rw-r--r-- | clang/include/clang/Frontend/PCHBitCodes.h | 4 | ||||
-rw-r--r-- | clang/include/clang/Frontend/PCHReader.h | 5 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 7 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHReader.cpp | 20 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHWriter.cpp | 33 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 28 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 36 |
7 files changed, 74 insertions, 59 deletions
diff --git a/clang/include/clang/Frontend/PCHBitCodes.h b/clang/include/clang/Frontend/PCHBitCodes.h index bce5c287e77..0b7cb211f4c 100644 --- a/clang/include/clang/Frontend/PCHBitCodes.h +++ b/clang/include/clang/Frontend/PCHBitCodes.h @@ -221,8 +221,8 @@ namespace clang { /// information of the compiler used to build this PCH file. VERSION_CONTROL_BRANCH_REVISION = 21, - /// \brief Record code for the array of unused static functions. - UNUSED_STATIC_FUNCS = 22, + /// \brief Record code for the array of unused file scoped decls. + UNUSED_FILESCOPED_DECLS = 22, /// \brief Record code for the table of offsets to macro definition /// entries in the preprocessing record. diff --git a/clang/include/clang/Frontend/PCHReader.h b/clang/include/clang/Frontend/PCHReader.h index 906e3e1b221..5aa90b717fa 100644 --- a/clang/include/clang/Frontend/PCHReader.h +++ b/clang/include/clang/Frontend/PCHReader.h @@ -381,9 +381,8 @@ private: /// file. llvm::SmallVector<uint64_t, 16> TentativeDefinitions; - /// \brief The set of unused static functions stored in the the PCH - /// file. - llvm::SmallVector<uint64_t, 16> UnusedStaticFuncs; + /// \brief The set of unused file scoped decls stored in the the PCH file. + llvm::SmallVector<uint64_t, 16> UnusedFileScopedDecls; /// \brief The set of weak undeclared identifiers stored in the the PCH file. llvm::SmallVector<uint64_t, 64> WeakUndeclaredIdentifiers; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index fdf91db8f54..d2b89824a79 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -348,8 +348,9 @@ public: /// \brief All the tentative definitions encountered in the TU. std::vector<VarDecl *> TentativeDefinitions; - /// \brief The set of static functions seen so far that have not been used. - std::vector<FunctionDecl*> UnusedStaticFuncs; + /// \brief The set of file scoped decls seen so far that have not been used + /// and must warn if not used. + std::vector<const DeclaratorDecl*> UnusedFileScopedDecls; class AccessedEntity { public: @@ -1876,6 +1877,8 @@ public: MultiStmtArg Handlers); void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock); + void MarkUnusedFileScopedDecl(const DeclaratorDecl *D); + /// DiagnoseUnusedExprResult - If the statement passed in is an expression /// whose result is unused, warn. void DiagnoseUnusedExprResult(const Stmt *S); diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 137c2d768ea..94917707975 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -1637,13 +1637,13 @@ PCHReader::ReadPCHBlock(PerFileData &F) { Record.begin(), Record.end()); break; - case pch::UNUSED_STATIC_FUNCS: + case pch::UNUSED_FILESCOPED_DECLS: // Optimization for the first block. - if (UnusedStaticFuncs.empty()) - UnusedStaticFuncs.swap(Record); + if (UnusedFileScopedDecls.empty()) + UnusedFileScopedDecls.swap(Record); else - UnusedStaticFuncs.insert(UnusedStaticFuncs.end(), - Record.begin(), Record.end()); + UnusedFileScopedDecls.insert(UnusedFileScopedDecls.end(), + Record.begin(), Record.end()); break; case pch::WEAK_UNDECLARED_IDENTIFIERS: @@ -3150,11 +3150,11 @@ void PCHReader::InitializeSema(Sema &S) { SemaObj->TentativeDefinitions.push_back(Var); } - // If there were any unused static functions, deserialize them and add to - // Sema's list of unused static functions. - for (unsigned I = 0, N = UnusedStaticFuncs.size(); I != N; ++I) { - FunctionDecl *FD = cast<FunctionDecl>(GetDecl(UnusedStaticFuncs[I])); - SemaObj->UnusedStaticFuncs.push_back(FD); + // If there were any unused file scoped decls, deserialize them and add to + // Sema's list of unused file scoped decls. + for (unsigned I = 0, N = UnusedFileScopedDecls.size(); I != N; ++I) { + DeclaratorDecl *D = cast<DeclaratorDecl>(GetDecl(UnusedFileScopedDecls[I])); + SemaObj->UnusedFileScopedDecls.push_back(D); } // If there were any weak undeclared identifiers, deserialize them and add to diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index a86bdb9278d..76fd5528dc8 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -626,7 +626,7 @@ void PCHWriter::WriteBlockInfoBlock() { RECORD(SPECIAL_TYPES); RECORD(STATISTICS); RECORD(TENTATIVE_DEFINITIONS); - RECORD(UNUSED_STATIC_FUNCS); + RECORD(UNUSED_FILESCOPED_DECLS); RECORD(LOCALLY_SCOPED_EXTERNAL_DECLS); RECORD(SELECTOR_OFFSETS); RECORD(METHOD_POOL); @@ -636,7 +636,6 @@ void PCHWriter::WriteBlockInfoBlock() { RECORD(STAT_CACHE); RECORD(EXT_VECTOR_DECLS); RECORD(VERSION_CONTROL_BRANCH_REVISION); - RECORD(UNUSED_STATIC_FUNCS); RECORD(MACRO_DEFINITION_OFFSETS); RECORD(CHAINED_METADATA); RECORD(REFERENCED_SELECTOR_POOL); @@ -2204,10 +2203,10 @@ void PCHWriter::WritePCHCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions); } - // Build a record containing all of the static unused functions in this file. - RecordData UnusedStaticFuncs; - for (unsigned i=0, e = SemaRef.UnusedStaticFuncs.size(); i !=e; ++i) - AddDeclRef(SemaRef.UnusedStaticFuncs[i], UnusedStaticFuncs); + // Build a record containing all of the file scoped decls in this file. + RecordData UnusedFileScopedDecls; + for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) + AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls); RecordData WeakUndeclaredIdentifiers; if (!SemaRef.WeakUndeclaredIdentifiers.empty()) { @@ -2333,9 +2332,9 @@ void PCHWriter::WritePCHCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, if (!TentativeDefinitions.empty()) Stream.EmitRecord(pch::TENTATIVE_DEFINITIONS, TentativeDefinitions); - // Write the record containing unused static functions. - if (!UnusedStaticFuncs.empty()) - Stream.EmitRecord(pch::UNUSED_STATIC_FUNCS, UnusedStaticFuncs); + // Write the record containing unused file scoped decls. + if (!UnusedFileScopedDecls.empty()) + Stream.EmitRecord(pch::UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls); // Write the record containing weak undeclared identifiers. if (!WeakUndeclaredIdentifiers.empty()) @@ -2436,11 +2435,11 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions); } - // Build a record containing all of the static unused functions in this file. - RecordData UnusedStaticFuncs; - for (unsigned i=0, e = SemaRef.UnusedStaticFuncs.size(); i !=e; ++i) { - if (SemaRef.UnusedStaticFuncs[i]->getPCHLevel() == 0) - AddDeclRef(SemaRef.UnusedStaticFuncs[i], UnusedStaticFuncs); + // Build a record containing all of the file scoped decls in this file. + RecordData UnusedFileScopedDecls; + for (unsigned i=0, e = SemaRef.UnusedFileScopedDecls.size(); i !=e; ++i) { + if (SemaRef.UnusedFileScopedDecls[i]->getPCHLevel() == 0) + AddDeclRef(SemaRef.UnusedFileScopedDecls[i], UnusedFileScopedDecls); } // We write the entire table, overwriting the tables from the chain. @@ -2558,9 +2557,9 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, if (!TentativeDefinitions.empty()) Stream.EmitRecord(pch::TENTATIVE_DEFINITIONS, TentativeDefinitions); - // Write the record containing unused static functions. - if (!UnusedStaticFuncs.empty()) - Stream.EmitRecord(pch::UNUSED_STATIC_FUNCS, UnusedStaticFuncs); + // Write the record containing unused file scoped decls. + if (!UnusedFileScopedDecls.empty()) + Stream.EmitRecord(pch::UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls); // Write the record containing weak undeclared identifiers. if (!WeakUndeclaredIdentifiers.empty()) diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 778bf8c98a2..f5c85ad99cd 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/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/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ea1cfa8f8a4..e1f9c82feca 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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; } |