AnalysisContext.h revision 9121ba232903ebe61e7bbe14ca294cf0f07dfa96
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" 19326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#include "llvm/ADT/OwningPtr.h" 20326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#include "llvm/ADT/FoldingSet.h" 21326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#include "llvm/ADT/PointerUnion.h" 22326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#include "llvm/ADT/DenseMap.h" 23326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#include "llvm/Support/Allocator.h" 24326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 25326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremeneknamespace clang { 26326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 27326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass Decl; 28326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass Stmt; 29326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass CFG; 30326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass CFGBlock; 31326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass LiveVariables; 32326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass ParentMap; 33db34ab70961ca4b24b600eb47053d7af304659f5Tom Careclass PseudoConstantAnalysis; 34326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass ImplicitParamDecl; 35326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass LocationContextManager; 36326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass StackFrameContext; 37d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 38c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xunamespace idx { class TranslationUnit; } 39c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 40326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek/// AnalysisContext contains the context data for the function or method under 41326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek/// analysis. 42326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass AnalysisContext { 43326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Decl *D; 44326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 45c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu // TranslationUnit is NULL if we don't have multiple translation units. 462ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu idx::TranslationUnit *TU; 47c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 48326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // AnalysisContext owns the following data. 49ad5a894df1841698c824381b414630799adc26caTed Kremenek CFG *cfg, *completeCFG; 50ad5a894df1841698c824381b414630799adc26caTed Kremenek bool builtCFG, builtCompleteCFG; 51326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek LiveVariables *liveness; 52ec49bf464c91a52b3a463940da6589d03bf40248Tom Care LiveVariables *relaxedLiveness; 53326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ParentMap *PM; 54db34ab70961ca4b24b600eb47053d7af304659f5Tom Care PseudoConstantAnalysis *PCA; 55326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars; 56326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek llvm::BumpPtrAllocator A; 579b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek bool UseUnoptimizedCFG; 58326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek bool AddEHEdges; 599121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski bool AddImplicitDtors; 609121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski bool AddInitializers; 61326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 622ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu AnalysisContext(const Decl *d, idx::TranslationUnit *tu, 639b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek bool useUnoptimizedCFG = false, 649121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski bool addehedges = false, 659121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski bool addImplicitDtors = false, 669121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski bool addInitializers = false) 67ad5a894df1841698c824381b414630799adc26caTed Kremenek : D(d), TU(tu), cfg(0), completeCFG(0), 68ad5a894df1841698c824381b414630799adc26caTed Kremenek builtCFG(false), builtCompleteCFG(false), 69ec49bf464c91a52b3a463940da6589d03bf40248Tom Care liveness(0), relaxedLiveness(0), PM(0), PCA(0), 709b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek ReferencedBlockVars(0), UseUnoptimizedCFG(useUnoptimizedCFG), 719121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski AddEHEdges(addehedges), AddImplicitDtors(addImplicitDtors), 729121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski AddInitializers(addInitializers) {} 73326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 74326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~AnalysisContext(); 75326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 76326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ASTContext &getASTContext() { return D->getASTContext(); } 77c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu const Decl *getDecl() const { return D; } 78c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 792ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu idx::TranslationUnit *getTranslationUnit() const { return TU; } 80c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 81326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// getAddEHEdges - Return true iff we are adding exceptional edges from 82326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// callExprs. If this is false, then try/catch statements and blocks 83326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// reachable from them can appear to be dead in the CFG, analysis passes must 84326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// cope with that. 85326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek bool getAddEHEdges() const { return AddEHEdges; } 869b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek 879b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek bool getUseUnoptimizedCFG() const { return UseUnoptimizedCFG; } 889121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski bool getAddImplicitDtors() const { return AddImplicitDtors; } 899121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski bool getAddInitializers() const { return AddInitializers; } 909b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek 91326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek Stmt *getBody(); 92326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek CFG *getCFG(); 93ad5a894df1841698c824381b414630799adc26caTed Kremenek 94ad5a894df1841698c824381b414630799adc26caTed Kremenek /// Return a version of the CFG without any edges pruned. 95ad5a894df1841698c824381b414630799adc26caTed Kremenek CFG *getUnoptimizedCFG(); 96ad5a894df1841698c824381b414630799adc26caTed Kremenek 97326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ParentMap &getParentMap(); 98db34ab70961ca4b24b600eb47053d7af304659f5Tom Care PseudoConstantAnalysis *getPseudoConstantAnalysis(); 99326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek LiveVariables *getLiveVariables(); 100ec49bf464c91a52b3a463940da6589d03bf40248Tom Care LiveVariables *getRelaxedLiveVariables(); 101326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 102326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek typedef const VarDecl * const * referenced_decls_iterator; 103326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 104326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek std::pair<referenced_decls_iterator, referenced_decls_iterator> 105326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek getReferencedBlockVars(const BlockDecl *BD); 106d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 107326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// Return the ImplicitParamDecl* associated with 'self' if this 108326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// AnalysisContext wraps an ObjCMethodDecl. Returns NULL otherwise. 109326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const ImplicitParamDecl *getSelfDecl() const; 110326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 111326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 112326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass AnalysisContextManager { 113326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap; 114326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ContextMap Contexts; 1159b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek bool UseUnoptimizedCFG; 1169121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski bool AddImplicitDtors; 1179121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski bool AddInitializers; 118326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 1199121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski AnalysisContextManager(bool useUnoptimizedCFG = false, 1209121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski bool addImplicitDtors = false, bool addInitializers = false) 1219121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski : UseUnoptimizedCFG(useUnoptimizedCFG), AddImplicitDtors(addImplicitDtors), 1229121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski AddInitializers(addInitializers) {} 1239b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek 124326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~AnalysisContextManager(); 125326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 1262ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu AnalysisContext *getContext(const Decl *D, idx::TranslationUnit *TU = 0); 127d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 1289b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek bool getUseUnoptimizedCFG() const { return UseUnoptimizedCFG; } 1299121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski bool getAddImplicitDtors() const { return AddImplicitDtors; } 1309121ba232903ebe61e7bbe14ca294cf0f07dfa96Marcin Swiderski bool getAddInitializers() const { return AddInitializers; } 1319b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek 132326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // Discard all previously created AnalysisContexts. 133326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek void clear(); 134326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 135326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 136326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass LocationContext : public llvm::FoldingSetNode { 137326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 138326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek enum ContextKind { StackFrame, Scope, Block }; 139326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 140326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekprivate: 141326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ContextKind Kind; 142a02d893f15d4663bdba3bd92ade10070bf0510e4Zhongxing Xu 143a02d893f15d4663bdba3bd92ade10070bf0510e4Zhongxing Xu // AnalysisContext can't be const since some methods may modify its member. 144326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek AnalysisContext *Ctx; 145a02d893f15d4663bdba3bd92ade10070bf0510e4Zhongxing Xu 146326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *Parent; 147326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 148326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekprotected: 149326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek LocationContext(ContextKind k, AnalysisContext *ctx, 150326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent) 151326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek : Kind(k), Ctx(ctx), Parent(parent) {} 152326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 153326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 154326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek virtual ~LocationContext(); 155d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 156326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ContextKind getKind() const { return Kind; } 157326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 158326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek AnalysisContext *getAnalysisContext() const { return Ctx; } 159326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 1602ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu idx::TranslationUnit *getTranslationUnit() const { 161c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu return Ctx->getTranslationUnit(); 162c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu } 163c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 164326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *getParent() const { return Parent; } 165326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 1668ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu bool isParentOf(const LocationContext *LC) const; 1678ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu 168326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Decl *getDecl() const { return getAnalysisContext()->getDecl(); } 169326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 170326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek CFG *getCFG() const { return getAnalysisContext()->getCFG(); } 171326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 172326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek LiveVariables *getLiveVariables() const { 173326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return getAnalysisContext()->getLiveVariables(); 174326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 175326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 176d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek ParentMap &getParentMap() const { 177326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return getAnalysisContext()->getParentMap(); 178326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 179326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 180326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const ImplicitParamDecl *getSelfDecl() const { 181326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return Ctx->getSelfDecl(); 182326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 183d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 184326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const StackFrameContext *getCurrentStackFrame() const; 185326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const StackFrameContext * 186326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek getStackFrameForDeclContext(const DeclContext *DC) const; 187326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 188326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek virtual void Profile(llvm::FoldingSetNodeID &ID) = 0; 189326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 190326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static bool classof(const LocationContext*) { return true; } 191326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 192326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 193326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static void ProfileCommon(llvm::FoldingSetNodeID &ID, 194326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ContextKind ck, 195326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek AnalysisContext *ctx, 196326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, 197326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const void* data); 198326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 199326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 200326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass StackFrameContext : public LocationContext { 201326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // The callsite where this stack frame is established. 202326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Stmt *CallSite; 203326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 204326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // The parent block of the callsite. 205326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const CFGBlock *Block; 206326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 207326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // The index of the callsite in the CFGBlock. 208326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek unsigned Index; 209326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 210326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek friend class LocationContextManager; 211326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek StackFrameContext(AnalysisContext *ctx, const LocationContext *parent, 212326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Stmt *s, const CFGBlock *blk, unsigned idx) 213d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek : LocationContext(StackFrame, ctx, parent), CallSite(s), Block(blk), 214326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek Index(idx) {} 215326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 216326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 217326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~StackFrameContext() {} 218326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 219326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Stmt *getCallSite() const { return CallSite; } 220326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 221326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const CFGBlock *getCallSiteBlock() const { return Block; } 222326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 223326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek unsigned getIndex() const { return Index; } 224326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 225326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek void Profile(llvm::FoldingSetNodeID &ID); 226d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 227326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, 228d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek const LocationContext *parent, const Stmt *s, 229326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const CFGBlock *blk, unsigned idx) { 230326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ProfileCommon(ID, StackFrame, ctx, parent, s); 231326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ID.AddPointer(blk); 232326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ID.AddInteger(idx); 233326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 234326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 235326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static bool classof(const LocationContext* Ctx) { 236326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return Ctx->getKind() == StackFrame; 237326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 238326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 239326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 240326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass ScopeContext : public LocationContext { 241326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Stmt *Enter; 242d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 243326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek friend class LocationContextManager; 244326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ScopeContext(AnalysisContext *ctx, const LocationContext *parent, 245326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Stmt *s) 246326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek : LocationContext(Scope, ctx, parent), Enter(s) {} 247326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 248326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 249326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~ScopeContext() {} 250326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 251326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek void Profile(llvm::FoldingSetNodeID &ID); 252326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 253326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, 254326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, const Stmt *s) { 255326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ProfileCommon(ID, Scope, ctx, parent, s); 256326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 257326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 258326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static bool classof(const LocationContext* Ctx) { 259326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return Ctx->getKind() == Scope; 260326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 261326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 262326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 263326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass BlockInvocationContext : public LocationContext { 264326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // FIXME: Add back context-sensivity (we don't want libAnalysis to know 265326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // about MemRegion). 266326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const BlockDecl *BD; 267326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 268326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek friend class LocationContextManager; 269326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 270326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent, 271326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const BlockDecl *bd) 272326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek : LocationContext(Block, ctx, parent), BD(bd) {} 273326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 274326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 275326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~BlockInvocationContext() {} 276326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 277326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const BlockDecl *getBlockDecl() const { return BD; } 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 BlockDecl *bd) { 283326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ProfileCommon(ID, Block, ctx, parent, bd); 284326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 285d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 286326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static bool classof(const LocationContext* Ctx) { 287326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return Ctx->getKind() == Block; 288326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 289326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 290326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 291326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass LocationContextManager { 292326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek llvm::FoldingSet<LocationContext> Contexts; 293326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 294326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~LocationContextManager(); 295d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 296326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const StackFrameContext *getStackFrame(AnalysisContext *ctx, 297326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, 298326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Stmt *s, const CFGBlock *blk, 299326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek unsigned idx); 300326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 301326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const ScopeContext *getScope(AnalysisContext *ctx, 302326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, 303326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Stmt *s); 304d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 305326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// Discard all previously created LocationContext objects. 306326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek void clear(); 307326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekprivate: 308326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek template <typename LOC, typename DATA> 309326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LOC *getLocationContext(AnalysisContext *ctx, 310326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, 311326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const DATA *d); 312326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 313326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 314326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek} // end clang namespace 315326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#endif 316