]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Analysis/AnalysisContext.h
Merge dtracetoolkit/dtruss from the vendor.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / Analysis / AnalysisContext.h
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   bool builtCFG;
45   LiveVariables *liveness;
46   ParentMap *PM;
47   llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
48   llvm::BumpPtrAllocator A;
49   bool AddEHEdges;
50 public:
51   AnalysisContext(const Decl *d, bool addehedges = false)
52     : D(d), cfg(0), builtCFG(false), liveness(0), PM(0),
53       ReferencedBlockVars(0), AddEHEdges(addehedges) {}
54
55   ~AnalysisContext();
56
57   ASTContext &getASTContext() { return D->getASTContext(); }
58   const Decl *getDecl() { return D; }
59   /// getAddEHEdges - Return true iff we are adding exceptional edges from
60   /// callExprs.  If this is false, then try/catch statements and blocks
61   /// reachable from them can appear to be dead in the CFG, analysis passes must
62   /// cope with that.
63   bool getAddEHEdges() const { return AddEHEdges; }
64   Stmt *getBody();
65   CFG *getCFG();
66   ParentMap &getParentMap();
67   LiveVariables *getLiveVariables();
68
69   typedef const VarDecl * const * referenced_decls_iterator;
70
71   std::pair<referenced_decls_iterator, referenced_decls_iterator>
72     getReferencedBlockVars(const BlockDecl *BD);
73
74   /// Return the ImplicitParamDecl* associated with 'self' if this
75   /// AnalysisContext wraps an ObjCMethodDecl.  Returns NULL otherwise.
76   const ImplicitParamDecl *getSelfDecl() const;
77 };
78
79 class AnalysisContextManager {
80   typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap;
81   ContextMap Contexts;
82 public:
83   ~AnalysisContextManager();
84
85   AnalysisContext *getContext(const Decl *D);
86
87   // Discard all previously created AnalysisContexts.
88   void clear();
89 };
90
91 class LocationContext : public llvm::FoldingSetNode {
92 public:
93   enum ContextKind { StackFrame, Scope, Block };
94
95 private:
96   ContextKind Kind;
97   AnalysisContext *Ctx;
98   const LocationContext *Parent;
99
100 protected:
101   LocationContext(ContextKind k, AnalysisContext *ctx,
102                   const LocationContext *parent)
103     : Kind(k), Ctx(ctx), Parent(parent) {}
104
105 public:
106   virtual ~LocationContext();
107
108   ContextKind getKind() const { return Kind; }
109
110   AnalysisContext *getAnalysisContext() const { return Ctx; }
111
112   const LocationContext *getParent() const { return Parent; }
113
114   bool isParentOf(const LocationContext *LC) const;
115
116   const Decl *getDecl() const { return getAnalysisContext()->getDecl(); }
117
118   CFG *getCFG() const { return getAnalysisContext()->getCFG(); }
119
120   LiveVariables *getLiveVariables() const {
121     return getAnalysisContext()->getLiveVariables();
122   }
123
124   ParentMap &getParentMap() const {
125     return getAnalysisContext()->getParentMap();
126   }
127
128   const ImplicitParamDecl *getSelfDecl() const {
129     return Ctx->getSelfDecl();
130   }
131
132   const StackFrameContext *getCurrentStackFrame() const;
133   const StackFrameContext *
134     getStackFrameForDeclContext(const DeclContext *DC) const;
135
136   virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
137
138   static bool classof(const LocationContext*) { return true; }
139
140 public:
141   static void ProfileCommon(llvm::FoldingSetNodeID &ID,
142                             ContextKind ck,
143                             AnalysisContext *ctx,
144                             const LocationContext *parent,
145                             const void* data);
146 };
147
148 class StackFrameContext : public LocationContext {
149   // The callsite where this stack frame is established.
150   const Stmt *CallSite;
151
152   // The parent block of the callsite.
153   const CFGBlock *Block;
154
155   // The index of the callsite in the CFGBlock.
156   unsigned Index;
157
158   friend class LocationContextManager;
159   StackFrameContext(AnalysisContext *ctx, const LocationContext *parent,
160                     const Stmt *s, const CFGBlock *blk, unsigned idx)
161     : LocationContext(StackFrame, ctx, parent), CallSite(s), Block(blk),
162       Index(idx) {}
163
164 public:
165   ~StackFrameContext() {}
166
167   const Stmt *getCallSite() const { return CallSite; }
168
169   const CFGBlock *getCallSiteBlock() const { return Block; }
170
171   unsigned getIndex() const { return Index; }
172
173   void Profile(llvm::FoldingSetNodeID &ID);
174
175   static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
176                       const LocationContext *parent, const Stmt *s,
177                       const CFGBlock *blk, unsigned idx) {
178     ProfileCommon(ID, StackFrame, ctx, parent, s);
179     ID.AddPointer(blk);
180     ID.AddInteger(idx);
181   }
182
183   static bool classof(const LocationContext* Ctx) {
184     return Ctx->getKind() == StackFrame;
185   }
186 };
187
188 class ScopeContext : public LocationContext {
189   const Stmt *Enter;
190
191   friend class LocationContextManager;
192   ScopeContext(AnalysisContext *ctx, const LocationContext *parent,
193                const Stmt *s)
194     : LocationContext(Scope, ctx, parent), Enter(s) {}
195
196 public:
197   ~ScopeContext() {}
198
199   void Profile(llvm::FoldingSetNodeID &ID);
200
201   static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
202                       const LocationContext *parent, const Stmt *s) {
203     ProfileCommon(ID, Scope, ctx, parent, s);
204   }
205
206   static bool classof(const LocationContext* Ctx) {
207     return Ctx->getKind() == Scope;
208   }
209 };
210
211 class BlockInvocationContext : public LocationContext {
212   // FIXME: Add back context-sensivity (we don't want libAnalysis to know
213   //  about MemRegion).
214   const BlockDecl *BD;
215
216   friend class LocationContextManager;
217
218   BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
219                          const BlockDecl *bd)
220     : LocationContext(Block, ctx, parent), BD(bd) {}
221
222 public:
223   ~BlockInvocationContext() {}
224
225   const BlockDecl *getBlockDecl() const { return BD; }
226
227   void Profile(llvm::FoldingSetNodeID &ID);
228
229   static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
230                       const LocationContext *parent, const BlockDecl *bd) {
231     ProfileCommon(ID, Block, ctx, parent, bd);
232   }
233
234   static bool classof(const LocationContext* Ctx) {
235     return Ctx->getKind() == Block;
236   }
237 };
238
239 class LocationContextManager {
240   llvm::FoldingSet<LocationContext> Contexts;
241 public:
242   ~LocationContextManager();
243
244   const StackFrameContext *getStackFrame(AnalysisContext *ctx,
245                                          const LocationContext *parent,
246                                          const Stmt *s, const CFGBlock *blk,
247                                          unsigned idx);
248
249   const ScopeContext *getScope(AnalysisContext *ctx,
250                                const LocationContext *parent,
251                                const Stmt *s);
252
253   /// Discard all previously created LocationContext objects.
254   void clear();
255 private:
256   template <typename LOC, typename DATA>
257   const LOC *getLocationContext(AnalysisContext *ctx,
258                                 const LocationContext *parent,
259                                 const DATA *d);
260 };
261
262 } // end clang namespace
263 #endif