summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Checker/ObjCUnusedIVarsChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Checker/ObjCUnusedIVarsChecker.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Checker/ObjCUnusedIVarsChecker.cpp161
1 files changed, 0 insertions, 161 deletions
diff --git a/contrib/llvm/tools/clang/lib/Checker/ObjCUnusedIVarsChecker.cpp b/contrib/llvm/tools/clang/lib/Checker/ObjCUnusedIVarsChecker.cpp
deleted file mode 100644
index 2523cff..0000000
--- a/contrib/llvm/tools/clang/lib/Checker/ObjCUnusedIVarsChecker.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-//==- ObjCUnusedIVarsChecker.cpp - Check for unused ivars --------*- C++ -*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a CheckObjCUnusedIvars, a checker that
-// analyzes an Objective-C class's interface/implementation to determine if it
-// has any ivars that are never accessed.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Checker/Checkers/LocalCheckers.h"
-#include "clang/Checker/BugReporter/PathDiagnostic.h"
-#include "clang/Checker/BugReporter/BugReporter.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/SourceManager.h"
-
-using namespace clang;
-
-enum IVarState { Unused, Used };
-typedef llvm::DenseMap<const ObjCIvarDecl*,IVarState> IvarUsageMap;
-
-static void Scan(IvarUsageMap& M, const Stmt* S) {
- if (!S)
- return;
-
- if (const ObjCIvarRefExpr *Ex = dyn_cast<ObjCIvarRefExpr>(S)) {
- const ObjCIvarDecl *D = Ex->getDecl();
- IvarUsageMap::iterator I = M.find(D);
- if (I != M.end())
- I->second = Used;
- return;
- }
-
- // Blocks can reference an instance variable of a class.
- if (const BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
- Scan(M, BE->getBody());
- return;
- }
-
- for (Stmt::const_child_iterator I=S->child_begin(),E=S->child_end(); I!=E;++I)
- Scan(M, *I);
-}
-
-static void Scan(IvarUsageMap& M, const ObjCPropertyImplDecl* D) {
- if (!D)
- return;
-
- const ObjCIvarDecl* ID = D->getPropertyIvarDecl();
-
- if (!ID)
- return;
-
- IvarUsageMap::iterator I = M.find(ID);
- if (I != M.end())
- I->second = Used;
-}
-
-static void Scan(IvarUsageMap& M, const ObjCContainerDecl* D) {
- // Scan the methods for accesses.
- for (ObjCContainerDecl::instmeth_iterator I = D->instmeth_begin(),
- E = D->instmeth_end(); I!=E; ++I)
- Scan(M, (*I)->getBody());
-
- if (const ObjCImplementationDecl *ID = dyn_cast<ObjCImplementationDecl>(D)) {
- // Scan for @synthesized property methods that act as setters/getters
- // to an ivar.
- for (ObjCImplementationDecl::propimpl_iterator I = ID->propimpl_begin(),
- E = ID->propimpl_end(); I!=E; ++I)
- Scan(M, *I);
-
- // Scan the associated categories as well.
- for (const ObjCCategoryDecl *CD =
- ID->getClassInterface()->getCategoryList(); CD ;
- CD = CD->getNextClassCategory()) {
- if (const ObjCCategoryImplDecl *CID = CD->getImplementation())
- Scan(M, CID);
- }
- }
-}
-
-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) {
-
- const ObjCInterfaceDecl* ID = D->getClassInterface();
- IvarUsageMap M;
-
- // Iterate over the ivars.
- for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(),
- E=ID->ivar_end(); I!=E; ++I) {
-
- const ObjCIvarDecl* ID = *I;
-
- // Ignore ivars that...
- // (a) aren't private
- // (b) explicitly marked unused
- // (c) are iboutlets
- if (ID->getAccessControl() != ObjCIvarDecl::Private ||
- ID->getAttr<UnusedAttr>() || ID->getAttr<IBOutletAttr>() ||
- ID->getAttr<IBOutletCollectionAttr>())
- continue;
-
- M[ID] = Unused;
- }
-
- 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) {
- std::string sbuf;
- llvm::raw_string_ostream os(sbuf);
- os << "Instance variable '" << I->first << "' in class '" << ID
- << "' is never used by the methods in its @implementation "
- "(although it may be used by category methods).";
-
- BR.EmitBasicReport("Unused instance variable", "Optimization",
- os.str(), I->first->getLocation());
- }
-}
OpenPOWER on IntegriCloud