blob: 02b85304dbd85b9e05ba723f8da31210e8a3272d [file] [log] [blame]
Ted Kremenek326be562010-01-25 05:19:37 +00001//=== 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//
David Blaikieba243b52011-11-09 06:07:30 +000010// This file defines AnalysisDeclContext, a class that manages the analysis
11// context data for path sensitive analysis.
Ted Kremenek326be562010-01-25 05:19:37 +000012//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
16#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
17
18#include "clang/AST/Decl.h"
Ted Kremenek892697d2010-12-16 07:46:53 +000019#include "clang/AST/Expr.h"
Ted Kremenekb8ad5ee2011-03-10 01:14:05 +000020#include "clang/Analysis/CFG.h"
Ted Kremenek326be562010-01-25 05:19:37 +000021#include "llvm/ADT/OwningPtr.h"
Ted Kremenekbc5cb8a2011-07-21 05:22:47 +000022#include "llvm/ADT/IntrusiveRefCntPtr.h"
Ted Kremenek326be562010-01-25 05:19:37 +000023#include "llvm/ADT/FoldingSet.h"
24#include "llvm/ADT/PointerUnion.h"
25#include "llvm/ADT/DenseMap.h"
26#include "llvm/Support/Allocator.h"
27
28namespace clang {
29
30class Decl;
31class Stmt;
Ted Kremenekaf13d5b2011-03-19 01:00:33 +000032class CFGReverseBlockReachabilityAnalysis;
Ted Kremenek283a3582011-02-23 01:51:53 +000033class CFGStmtMap;
Ted Kremenek326be562010-01-25 05:19:37 +000034class LiveVariables;
Ted Kremeneka5937bb2011-10-07 22:21:02 +000035class ManagedAnalysis;
Ted Kremenek326be562010-01-25 05:19:37 +000036class ParentMap;
Tom Caredb34ab72010-08-23 19:51:57 +000037class PseudoConstantAnalysis;
Ted Kremenek326be562010-01-25 05:19:37 +000038class ImplicitParamDecl;
39class LocationContextManager;
40class StackFrameContext;
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +000041class BlockInvocationContext;
Ted Kremenek1d26f482011-10-24 01:32:45 +000042class AnalysisDeclContextManager;
David Blaikieba243b52011-11-09 06:07:30 +000043class LocationContext;
Ted Kremenekb1b5daf2011-10-23 02:31:52 +000044
Zhongxing Xuc6238d22010-07-19 01:31:21 +000045namespace idx { class TranslationUnit; }
46
Ted Kremeneka5937bb2011-10-07 22:21:02 +000047/// The base class of a hierarchy of objects representing analyses tied
Ted Kremenek1d26f482011-10-24 01:32:45 +000048/// to AnalysisDeclContext.
Ted Kremeneka5937bb2011-10-07 22:21:02 +000049class ManagedAnalysis {
50protected:
51 ManagedAnalysis() {}
52public:
53 virtual ~ManagedAnalysis();
David Blaikieba243b52011-11-09 06:07:30 +000054
Ted Kremeneka5937bb2011-10-07 22:21:02 +000055 // Subclasses need to implement:
56 //
57 // static const void *getTag();
58 //
59 // Which returns a fixed pointer address to distinguish classes of
60 // analysis objects. They also need to implement:
61 //
Ted Kremenek1d26f482011-10-24 01:32:45 +000062 // static [Derived*] create(AnalysisDeclContext &Ctx);
Ted Kremeneka5937bb2011-10-07 22:21:02 +000063 //
Ted Kremenek1d26f482011-10-24 01:32:45 +000064 // which creates the analysis object given an AnalysisDeclContext.
Ted Kremeneka5937bb2011-10-07 22:21:02 +000065};
David Blaikieba243b52011-11-09 06:07:30 +000066
67
68/// AnalysisDeclContext contains the context data for the function or method
69/// under analysis.
Ted Kremenek1d26f482011-10-24 01:32:45 +000070class AnalysisDeclContext {
David Blaikieba243b52011-11-09 06:07:30 +000071 /// Backpoint to the AnalysisManager object that created this
72 /// AnalysisDeclContext. This may be null.
Ted Kremenek1d26f482011-10-24 01:32:45 +000073 AnalysisDeclContextManager *Manager;
David Blaikieba243b52011-11-09 06:07:30 +000074
Ted Kremenekcca300a2012-09-21 00:09:03 +000075 const Decl * const D;
Ted Kremenek326be562010-01-25 05:19:37 +000076
Dylan Noblesmith6f42b622012-02-05 02:12:40 +000077 OwningPtr<CFG> cfg, completeCFG;
78 OwningPtr<CFGStmtMap> cfgStmtMap;
Ted Kremenekb8ad5ee2011-03-10 01:14:05 +000079
80 CFG::BuildOptions cfgBuildOptions;
81 CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
David Blaikieba243b52011-11-09 06:07:30 +000082
Ted Kremenekad5a8942010-08-02 23:46:59 +000083 bool builtCFG, builtCompleteCFG;
Dylan Noblesmith6f42b622012-02-05 02:12:40 +000084 OwningPtr<ParentMap> PM;
85 OwningPtr<PseudoConstantAnalysis> PCA;
86 OwningPtr<CFGReverseBlockReachabilityAnalysis> CFA;
Ted Kremenekb8ad5ee2011-03-10 01:14:05 +000087
Ted Kremenek326be562010-01-25 05:19:37 +000088 llvm::BumpPtrAllocator A;
Ted Kremenekb8ad5ee2011-03-10 01:14:05 +000089
Ted Kremenekb8ad5ee2011-03-10 01:14:05 +000090 llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
91
Ted Kremeneka5937bb2011-10-07 22:21:02 +000092 void *ManagedAnalyses;
93
Ted Kremenek326be562010-01-25 05:19:37 +000094public:
Ted Kremenek1d26f482011-10-24 01:32:45 +000095 AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
Jordy Rosed2001872012-04-28 01:58:08 +000096 const Decl *D);
Ted Kremenekbc5cb8a2011-07-21 05:22:47 +000097
Ted Kremenek1d26f482011-10-24 01:32:45 +000098 AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
Ted Kremenekb1b5daf2011-10-23 02:31:52 +000099 const Decl *D,
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000100 const CFG::BuildOptions &BuildOptions);
Ted Kremenek326be562010-01-25 05:19:37 +0000101
Ted Kremenek1d26f482011-10-24 01:32:45 +0000102 ~AnalysisDeclContext();
Ted Kremenek326be562010-01-25 05:19:37 +0000103
Ted Kremenek445895a2012-09-21 00:09:05 +0000104 ASTContext &getASTContext() const { return D->getASTContext(); }
Zhongxing Xuc6238d22010-07-19 01:31:21 +0000105 const Decl *getDecl() const { return D; }
106
Ted Kremenekddc0c482012-09-21 06:13:13 +0000107 /// Return the AnalysisDeclContextManager (if any) that created
108 /// this AnalysisDeclContext.
109 AnalysisDeclContextManager *getManager() const {
110 return Manager;
111 }
112
Ted Kremenek74fb1a42011-07-19 14:18:43 +0000113 /// Return the build options used to construct the CFG.
114 CFG::BuildOptions &getCFGBuildOptions() {
115 return cfgBuildOptions;
116 }
117
118 const CFG::BuildOptions &getCFGBuildOptions() const {
119 return cfgBuildOptions;
120 }
David Blaikieba243b52011-11-09 06:07:30 +0000121
Sylvestre Ledruf3477c12012-09-27 10:16:10 +0000122 /// getAddEHEdges - Return true iff we are adding exceptional edges from
Ted Kremenek326be562010-01-25 05:19:37 +0000123 /// callExprs. If this is false, then try/catch statements and blocks
124 /// reachable from them can appear to be dead in the CFG, analysis passes must
125 /// cope with that.
David Blaikieba243b52011-11-09 06:07:30 +0000126 bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; }
Ted Kremenekb8ad5ee2011-03-10 01:14:05 +0000127 bool getUseUnoptimizedCFG() const {
Ted Kremenekbc5cb8a2011-07-21 05:22:47 +0000128 return !cfgBuildOptions.PruneTriviallyFalseEdges;
Ted Kremenekb8ad5ee2011-03-10 01:14:05 +0000129 }
130 bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
131 bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }
Ted Kremenek9b823e82010-08-03 00:09:51 +0000132
Ted Kremenek0d28d362011-03-10 03:50:34 +0000133 void registerForcedBlockExpression(const Stmt *stmt);
134 const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);
David Blaikieba243b52011-11-09 06:07:30 +0000135
Anna Zaksa2d7e652011-09-19 23:17:48 +0000136 Stmt *getBody() const;
Ted Kremenek326be562010-01-25 05:19:37 +0000137 CFG *getCFG();
David Blaikieba243b52011-11-09 06:07:30 +0000138
Ted Kremenek283a3582011-02-23 01:51:53 +0000139 CFGStmtMap *getCFGStmtMap();
Anders Carlsson04eeba42011-01-16 22:05:23 +0000140
Ted Kremenekaf13d5b2011-03-19 01:00:33 +0000141 CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis();
David Blaikieba243b52011-11-09 06:07:30 +0000142
Ted Kremenekad5a8942010-08-02 23:46:59 +0000143 /// Return a version of the CFG without any edges pruned.
144 CFG *getUnoptimizedCFG();
145
Ted Kremenek682060c2011-12-22 23:33:52 +0000146 void dumpCFG(bool ShowColors);
Anders Carlsson04eeba42011-01-16 22:05:23 +0000147
Chandler Carruth5d989942011-07-06 16:21:37 +0000148 /// \brief Returns true if we have built a CFG for this analysis context.
149 /// Note that this doesn't correspond to whether or not a valid CFG exists, it
150 /// corresponds to whether we *attempted* to build one.
151 bool isCFGBuilt() const { return builtCFG; }
152
Ted Kremenek326be562010-01-25 05:19:37 +0000153 ParentMap &getParentMap();
Tom Caredb34ab72010-08-23 19:51:57 +0000154 PseudoConstantAnalysis *getPseudoConstantAnalysis();
Ted Kremenek326be562010-01-25 05:19:37 +0000155
156 typedef const VarDecl * const * referenced_decls_iterator;
157
158 std::pair<referenced_decls_iterator, referenced_decls_iterator>
159 getReferencedBlockVars(const BlockDecl *BD);
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000160
Ted Kremenek326be562010-01-25 05:19:37 +0000161 /// Return the ImplicitParamDecl* associated with 'self' if this
Ted Kremenek1d26f482011-10-24 01:32:45 +0000162 /// AnalysisDeclContext wraps an ObjCMethodDecl. Returns NULL otherwise.
Ted Kremenek326be562010-01-25 05:19:37 +0000163 const ImplicitParamDecl *getSelfDecl() const;
David Blaikieba243b52011-11-09 06:07:30 +0000164
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000165 const StackFrameContext *getStackFrame(LocationContext const *Parent,
166 const Stmt *S,
167 const CFGBlock *Blk,
David Blaikieba243b52011-11-09 06:07:30 +0000168 unsigned Idx);
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000169
170 const BlockInvocationContext *
171 getBlockInvocationContext(const LocationContext *parent,
172 const BlockDecl *BD,
173 const void *ContextData);
David Blaikieba243b52011-11-09 06:07:30 +0000174
Ted Kremeneka5937bb2011-10-07 22:21:02 +0000175 /// Return the specified analysis object, lazily running the analysis if
176 /// necessary. Return NULL if the analysis could not run.
177 template <typename T>
178 T *getAnalysis() {
179 const void *tag = T::getTag();
180 ManagedAnalysis *&data = getAnalysisImpl(tag);
181 if (!data) {
182 data = T::create(*this);
183 }
184 return static_cast<T*>(data);
185 }
186private:
187 ManagedAnalysis *&getAnalysisImpl(const void* tag);
David Blaikieba243b52011-11-09 06:07:30 +0000188
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000189 LocationContextManager &getLocationContextManager();
Ted Kremenek326be562010-01-25 05:19:37 +0000190};
191
192class LocationContext : public llvm::FoldingSetNode {
193public:
194 enum ContextKind { StackFrame, Scope, Block };
195
196private:
197 ContextKind Kind;
Zhongxing Xua02d8932010-07-20 02:14:22 +0000198
David Blaikieba243b52011-11-09 06:07:30 +0000199 // AnalysisDeclContext can't be const since some methods may modify its
200 // member.
Ted Kremenek1d26f482011-10-24 01:32:45 +0000201 AnalysisDeclContext *Ctx;
Zhongxing Xua02d8932010-07-20 02:14:22 +0000202
Ted Kremenek326be562010-01-25 05:19:37 +0000203 const LocationContext *Parent;
204
205protected:
Ted Kremenek1d26f482011-10-24 01:32:45 +0000206 LocationContext(ContextKind k, AnalysisDeclContext *ctx,
Ted Kremenek326be562010-01-25 05:19:37 +0000207 const LocationContext *parent)
208 : Kind(k), Ctx(ctx), Parent(parent) {}
209
210public:
211 virtual ~LocationContext();
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000212
Ted Kremenek326be562010-01-25 05:19:37 +0000213 ContextKind getKind() const { return Kind; }
214
Ted Kremenek1d26f482011-10-24 01:32:45 +0000215 AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; }
Ted Kremenek326be562010-01-25 05:19:37 +0000216
217 const LocationContext *getParent() const { return Parent; }
218
Zhongxing Xu8ddf7ce2010-02-17 08:45:06 +0000219 bool isParentOf(const LocationContext *LC) const;
220
Ted Kremenek1d26f482011-10-24 01:32:45 +0000221 const Decl *getDecl() const { return getAnalysisDeclContext()->getDecl(); }
Ted Kremenek326be562010-01-25 05:19:37 +0000222
Ted Kremenek1d26f482011-10-24 01:32:45 +0000223 CFG *getCFG() const { return getAnalysisDeclContext()->getCFG(); }
Ted Kremenek326be562010-01-25 05:19:37 +0000224
Ted Kremeneka5937bb2011-10-07 22:21:02 +0000225 template <typename T>
226 T *getAnalysis() const {
Ted Kremenek1d26f482011-10-24 01:32:45 +0000227 return getAnalysisDeclContext()->getAnalysis<T>();
Ted Kremenek326be562010-01-25 05:19:37 +0000228 }
229
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000230 ParentMap &getParentMap() const {
Ted Kremenek1d26f482011-10-24 01:32:45 +0000231 return getAnalysisDeclContext()->getParentMap();
Ted Kremenek326be562010-01-25 05:19:37 +0000232 }
233
234 const ImplicitParamDecl *getSelfDecl() const {
235 return Ctx->getSelfDecl();
236 }
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000237
Ted Kremenek326be562010-01-25 05:19:37 +0000238 const StackFrameContext *getCurrentStackFrame() const;
Ted Kremenek326be562010-01-25 05:19:37 +0000239
240 virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
241
242 static bool classof(const LocationContext*) { return true; }
243
244public:
245 static void ProfileCommon(llvm::FoldingSetNodeID &ID,
246 ContextKind ck,
Ted Kremenek1d26f482011-10-24 01:32:45 +0000247 AnalysisDeclContext *ctx,
Ted Kremenek326be562010-01-25 05:19:37 +0000248 const LocationContext *parent,
Ted Kremenek9c378f72011-08-12 23:37:29 +0000249 const void *data);
Ted Kremenek326be562010-01-25 05:19:37 +0000250};
251
252class StackFrameContext : public LocationContext {
Zhongxing Xu26c9cb52011-01-10 11:28:29 +0000253 // The callsite where this stack frame is established.
Ted Kremenek892697d2010-12-16 07:46:53 +0000254 const Stmt *CallSite;
Ted Kremenek326be562010-01-25 05:19:37 +0000255
256 // The parent block of the callsite.
257 const CFGBlock *Block;
258
259 // The index of the callsite in the CFGBlock.
260 unsigned Index;
261
262 friend class LocationContextManager;
Ted Kremenek1d26f482011-10-24 01:32:45 +0000263 StackFrameContext(AnalysisDeclContext *ctx, const LocationContext *parent,
David Blaikieba243b52011-11-09 06:07:30 +0000264 const Stmt *s, const CFGBlock *blk,
Zhongxing Xud7064342010-11-24 13:08:51 +0000265 unsigned idx)
Ted Kremenek892697d2010-12-16 07:46:53 +0000266 : LocationContext(StackFrame, ctx, parent), CallSite(s),
Zhongxing Xud7064342010-11-24 13:08:51 +0000267 Block(blk), Index(idx) {}
Ted Kremenek326be562010-01-25 05:19:37 +0000268
269public:
270 ~StackFrameContext() {}
271
Ted Kremenek892697d2010-12-16 07:46:53 +0000272 const Stmt *getCallSite() const { return CallSite; }
Zhongxing Xud7064342010-11-24 13:08:51 +0000273
Ted Kremenek326be562010-01-25 05:19:37 +0000274 const CFGBlock *getCallSiteBlock() const { return Block; }
275
276 unsigned getIndex() const { return Index; }
277
278 void Profile(llvm::FoldingSetNodeID &ID);
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000279
Ted Kremenek1d26f482011-10-24 01:32:45 +0000280 static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000281 const LocationContext *parent, const Stmt *s,
Ted Kremenek892697d2010-12-16 07:46:53 +0000282 const CFGBlock *blk, unsigned idx) {
Ted Kremenek326be562010-01-25 05:19:37 +0000283 ProfileCommon(ID, StackFrame, ctx, parent, s);
284 ID.AddPointer(blk);
285 ID.AddInteger(idx);
286 }
287
Ted Kremenek9c378f72011-08-12 23:37:29 +0000288 static bool classof(const LocationContext *Ctx) {
Ted Kremenek326be562010-01-25 05:19:37 +0000289 return Ctx->getKind() == StackFrame;
290 }
291};
292
293class ScopeContext : public LocationContext {
294 const Stmt *Enter;
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000295
Ted Kremenek326be562010-01-25 05:19:37 +0000296 friend class LocationContextManager;
Ted Kremenek1d26f482011-10-24 01:32:45 +0000297 ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent,
Ted Kremenek326be562010-01-25 05:19:37 +0000298 const Stmt *s)
299 : LocationContext(Scope, ctx, parent), Enter(s) {}
300
301public:
302 ~ScopeContext() {}
303
304 void Profile(llvm::FoldingSetNodeID &ID);
305
Ted Kremenek1d26f482011-10-24 01:32:45 +0000306 static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
Ted Kremenek326be562010-01-25 05:19:37 +0000307 const LocationContext *parent, const Stmt *s) {
308 ProfileCommon(ID, Scope, ctx, parent, s);
309 }
310
Ted Kremenek9c378f72011-08-12 23:37:29 +0000311 static bool classof(const LocationContext *Ctx) {
Ted Kremenek326be562010-01-25 05:19:37 +0000312 return Ctx->getKind() == Scope;
313 }
314};
315
316class BlockInvocationContext : public LocationContext {
Ted Kremenek326be562010-01-25 05:19:37 +0000317 const BlockDecl *BD;
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000318
319 // FIXME: Come up with a more type-safe way to model context-sensitivity.
320 const void *ContextData;
Ted Kremenek326be562010-01-25 05:19:37 +0000321
322 friend class LocationContextManager;
323
David Blaikieba243b52011-11-09 06:07:30 +0000324 BlockInvocationContext(AnalysisDeclContext *ctx,
325 const LocationContext *parent,
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000326 const BlockDecl *bd, const void *contextData)
327 : LocationContext(Block, ctx, parent), BD(bd), ContextData(contextData) {}
Ted Kremenek326be562010-01-25 05:19:37 +0000328
329public:
330 ~BlockInvocationContext() {}
331
332 const BlockDecl *getBlockDecl() const { return BD; }
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000333
334 const void *getContextData() const { return ContextData; }
Ted Kremenek326be562010-01-25 05:19:37 +0000335
336 void Profile(llvm::FoldingSetNodeID &ID);
337
Ted Kremenek1d26f482011-10-24 01:32:45 +0000338 static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000339 const LocationContext *parent, const BlockDecl *bd,
340 const void *contextData) {
Ted Kremenek326be562010-01-25 05:19:37 +0000341 ProfileCommon(ID, Block, ctx, parent, bd);
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000342 ID.AddPointer(contextData);
Ted Kremenek326be562010-01-25 05:19:37 +0000343 }
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000344
Ted Kremenek9c378f72011-08-12 23:37:29 +0000345 static bool classof(const LocationContext *Ctx) {
Ted Kremenek326be562010-01-25 05:19:37 +0000346 return Ctx->getKind() == Block;
347 }
348};
349
350class LocationContextManager {
351 llvm::FoldingSet<LocationContext> Contexts;
352public:
353 ~LocationContextManager();
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000354
Ted Kremenek1d26f482011-10-24 01:32:45 +0000355 const StackFrameContext *getStackFrame(AnalysisDeclContext *ctx,
Ted Kremenek326be562010-01-25 05:19:37 +0000356 const LocationContext *parent,
Ted Kremenek892697d2010-12-16 07:46:53 +0000357 const Stmt *s,
Zhongxing Xud7064342010-11-24 13:08:51 +0000358 const CFGBlock *blk, unsigned idx);
Ted Kremenek326be562010-01-25 05:19:37 +0000359
Ted Kremenek1d26f482011-10-24 01:32:45 +0000360 const ScopeContext *getScope(AnalysisDeclContext *ctx,
Ted Kremenek326be562010-01-25 05:19:37 +0000361 const LocationContext *parent,
362 const Stmt *s);
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000363
364 const BlockInvocationContext *
365 getBlockInvocationContext(AnalysisDeclContext *ctx,
366 const LocationContext *parent,
367 const BlockDecl *BD,
368 const void *ContextData);
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000369
Ted Kremenek326be562010-01-25 05:19:37 +0000370 /// Discard all previously created LocationContext objects.
371 void clear();
372private:
373 template <typename LOC, typename DATA>
Ted Kremenek1d26f482011-10-24 01:32:45 +0000374 const LOC *getLocationContext(AnalysisDeclContext *ctx,
Ted Kremenek326be562010-01-25 05:19:37 +0000375 const LocationContext *parent,
376 const DATA *d);
377};
378
Ted Kremenek1d26f482011-10-24 01:32:45 +0000379class AnalysisDeclContextManager {
380 typedef llvm::DenseMap<const Decl*, AnalysisDeclContext*> ContextMap;
David Blaikieba243b52011-11-09 06:07:30 +0000381
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000382 ContextMap Contexts;
383 LocationContextManager LocContexts;
384 CFG::BuildOptions cfgBuildOptions;
Ted Kremeneka43df952012-09-21 00:09:11 +0000385
386 /// Flag to indicate whether or not bodies should be synthesized
387 /// for well-known functions.
388 bool SynthesizeBodies;
David Blaikieba243b52011-11-09 06:07:30 +0000389
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000390public:
Ted Kremenek1d26f482011-10-24 01:32:45 +0000391 AnalysisDeclContextManager(bool useUnoptimizedCFG = false,
Jordan Rose5a1ffe92012-09-05 22:55:23 +0000392 bool addImplicitDtors = false,
393 bool addInitializers = false,
Ted Kremeneka43df952012-09-21 00:09:11 +0000394 bool addTemporaryDtors = false,
395 bool synthesizeBodies = false);
David Blaikieba243b52011-11-09 06:07:30 +0000396
Ted Kremenek1d26f482011-10-24 01:32:45 +0000397 ~AnalysisDeclContextManager();
David Blaikieba243b52011-11-09 06:07:30 +0000398
Jordy Rosed2001872012-04-28 01:58:08 +0000399 AnalysisDeclContext *getContext(const Decl *D);
David Blaikieba243b52011-11-09 06:07:30 +0000400
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000401 bool getUseUnoptimizedCFG() const {
402 return !cfgBuildOptions.PruneTriviallyFalseEdges;
403 }
David Blaikieba243b52011-11-09 06:07:30 +0000404
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000405 CFG::BuildOptions &getCFGBuildOptions() {
406 return cfgBuildOptions;
407 }
Ted Kremeneka43df952012-09-21 00:09:11 +0000408
409 /// Return true if faux bodies should be synthesized for well-known
410 /// functions.
411 bool synthesizeBodies() const { return SynthesizeBodies; }
David Blaikieba243b52011-11-09 06:07:30 +0000412
Ted Kremenek1d26f482011-10-24 01:32:45 +0000413 const StackFrameContext *getStackFrame(AnalysisDeclContext *Ctx,
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000414 LocationContext const *Parent,
415 const Stmt *S,
416 const CFGBlock *Blk,
417 unsigned Idx) {
418 return LocContexts.getStackFrame(Ctx, Parent, S, Blk, Idx);
419 }
David Blaikieba243b52011-11-09 06:07:30 +0000420
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000421 // Get the top level stack frame.
Jordy Rosed2001872012-04-28 01:58:08 +0000422 const StackFrameContext *getStackFrame(const Decl *D) {
423 return LocContexts.getStackFrame(getContext(D), 0, 0, 0, 0);
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000424 }
David Blaikieba243b52011-11-09 06:07:30 +0000425
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000426 // Get a stack frame with parent.
David Blaikieba243b52011-11-09 06:07:30 +0000427 StackFrameContext const *getStackFrame(const Decl *D,
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000428 LocationContext const *Parent,
429 const Stmt *S,
430 const CFGBlock *Blk,
431 unsigned Idx) {
432 return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx);
433 }
434
Ted Kremenek1d26f482011-10-24 01:32:45 +0000435 /// Discard all previously created AnalysisDeclContexts.
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000436 void clear();
437
438private:
Ted Kremenek1d26f482011-10-24 01:32:45 +0000439 friend class AnalysisDeclContext;
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000440
441 LocationContextManager &getLocationContextManager() {
442 return LocContexts;
443 }
444};
445
Ted Kremenek326be562010-01-25 05:19:37 +0000446} // end clang namespace
447#endif