AnalysisContext.h revision 892697dd2287caf7c29aaaa82909b0e90b8b63fe
1bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- C++ -*-// 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert// 3bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor// The LLVM Compiler Infrastructure 4bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor// 5bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor// This file is distributed under the University of Illinois Open Source 6bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor// License. See LICENSE.TXT for details. 7bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor// 8bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor//===----------------------------------------------------------------------===// 9bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor// 10bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor// This file defines AnalysisContext, a class that manages the analysis context 11bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor// data for path sensitive analysis. 12bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor// 13bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor//===----------------------------------------------------------------------===// 14bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 15bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H 16bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H 17bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 18bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor#include "clang/AST/Decl.h" 19bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor#include "clang/AST/Expr.h" 20bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor#include "llvm/ADT/OwningPtr.h" 21bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor#include "llvm/ADT/FoldingSet.h" 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert#include "llvm/ADT/PointerUnion.h" 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert#include "llvm/ADT/DenseMap.h" 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert#include "llvm/Support/Allocator.h" 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertnamespace clang { 27bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertclass Decl; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertclass Stmt; 30bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorclass CFG; 31bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorclass CFGBlock; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertclass LiveVariables; 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertclass ParentMap; 34bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorclass PseudoConstantAnalysis; 35bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorclass ImplicitParamDecl; 36bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorclass LocationContextManager; 37bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorclass StackFrameContext; 38bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 39bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnornamespace idx { class TranslationUnit; } 40bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 41bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/// AnalysisContext contains the context data for the function or method under 42bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/// analysis. 43bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorclass AnalysisContext { 44bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const Decl *D; 45bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 46bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // TranslationUnit is NULL if we don't have multiple translation units. 47bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor idx::TranslationUnit *TU; 48bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 49bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // AnalysisContext owns the following data. 50bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor CFG *cfg, *completeCFG; 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bool builtCFG, builtCompleteCFG; 52bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor LiveVariables *liveness; 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LiveVariables *relaxedLiveness; 54bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ParentMap *PM; 55bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor PseudoConstantAnalysis *PCA; 56bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars; 57bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor llvm::BumpPtrAllocator A; 58bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool UseUnoptimizedCFG; 59bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool AddEHEdges; 60bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool AddImplicitDtors; 61bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool AddInitializers; 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic: 63bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor AnalysisContext(const Decl *d, idx::TranslationUnit *tu, 64bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool useUnoptimizedCFG = false, 65bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool addehedges = false, 66bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool addImplicitDtors = false, 67bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool addInitializers = false) 68bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor : D(d), TU(tu), cfg(0), completeCFG(0), 69bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor builtCFG(false), builtCompleteCFG(false), 70bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor liveness(0), relaxedLiveness(0), PM(0), PCA(0), 71bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ReferencedBlockVars(0), UseUnoptimizedCFG(useUnoptimizedCFG), 72bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor AddEHEdges(addehedges), AddImplicitDtors(addImplicitDtors), 73bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor AddInitializers(addInitializers) {} 74bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 75bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ~AnalysisContext(); 76bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 77bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ASTContext &getASTContext() { return D->getASTContext(); } 78bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const Decl *getDecl() const { return D; } 79bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 80bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor idx::TranslationUnit *getTranslationUnit() const { return TU; } 81bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 82bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /// getAddEHEdges - Return true iff we are adding exceptional edges from 83bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /// callExprs. If this is false, then try/catch statements and blocks 84bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /// reachable from them can appear to be dead in the CFG, analysis passes must 85bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /// cope with that. 86bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool getAddEHEdges() const { return AddEHEdges; } 87bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 88bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool getUseUnoptimizedCFG() const { return UseUnoptimizedCFG; } 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert bool getAddImplicitDtors() const { return AddImplicitDtors; } 90bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool getAddInitializers() const { return AddInitializers; } 91bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 92bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Stmt *getBody(); 93bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor CFG *getCFG(); 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /// Return a version of the CFG without any edges pruned. 96bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor CFG *getUnoptimizedCFG(); 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 98bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ParentMap &getParentMap(); 99bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor PseudoConstantAnalysis *getPseudoConstantAnalysis(); 100bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor LiveVariables *getLiveVariables(); 101bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor LiveVariables *getRelaxedLiveVariables(); 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 103bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor typedef const VarDecl * const * referenced_decls_iterator; 104bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert std::pair<referenced_decls_iterator, referenced_decls_iterator> 106bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor getReferencedBlockVars(const BlockDecl *BD); 107bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 108bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor /// Return the ImplicitParamDecl* associated with 'self' if this 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /// AnalysisContext wraps an ObjCMethodDecl. Returns NULL otherwise. 110bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const ImplicitParamDecl *getSelfDecl() const; 111bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor}; 112bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertclass AnalysisContextManager { 114bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap; 115bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ContextMap Contexts; 116bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool UseUnoptimizedCFG; 117bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool AddImplicitDtors; 118bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool AddInitializers; 119bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpublic: 120bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor AnalysisContextManager(bool useUnoptimizedCFG = false, 121bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool addImplicitDtors = false, bool addInitializers = false) 122bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor : UseUnoptimizedCFG(useUnoptimizedCFG), AddImplicitDtors(addImplicitDtors), 123bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor AddInitializers(addInitializers) {} 124bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 125bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ~AnalysisContextManager(); 126bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 127bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor AnalysisContext *getContext(const Decl *D, idx::TranslationUnit *TU = 0); 128bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 129bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool getUseUnoptimizedCFG() const { return UseUnoptimizedCFG; } 130bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool getAddImplicitDtors() const { return AddImplicitDtors; } 131bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool getAddInitializers() const { return AddInitializers; } 132bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 133bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // Discard all previously created AnalysisContexts. 134bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor void clear(); 135bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor}; 136bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 137bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorclass LocationContext : public llvm::FoldingSetNode { 138bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpublic: 139bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor enum ContextKind { StackFrame, Scope, Block }; 140bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 141bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorprivate: 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ContextKind Kind; 143bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 144bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // AnalysisContext can't be const since some methods may modify its member. 145bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor AnalysisContext *Ctx; 146bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 147bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const LocationContext *Parent; 148bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 149bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorprotected: 150bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor LocationContext(ContextKind k, AnalysisContext *ctx, 151bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const LocationContext *parent) 152bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor : Kind(k), Ctx(ctx), Parent(parent) {} 153bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 154bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpublic: 155bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor virtual ~LocationContext(); 156bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 157bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ContextKind getKind() const { return Kind; } 158bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 159bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor AnalysisContext *getAnalysisContext() const { return Ctx; } 160bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 161bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor idx::TranslationUnit *getTranslationUnit() const { 162bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return Ctx->getTranslationUnit(); 163bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 164bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 165bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const LocationContext *getParent() const { return Parent; } 166bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 167bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool isParentOf(const LocationContext *LC) const; 168bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 169bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const Decl *getDecl() const { return getAnalysisContext()->getDecl(); } 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor CFG *getCFG() const { return getAnalysisContext()->getCFG(); } 172bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 173bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor LiveVariables *getLiveVariables() const { 174bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return getAnalysisContext()->getLiveVariables(); 175bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 176bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 177bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ParentMap &getParentMap() const { 178bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return getAnalysisContext()->getParentMap(); 179bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 180bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 181bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const ImplicitParamDecl *getSelfDecl() const { 182bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return Ctx->getSelfDecl(); 183bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 184bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 185bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const StackFrameContext *getCurrentStackFrame() const; 186bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const StackFrameContext * 187bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor getStackFrameForDeclContext(const DeclContext *DC) const; 188bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 189bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor virtual void Profile(llvm::FoldingSetNodeID &ID) = 0; 190bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 191bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor static bool classof(const LocationContext*) { return true; } 192bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 193bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpublic: 194bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor static void ProfileCommon(llvm::FoldingSetNodeID &ID, 195bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ContextKind ck, 196bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor AnalysisContext *ctx, 197bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const LocationContext *parent, 198bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const void* data); 199bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor}; 200bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 201bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorclass StackFrameContext : public LocationContext { 202bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // The callsite where this stack frame is established. The int bit indicates 203bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // whether the call expr should return an l-value when it has reference type. 204bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const Stmt *CallSite; 205bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 206bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // The parent block of the callsite. 207bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const CFGBlock *Block; 208bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // The index of the callsite in the CFGBlock. 210bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor unsigned Index; 211bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 212bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor friend class LocationContextManager; 213bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor StackFrameContext(AnalysisContext *ctx, const LocationContext *parent, 214bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const Stmt *s, const CFGBlock *blk, 215bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor unsigned idx) 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert : LocationContext(StackFrame, ctx, parent), CallSite(s), 217bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor Block(blk), Index(idx) {} 218bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 219bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpublic: 220bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ~StackFrameContext() {} 221bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 222bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const Stmt *getCallSite() const { return CallSite; } 223bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 224bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor bool evalAsLValue() const { 225bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor if (const Expr *CE = dyn_cast<Expr>(CallSite)) 226bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return CE->isLValue(); 227bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return false; 228bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 229bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 230bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const CFGBlock *getCallSiteBlock() const { return Block; } 231bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 232bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor unsigned getIndex() const { return Index; } 233bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 234bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor void Profile(llvm::FoldingSetNodeID &ID); 235bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 236bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, 237bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const LocationContext *parent, const Stmt *s, 238bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const CFGBlock *blk, unsigned idx) { 239bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ProfileCommon(ID, StackFrame, ctx, parent, s); 240bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ID.AddPointer(blk); 241bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ID.AddInteger(idx); 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 244bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor static bool classof(const LocationContext* Ctx) { 245bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return Ctx->getKind() == StackFrame; 246bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}; 248bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 249bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorclass ScopeContext : public LocationContext { 250bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const Stmt *Enter; 251bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 252bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor friend class LocationContextManager; 253bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ScopeContext(AnalysisContext *ctx, const LocationContext *parent, 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert const Stmt *s) 255bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor : LocationContext(Scope, ctx, parent), Enter(s) {} 256bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 257bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpublic: 258bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ~ScopeContext() {} 259bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 260bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor void Profile(llvm::FoldingSetNodeID &ID); 261bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 262bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, 263bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const LocationContext *parent, const Stmt *s) { 264bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ProfileCommon(ID, Scope, ctx, parent, s); 265bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 267bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor static bool classof(const LocationContext* Ctx) { 268bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return Ctx->getKind() == Scope; 269bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 270bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor}; 271bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 272bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorclass BlockInvocationContext : public LocationContext { 273bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // FIXME: Add back context-sensivity (we don't want libAnalysis to know 274bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor // about MemRegion). 275bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const BlockDecl *BD; 276bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 277bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor friend class LocationContextManager; 278bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 279bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent, 280bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const BlockDecl *bd) 281bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor : LocationContext(Block, ctx, parent), BD(bd) {} 282bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 283bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpublic: 284bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ~BlockInvocationContext() {} 285bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 286bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const BlockDecl *getBlockDecl() const { return BD; } 287bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 288bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor void Profile(llvm::FoldingSetNodeID &ID); 289bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 290bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, 291bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor const LocationContext *parent, const BlockDecl *bd) { 292bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor ProfileCommon(ID, Block, ctx, parent, bd); 293bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 294bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 295bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor static bool classof(const LocationContext* Ctx) { 296bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor return Ctx->getKind() == Block; 297bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor } 298bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor}; 299bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor 3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertclass LocationContextManager { 301bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor llvm::FoldingSet<LocationContext> Contexts; 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic: 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ~LocationContextManager(); 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert const StackFrameContext *getStackFrame(AnalysisContext *ctx, 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert const LocationContext *parent, 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert const Stmt *s, 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert const CFGBlock *blk, unsigned idx); 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert const ScopeContext *getScope(AnalysisContext *ctx, 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert const LocationContext *parent, 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert const Stmt *s); 3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /// Discard all previously created LocationContext objects. 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert void clear(); 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertprivate: 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert template <typename LOC, typename DATA> 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert const LOC *getLocationContext(AnalysisContext *ctx, 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert const LocationContext *parent, 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert const DATA *d); 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}; 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} // end clang namespace 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert#endif 3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert