summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/CheckObjCUnusedIVars.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-07-23 00:45:26 +0000
committerTed Kremenek <kremenek@apple.com>2008-07-23 00:45:26 +0000
commit3b28f4911c444e40ab82a90b7797b9118db6685b (patch)
tree39ae63fc75ebb836dd5b19409c0aecde1f351fe5 /clang/lib/Analysis/CheckObjCUnusedIVars.cpp
parentfa1211f69bff82013a10a89298229398da8fab9b (diff)
downloadbcm5719-llvm-3b28f4911c444e40ab82a90b7797b9118db6685b.tar.gz
bcm5719-llvm-3b28f4911c444e40ab82a90b7797b9118db6685b.zip
Add prototype implementation of unused ivar check.
llvm-svn: 53942
Diffstat (limited to 'clang/lib/Analysis/CheckObjCUnusedIVars.cpp')
-rw-r--r--clang/lib/Analysis/CheckObjCUnusedIVars.cpp87
1 files changed, 87 insertions, 0 deletions
diff --git a/clang/lib/Analysis/CheckObjCUnusedIVars.cpp b/clang/lib/Analysis/CheckObjCUnusedIVars.cpp
new file mode 100644
index 00000000000..4eb273314d5
--- /dev/null
+++ b/clang/lib/Analysis/CheckObjCUnusedIVars.cpp
@@ -0,0 +1,87 @@
+//==- CheckObjCUnusedIVars.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/Analysis/LocalCheckers.h"
+#include "clang/Analysis/PathDiagnostic.h"
+#include "clang/Analysis/PathSensitive/BugReporter.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/LangOptions.h"
+#include <sstream>
+
+using namespace clang;
+
+enum IVarState { Unused, Used };
+typedef llvm::DenseMap<ObjCIvarDecl*,IVarState> IvarUsageMap;
+
+static void Scan(IvarUsageMap& M, Stmt* S) {
+ if (!S)
+ return;
+
+ if (ObjCIvarRefExpr* Ex = dyn_cast<ObjCIvarRefExpr>(S)) {
+ ObjCIvarDecl* D = Ex->getDecl();
+ IvarUsageMap::iterator I = M.find(D);
+ if (I != M.end()) I->second = Used;
+ }
+ else
+ for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E;++I)
+ Scan(M, *I);
+}
+
+void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {
+
+ 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) {
+
+ ObjCIvarDecl* ID = *I;
+
+ // Ignore ivars that aren't private.
+ ObjCIvarDecl::AccessControl ac = ID->getAccessControl();
+ if (!(ac == ObjCIvarDecl::None || ac == ObjCIvarDecl::Private))
+ continue;
+
+ if (ID->getAttr<IBOutletAttr>() == 0)
+ continue;
+
+ M[ID] = Unused;
+ }
+
+ if (M.empty())
+ return;
+
+ // Now scan the methods for accesses.
+ for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
+ E = D->instmeth_end(); I!=E; ++I)
+ Scan(M, (*I)->getBody());
+
+ // Find ivars that are unused.
+ for (IvarUsageMap::iterator I = M.begin(), E = M.end(); I!=E; ++I)
+ if (I->second == Unused) {
+
+ std::ostringstream os;
+ os << "Private ivar '" << I->first->getName() << "' is never used.";
+
+ BR.EmitBasicReport("unused ivar",
+ os.str().c_str(), I->first->getLocation());
+ }
+}
+
OpenPOWER on IntegriCloud