AnalysisContext.h revision ba243b59a1074e0962f6abfa3bb9aa984eac1245
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// 10ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie// This file defines AnalysisDeclContext, a class that manages the analysis 11ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie// context 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; 35a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenekclass ManagedAnalysis; 36326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass ParentMap; 37db34ab70961ca4b24b600eb47053d7af304659f5Tom Careclass PseudoConstantAnalysis; 38326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass ImplicitParamDecl; 39326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass LocationContextManager; 40326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass StackFrameContext; 411d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekclass AnalysisDeclContextManager; 42ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikieclass LocationContext; 43b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek 44c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xunamespace idx { class TranslationUnit; } 45c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 46a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek/// The base class of a hierarchy of objects representing analyses tied 471d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek/// to AnalysisDeclContext. 48a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenekclass ManagedAnalysis { 49a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenekprotected: 50a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek ManagedAnalysis() {} 51a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenekpublic: 52a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek virtual ~ManagedAnalysis(); 53ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 54a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek // Subclasses need to implement: 55a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek // 56a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek // static const void *getTag(); 57a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek // 58a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek // Which returns a fixed pointer address to distinguish classes of 59a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek // analysis objects. They also need to implement: 60a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek // 611d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek // static [Derived*] create(AnalysisDeclContext &Ctx); 62a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek // 631d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek // which creates the analysis object given an AnalysisDeclContext. 64a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek}; 65ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 66ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 67ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie/// AnalysisDeclContext contains the context data for the function or method 68ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie/// under analysis. 691d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekclass AnalysisDeclContext { 70ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie /// Backpoint to the AnalysisManager object that created this 71ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie /// AnalysisDeclContext. This may be null. 721d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContextManager *Manager; 73ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 74326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Decl *D; 75326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 76c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu // TranslationUnit is NULL if we don't have multiple translation units. 772ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu idx::TranslationUnit *TU; 78c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 79b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::OwningPtr<CFG> cfg, completeCFG; 80b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::OwningPtr<CFGStmtMap> cfgStmtMap; 81b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek 82b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek CFG::BuildOptions cfgBuildOptions; 83b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs; 84ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 85ad5a894df1841698c824381b414630799adc26caTed Kremenek bool builtCFG, builtCompleteCFG; 86b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek 87b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::OwningPtr<LiveVariables> liveness; 88b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::OwningPtr<LiveVariables> relaxedLiveness; 89b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::OwningPtr<ParentMap> PM; 90b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::OwningPtr<PseudoConstantAnalysis> PCA; 91af13d5b25b360e698cc1cf1055ad7d14e008e505Ted Kremenek llvm::OwningPtr<CFGReverseBlockReachabilityAnalysis> CFA; 92b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek 93326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek llvm::BumpPtrAllocator A; 94b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek 95b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek // FIXME: remove. 96b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars; 97b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek 98a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek void *ManagedAnalyses; 99a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek 100326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 1011d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContext(AnalysisDeclContextManager *Mgr, 102b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek const Decl *D, 103b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek idx::TranslationUnit *TU); 104bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek 1051d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContext(AnalysisDeclContextManager *Mgr, 106b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek const Decl *D, 107b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek idx::TranslationUnit *TU, 108b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek const CFG::BuildOptions &BuildOptions); 109326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 1101d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek ~AnalysisDeclContext(); 111326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 112326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ASTContext &getASTContext() { return D->getASTContext(); } 113c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu const Decl *getDecl() const { return D; } 114c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 1152ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu idx::TranslationUnit *getTranslationUnit() const { return TU; } 116c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 11774fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek /// Return the build options used to construct the CFG. 11874fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek CFG::BuildOptions &getCFGBuildOptions() { 11974fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek return cfgBuildOptions; 12074fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek } 12174fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek 12274fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek const CFG::BuildOptions &getCFGBuildOptions() const { 12374fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek return cfgBuildOptions; 12474fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek } 125ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 126326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// getAddEHEdges - Return true iff we are adding exceptional edges from 127326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// callExprs. If this is false, then try/catch statements and blocks 128326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// reachable from them can appear to be dead in the CFG, analysis passes must 129326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// cope with that. 130ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; } 131b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek bool getUseUnoptimizedCFG() const { 132bc5cb8a5fe2b88f917d47ceb58b53696a121e57eTed Kremenek return !cfgBuildOptions.PruneTriviallyFalseEdges; 133b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek } 134b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; } 135b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; } 1369b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek 1370d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek void registerForcedBlockExpression(const Stmt *stmt); 1380d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt); 139ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 140a2d7e6511a8767dc67381c210601b895a8ebae39Anna Zaks Stmt *getBody() const; 141326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek CFG *getCFG(); 142ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 143283a358aecb75e30fcd486f2206f6c03c5e7f11dTed Kremenek CFGStmtMap *getCFGStmtMap(); 14404eeba43040969c05cfcb563195ef5b199297b62Anders Carlsson 145af13d5b25b360e698cc1cf1055ad7d14e008e505Ted Kremenek CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis(); 146ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 147ad5a894df1841698c824381b414630799adc26caTed Kremenek /// Return a version of the CFG without any edges pruned. 148ad5a894df1841698c824381b414630799adc26caTed Kremenek CFG *getUnoptimizedCFG(); 149ad5a894df1841698c824381b414630799adc26caTed Kremenek 15004eeba43040969c05cfcb563195ef5b199297b62Anders Carlsson void dumpCFG(); 15104eeba43040969c05cfcb563195ef5b199297b62Anders Carlsson 1525d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth /// \brief Returns true if we have built a CFG for this analysis context. 1535d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth /// Note that this doesn't correspond to whether or not a valid CFG exists, it 1545d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth /// corresponds to whether we *attempted* to build one. 1555d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth bool isCFGBuilt() const { return builtCFG; } 1565d98994c7749312a43ce6adf45537979a98e7afdChandler Carruth 157326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ParentMap &getParentMap(); 158db34ab70961ca4b24b600eb47053d7af304659f5Tom Care PseudoConstantAnalysis *getPseudoConstantAnalysis(); 159326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 160326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek typedef const VarDecl * const * referenced_decls_iterator; 161326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 162326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek std::pair<referenced_decls_iterator, referenced_decls_iterator> 163326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek getReferencedBlockVars(const BlockDecl *BD); 164d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 165326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// Return the ImplicitParamDecl* associated with 'self' if this 1661d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek /// AnalysisDeclContext wraps an ObjCMethodDecl. Returns NULL otherwise. 167326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const ImplicitParamDecl *getSelfDecl() const; 168ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 169b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek const StackFrameContext *getStackFrame(LocationContext const *Parent, 170b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek const Stmt *S, 171b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek const CFGBlock *Blk, 172ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie unsigned Idx); 173ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 174a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek /// Return the specified analysis object, lazily running the analysis if 175a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek /// necessary. Return NULL if the analysis could not run. 176a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek template <typename T> 177a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek T *getAnalysis() { 178a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek const void *tag = T::getTag(); 179a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek ManagedAnalysis *&data = getAnalysisImpl(tag); 180a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek if (!data) { 181a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek data = T::create(*this); 182a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek } 183a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek return static_cast<T*>(data); 184a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek } 185a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenekprivate: 186a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek ManagedAnalysis *&getAnalysisImpl(const void* tag); 187ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 188b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek LocationContextManager &getLocationContextManager(); 189326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 190326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 191326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass LocationContext : public llvm::FoldingSetNode { 192326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 193326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek enum ContextKind { StackFrame, Scope, Block }; 194326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 195326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekprivate: 196326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ContextKind Kind; 197a02d893f15d4663bdba3bd92ade10070bf0510e4Zhongxing Xu 198ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie // AnalysisDeclContext can't be const since some methods may modify its 199ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie // member. 2001d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContext *Ctx; 201a02d893f15d4663bdba3bd92ade10070bf0510e4Zhongxing Xu 202326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *Parent; 203326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 204326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekprotected: 2051d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek LocationContext(ContextKind k, AnalysisDeclContext *ctx, 206326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent) 207326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek : Kind(k), Ctx(ctx), Parent(parent) {} 208326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 209326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 210326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek virtual ~LocationContext(); 211d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 212326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ContextKind getKind() const { return Kind; } 213326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 2141d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; } 215326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 216ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie idx::TranslationUnit *getTranslationUnit() const { 217ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie return Ctx->getTranslationUnit(); 218c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu } 219c6238d2786cfd961b94580b3d3675a1b3ff0721cZhongxing Xu 220326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *getParent() const { return Parent; } 221326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 2228ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu bool isParentOf(const LocationContext *LC) const; 2238ddf7cead8a67342a4584a203e0bf736b7efedbeZhongxing Xu 2241d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek const Decl *getDecl() const { return getAnalysisDeclContext()->getDecl(); } 225326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 2261d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek CFG *getCFG() const { return getAnalysisDeclContext()->getCFG(); } 227326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 228a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek template <typename T> 229a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek T *getAnalysis() const { 2301d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek return getAnalysisDeclContext()->getAnalysis<T>(); 231326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 232326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 233d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek ParentMap &getParentMap() const { 2341d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek return getAnalysisDeclContext()->getParentMap(); 235326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 236326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 237326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const ImplicitParamDecl *getSelfDecl() const { 238326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return Ctx->getSelfDecl(); 239326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 240d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 241326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const StackFrameContext *getCurrentStackFrame() const; 242326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const StackFrameContext * 243326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek getStackFrameForDeclContext(const DeclContext *DC) const; 244326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 245326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek virtual void Profile(llvm::FoldingSetNodeID &ID) = 0; 246326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 247326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static bool classof(const LocationContext*) { return true; } 248326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 249326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 250326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek static void ProfileCommon(llvm::FoldingSetNodeID &ID, 251326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ContextKind ck, 2521d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContext *ctx, 253326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, 2549c378f705405d37f49795d5e915989de774fe11fTed Kremenek const void *data); 255326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 256326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 257326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass StackFrameContext : public LocationContext { 25826c9cb55cb96643c0759c08d037c16c309864087Zhongxing Xu // The callsite where this stack frame is established. 259892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek const Stmt *CallSite; 260326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 261326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // The parent block of the callsite. 262326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const CFGBlock *Block; 263326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 264326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // The index of the callsite in the CFGBlock. 265326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek unsigned Index; 266326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 267326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek friend class LocationContextManager; 2681d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek StackFrameContext(AnalysisDeclContext *ctx, const LocationContext *parent, 269ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie const Stmt *s, const CFGBlock *blk, 270d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu unsigned idx) 271892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek : LocationContext(StackFrame, ctx, parent), CallSite(s), 272d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu Block(blk), Index(idx) {} 273326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 274326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 275326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~StackFrameContext() {} 276326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 277892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek const Stmt *getCallSite() const { return CallSite; } 278d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu 279326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const CFGBlock *getCallSiteBlock() const { return Block; } 280326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 281326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek unsigned getIndex() const { return Index; } 282326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 283326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek void Profile(llvm::FoldingSetNodeID &ID); 284d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 2851d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx, 286d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek const LocationContext *parent, const Stmt *s, 287892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek const CFGBlock *blk, unsigned idx) { 288326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ProfileCommon(ID, StackFrame, ctx, parent, s); 289326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ID.AddPointer(blk); 290326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ID.AddInteger(idx); 291326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 292326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 2939c378f705405d37f49795d5e915989de774fe11fTed Kremenek static bool classof(const LocationContext *Ctx) { 294326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return Ctx->getKind() == StackFrame; 295326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 296326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 297326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 298326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass ScopeContext : public LocationContext { 299326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Stmt *Enter; 300d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 301326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek friend class LocationContextManager; 3021d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent, 303326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Stmt *s) 304326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek : LocationContext(Scope, ctx, parent), Enter(s) {} 305326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 306326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 307326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~ScopeContext() {} 308326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 309326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek void Profile(llvm::FoldingSetNodeID &ID); 310326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 3111d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx, 312326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, const Stmt *s) { 313326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ProfileCommon(ID, Scope, ctx, parent, s); 314326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 315326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 3169c378f705405d37f49795d5e915989de774fe11fTed Kremenek static bool classof(const LocationContext *Ctx) { 317326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return Ctx->getKind() == Scope; 318326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 319326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 320326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 321326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass BlockInvocationContext : public LocationContext { 322326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // FIXME: Add back context-sensivity (we don't want libAnalysis to know 323326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek // about MemRegion). 324326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const BlockDecl *BD; 325326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 326326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek friend class LocationContextManager; 327326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 328ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie BlockInvocationContext(AnalysisDeclContext *ctx, 329ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie const LocationContext *parent, 330326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const BlockDecl *bd) 331326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek : LocationContext(Block, ctx, parent), BD(bd) {} 332326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 333326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 334326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~BlockInvocationContext() {} 335326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 336326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const BlockDecl *getBlockDecl() const { return BD; } 337326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 338326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek void Profile(llvm::FoldingSetNodeID &ID); 339326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 3401d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx, 341326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, const BlockDecl *bd) { 342326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ProfileCommon(ID, Block, ctx, parent, bd); 343326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 344d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 3459c378f705405d37f49795d5e915989de774fe11fTed Kremenek static bool classof(const LocationContext *Ctx) { 346326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek return Ctx->getKind() == Block; 347326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek } 348326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 349326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 350326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekclass LocationContextManager { 351326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek llvm::FoldingSet<LocationContext> Contexts; 352326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekpublic: 353326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek ~LocationContextManager(); 354d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 3551d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek const StackFrameContext *getStackFrame(AnalysisDeclContext *ctx, 356326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, 357892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek const Stmt *s, 358d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu const CFGBlock *blk, unsigned idx); 359326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 3601d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek const ScopeContext *getScope(AnalysisDeclContext *ctx, 361326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, 362326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const Stmt *s); 363d064fdc4b7b64ca55b40b70490c79d6f569df78eTed Kremenek 364326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek /// Discard all previously created LocationContext objects. 365326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek void clear(); 366326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenekprivate: 367326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek template <typename LOC, typename DATA> 3681d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek const LOC *getLocationContext(AnalysisDeclContext *ctx, 369326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const LocationContext *parent, 370326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek const DATA *d); 371326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek}; 372326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek 3731d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenekclass AnalysisDeclContextManager { 3741d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek typedef llvm::DenseMap<const Decl*, AnalysisDeclContext*> ContextMap; 375ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 376b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek ContextMap Contexts; 377b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek LocationContextManager LocContexts; 378b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek CFG::BuildOptions cfgBuildOptions; 379ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 380b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenekpublic: 3811d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContextManager(bool useUnoptimizedCFG = false, 382b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek bool addImplicitDtors = false, 383b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek bool addInitializers = false); 384ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 3851d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek ~AnalysisDeclContextManager(); 386ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 3871d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContext *getContext(const Decl *D, idx::TranslationUnit *TU = 0); 388ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 389b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek bool getUseUnoptimizedCFG() const { 390b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek return !cfgBuildOptions.PruneTriviallyFalseEdges; 391b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek } 392ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 393b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek CFG::BuildOptions &getCFGBuildOptions() { 394b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek return cfgBuildOptions; 395b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek } 396ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 3971d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek const StackFrameContext *getStackFrame(AnalysisDeclContext *Ctx, 398b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek LocationContext const *Parent, 399b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek const Stmt *S, 400b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek const CFGBlock *Blk, 401b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek unsigned Idx) { 402b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek return LocContexts.getStackFrame(Ctx, Parent, S, Blk, Idx); 403b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek } 404ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 405b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek // Get the top level stack frame. 406ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie const StackFrameContext *getStackFrame(Decl const *D, 407b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek idx::TranslationUnit *TU) { 408b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek return LocContexts.getStackFrame(getContext(D, TU), 0, 0, 0, 0); 409b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek } 410ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 411b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek // Get a stack frame with parent. 412ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie StackFrameContext const *getStackFrame(const Decl *D, 413b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek LocationContext const *Parent, 414b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek const Stmt *S, 415b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek const CFGBlock *Blk, 416b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek unsigned Idx) { 417b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx); 418b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek } 419b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek 420ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 4211d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek /// Discard all previously created AnalysisDeclContexts. 422b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek void clear(); 423b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek 424b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenekprivate: 4251d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek friend class AnalysisDeclContext; 426b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek 427b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek LocationContextManager &getLocationContextManager() { 428b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek return LocContexts; 429b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek } 430b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek}; 431b1b5daf30d2597e066936772bd206500232d7d65Ted Kremenek 432326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek} // end clang namespace 433326be568e2cb04285c84e6e26a3e6b3822607361Ted Kremenek#endif 434