xref: /aosp_15_r20/external/clang/include/clang/Analysis/AnalysisContext.h (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //=== AnalysisContext.h - Analysis context for Path Sens analysis --*- C++ -*-//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file defines AnalysisDeclContext, a class that manages the analysis
11*67e74705SXin Li // context data for path sensitive analysis.
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li 
15*67e74705SXin Li #ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
16*67e74705SXin Li #define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
17*67e74705SXin Li 
18*67e74705SXin Li #include "clang/AST/Decl.h"
19*67e74705SXin Li #include "clang/Analysis/CFG.h"
20*67e74705SXin Li #include "clang/Analysis/CodeInjector.h"
21*67e74705SXin Li #include "llvm/ADT/DenseMap.h"
22*67e74705SXin Li #include "llvm/ADT/FoldingSet.h"
23*67e74705SXin Li #include "llvm/Support/Allocator.h"
24*67e74705SXin Li #include <memory>
25*67e74705SXin Li 
26*67e74705SXin Li namespace clang {
27*67e74705SXin Li 
28*67e74705SXin Li class Stmt;
29*67e74705SXin Li class CFGReverseBlockReachabilityAnalysis;
30*67e74705SXin Li class CFGStmtMap;
31*67e74705SXin Li class LiveVariables;
32*67e74705SXin Li class ManagedAnalysis;
33*67e74705SXin Li class ParentMap;
34*67e74705SXin Li class PseudoConstantAnalysis;
35*67e74705SXin Li class LocationContextManager;
36*67e74705SXin Li class StackFrameContext;
37*67e74705SXin Li class BlockInvocationContext;
38*67e74705SXin Li class AnalysisDeclContextManager;
39*67e74705SXin Li class LocationContext;
40*67e74705SXin Li 
41*67e74705SXin Li namespace idx { class TranslationUnit; }
42*67e74705SXin Li 
43*67e74705SXin Li /// The base class of a hierarchy of objects representing analyses tied
44*67e74705SXin Li /// to AnalysisDeclContext.
45*67e74705SXin Li class ManagedAnalysis {
46*67e74705SXin Li protected:
ManagedAnalysis()47*67e74705SXin Li   ManagedAnalysis() {}
48*67e74705SXin Li public:
49*67e74705SXin Li   virtual ~ManagedAnalysis();
50*67e74705SXin Li 
51*67e74705SXin Li   // Subclasses need to implement:
52*67e74705SXin Li   //
53*67e74705SXin Li   //  static const void *getTag();
54*67e74705SXin Li   //
55*67e74705SXin Li   // Which returns a fixed pointer address to distinguish classes of
56*67e74705SXin Li   // analysis objects.  They also need to implement:
57*67e74705SXin Li   //
58*67e74705SXin Li   //  static [Derived*] create(AnalysisDeclContext &Ctx);
59*67e74705SXin Li   //
60*67e74705SXin Li   // which creates the analysis object given an AnalysisDeclContext.
61*67e74705SXin Li };
62*67e74705SXin Li 
63*67e74705SXin Li 
64*67e74705SXin Li /// AnalysisDeclContext contains the context data for the function or method
65*67e74705SXin Li /// under analysis.
66*67e74705SXin Li class AnalysisDeclContext {
67*67e74705SXin Li   /// Backpoint to the AnalysisManager object that created this
68*67e74705SXin Li   /// AnalysisDeclContext. This may be null.
69*67e74705SXin Li   AnalysisDeclContextManager *Manager;
70*67e74705SXin Li 
71*67e74705SXin Li   const Decl * const D;
72*67e74705SXin Li 
73*67e74705SXin Li   std::unique_ptr<CFG> cfg, completeCFG;
74*67e74705SXin Li   std::unique_ptr<CFGStmtMap> cfgStmtMap;
75*67e74705SXin Li 
76*67e74705SXin Li   CFG::BuildOptions cfgBuildOptions;
77*67e74705SXin Li   CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
78*67e74705SXin Li 
79*67e74705SXin Li   bool builtCFG, builtCompleteCFG;
80*67e74705SXin Li   std::unique_ptr<ParentMap> PM;
81*67e74705SXin Li   std::unique_ptr<PseudoConstantAnalysis> PCA;
82*67e74705SXin Li   std::unique_ptr<CFGReverseBlockReachabilityAnalysis> CFA;
83*67e74705SXin Li 
84*67e74705SXin Li   llvm::BumpPtrAllocator A;
85*67e74705SXin Li 
86*67e74705SXin Li   llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
87*67e74705SXin Li 
88*67e74705SXin Li   void *ManagedAnalyses;
89*67e74705SXin Li 
90*67e74705SXin Li public:
91*67e74705SXin Li   AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
92*67e74705SXin Li                   const Decl *D);
93*67e74705SXin Li 
94*67e74705SXin Li   AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
95*67e74705SXin Li                   const Decl *D,
96*67e74705SXin Li                   const CFG::BuildOptions &BuildOptions);
97*67e74705SXin Li 
98*67e74705SXin Li   ~AnalysisDeclContext();
99*67e74705SXin Li 
getASTContext()100*67e74705SXin Li   ASTContext &getASTContext() const { return D->getASTContext(); }
getDecl()101*67e74705SXin Li   const Decl *getDecl() const { return D; }
102*67e74705SXin Li 
103*67e74705SXin Li   /// Return the AnalysisDeclContextManager (if any) that created
104*67e74705SXin Li   /// this AnalysisDeclContext.
getManager()105*67e74705SXin Li   AnalysisDeclContextManager *getManager() const {
106*67e74705SXin Li     return Manager;
107*67e74705SXin Li   }
108*67e74705SXin Li 
109*67e74705SXin Li   /// Return the build options used to construct the CFG.
getCFGBuildOptions()110*67e74705SXin Li   CFG::BuildOptions &getCFGBuildOptions() {
111*67e74705SXin Li     return cfgBuildOptions;
112*67e74705SXin Li   }
113*67e74705SXin Li 
getCFGBuildOptions()114*67e74705SXin Li   const CFG::BuildOptions &getCFGBuildOptions() const {
115*67e74705SXin Li     return cfgBuildOptions;
116*67e74705SXin Li   }
117*67e74705SXin Li 
118*67e74705SXin Li   /// getAddEHEdges - Return true iff we are adding exceptional edges from
119*67e74705SXin Li   /// callExprs.  If this is false, then try/catch statements and blocks
120*67e74705SXin Li   /// reachable from them can appear to be dead in the CFG, analysis passes must
121*67e74705SXin Li   /// cope with that.
getAddEHEdges()122*67e74705SXin Li   bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; }
getUseUnoptimizedCFG()123*67e74705SXin Li   bool getUseUnoptimizedCFG() const {
124*67e74705SXin Li       return !cfgBuildOptions.PruneTriviallyFalseEdges;
125*67e74705SXin Li   }
getAddImplicitDtors()126*67e74705SXin Li   bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
getAddInitializers()127*67e74705SXin Li   bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }
128*67e74705SXin Li 
129*67e74705SXin Li   void registerForcedBlockExpression(const Stmt *stmt);
130*67e74705SXin Li   const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);
131*67e74705SXin Li 
132*67e74705SXin Li   /// \brief Get the body of the Declaration.
133*67e74705SXin Li   Stmt *getBody() const;
134*67e74705SXin Li 
135*67e74705SXin Li   /// \brief Get the body of the Declaration.
136*67e74705SXin Li   /// \param[out] IsAutosynthesized Specifies if the body is auto-generated
137*67e74705SXin Li   ///             by the BodyFarm.
138*67e74705SXin Li   Stmt *getBody(bool &IsAutosynthesized) const;
139*67e74705SXin Li 
140*67e74705SXin Li   /// \brief Checks if the body of the Decl is generated by the BodyFarm.
141*67e74705SXin Li   ///
142*67e74705SXin Li   /// Note, the lookup is not free. We are going to call getBody behind
143*67e74705SXin Li   /// the scenes.
144*67e74705SXin Li   /// \sa getBody
145*67e74705SXin Li   bool isBodyAutosynthesized() const;
146*67e74705SXin Li 
147*67e74705SXin Li   /// \brief Checks if the body of the Decl is generated by the BodyFarm from a
148*67e74705SXin Li   /// model file.
149*67e74705SXin Li   ///
150*67e74705SXin Li   /// Note, the lookup is not free. We are going to call getBody behind
151*67e74705SXin Li   /// the scenes.
152*67e74705SXin Li   /// \sa getBody
153*67e74705SXin Li   bool isBodyAutosynthesizedFromModelFile() const;
154*67e74705SXin Li 
155*67e74705SXin Li   CFG *getCFG();
156*67e74705SXin Li 
157*67e74705SXin Li   CFGStmtMap *getCFGStmtMap();
158*67e74705SXin Li 
159*67e74705SXin Li   CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis();
160*67e74705SXin Li 
161*67e74705SXin Li   /// Return a version of the CFG without any edges pruned.
162*67e74705SXin Li   CFG *getUnoptimizedCFG();
163*67e74705SXin Li 
164*67e74705SXin Li   void dumpCFG(bool ShowColors);
165*67e74705SXin Li 
166*67e74705SXin Li   /// \brief Returns true if we have built a CFG for this analysis context.
167*67e74705SXin Li   /// Note that this doesn't correspond to whether or not a valid CFG exists, it
168*67e74705SXin Li   /// corresponds to whether we *attempted* to build one.
isCFGBuilt()169*67e74705SXin Li   bool isCFGBuilt() const { return builtCFG; }
170*67e74705SXin Li 
171*67e74705SXin Li   ParentMap &getParentMap();
172*67e74705SXin Li   PseudoConstantAnalysis *getPseudoConstantAnalysis();
173*67e74705SXin Li 
174*67e74705SXin Li   typedef const VarDecl * const * referenced_decls_iterator;
175*67e74705SXin Li 
176*67e74705SXin Li   llvm::iterator_range<referenced_decls_iterator>
177*67e74705SXin Li   getReferencedBlockVars(const BlockDecl *BD);
178*67e74705SXin Li 
179*67e74705SXin Li   /// Return the ImplicitParamDecl* associated with 'self' if this
180*67e74705SXin Li   /// AnalysisDeclContext wraps an ObjCMethodDecl.  Returns NULL otherwise.
181*67e74705SXin Li   const ImplicitParamDecl *getSelfDecl() const;
182*67e74705SXin Li 
183*67e74705SXin Li   const StackFrameContext *getStackFrame(LocationContext const *Parent,
184*67e74705SXin Li                                          const Stmt *S,
185*67e74705SXin Li                                          const CFGBlock *Blk,
186*67e74705SXin Li                                          unsigned Idx);
187*67e74705SXin Li 
188*67e74705SXin Li   const BlockInvocationContext *
189*67e74705SXin Li   getBlockInvocationContext(const LocationContext *parent,
190*67e74705SXin Li                             const BlockDecl *BD,
191*67e74705SXin Li                             const void *ContextData);
192*67e74705SXin Li 
193*67e74705SXin Li   /// Return the specified analysis object, lazily running the analysis if
194*67e74705SXin Li   /// necessary.  Return NULL if the analysis could not run.
195*67e74705SXin Li   template <typename T>
getAnalysis()196*67e74705SXin Li   T *getAnalysis() {
197*67e74705SXin Li     const void *tag = T::getTag();
198*67e74705SXin Li     ManagedAnalysis *&data = getAnalysisImpl(tag);
199*67e74705SXin Li     if (!data) {
200*67e74705SXin Li       data = T::create(*this);
201*67e74705SXin Li     }
202*67e74705SXin Li     return static_cast<T*>(data);
203*67e74705SXin Li   }
204*67e74705SXin Li 
205*67e74705SXin Li   /// Returns true if the root namespace of the given declaration is the 'std'
206*67e74705SXin Li   /// C++ namespace.
207*67e74705SXin Li   static bool isInStdNamespace(const Decl *D);
208*67e74705SXin Li private:
209*67e74705SXin Li   ManagedAnalysis *&getAnalysisImpl(const void* tag);
210*67e74705SXin Li 
211*67e74705SXin Li   LocationContextManager &getLocationContextManager();
212*67e74705SXin Li };
213*67e74705SXin Li 
214*67e74705SXin Li class LocationContext : public llvm::FoldingSetNode {
215*67e74705SXin Li public:
216*67e74705SXin Li   enum ContextKind { StackFrame, Scope, Block };
217*67e74705SXin Li 
218*67e74705SXin Li private:
219*67e74705SXin Li   ContextKind Kind;
220*67e74705SXin Li 
221*67e74705SXin Li   // AnalysisDeclContext can't be const since some methods may modify its
222*67e74705SXin Li   // member.
223*67e74705SXin Li   AnalysisDeclContext *Ctx;
224*67e74705SXin Li 
225*67e74705SXin Li   const LocationContext *Parent;
226*67e74705SXin Li 
227*67e74705SXin Li protected:
LocationContext(ContextKind k,AnalysisDeclContext * ctx,const LocationContext * parent)228*67e74705SXin Li   LocationContext(ContextKind k, AnalysisDeclContext *ctx,
229*67e74705SXin Li                   const LocationContext *parent)
230*67e74705SXin Li     : Kind(k), Ctx(ctx), Parent(parent) {}
231*67e74705SXin Li 
232*67e74705SXin Li public:
233*67e74705SXin Li   virtual ~LocationContext();
234*67e74705SXin Li 
getKind()235*67e74705SXin Li   ContextKind getKind() const { return Kind; }
236*67e74705SXin Li 
getAnalysisDeclContext()237*67e74705SXin Li   AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; }
238*67e74705SXin Li 
getParent()239*67e74705SXin Li   const LocationContext *getParent() const { return Parent; }
240*67e74705SXin Li 
241*67e74705SXin Li   bool isParentOf(const LocationContext *LC) const;
242*67e74705SXin Li 
getDecl()243*67e74705SXin Li   const Decl *getDecl() const { return getAnalysisDeclContext()->getDecl(); }
244*67e74705SXin Li 
getCFG()245*67e74705SXin Li   CFG *getCFG() const { return getAnalysisDeclContext()->getCFG(); }
246*67e74705SXin Li 
247*67e74705SXin Li   template <typename T>
getAnalysis()248*67e74705SXin Li   T *getAnalysis() const {
249*67e74705SXin Li     return getAnalysisDeclContext()->getAnalysis<T>();
250*67e74705SXin Li   }
251*67e74705SXin Li 
getParentMap()252*67e74705SXin Li   ParentMap &getParentMap() const {
253*67e74705SXin Li     return getAnalysisDeclContext()->getParentMap();
254*67e74705SXin Li   }
255*67e74705SXin Li 
getSelfDecl()256*67e74705SXin Li   const ImplicitParamDecl *getSelfDecl() const {
257*67e74705SXin Li     return Ctx->getSelfDecl();
258*67e74705SXin Li   }
259*67e74705SXin Li 
260*67e74705SXin Li   const StackFrameContext *getCurrentStackFrame() const;
261*67e74705SXin Li 
262*67e74705SXin Li   /// Return true if the current LocationContext has no caller context.
263*67e74705SXin Li   virtual bool inTopFrame() const;
264*67e74705SXin Li 
265*67e74705SXin Li   virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
266*67e74705SXin Li 
267*67e74705SXin Li   void dumpStack(raw_ostream &OS, StringRef Indent = "") const;
268*67e74705SXin Li   void dumpStack() const;
269*67e74705SXin Li 
270*67e74705SXin Li public:
271*67e74705SXin Li   static void ProfileCommon(llvm::FoldingSetNodeID &ID,
272*67e74705SXin Li                             ContextKind ck,
273*67e74705SXin Li                             AnalysisDeclContext *ctx,
274*67e74705SXin Li                             const LocationContext *parent,
275*67e74705SXin Li                             const void *data);
276*67e74705SXin Li };
277*67e74705SXin Li 
278*67e74705SXin Li class StackFrameContext : public LocationContext {
279*67e74705SXin Li   // The callsite where this stack frame is established.
280*67e74705SXin Li   const Stmt *CallSite;
281*67e74705SXin Li 
282*67e74705SXin Li   // The parent block of the callsite.
283*67e74705SXin Li   const CFGBlock *Block;
284*67e74705SXin Li 
285*67e74705SXin Li   // The index of the callsite in the CFGBlock.
286*67e74705SXin Li   unsigned Index;
287*67e74705SXin Li 
288*67e74705SXin Li   friend class LocationContextManager;
StackFrameContext(AnalysisDeclContext * ctx,const LocationContext * parent,const Stmt * s,const CFGBlock * blk,unsigned idx)289*67e74705SXin Li   StackFrameContext(AnalysisDeclContext *ctx, const LocationContext *parent,
290*67e74705SXin Li                     const Stmt *s, const CFGBlock *blk,
291*67e74705SXin Li                     unsigned idx)
292*67e74705SXin Li     : LocationContext(StackFrame, ctx, parent), CallSite(s),
293*67e74705SXin Li       Block(blk), Index(idx) {}
294*67e74705SXin Li 
295*67e74705SXin Li public:
~StackFrameContext()296*67e74705SXin Li   ~StackFrameContext() override {}
297*67e74705SXin Li 
getCallSite()298*67e74705SXin Li   const Stmt *getCallSite() const { return CallSite; }
299*67e74705SXin Li 
getCallSiteBlock()300*67e74705SXin Li   const CFGBlock *getCallSiteBlock() const { return Block; }
301*67e74705SXin Li 
302*67e74705SXin Li   /// Return true if the current LocationContext has no caller context.
inTopFrame()303*67e74705SXin Li   bool inTopFrame() const override { return getParent() == nullptr;  }
304*67e74705SXin Li 
getIndex()305*67e74705SXin Li   unsigned getIndex() const { return Index; }
306*67e74705SXin Li 
307*67e74705SXin Li   void Profile(llvm::FoldingSetNodeID &ID) override;
308*67e74705SXin Li 
Profile(llvm::FoldingSetNodeID & ID,AnalysisDeclContext * ctx,const LocationContext * parent,const Stmt * s,const CFGBlock * blk,unsigned idx)309*67e74705SXin Li   static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
310*67e74705SXin Li                       const LocationContext *parent, const Stmt *s,
311*67e74705SXin Li                       const CFGBlock *blk, unsigned idx) {
312*67e74705SXin Li     ProfileCommon(ID, StackFrame, ctx, parent, s);
313*67e74705SXin Li     ID.AddPointer(blk);
314*67e74705SXin Li     ID.AddInteger(idx);
315*67e74705SXin Li   }
316*67e74705SXin Li 
classof(const LocationContext * Ctx)317*67e74705SXin Li   static bool classof(const LocationContext *Ctx) {
318*67e74705SXin Li     return Ctx->getKind() == StackFrame;
319*67e74705SXin Li   }
320*67e74705SXin Li };
321*67e74705SXin Li 
322*67e74705SXin Li class ScopeContext : public LocationContext {
323*67e74705SXin Li   const Stmt *Enter;
324*67e74705SXin Li 
325*67e74705SXin Li   friend class LocationContextManager;
ScopeContext(AnalysisDeclContext * ctx,const LocationContext * parent,const Stmt * s)326*67e74705SXin Li   ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent,
327*67e74705SXin Li                const Stmt *s)
328*67e74705SXin Li     : LocationContext(Scope, ctx, parent), Enter(s) {}
329*67e74705SXin Li 
330*67e74705SXin Li public:
~ScopeContext()331*67e74705SXin Li   ~ScopeContext() override {}
332*67e74705SXin Li 
333*67e74705SXin Li   void Profile(llvm::FoldingSetNodeID &ID) override;
334*67e74705SXin Li 
Profile(llvm::FoldingSetNodeID & ID,AnalysisDeclContext * ctx,const LocationContext * parent,const Stmt * s)335*67e74705SXin Li   static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
336*67e74705SXin Li                       const LocationContext *parent, const Stmt *s) {
337*67e74705SXin Li     ProfileCommon(ID, Scope, ctx, parent, s);
338*67e74705SXin Li   }
339*67e74705SXin Li 
classof(const LocationContext * Ctx)340*67e74705SXin Li   static bool classof(const LocationContext *Ctx) {
341*67e74705SXin Li     return Ctx->getKind() == Scope;
342*67e74705SXin Li   }
343*67e74705SXin Li };
344*67e74705SXin Li 
345*67e74705SXin Li class BlockInvocationContext : public LocationContext {
346*67e74705SXin Li   const BlockDecl *BD;
347*67e74705SXin Li 
348*67e74705SXin Li   // FIXME: Come up with a more type-safe way to model context-sensitivity.
349*67e74705SXin Li   const void *ContextData;
350*67e74705SXin Li 
351*67e74705SXin Li   friend class LocationContextManager;
352*67e74705SXin Li 
BlockInvocationContext(AnalysisDeclContext * ctx,const LocationContext * parent,const BlockDecl * bd,const void * contextData)353*67e74705SXin Li   BlockInvocationContext(AnalysisDeclContext *ctx,
354*67e74705SXin Li                          const LocationContext *parent,
355*67e74705SXin Li                          const BlockDecl *bd, const void *contextData)
356*67e74705SXin Li     : LocationContext(Block, ctx, parent), BD(bd), ContextData(contextData) {}
357*67e74705SXin Li 
358*67e74705SXin Li public:
~BlockInvocationContext()359*67e74705SXin Li   ~BlockInvocationContext() override {}
360*67e74705SXin Li 
getBlockDecl()361*67e74705SXin Li   const BlockDecl *getBlockDecl() const { return BD; }
362*67e74705SXin Li 
getContextData()363*67e74705SXin Li   const void *getContextData() const { return ContextData; }
364*67e74705SXin Li 
365*67e74705SXin Li   void Profile(llvm::FoldingSetNodeID &ID) override;
366*67e74705SXin Li 
Profile(llvm::FoldingSetNodeID & ID,AnalysisDeclContext * ctx,const LocationContext * parent,const BlockDecl * bd,const void * contextData)367*67e74705SXin Li   static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
368*67e74705SXin Li                       const LocationContext *parent, const BlockDecl *bd,
369*67e74705SXin Li                       const void *contextData) {
370*67e74705SXin Li     ProfileCommon(ID, Block, ctx, parent, bd);
371*67e74705SXin Li     ID.AddPointer(contextData);
372*67e74705SXin Li   }
373*67e74705SXin Li 
classof(const LocationContext * Ctx)374*67e74705SXin Li   static bool classof(const LocationContext *Ctx) {
375*67e74705SXin Li     return Ctx->getKind() == Block;
376*67e74705SXin Li   }
377*67e74705SXin Li };
378*67e74705SXin Li 
379*67e74705SXin Li class LocationContextManager {
380*67e74705SXin Li   llvm::FoldingSet<LocationContext> Contexts;
381*67e74705SXin Li public:
382*67e74705SXin Li   ~LocationContextManager();
383*67e74705SXin Li 
384*67e74705SXin Li   const StackFrameContext *getStackFrame(AnalysisDeclContext *ctx,
385*67e74705SXin Li                                          const LocationContext *parent,
386*67e74705SXin Li                                          const Stmt *s,
387*67e74705SXin Li                                          const CFGBlock *blk, unsigned idx);
388*67e74705SXin Li 
389*67e74705SXin Li   const ScopeContext *getScope(AnalysisDeclContext *ctx,
390*67e74705SXin Li                                const LocationContext *parent,
391*67e74705SXin Li                                const Stmt *s);
392*67e74705SXin Li 
393*67e74705SXin Li   const BlockInvocationContext *
394*67e74705SXin Li   getBlockInvocationContext(AnalysisDeclContext *ctx,
395*67e74705SXin Li                             const LocationContext *parent,
396*67e74705SXin Li                             const BlockDecl *BD,
397*67e74705SXin Li                             const void *ContextData);
398*67e74705SXin Li 
399*67e74705SXin Li   /// Discard all previously created LocationContext objects.
400*67e74705SXin Li   void clear();
401*67e74705SXin Li private:
402*67e74705SXin Li   template <typename LOC, typename DATA>
403*67e74705SXin Li   const LOC *getLocationContext(AnalysisDeclContext *ctx,
404*67e74705SXin Li                                 const LocationContext *parent,
405*67e74705SXin Li                                 const DATA *d);
406*67e74705SXin Li };
407*67e74705SXin Li 
408*67e74705SXin Li class AnalysisDeclContextManager {
409*67e74705SXin Li   typedef llvm::DenseMap<const Decl*, AnalysisDeclContext*> ContextMap;
410*67e74705SXin Li 
411*67e74705SXin Li   ContextMap Contexts;
412*67e74705SXin Li   LocationContextManager LocContexts;
413*67e74705SXin Li   CFG::BuildOptions cfgBuildOptions;
414*67e74705SXin Li 
415*67e74705SXin Li   /// Pointer to an interface that can provide function bodies for
416*67e74705SXin Li   /// declarations from external source.
417*67e74705SXin Li   std::unique_ptr<CodeInjector> Injector;
418*67e74705SXin Li 
419*67e74705SXin Li   /// Flag to indicate whether or not bodies should be synthesized
420*67e74705SXin Li   /// for well-known functions.
421*67e74705SXin Li   bool SynthesizeBodies;
422*67e74705SXin Li 
423*67e74705SXin Li public:
424*67e74705SXin Li   AnalysisDeclContextManager(bool useUnoptimizedCFG = false,
425*67e74705SXin Li                              bool addImplicitDtors = false,
426*67e74705SXin Li                              bool addInitializers = false,
427*67e74705SXin Li                              bool addTemporaryDtors = false,
428*67e74705SXin Li                              bool synthesizeBodies = false,
429*67e74705SXin Li                              bool addStaticInitBranches = false,
430*67e74705SXin Li                              bool addCXXNewAllocator = true,
431*67e74705SXin Li                              CodeInjector* injector = nullptr);
432*67e74705SXin Li 
433*67e74705SXin Li   ~AnalysisDeclContextManager();
434*67e74705SXin Li 
435*67e74705SXin Li   AnalysisDeclContext *getContext(const Decl *D);
436*67e74705SXin Li 
getUseUnoptimizedCFG()437*67e74705SXin Li   bool getUseUnoptimizedCFG() const {
438*67e74705SXin Li     return !cfgBuildOptions.PruneTriviallyFalseEdges;
439*67e74705SXin Li   }
440*67e74705SXin Li 
getCFGBuildOptions()441*67e74705SXin Li   CFG::BuildOptions &getCFGBuildOptions() {
442*67e74705SXin Li     return cfgBuildOptions;
443*67e74705SXin Li   }
444*67e74705SXin Li 
445*67e74705SXin Li   /// Return true if faux bodies should be synthesized for well-known
446*67e74705SXin Li   /// functions.
synthesizeBodies()447*67e74705SXin Li   bool synthesizeBodies() const { return SynthesizeBodies; }
448*67e74705SXin Li 
getStackFrame(AnalysisDeclContext * Ctx,LocationContext const * Parent,const Stmt * S,const CFGBlock * Blk,unsigned Idx)449*67e74705SXin Li   const StackFrameContext *getStackFrame(AnalysisDeclContext *Ctx,
450*67e74705SXin Li                                          LocationContext const *Parent,
451*67e74705SXin Li                                          const Stmt *S,
452*67e74705SXin Li                                          const CFGBlock *Blk,
453*67e74705SXin Li                                          unsigned Idx) {
454*67e74705SXin Li     return LocContexts.getStackFrame(Ctx, Parent, S, Blk, Idx);
455*67e74705SXin Li   }
456*67e74705SXin Li 
457*67e74705SXin Li   // Get the top level stack frame.
getStackFrame(const Decl * D)458*67e74705SXin Li   const StackFrameContext *getStackFrame(const Decl *D) {
459*67e74705SXin Li     return LocContexts.getStackFrame(getContext(D), nullptr, nullptr, nullptr,
460*67e74705SXin Li                                      0);
461*67e74705SXin Li   }
462*67e74705SXin Li 
463*67e74705SXin Li   // Get a stack frame with parent.
getStackFrame(const Decl * D,LocationContext const * Parent,const Stmt * S,const CFGBlock * Blk,unsigned Idx)464*67e74705SXin Li   StackFrameContext const *getStackFrame(const Decl *D,
465*67e74705SXin Li                                          LocationContext const *Parent,
466*67e74705SXin Li                                          const Stmt *S,
467*67e74705SXin Li                                          const CFGBlock *Blk,
468*67e74705SXin Li                                          unsigned Idx) {
469*67e74705SXin Li     return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx);
470*67e74705SXin Li   }
471*67e74705SXin Li 
472*67e74705SXin Li   /// Discard all previously created AnalysisDeclContexts.
473*67e74705SXin Li   void clear();
474*67e74705SXin Li 
475*67e74705SXin Li private:
476*67e74705SXin Li   friend class AnalysisDeclContext;
477*67e74705SXin Li 
getLocationContextManager()478*67e74705SXin Li   LocationContextManager &getLocationContextManager() {
479*67e74705SXin Li     return LocContexts;
480*67e74705SXin Li   }
481*67e74705SXin Li };
482*67e74705SXin Li 
483*67e74705SXin Li } // end clang namespace
484*67e74705SXin Li #endif
485