AnalysisContext.h revision bc5cb8a5fe2b88f917d47ceb58b53696a121e57e
1326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- C++ -*-// 2326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek// 3326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek// The LLVM Compiler Infrastructure 4326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek// 5326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek// This file is distributed under the University of Illinois Open Source 6326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek// License. See LICENSE.TXT for details. 7326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek// 8326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek//===----------------------------------------------------------------------===// 9326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek// 10326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek// This file defines AnalysisContext, a class that manages the analysis context 11326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek// data for path sensitive analysis. 12326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek// 13326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek//===----------------------------------------------------------------------===// 14326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 15326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H 16326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H 17326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 18326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#include "clang/AST/Decl.h" 19892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek#include "clang/AST/Expr.h" 20b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek#include "clang/Analysis/CFG.h" 21326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#include "llvm/ADT/OwningPtr.h" 22bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek#include "llvm/ADT/IntrusiveRefCntPtr.h" 23326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#include "llvm/ADT/FoldingSet.h" 24326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#include "llvm/ADT/PointerUnion.h" 25326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#include "llvm/ADT/DenseMap.h" 26326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#include "llvm/Support/Allocator.h" 27326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 28326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremeneknamespace clang { 29326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 30326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass Decl; 31326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass Stmt; 32af13d5b25b360e698cc1cf1055ad7d14e008e505Ted Kremenekclass CFGReverseBlockReachabilityAnalysis; 33283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenekclass CFGStmtMap; 34326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass LiveVariables; 35326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass ParentMap; 36db34ab70961ca4b24b600eb47053d7af304659f5Tom Careclass PseudoConstantAnalysis; 37326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass ImplicitParamDecl; 38326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass LocationContextManager; 39326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass StackFrameContext; 40d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 41c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xunamespace idx { class TranslationUnit; } 42c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 43326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek/// AnalysisContext contains the context data for the function or method under 44326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek/// analysis. 45326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass AnalysisContext { 46326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Decl *D; 47326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 48c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu // TranslationUnit is NULL if we don't have multiple translation units. 492ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu idx::TranslationUnit *TU; 50c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 51b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::OwningPtr<CFG> cfg, completeCFG; 52b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::OwningPtr<CFGStmtMap> cfgStmtMap; 53b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek 54b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek CFG::BuildOptions cfgBuildOptions; 55b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs; 56b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek 57ad5a894df1841698c824381b414630799adc26caTed Kremenek bool builtCFG, builtCompleteCFG; 58b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek 59b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::OwningPtr<LiveVariables> liveness; 60b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::OwningPtr<LiveVariables> relaxedLiveness; 61b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::OwningPtr<ParentMap> PM; 62b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::OwningPtr<PseudoConstantAnalysis> PCA; 63af13d5b25b360e698cc1cf1055ad7d14e008e505Ted Kremenek llvm::OwningPtr<CFGReverseBlockReachabilityAnalysis> CFA; 64b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek 65326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek llvm::BumpPtrAllocator A; 66b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek 67b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek // FIXME: remove. 68b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars; 69b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek 70326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 71bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek AnalysisContext(const Decl *d, idx::TranslationUnit *tu); 72bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek 732ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu AnalysisContext(const Decl *d, idx::TranslationUnit *tu, 74bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek const CFG::BuildOptions &buildOptions); 75326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 76326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~AnalysisContext(); 77326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 78326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ASTContext &getASTContext() { return D->getASTContext(); } 79c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu const Decl *getDecl() const { return D; } 80c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 812ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu idx::TranslationUnit *getTranslationUnit() const { return TU; } 82c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 8374fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek /// Return the build options used to construct the CFG. 8474fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek CFG::BuildOptions &getCFGBuildOptions() { 8574fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek return cfgBuildOptions; 8674fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek } 8774fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek 8874fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek const CFG::BuildOptions &getCFGBuildOptions() const { 8974fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek return cfgBuildOptions; 9074fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek } 9174fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek 92326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// getAddEHEdges - Return true iff we are adding exceptional edges from 93326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// callExprs. If this is false, then try/catch statements and blocks 94326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// reachable from them can appear to be dead in the CFG, analysis passes must 95326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// cope with that. 96b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; } 97b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek bool getUseUnoptimizedCFG() const { 98bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek return !cfgBuildOptions.PruneTriviallyFalseEdges; 99b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek } 100b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; } 101b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; } 1029b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek 1030d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek void registerForcedBlockExpression(const Stmt *stmt); 1040d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt); 1050d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 106326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek Stmt *getBody(); 107326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek CFG *getCFG(); 108283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek 109283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek CFGStmtMap *getCFGStmtMap(); 11004eeba43040969c05cfcb563195ef5b199297b62Anders Carlsson 111af13d5b25b360e698cc1cf1055ad7d14e008e505Ted Kremenek CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis(); 11242461eecee98fff3671b3c14ce10f1a9e18cc95cTed Kremenek 113ad5a894df1841698c824381b414630799adc26caTed Kremenek /// Return a version of the CFG without any edges pruned. 114ad5a894df1841698c824381b414630799adc26caTed Kremenek CFG *getUnoptimizedCFG(); 115ad5a894df1841698c824381b414630799adc26caTed Kremenek 11604eeba43040969c05cfcb563195ef5b199297b62Anders Carlsson void dumpCFG(); 11704eeba43040969c05cfcb563195ef5b199297b62Anders Carlsson 1185d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth /// \brief Returns true if we have built a CFG for this analysis context. 1195d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth /// Note that this doesn't correspond to whether or not a valid CFG exists, it 1205d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth /// corresponds to whether we *attempted* to build one. 1215d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth bool isCFGBuilt() const { return builtCFG; } 1225d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 123326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ParentMap &getParentMap(); 124db34ab70961ca4b24b600eb47053d7af304659f5Tom Care PseudoConstantAnalysis *getPseudoConstantAnalysis(); 125326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek LiveVariables *getLiveVariables(); 126ec49bf464c91a52b3a463940da6589d03bf40248Tom Care LiveVariables *getRelaxedLiveVariables(); 127326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 128326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek typedef const VarDecl * const * referenced_decls_iterator; 129326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 130326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek std::pair<referenced_decls_iterator, referenced_decls_iterator> 131326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek getReferencedBlockVars(const BlockDecl *BD); 132d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 133326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// Return the ImplicitParamDecl* associated with 'self' if this 134326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// AnalysisContext wraps an ObjCMethodDecl. Returns NULL otherwise. 135326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const ImplicitParamDecl *getSelfDecl() const; 136326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 137326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 138326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass AnalysisContextManager { 139326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap; 140326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ContextMap Contexts; 141bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek CFG::BuildOptions cfgBuildOptions; 142326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 1439121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski AnalysisContextManager(bool useUnoptimizedCFG = false, 144bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek bool addImplicitDtors = false, 145bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek bool addInitializers = false); 1469b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek 147326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~AnalysisContextManager(); 148326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 1492ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu AnalysisContext *getContext(const Decl *D, idx::TranslationUnit *TU = 0); 150d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 151bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek bool getUseUnoptimizedCFG() const { 152bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek return !cfgBuildOptions.PruneTriviallyFalseEdges; 153bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek } 154bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek 155bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek CFG::BuildOptions &getCFGBuildOptions() { 156bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek return cfgBuildOptions; 157bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek } 1589b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek 159bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek /// Discard all previously created AnalysisContexts. 160326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek void clear(); 161326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 162326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 163326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass LocationContext : public llvm::FoldingSetNode { 164326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 165326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek enum ContextKind { StackFrame, Scope, Block }; 166326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 167326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekprivate: 168326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ContextKind Kind; 169a02d893f15d4663bdba3bd92ade10070bf0510e4Zhongxing Xu 170a02d893f15d4663bdba3bd92ade10070bf0510e4Zhongxing Xu // AnalysisContext can't be const since some methods may modify its member. 171326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek AnalysisContext *Ctx; 172a02d893f15d4663bdba3bd92ade10070bf0510e4Zhongxing Xu 173326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *Parent; 174326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 175326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekprotected: 176326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek LocationContext(ContextKind k, AnalysisContext *ctx, 177326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent) 178326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek : Kind(k), Ctx(ctx), Parent(parent) {} 179326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 180326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 181326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek virtual ~LocationContext(); 182d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 183326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ContextKind getKind() const { return Kind; } 184326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 185326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek AnalysisContext *getAnalysisContext() const { return Ctx; } 186326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 1872ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu idx::TranslationUnit *getTranslationUnit() const { 188c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu return Ctx->getTranslationUnit(); 189c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu } 190c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 191326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *getParent() const { return Parent; } 192326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 1938ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu bool isParentOf(const LocationContext *LC) const; 1948ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu 195326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Decl *getDecl() const { return getAnalysisContext()->getDecl(); } 196326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 197326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek CFG *getCFG() const { return getAnalysisContext()->getCFG(); } 198326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 199326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek LiveVariables *getLiveVariables() const { 200326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return getAnalysisContext()->getLiveVariables(); 201326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 202326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 203d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek ParentMap &getParentMap() const { 204326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return getAnalysisContext()->getParentMap(); 205326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 206326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 207326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const ImplicitParamDecl *getSelfDecl() const { 208326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return Ctx->getSelfDecl(); 209326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 210d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 211326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const StackFrameContext *getCurrentStackFrame() const; 212326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const StackFrameContext * 213326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek getStackFrameForDeclContext(const DeclContext *DC) const; 214326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 215326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek virtual void Profile(llvm::FoldingSetNodeID &ID) = 0; 216326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 217326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static bool classof(const LocationContext*) { return true; } 218326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 219326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 220326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static void ProfileCommon(llvm::FoldingSetNodeID &ID, 221326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ContextKind ck, 222326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek AnalysisContext *ctx, 223326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, 224326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const void* data); 225326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 226326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 227326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass StackFrameContext : public LocationContext { 22826c9cb55cb96643c0759c08d037c16c309864087Zhongxing Xu // The callsite where this stack frame is established. 229892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek const Stmt *CallSite; 230326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 231326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // The parent block of the callsite. 232326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const CFGBlock *Block; 233326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 234326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // The index of the callsite in the CFGBlock. 235326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek unsigned Index; 236326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 237326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek friend class LocationContextManager; 238326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek StackFrameContext(AnalysisContext *ctx, const LocationContext *parent, 239892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek const Stmt *s, const CFGBlock *blk, 240d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu unsigned idx) 241892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek : LocationContext(StackFrame, ctx, parent), CallSite(s), 242d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu Block(blk), Index(idx) {} 243326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 244326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 245326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~StackFrameContext() {} 246326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 247892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek const Stmt *getCallSite() const { return CallSite; } 248d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu 249326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const CFGBlock *getCallSiteBlock() const { return Block; } 250326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 251326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek unsigned getIndex() const { return Index; } 252326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 253326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek void Profile(llvm::FoldingSetNodeID &ID); 254d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 255326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, 256d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek const LocationContext *parent, const Stmt *s, 257892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek const CFGBlock *blk, unsigned idx) { 258326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ProfileCommon(ID, StackFrame, ctx, parent, s); 259326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ID.AddPointer(blk); 260326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ID.AddInteger(idx); 261326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 262326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 263326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static bool classof(const LocationContext* Ctx) { 264326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return Ctx->getKind() == StackFrame; 265326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 266326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 267326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 268326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass ScopeContext : public LocationContext { 269326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Stmt *Enter; 270d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 271326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek friend class LocationContextManager; 272326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ScopeContext(AnalysisContext *ctx, const LocationContext *parent, 273326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Stmt *s) 274326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek : LocationContext(Scope, ctx, parent), Enter(s) {} 275326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 276326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 277326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~ScopeContext() {} 278326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 279326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek void Profile(llvm::FoldingSetNodeID &ID); 280326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 281326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, 282326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, const Stmt *s) { 283326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ProfileCommon(ID, Scope, ctx, parent, s); 284326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 285326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 286326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static bool classof(const LocationContext* Ctx) { 287326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return Ctx->getKind() == Scope; 288326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 289326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 290326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 291326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass BlockInvocationContext : public LocationContext { 292326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // FIXME: Add back context-sensivity (we don't want libAnalysis to know 293326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // about MemRegion). 294326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const BlockDecl *BD; 295326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 296326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek friend class LocationContextManager; 297326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 298326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent, 299326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const BlockDecl *bd) 300326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek : LocationContext(Block, ctx, parent), BD(bd) {} 301326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 302326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 303326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~BlockInvocationContext() {} 304326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 305326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const BlockDecl *getBlockDecl() const { return BD; } 306326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 307326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek void Profile(llvm::FoldingSetNodeID &ID); 308326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 309326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, 310326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, const BlockDecl *bd) { 311326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ProfileCommon(ID, Block, ctx, parent, bd); 312326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 313d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 314326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static bool classof(const LocationContext* Ctx) { 315326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return Ctx->getKind() == Block; 316326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 317326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 318326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 319326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass LocationContextManager { 320326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek llvm::FoldingSet<LocationContext> Contexts; 321326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 322326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~LocationContextManager(); 323d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 324326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const StackFrameContext *getStackFrame(AnalysisContext *ctx, 325326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, 326892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek const Stmt *s, 327d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu const CFGBlock *blk, unsigned idx); 328326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 329326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const ScopeContext *getScope(AnalysisContext *ctx, 330326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, 331326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Stmt *s); 332d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 333326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// Discard all previously created LocationContext objects. 334326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek void clear(); 335326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekprivate: 336326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek template <typename LOC, typename DATA> 337326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LOC *getLocationContext(AnalysisContext *ctx, 338326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, 339326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const DATA *d); 340326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 341326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 342326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek} // end clang namespace 343326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#endif 344