diff options
Diffstat (limited to 'lib/Analysis/CheckObjCUnusedIVars.cpp')
-rw-r--r-- | lib/Analysis/CheckObjCUnusedIVars.cpp | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/lib/Analysis/CheckObjCUnusedIVars.cpp b/lib/Analysis/CheckObjCUnusedIVars.cpp index 2d9b53163f..3ee5cb12d9 100644 --- a/lib/Analysis/CheckObjCUnusedIVars.cpp +++ b/lib/Analysis/CheckObjCUnusedIVars.cpp @@ -85,6 +85,17 @@ static void Scan(IvarUsageMap& M, const ObjCContainerDecl* D) { } } +static void Scan(IvarUsageMap &M, const DeclContext *C, const FileID FID, + SourceManager &SM) { + for (DeclContext::decl_iterator I=C->decls_begin(), E=C->decls_end(); + I!=E; ++I) + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) { + SourceLocation L = FD->getLocStart(); + if (SM.getFileID(L) == FID) + Scan(M, FD->getBody()); + } +} + void clang::CheckObjCUnusedIvar(const ObjCImplementationDecl *D, BugReporter &BR) { @@ -110,10 +121,30 @@ void clang::CheckObjCUnusedIvar(const ObjCImplementationDecl *D, if (M.empty()) return; - + // Now scan the implementation declaration. Scan(M, D); + + // Any potentially unused ivars? + bool hasUnused = false; + for (IvarUsageMap::iterator I = M.begin(), E = M.end(); I!=E; ++I) + if (I->second == Unused) { + hasUnused = true; + break; + } + + if (!hasUnused) + return; + + // We found some potentially unused ivars. Scan the entire translation unit + // for functions inside the @implementation that reference these ivars. + // FIXME: In the future hopefully we can just use the lexical DeclContext + // to go from the ObjCImplementationDecl to the lexically "nested" + // C functions. + SourceManager &SM = BR.getSourceManager(); + Scan(M, D->getDeclContext(), SM.getFileID(D->getLocation()), SM); + // Find ivars that are unused. for (IvarUsageMap::iterator I = M.begin(), E = M.end(); I!=E; ++I) if (I->second == Unused) { |