blob: 0ebdf15f2c4efecc824d706c927099928b2b701a [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 Kremenekb8ad5ee2011-03-10 01:14:05 +000019#include "clang/Analysis/CFG.h"
Stephen Hines176edba2014-12-01 14:53:08 -080020#include "clang/Analysis/CodeInjector.h"
Ted Kremenek326be562010-01-25 05:19:37 +000021#include "llvm/ADT/DenseMap.h"
Chandler Carruth30a2e162012-12-04 09:18:49 +000022#include "llvm/ADT/FoldingSet.h"
Ted Kremenek326be562010-01-25 05:19:37 +000023#include "llvm/Support/Allocator.h"
Stephen Hines651f13c2014-04-23 16:59:28 -070024#include <memory>
Ted Kremenek326be562010-01-25 05:19:37 +000025
26namespace clang {
27
Ted Kremenek326be562010-01-25 05:19:37 +000028class Stmt;
Ted Kremenekaf13d5b2011-03-19 01:00:33 +000029class CFGReverseBlockReachabilityAnalysis;
Ted Kremenek283a3582011-02-23 01:51:53 +000030class CFGStmtMap;
Ted Kremenek326be562010-01-25 05:19:37 +000031class LiveVariables;
Ted Kremeneka5937bb2011-10-07 22:21:02 +000032class ManagedAnalysis;
Ted Kremenek326be562010-01-25 05:19:37 +000033class ParentMap;
Tom Caredb34ab72010-08-23 19:51:57 +000034class PseudoConstantAnalysis;
Ted Kremenek326be562010-01-25 05:19:37 +000035class LocationContextManager;
36class StackFrameContext;
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +000037class BlockInvocationContext;
Ted Kremenek1d26f482011-10-24 01:32:45 +000038class AnalysisDeclContextManager;
David Blaikieba243b52011-11-09 06:07:30 +000039class LocationContext;
Ted Kremenekb1b5daf2011-10-23 02:31:52 +000040
Zhongxing Xuc6238d22010-07-19 01:31:21 +000041namespace idx { class TranslationUnit; }
42
Ted Kremeneka5937bb2011-10-07 22:21:02 +000043/// The base class of a hierarchy of objects representing analyses tied
Ted Kremenek1d26f482011-10-24 01:32:45 +000044/// to AnalysisDeclContext.
Ted Kremeneka5937bb2011-10-07 22:21:02 +000045class ManagedAnalysis {
46protected:
47 ManagedAnalysis() {}
48public:
49 virtual ~ManagedAnalysis();
David Blaikieba243b52011-11-09 06:07:30 +000050
Ted Kremeneka5937bb2011-10-07 22:21:02 +000051 // Subclasses need to implement:
52 //
53 // static const void *getTag();
54 //
55 // Which returns a fixed pointer address to distinguish classes of
56 // analysis objects. They also need to implement:
57 //
Ted Kremenek1d26f482011-10-24 01:32:45 +000058 // static [Derived*] create(AnalysisDeclContext &Ctx);
Ted Kremeneka5937bb2011-10-07 22:21:02 +000059 //
Ted Kremenek1d26f482011-10-24 01:32:45 +000060 // which creates the analysis object given an AnalysisDeclContext.
Ted Kremeneka5937bb2011-10-07 22:21:02 +000061};
David Blaikieba243b52011-11-09 06:07:30 +000062
63
64/// AnalysisDeclContext contains the context data for the function or method
65/// under analysis.
Ted Kremenek1d26f482011-10-24 01:32:45 +000066class AnalysisDeclContext {
David Blaikieba243b52011-11-09 06:07:30 +000067 /// Backpoint to the AnalysisManager object that created this
68 /// AnalysisDeclContext. This may be null.
Ted Kremenek1d26f482011-10-24 01:32:45 +000069 AnalysisDeclContextManager *Manager;
David Blaikieba243b52011-11-09 06:07:30 +000070
Ted Kremenekcca300a2012-09-21 00:09:03 +000071 const Decl * const D;
Ted Kremenek326be562010-01-25 05:19:37 +000072
Stephen Hines651f13c2014-04-23 16:59:28 -070073 std::unique_ptr<CFG> cfg, completeCFG;
74 std::unique_ptr<CFGStmtMap> cfgStmtMap;
Ted Kremenekb8ad5ee2011-03-10 01:14:05 +000075
76 CFG::BuildOptions cfgBuildOptions;
77 CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
David Blaikieba243b52011-11-09 06:07:30 +000078
Ted Kremenekad5a8942010-08-02 23:46:59 +000079 bool builtCFG, builtCompleteCFG;
Stephen Hines651f13c2014-04-23 16:59:28 -070080 std::unique_ptr<ParentMap> PM;
81 std::unique_ptr<PseudoConstantAnalysis> PCA;
82 std::unique_ptr<CFGReverseBlockReachabilityAnalysis> CFA;
Ted Kremenekb8ad5ee2011-03-10 01:14:05 +000083
Ted Kremenek326be562010-01-25 05:19:37 +000084 llvm::BumpPtrAllocator A;
Ted Kremenekb8ad5ee2011-03-10 01:14:05 +000085
Ted Kremenekb8ad5ee2011-03-10 01:14:05 +000086 llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
87
Ted Kremeneka5937bb2011-10-07 22:21:02 +000088 void *ManagedAnalyses;
89
Ted Kremenek326be562010-01-25 05:19:37 +000090public:
Ted Kremenek1d26f482011-10-24 01:32:45 +000091 AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
Jordy Rosed2001872012-04-28 01:58:08 +000092 const Decl *D);
Ted Kremenekbc5cb8a2011-07-21 05:22:47 +000093
Ted Kremenek1d26f482011-10-24 01:32:45 +000094 AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
Ted Kremenekb1b5daf2011-10-23 02:31:52 +000095 const Decl *D,
Ted Kremenekb1b5daf2011-10-23 02:31:52 +000096 const CFG::BuildOptions &BuildOptions);
Ted Kremenek326be562010-01-25 05:19:37 +000097
Ted Kremenek1d26f482011-10-24 01:32:45 +000098 ~AnalysisDeclContext();
Ted Kremenek326be562010-01-25 05:19:37 +000099
Ted Kremenek445895a2012-09-21 00:09:05 +0000100 ASTContext &getASTContext() const { return D->getASTContext(); }
Zhongxing Xuc6238d22010-07-19 01:31:21 +0000101 const Decl *getDecl() const { return D; }
102
Ted Kremenekddc0c482012-09-21 06:13:13 +0000103 /// Return the AnalysisDeclContextManager (if any) that created
104 /// this AnalysisDeclContext.
105 AnalysisDeclContextManager *getManager() const {
106 return Manager;
107 }
108
Ted Kremenek74fb1a42011-07-19 14:18:43 +0000109 /// Return the build options used to construct the CFG.
110 CFG::BuildOptions &getCFGBuildOptions() {
111 return cfgBuildOptions;
112 }
113
114 const CFG::BuildOptions &getCFGBuildOptions() const {
115 return cfgBuildOptions;
116 }
David Blaikieba243b52011-11-09 06:07:30 +0000117
Sylvestre Ledruf3477c12012-09-27 10:16:10 +0000118 /// getAddEHEdges - Return true iff we are adding exceptional edges from
Ted Kremenek326be562010-01-25 05:19:37 +0000119 /// callExprs. If this is false, then try/catch statements and blocks
120 /// reachable from them can appear to be dead in the CFG, analysis passes must
121 /// cope with that.
David Blaikieba243b52011-11-09 06:07:30 +0000122 bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; }
Ted Kremenekb8ad5ee2011-03-10 01:14:05 +0000123 bool getUseUnoptimizedCFG() const {
Ted Kremenekbc5cb8a2011-07-21 05:22:47 +0000124 return !cfgBuildOptions.PruneTriviallyFalseEdges;
Ted Kremenekb8ad5ee2011-03-10 01:14:05 +0000125 }
126 bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
127 bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }
Ted Kremenek9b823e82010-08-03 00:09:51 +0000128
Ted Kremenek0d28d362011-03-10 03:50:34 +0000129 void registerForcedBlockExpression(const Stmt *stmt);
130 const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);
David Blaikieba243b52011-11-09 06:07:30 +0000131
Anna Zaks453cb852013-02-02 00:30:04 +0000132 /// \brief Get the body of the Declaration.
Anna Zaksa2d7e652011-09-19 23:17:48 +0000133 Stmt *getBody() const;
Anna Zaks453cb852013-02-02 00:30:04 +0000134
135 /// \brief Get the body of the Declaration.
Anna Zaks087f4072013-02-05 19:52:24 +0000136 /// \param[out] IsAutosynthesized Specifies if the body is auto-generated
137 /// by the BodyFarm.
Anna Zaks453cb852013-02-02 00:30:04 +0000138 Stmt *getBody(bool &IsAutosynthesized) const;
139
140 /// \brief Checks if the body of the Decl is generated by the BodyFarm.
141 ///
142 /// Note, the lookup is not free. We are going to call getBody behind
Anna Zaks087f4072013-02-05 19:52:24 +0000143 /// the scenes.
Anna Zaks453cb852013-02-02 00:30:04 +0000144 /// \sa getBody
145 bool isBodyAutosynthesized() const;
146
Stephen Hines176edba2014-12-01 14:53:08 -0800147 /// \brief Checks if the body of the Decl is generated by the BodyFarm from a
148 /// model file.
149 ///
150 /// Note, the lookup is not free. We are going to call getBody behind
151 /// the scenes.
152 /// \sa getBody
153 bool isBodyAutosynthesizedFromModelFile() const;
154
Ted Kremenek326be562010-01-25 05:19:37 +0000155 CFG *getCFG();
David Blaikieba243b52011-11-09 06:07:30 +0000156
Ted Kremenek283a3582011-02-23 01:51:53 +0000157 CFGStmtMap *getCFGStmtMap();
Anders Carlsson04eeba42011-01-16 22:05:23 +0000158
Ted Kremenekaf13d5b2011-03-19 01:00:33 +0000159 CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis();
David Blaikieba243b52011-11-09 06:07:30 +0000160
Ted Kremenekad5a8942010-08-02 23:46:59 +0000161 /// Return a version of the CFG without any edges pruned.
162 CFG *getUnoptimizedCFG();
163
Ted Kremenek682060c2011-12-22 23:33:52 +0000164 void dumpCFG(bool ShowColors);
Anders Carlsson04eeba42011-01-16 22:05:23 +0000165
Chandler Carruth5d989942011-07-06 16:21:37 +0000166 /// \brief Returns true if we have built a CFG for this analysis context.
167 /// Note that this doesn't correspond to whether or not a valid CFG exists, it
168 /// corresponds to whether we *attempted* to build one.
169 bool isCFGBuilt() const { return builtCFG; }
170
Ted Kremenek326be562010-01-25 05:19:37 +0000171 ParentMap &getParentMap();
Tom Caredb34ab72010-08-23 19:51:57 +0000172 PseudoConstantAnalysis *getPseudoConstantAnalysis();
Ted Kremenek326be562010-01-25 05:19:37 +0000173
174 typedef const VarDecl * const * referenced_decls_iterator;
175
176 std::pair<referenced_decls_iterator, referenced_decls_iterator>
177 getReferencedBlockVars(const BlockDecl *BD);
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000178
Ted Kremenek326be562010-01-25 05:19:37 +0000179 /// Return the ImplicitParamDecl* associated with 'self' if this
Ted Kremenek1d26f482011-10-24 01:32:45 +0000180 /// AnalysisDeclContext wraps an ObjCMethodDecl. Returns NULL otherwise.
Ted Kremenek326be562010-01-25 05:19:37 +0000181 const ImplicitParamDecl *getSelfDecl() const;
David Blaikieba243b52011-11-09 06:07:30 +0000182
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000183 const StackFrameContext *getStackFrame(LocationContext const *Parent,
184 const Stmt *S,
185 const CFGBlock *Blk,
David Blaikieba243b52011-11-09 06:07:30 +0000186 unsigned Idx);
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000187
188 const BlockInvocationContext *
189 getBlockInvocationContext(const LocationContext *parent,
190 const BlockDecl *BD,
191 const void *ContextData);
David Blaikieba243b52011-11-09 06:07:30 +0000192
Ted Kremeneka5937bb2011-10-07 22:21:02 +0000193 /// Return the specified analysis object, lazily running the analysis if
194 /// necessary. Return NULL if the analysis could not run.
195 template <typename T>
196 T *getAnalysis() {
197 const void *tag = T::getTag();
198 ManagedAnalysis *&data = getAnalysisImpl(tag);
199 if (!data) {
200 data = T::create(*this);
201 }
202 return static_cast<T*>(data);
203 }
204private:
205 ManagedAnalysis *&getAnalysisImpl(const void* tag);
David Blaikieba243b52011-11-09 06:07:30 +0000206
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000207 LocationContextManager &getLocationContextManager();
Ted Kremenek326be562010-01-25 05:19:37 +0000208};
209
210class LocationContext : public llvm::FoldingSetNode {
211public:
212 enum ContextKind { StackFrame, Scope, Block };
213
214private:
215 ContextKind Kind;
Zhongxing Xua02d8932010-07-20 02:14:22 +0000216
David Blaikieba243b52011-11-09 06:07:30 +0000217 // AnalysisDeclContext can't be const since some methods may modify its
218 // member.
Ted Kremenek1d26f482011-10-24 01:32:45 +0000219 AnalysisDeclContext *Ctx;
Zhongxing Xua02d8932010-07-20 02:14:22 +0000220
Ted Kremenek326be562010-01-25 05:19:37 +0000221 const LocationContext *Parent;
222
223protected:
Ted Kremenek1d26f482011-10-24 01:32:45 +0000224 LocationContext(ContextKind k, AnalysisDeclContext *ctx,
Ted Kremenek326be562010-01-25 05:19:37 +0000225 const LocationContext *parent)
226 : Kind(k), Ctx(ctx), Parent(parent) {}
227
228public:
229 virtual ~LocationContext();
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000230
Ted Kremenek326be562010-01-25 05:19:37 +0000231 ContextKind getKind() const { return Kind; }
232
Ted Kremenek1d26f482011-10-24 01:32:45 +0000233 AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; }
Ted Kremenek326be562010-01-25 05:19:37 +0000234
235 const LocationContext *getParent() const { return Parent; }
236
Zhongxing Xu8ddf7ce2010-02-17 08:45:06 +0000237 bool isParentOf(const LocationContext *LC) const;
238
Ted Kremenek1d26f482011-10-24 01:32:45 +0000239 const Decl *getDecl() const { return getAnalysisDeclContext()->getDecl(); }
Ted Kremenek326be562010-01-25 05:19:37 +0000240
Ted Kremenek1d26f482011-10-24 01:32:45 +0000241 CFG *getCFG() const { return getAnalysisDeclContext()->getCFG(); }
Ted Kremenek326be562010-01-25 05:19:37 +0000242
Ted Kremeneka5937bb2011-10-07 22:21:02 +0000243 template <typename T>
244 T *getAnalysis() const {
Ted Kremenek1d26f482011-10-24 01:32:45 +0000245 return getAnalysisDeclContext()->getAnalysis<T>();
Ted Kremenek326be562010-01-25 05:19:37 +0000246 }
247
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000248 ParentMap &getParentMap() const {
Ted Kremenek1d26f482011-10-24 01:32:45 +0000249 return getAnalysisDeclContext()->getParentMap();
Ted Kremenek326be562010-01-25 05:19:37 +0000250 }
251
252 const ImplicitParamDecl *getSelfDecl() const {
253 return Ctx->getSelfDecl();
254 }
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000255
Ted Kremenek326be562010-01-25 05:19:37 +0000256 const StackFrameContext *getCurrentStackFrame() const;
Ted Kremenek326be562010-01-25 05:19:37 +0000257
Anna Zaksfadcd5d2012-11-03 02:54:16 +0000258 /// Return true if the current LocationContext has no caller context.
259 virtual bool inTopFrame() const;
260
Ted Kremenek326be562010-01-25 05:19:37 +0000261 virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
262
Jordan Roseac7cc2d2013-07-19 00:59:08 +0000263 void dumpStack(raw_ostream &OS, StringRef Indent = "") const;
Stephen Hines651f13c2014-04-23 16:59:28 -0700264 void dumpStack() const;
Jordan Rose75f8bd02013-03-30 01:31:35 +0000265
Ted Kremenek326be562010-01-25 05:19:37 +0000266public:
267 static void ProfileCommon(llvm::FoldingSetNodeID &ID,
268 ContextKind ck,
Ted Kremenek1d26f482011-10-24 01:32:45 +0000269 AnalysisDeclContext *ctx,
Ted Kremenek326be562010-01-25 05:19:37 +0000270 const LocationContext *parent,
Ted Kremenek9c378f72011-08-12 23:37:29 +0000271 const void *data);
Ted Kremenek326be562010-01-25 05:19:37 +0000272};
273
274class StackFrameContext : public LocationContext {
Zhongxing Xu26c9cb52011-01-10 11:28:29 +0000275 // The callsite where this stack frame is established.
Ted Kremenek892697d2010-12-16 07:46:53 +0000276 const Stmt *CallSite;
Ted Kremenek326be562010-01-25 05:19:37 +0000277
278 // The parent block of the callsite.
279 const CFGBlock *Block;
280
281 // The index of the callsite in the CFGBlock.
282 unsigned Index;
283
284 friend class LocationContextManager;
Ted Kremenek1d26f482011-10-24 01:32:45 +0000285 StackFrameContext(AnalysisDeclContext *ctx, const LocationContext *parent,
David Blaikieba243b52011-11-09 06:07:30 +0000286 const Stmt *s, const CFGBlock *blk,
Zhongxing Xud7064342010-11-24 13:08:51 +0000287 unsigned idx)
Ted Kremenek892697d2010-12-16 07:46:53 +0000288 : LocationContext(StackFrame, ctx, parent), CallSite(s),
Zhongxing Xud7064342010-11-24 13:08:51 +0000289 Block(blk), Index(idx) {}
Ted Kremenek326be562010-01-25 05:19:37 +0000290
291public:
292 ~StackFrameContext() {}
293
Ted Kremenek892697d2010-12-16 07:46:53 +0000294 const Stmt *getCallSite() const { return CallSite; }
Zhongxing Xud7064342010-11-24 13:08:51 +0000295
Ted Kremenek326be562010-01-25 05:19:37 +0000296 const CFGBlock *getCallSiteBlock() const { return Block; }
297
Anna Zaksfadcd5d2012-11-03 02:54:16 +0000298 /// Return true if the current LocationContext has no caller context.
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700299 bool inTopFrame() const override { return getParent() == nullptr; }
Anna Zaksfadcd5d2012-11-03 02:54:16 +0000300
Ted Kremenek326be562010-01-25 05:19:37 +0000301 unsigned getIndex() const { return Index; }
302
Stephen Hines651f13c2014-04-23 16:59:28 -0700303 void Profile(llvm::FoldingSetNodeID &ID) override;
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000304
Ted Kremenek1d26f482011-10-24 01:32:45 +0000305 static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000306 const LocationContext *parent, const Stmt *s,
Ted Kremenek892697d2010-12-16 07:46:53 +0000307 const CFGBlock *blk, unsigned idx) {
Ted Kremenek326be562010-01-25 05:19:37 +0000308 ProfileCommon(ID, StackFrame, ctx, parent, s);
309 ID.AddPointer(blk);
310 ID.AddInteger(idx);
311 }
312
Ted Kremenek9c378f72011-08-12 23:37:29 +0000313 static bool classof(const LocationContext *Ctx) {
Ted Kremenek326be562010-01-25 05:19:37 +0000314 return Ctx->getKind() == StackFrame;
315 }
316};
317
318class ScopeContext : public LocationContext {
319 const Stmt *Enter;
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000320
Ted Kremenek326be562010-01-25 05:19:37 +0000321 friend class LocationContextManager;
Ted Kremenek1d26f482011-10-24 01:32:45 +0000322 ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent,
Ted Kremenek326be562010-01-25 05:19:37 +0000323 const Stmt *s)
324 : LocationContext(Scope, ctx, parent), Enter(s) {}
325
326public:
327 ~ScopeContext() {}
328
Stephen Hines651f13c2014-04-23 16:59:28 -0700329 void Profile(llvm::FoldingSetNodeID &ID) override;
Ted Kremenek326be562010-01-25 05:19:37 +0000330
Ted Kremenek1d26f482011-10-24 01:32:45 +0000331 static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
Ted Kremenek326be562010-01-25 05:19:37 +0000332 const LocationContext *parent, const Stmt *s) {
333 ProfileCommon(ID, Scope, ctx, parent, s);
334 }
335
Ted Kremenek9c378f72011-08-12 23:37:29 +0000336 static bool classof(const LocationContext *Ctx) {
Ted Kremenek326be562010-01-25 05:19:37 +0000337 return Ctx->getKind() == Scope;
338 }
339};
340
341class BlockInvocationContext : public LocationContext {
Ted Kremenek326be562010-01-25 05:19:37 +0000342 const BlockDecl *BD;
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000343
344 // FIXME: Come up with a more type-safe way to model context-sensitivity.
345 const void *ContextData;
Ted Kremenek326be562010-01-25 05:19:37 +0000346
347 friend class LocationContextManager;
348
David Blaikieba243b52011-11-09 06:07:30 +0000349 BlockInvocationContext(AnalysisDeclContext *ctx,
350 const LocationContext *parent,
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000351 const BlockDecl *bd, const void *contextData)
352 : LocationContext(Block, ctx, parent), BD(bd), ContextData(contextData) {}
Ted Kremenek326be562010-01-25 05:19:37 +0000353
354public:
355 ~BlockInvocationContext() {}
356
357 const BlockDecl *getBlockDecl() const { return BD; }
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000358
359 const void *getContextData() const { return ContextData; }
Ted Kremenek326be562010-01-25 05:19:37 +0000360
Stephen Hines651f13c2014-04-23 16:59:28 -0700361 void Profile(llvm::FoldingSetNodeID &ID) override;
Ted Kremenek326be562010-01-25 05:19:37 +0000362
Ted Kremenek1d26f482011-10-24 01:32:45 +0000363 static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000364 const LocationContext *parent, const BlockDecl *bd,
365 const void *contextData) {
Ted Kremenek326be562010-01-25 05:19:37 +0000366 ProfileCommon(ID, Block, ctx, parent, bd);
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000367 ID.AddPointer(contextData);
Ted Kremenek326be562010-01-25 05:19:37 +0000368 }
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000369
Ted Kremenek9c378f72011-08-12 23:37:29 +0000370 static bool classof(const LocationContext *Ctx) {
Ted Kremenek326be562010-01-25 05:19:37 +0000371 return Ctx->getKind() == Block;
372 }
373};
374
375class LocationContextManager {
376 llvm::FoldingSet<LocationContext> Contexts;
377public:
378 ~LocationContextManager();
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000379
Ted Kremenek1d26f482011-10-24 01:32:45 +0000380 const StackFrameContext *getStackFrame(AnalysisDeclContext *ctx,
Ted Kremenek326be562010-01-25 05:19:37 +0000381 const LocationContext *parent,
Ted Kremenek892697d2010-12-16 07:46:53 +0000382 const Stmt *s,
Zhongxing Xud7064342010-11-24 13:08:51 +0000383 const CFGBlock *blk, unsigned idx);
Ted Kremenek326be562010-01-25 05:19:37 +0000384
Ted Kremenek1d26f482011-10-24 01:32:45 +0000385 const ScopeContext *getScope(AnalysisDeclContext *ctx,
Ted Kremenek326be562010-01-25 05:19:37 +0000386 const LocationContext *parent,
387 const Stmt *s);
Ted Kremenek7fa9b4f2012-06-01 20:04:04 +0000388
389 const BlockInvocationContext *
390 getBlockInvocationContext(AnalysisDeclContext *ctx,
391 const LocationContext *parent,
392 const BlockDecl *BD,
393 const void *ContextData);
Ted Kremenekd064fdc2010-03-23 00:13:23 +0000394
Ted Kremenek326be562010-01-25 05:19:37 +0000395 /// Discard all previously created LocationContext objects.
396 void clear();
397private:
398 template <typename LOC, typename DATA>
Ted Kremenek1d26f482011-10-24 01:32:45 +0000399 const LOC *getLocationContext(AnalysisDeclContext *ctx,
Ted Kremenek326be562010-01-25 05:19:37 +0000400 const LocationContext *parent,
401 const DATA *d);
402};
403
Ted Kremenek1d26f482011-10-24 01:32:45 +0000404class AnalysisDeclContextManager {
405 typedef llvm::DenseMap<const Decl*, AnalysisDeclContext*> ContextMap;
David Blaikieba243b52011-11-09 06:07:30 +0000406
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000407 ContextMap Contexts;
408 LocationContextManager LocContexts;
409 CFG::BuildOptions cfgBuildOptions;
Stephen Hines176edba2014-12-01 14:53:08 -0800410
411 /// Pointer to an interface that can provide function bodies for
412 /// declarations from external source.
413 std::unique_ptr<CodeInjector> Injector;
Ted Kremeneka43df952012-09-21 00:09:11 +0000414
415 /// Flag to indicate whether or not bodies should be synthesized
416 /// for well-known functions.
417 bool SynthesizeBodies;
David Blaikieba243b52011-11-09 06:07:30 +0000418
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000419public:
Ted Kremenek1d26f482011-10-24 01:32:45 +0000420 AnalysisDeclContextManager(bool useUnoptimizedCFG = false,
Jordan Rose5a1ffe92012-09-05 22:55:23 +0000421 bool addImplicitDtors = false,
422 bool addInitializers = false,
Ted Kremeneka43df952012-09-21 00:09:11 +0000423 bool addTemporaryDtors = false,
Ted Kremenek02a88c32013-03-29 00:09:22 +0000424 bool synthesizeBodies = false,
Stephen Hines651f13c2014-04-23 16:59:28 -0700425 bool addStaticInitBranches = false,
Stephen Hines176edba2014-12-01 14:53:08 -0800426 bool addCXXNewAllocator = true,
427 CodeInjector* injector = nullptr);
David Blaikieba243b52011-11-09 06:07:30 +0000428
Ted Kremenek1d26f482011-10-24 01:32:45 +0000429 ~AnalysisDeclContextManager();
David Blaikieba243b52011-11-09 06:07:30 +0000430
Jordy Rosed2001872012-04-28 01:58:08 +0000431 AnalysisDeclContext *getContext(const Decl *D);
David Blaikieba243b52011-11-09 06:07:30 +0000432
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000433 bool getUseUnoptimizedCFG() const {
434 return !cfgBuildOptions.PruneTriviallyFalseEdges;
435 }
David Blaikieba243b52011-11-09 06:07:30 +0000436
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000437 CFG::BuildOptions &getCFGBuildOptions() {
438 return cfgBuildOptions;
439 }
Ted Kremeneka43df952012-09-21 00:09:11 +0000440
441 /// Return true if faux bodies should be synthesized for well-known
442 /// functions.
443 bool synthesizeBodies() const { return SynthesizeBodies; }
David Blaikieba243b52011-11-09 06:07:30 +0000444
Ted Kremenek1d26f482011-10-24 01:32:45 +0000445 const StackFrameContext *getStackFrame(AnalysisDeclContext *Ctx,
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000446 LocationContext const *Parent,
447 const Stmt *S,
448 const CFGBlock *Blk,
449 unsigned Idx) {
450 return LocContexts.getStackFrame(Ctx, Parent, S, Blk, Idx);
451 }
David Blaikieba243b52011-11-09 06:07:30 +0000452
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000453 // Get the top level stack frame.
Jordy Rosed2001872012-04-28 01:58:08 +0000454 const StackFrameContext *getStackFrame(const Decl *D) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700455 return LocContexts.getStackFrame(getContext(D), nullptr, nullptr, nullptr,
456 0);
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000457 }
David Blaikieba243b52011-11-09 06:07:30 +0000458
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000459 // Get a stack frame with parent.
David Blaikieba243b52011-11-09 06:07:30 +0000460 StackFrameContext const *getStackFrame(const Decl *D,
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000461 LocationContext const *Parent,
462 const Stmt *S,
463 const CFGBlock *Blk,
464 unsigned Idx) {
465 return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx);
466 }
467
Ted Kremenek1d26f482011-10-24 01:32:45 +0000468 /// Discard all previously created AnalysisDeclContexts.
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000469 void clear();
470
471private:
Ted Kremenek1d26f482011-10-24 01:32:45 +0000472 friend class AnalysisDeclContext;
Ted Kremenekb1b5daf2011-10-23 02:31:52 +0000473
474 LocationContextManager &getLocationContextManager() {
475 return LocContexts;
476 }
477};
478
Ted Kremenek326be562010-01-25 05:19:37 +0000479} // end clang namespace
480#endif