clang: lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
25#include "llvm/ADT/STLExtras.h"
26
27using namespace clang;
28using namespace ento;
29
31typedef llvm::DenseMap<const ObjCIvarDecl*,IVarState> IvarUsageMap;
32
34 if (!S)
35 return;
36
37 if (const ObjCIvarRefExpr *Ex = dyn_cast(S)) {
39 IvarUsageMap::iterator I = M.find(D);
40 if (I != M.end())
41 I->second = Used;
42 return;
43 }
44
45
46 if (const BlockExpr *BE = dyn_cast(S)) {
47 Scan(M, BE->getBody());
48 return;
49 }
50
51 if (const PseudoObjectExpr *POE = dyn_cast(S))
52 for (const Expr *sub : POE->semantics()) {
53 if (const OpaqueValueExpr *OVE = dyn_cast(sub))
54 sub = OVE->getSourceExpr();
56 }
57
58 for (const Stmt *SubStmt : S->children())
59 Scan(M, SubStmt);
60}
61
63 if ()
64 return;
65
66 const ObjCIvarDecl *ID = D->getPropertyIvarDecl();
67
68 if (!ID)
69 return;
70
71 IvarUsageMap::iterator I = M.find(ID);
72 if (I != M.end())
73 I->second = Used;
74}
75
77
78 for (const auto *I : D->instance_methods())
79 Scan(M, I->getBody());
80
82
83
84 for (const auto *I : ID->property_impls())
86
87
88 for (const auto *Cat : ID->getClassInterface()->visible_categories()) {
91 }
92 }
93}
94
97 for (const auto *I : C->decls())
98 if (const auto *FD = dyn_cast(I)) {
100 if (SM.getFileID(L) == FID)
101 Scan(M, FD->getBody());
102 }
103}
104
108
111
112
113 for (const auto *Ivar : ID->ivars()) {
114
115
116
117
118
120 Ivar->hasAttr() || Ivar->hasAttr() ||
121 Ivar->hasAttr() || Ivar->isUnnamedBitField())
122 continue;
123
125 }
126
127 if (M.empty())
128 return;
129
130
132
133
134 bool hasUnused = false;
135 for (IVarState State : llvm::make_second_range(M))
136 if (State == Unused) {
137 hasUnused = true;
138 break;
139 }
140
141 if (!hasUnused)
142 return;
143
144
145
146
147
148
151
152
153 for (auto [Ivar, State] : M)
154 if (State == Unused) {
155 std::string sbuf;
156 llvm::raw_string_ostream os(sbuf);
157 os << "Instance variable '" << *Ivar << "' in class '" << *ID
158 << "' is never used by the methods in its @implementation "
159 "(although it may be used by category methods).";
160
164 "Optimization", os.str(), L);
165 }
166}
167
168
169
170
171
172namespace {
173class ObjCUnusedIvarsChecker : public Checker<
174 check::ASTDecl > {
175public:
179 }
180};
181}
182
183void ento::registerObjCUnusedIvarsChecker(CheckerManager &mgr) {
185}
186
187bool ento::shouldRegisterObjCUnusedIvarsChecker(const CheckerManager &mgr) {
188 return true;
189}
Defines the clang::LangOptions interface.
static void checkObjCUnusedIvar(const ObjCImplementationDecl *D, BugReporter &BR, const CheckerBase *Checker)
llvm::DenseMap< const ObjCIvarDecl *, IVarState > IvarUsageMap
static void Scan(IvarUsageMap &M, const Stmt *S)
Defines the SourceManager interface.
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
SourceLocation getLocation() const
DeclContext * getDeclContext()
This represents one expression.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCContainerDecl - Represents a container for method declarations.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
Stmt - This represents one statement.
BugReporter is a utility class for generating PathDiagnostics for analysis.
const SourceManager & getSourceManager()
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges={}, ArrayRef< FixItHint > Fixits={})
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
The JSON file list parser is used to communicate input to InstallAPI.