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