 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
8.3% |
1 / 12 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
16.7% |
2 / 12 |
| |
|
Line Coverage: |
66.7% |
30 / 45 |
| |
 |
|
 |
1 : //=== AnalysisContext.h - Analysis context for Path Sens analysis --*- C++ -*-//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file defines AnalysisContext, a class that manages the analysis context
11 : // data for path sensitive analysis.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
16 : #define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
17 :
18 : #include "clang/AST/Decl.h"
19 : #include "llvm/ADT/OwningPtr.h"
20 : #include "llvm/ADT/FoldingSet.h"
21 : #include "llvm/ADT/PointerUnion.h"
22 : #include "llvm/ADT/DenseMap.h"
23 : #include "llvm/Support/Allocator.h"
24 :
25 : namespace clang {
26 :
27 : class Decl;
28 : class Stmt;
29 : class CFG;
30 : class CFGBlock;
31 : class LiveVariables;
32 : class ParentMap;
33 : class ImplicitParamDecl;
34 : class LocationContextManager;
35 : class StackFrameContext;
36 :
37 : /// AnalysisContext contains the context data for the function or method under
38 : /// analysis.
39 : class AnalysisContext {
40 : const Decl *D;
41 :
42 : // AnalysisContext owns the following data.
43 : CFG *cfg;
44 : LiveVariables *liveness;
45 : ParentMap *PM;
46 : llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
47 : llvm::BumpPtrAllocator A;
48 : bool AddEHEdges;
49 : public:
50 11950: AnalysisContext(const Decl *d, bool addehedges = false)
51 : : D(d), cfg(0), liveness(0), PM(0), ReferencedBlockVars(0),
52 11950: AddEHEdges(addehedges) {}
53 :
54 : ~AnalysisContext();
55 :
56 1998: ASTContext &getASTContext() { return D->getASTContext(); }
57 16758: const Decl *getDecl() { return D; }
58 : /// getAddEHEdges - Return true iff we are adding exceptional edges from
59 : /// callExprs. If this is false, then try/catch statements and blocks
60 : /// reachable from them can appear to be dead in the CFG, analysis passes must
61 : /// cope with that.
62 3471: bool getAddEHEdges() const { return AddEHEdges; }
63 : Stmt *getBody();
64 : CFG *getCFG();
65 : ParentMap &getParentMap();
66 : LiveVariables *getLiveVariables();
67 :
68 : typedef const VarDecl * const * referenced_decls_iterator;
69 :
70 : std::pair<referenced_decls_iterator, referenced_decls_iterator>
71 : getReferencedBlockVars(const BlockDecl *BD);
72 :
73 : /// Return the ImplicitParamDecl* associated with 'self' if this
74 : /// AnalysisContext wraps an ObjCMethodDecl. Returns NULL otherwise.
75 : const ImplicitParamDecl *getSelfDecl() const;
76 : };
77 :
78 188: class AnalysisContextManager {
79 : typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap;
80 : ContextMap Contexts;
81 : public:
82 : ~AnalysisContextManager();
83 :
84 : AnalysisContext *getContext(const Decl *D);
85 :
86 : // Discard all previously created AnalysisContexts.
87 : void clear();
88 : };
89 :
90 : class LocationContext : public llvm::FoldingSetNode {
91 : public:
92 : enum ContextKind { StackFrame, Scope, Block };
93 :
94 : private:
95 : ContextKind Kind;
96 : AnalysisContext *Ctx;
97 : const LocationContext *Parent;
98 :
99 : protected:
100 : LocationContext(ContextKind k, AnalysisContext *ctx,
101 1946: const LocationContext *parent)
102 1946: : Kind(k), Ctx(ctx), Parent(parent) {}
103 :
104 : public:
105 : virtual ~LocationContext();
106 :
107 50178: ContextKind getKind() const { return Kind; }
108 :
109 81395: AnalysisContext *getAnalysisContext() const { return Ctx; }
110 :
111 219: const LocationContext *getParent() const { return Parent; }
112 :
113 16758: const Decl *getDecl() const { return getAnalysisContext()->getDecl(); }
114 :
115 41234: CFG *getCFG() const { return getAnalysisContext()->getCFG(); }
116 :
117 12853: LiveVariables *getLiveVariables() const {
118 12853: return getAnalysisContext()->getLiveVariables();
119 : }
120 :
121 8153: ParentMap &getParentMap() const {
122 8153: return getAnalysisContext()->getParentMap();
123 : }
124 :
125 214: const ImplicitParamDecl *getSelfDecl() const {
126 214: return Ctx->getSelfDecl();
127 : }
128 :
129 : const StackFrameContext *getCurrentStackFrame() const;
130 : const StackFrameContext *
131 : getStackFrameForDeclContext(const DeclContext *DC) const;
132 :
133 : virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
134 :
135 : static bool classof(const LocationContext*) { return true; }
136 :
137 : public:
138 : static void ProfileCommon(llvm::FoldingSetNodeID &ID,
139 : ContextKind ck,
140 : AnalysisContext *ctx,
141 : const LocationContext *parent,
142 : const void* data);
143 : };
144 :
145 : class StackFrameContext : public LocationContext {
146 : // The callsite where this stack frame is established.
147 : const Stmt *CallSite;
148 :
149 : // The parent block of the callsite.
150 : const CFGBlock *Block;
151 :
152 : // The index of the callsite in the CFGBlock.
153 : unsigned Index;
154 :
155 : friend class LocationContextManager;
156 : StackFrameContext(AnalysisContext *ctx, const LocationContext *parent,
157 1946: const Stmt *s, const CFGBlock *blk, unsigned idx)
158 : : LocationContext(StackFrame, ctx, parent), CallSite(s), Block(blk),
159 1946: Index(idx) {}
160 :
161 : public:
1946: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
162 1946: ~StackFrameContext() {}
163 :
164 0: const Stmt *getCallSite() const { return CallSite; }
165 :
166 0: const CFGBlock *getCallSiteBlock() const { return Block; }
167 :
168 0: unsigned getIndex() const { return Index; }
169 :
170 : void Profile(llvm::FoldingSetNodeID &ID);
171 :
172 : static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
173 : const LocationContext *parent, const Stmt *s,
174 2331: const CFGBlock *blk, unsigned idx) {
175 2331: ProfileCommon(ID, StackFrame, ctx, parent, s);
176 2331: ID.AddPointer(blk);
177 2331: ID.AddInteger(idx);
178 2331: }
179 :
180 50178: static bool classof(const LocationContext* Ctx) {
181 50178: return Ctx->getKind() == StackFrame;
182 : }
183 : };
184 :
185 : class ScopeContext : public LocationContext {
186 : const Stmt *Enter;
187 :
188 : friend class LocationContextManager;
189 : ScopeContext(AnalysisContext *ctx, const LocationContext *parent,
190 0: const Stmt *s)
191 0: : LocationContext(Scope, ctx, parent), Enter(s) {}
192 :
193 : public:
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
194 0: ~ScopeContext() {}
195 :
196 : void Profile(llvm::FoldingSetNodeID &ID);
197 :
198 : static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
199 0: const LocationContext *parent, const Stmt *s) {
200 0: ProfileCommon(ID, Scope, ctx, parent, s);
201 0: }
202 :
203 0: static bool classof(const LocationContext* Ctx) {
204 0: return Ctx->getKind() == Scope;
205 : }
206 : };
207 :
208 : class BlockInvocationContext : public LocationContext {
209 : // FIXME: Add back context-sensivity (we don't want libAnalysis to know
210 : // about MemRegion).
211 : const BlockDecl *BD;
212 :
213 : friend class LocationContextManager;
214 :
215 : BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
216 : const BlockDecl *bd)
217 : : LocationContext(Block, ctx, parent), BD(bd) {}
218 :
219 : public:
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
220 0: ~BlockInvocationContext() {}
221 :
222 : const BlockDecl *getBlockDecl() const { return BD; }
223 :
224 : void Profile(llvm::FoldingSetNodeID &ID);
225 :
226 : static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
227 0: const LocationContext *parent, const BlockDecl *bd) {
228 0: ProfileCommon(ID, Block, ctx, parent, bd);
229 0: }
230 :
231 : static bool classof(const LocationContext* Ctx) {
232 : return Ctx->getKind() == Block;
233 : }
234 : };
235 :
236 188: class LocationContextManager {
237 : llvm::FoldingSet<LocationContext> Contexts;
238 : public:
239 : ~LocationContextManager();
240 :
241 : const StackFrameContext *getStackFrame(AnalysisContext *ctx,
242 : const LocationContext *parent,
243 : const Stmt *s, const CFGBlock *blk,
244 : unsigned idx);
245 :
246 : const ScopeContext *getScope(AnalysisContext *ctx,
247 : const LocationContext *parent,
248 : const Stmt *s);
249 :
250 : /// Discard all previously created LocationContext objects.
251 : void clear();
252 : private:
253 : template <typename LOC, typename DATA>
254 : const LOC *getLocationContext(AnalysisContext *ctx,
255 : const LocationContext *parent,
256 : const DATA *d);
257 : };
258 :
259 : } // end clang namespace
260 : #endif
Generated: 2010-02-10 01:31 by zcov