AnalysisContext.h revision 7fa9b4f258636d89342eda28f21a986c8ac353b1
198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- C++ -*-// 298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project// 398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project// The LLVM Compiler Infrastructure 498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project// 598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project// This file is distributed under the University of Illinois Open Source 698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project// License. See LICENSE.TXT for details. 798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project// 898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project//===----------------------------------------------------------------------===// 998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project// 1098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project// This file defines AnalysisDeclContext, a class that manages the analysis 1198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project// context data for path sensitive analysis. 1298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project// 1398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project//===----------------------------------------------------------------------===// 1498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H 1698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H 1798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 1898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "clang/AST/Decl.h" 1998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "clang/AST/Expr.h" 2098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "clang/Analysis/CFG.h" 2198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "llvm/ADT/OwningPtr.h" 2298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "llvm/ADT/IntrusiveRefCntPtr.h" 2398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "llvm/ADT/FoldingSet.h" 2498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "llvm/ADT/PointerUnion.h" 2598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "llvm/ADT/DenseMap.h" 2698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project#include "llvm/Support/Allocator.h" 2798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 2898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectnamespace clang { 2998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 3098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass Decl; 3198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass Stmt; 3298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass CFGReverseBlockReachabilityAnalysis; 3398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass CFGStmtMap; 3498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass LiveVariables; 3598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass ManagedAnalysis; 3698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass ParentMap; 3798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass PseudoConstantAnalysis; 3898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass ImplicitParamDecl; 3998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass LocationContextManager; 4098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass StackFrameContext; 4198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass BlockInvocationContext; 4298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass AnalysisDeclContextManager; 4398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass LocationContext; 4498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 4598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectnamespace idx { class TranslationUnit; } 4698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 4798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/// The base class of a hierarchy of objects representing analyses tied 4898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/// to AnalysisDeclContext. 4998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass ManagedAnalysis { 5098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectprotected: 5198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ManagedAnalysis() {} 5298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectpublic: 5398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project virtual ~ManagedAnalysis(); 5498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 5598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // Subclasses need to implement: 5698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // 5798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // static const void *getTag(); 5898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // 5998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // Which returns a fixed pointer address to distinguish classes of 6098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // analysis objects. They also need to implement: 6198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // 6298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // static [Derived*] create(AnalysisDeclContext &Ctx); 6398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // 6498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // which creates the analysis object given an AnalysisDeclContext. 6598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}; 6698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 6798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 6898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/// AnalysisDeclContext contains the context data for the function or method 6998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project/// under analysis. 7098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass AnalysisDeclContext { 7198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// Backpoint to the AnalysisManager object that created this 7298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// AnalysisDeclContext. This may be null. 7398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project AnalysisDeclContextManager *Manager; 7498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 7598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const Decl *D; 7698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 7798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project OwningPtr<CFG> cfg, completeCFG; 7898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project OwningPtr<CFGStmtMap> cfgStmtMap; 7998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 8098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project CFG::BuildOptions cfgBuildOptions; 8198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs; 8298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 8398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project bool builtCFG, builtCompleteCFG; 8498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 8598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project OwningPtr<LiveVariables> liveness; 8698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project OwningPtr<LiveVariables> relaxedLiveness; 8798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project OwningPtr<ParentMap> PM; 8898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project OwningPtr<PseudoConstantAnalysis> PCA; 8998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project OwningPtr<CFGReverseBlockReachabilityAnalysis> CFA; 9098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 9198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project llvm::BumpPtrAllocator A; 9298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 9398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars; 9498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 9598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project void *ManagedAnalyses; 9698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 9798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectpublic: 9898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project AnalysisDeclContext(AnalysisDeclContextManager *Mgr, 9998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const Decl *D); 10098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 10198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project AnalysisDeclContext(AnalysisDeclContextManager *Mgr, 10298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const Decl *D, 10398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const CFG::BuildOptions &BuildOptions); 10498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 10598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ~AnalysisDeclContext(); 10698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 10798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ASTContext &getASTContext() { return D->getASTContext(); } 10898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const Decl *getDecl() const { return D; } 10998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 11098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// Return the build options used to construct the CFG. 11198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project CFG::BuildOptions &getCFGBuildOptions() { 11298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return cfgBuildOptions; 11398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 11498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 11598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const CFG::BuildOptions &getCFGBuildOptions() const { 11698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return cfgBuildOptions; 11798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 11898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 11998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// getAddEHEdges - Return true iff we are adding exceptional edges from 12098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// callExprs. If this is false, then try/catch statements and blocks 12198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// reachable from them can appear to be dead in the CFG, analysis passes must 12298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// cope with that. 12398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; } 12498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project bool getUseUnoptimizedCFG() const { 12598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return !cfgBuildOptions.PruneTriviallyFalseEdges; 12698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 12798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; } 12898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; } 12998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 13098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project void registerForcedBlockExpression(const Stmt *stmt); 13198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt); 13298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 13398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Stmt *getBody() const; 13498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project CFG *getCFG(); 13598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 13698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project CFGStmtMap *getCFGStmtMap(); 13798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 13898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis(); 13998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 14098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// Return a version of the CFG without any edges pruned. 14198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project CFG *getUnoptimizedCFG(); 14298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 14398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project void dumpCFG(bool ShowColors); 14498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 14598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// \brief Returns true if we have built a CFG for this analysis context. 14698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// Note that this doesn't correspond to whether or not a valid CFG exists, it 14798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// corresponds to whether we *attempted* to build one. 14898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project bool isCFGBuilt() const { return builtCFG; } 14998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 15098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ParentMap &getParentMap(); 15198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project PseudoConstantAnalysis *getPseudoConstantAnalysis(); 15298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 15398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project typedef const VarDecl * const * referenced_decls_iterator; 15498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 15598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project std::pair<referenced_decls_iterator, referenced_decls_iterator> 15698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project getReferencedBlockVars(const BlockDecl *BD); 15798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 15898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// Return the ImplicitParamDecl* associated with 'self' if this 15998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// AnalysisDeclContext wraps an ObjCMethodDecl. Returns NULL otherwise. 16098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const ImplicitParamDecl *getSelfDecl() const; 16198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 16298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const StackFrameContext *getStackFrame(LocationContext const *Parent, 16398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const Stmt *S, 16498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const CFGBlock *Blk, 16598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project unsigned Idx); 16698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 16798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const BlockInvocationContext * 16898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project getBlockInvocationContext(const LocationContext *parent, 16998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const BlockDecl *BD, 17098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const void *ContextData); 17198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 17298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// Return the specified analysis object, lazily running the analysis if 17398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project /// necessary. Return NULL if the analysis could not run. 17498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project template <typename T> 17598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project T *getAnalysis() { 17698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const void *tag = T::getTag(); 17798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ManagedAnalysis *&data = getAnalysisImpl(tag); 17898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project if (!data) { 17998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project data = T::create(*this); 18098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 18198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return static_cast<T*>(data); 18298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 18398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectprivate: 18498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ManagedAnalysis *&getAnalysisImpl(const void* tag); 18598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 18698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project LocationContextManager &getLocationContextManager(); 18798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}; 18898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 18998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass LocationContext : public llvm::FoldingSetNode { 19098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectpublic: 19198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project enum ContextKind { StackFrame, Scope, Block }; 19298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 19398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectprivate: 19498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ContextKind Kind; 19598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 19698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // AnalysisDeclContext can't be const since some methods may modify its 19798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // member. 19898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project AnalysisDeclContext *Ctx; 19998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 20098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const LocationContext *Parent; 20198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 20298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectprotected: 20398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project LocationContext(ContextKind k, AnalysisDeclContext *ctx, 20498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const LocationContext *parent) 20598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project : Kind(k), Ctx(ctx), Parent(parent) {} 20698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 20798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectpublic: 20898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project virtual ~LocationContext(); 20998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 21098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ContextKind getKind() const { return Kind; } 21198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 21298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; } 21398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 21498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const LocationContext *getParent() const { return Parent; } 21598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 21698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project bool isParentOf(const LocationContext *LC) const; 21798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 21898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const Decl *getDecl() const { return getAnalysisDeclContext()->getDecl(); } 21998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 22098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project CFG *getCFG() const { return getAnalysisDeclContext()->getCFG(); } 22198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 22298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project template <typename T> 22398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project T *getAnalysis() const { 22498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return getAnalysisDeclContext()->getAnalysis<T>(); 22598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 22698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 22798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ParentMap &getParentMap() const { 22898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return getAnalysisDeclContext()->getParentMap(); 22998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 23098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 23198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const ImplicitParamDecl *getSelfDecl() const { 23298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return Ctx->getSelfDecl(); 23398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 23498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 23598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const StackFrameContext *getCurrentStackFrame() const; 23698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 23798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project virtual void Profile(llvm::FoldingSetNodeID &ID) = 0; 23898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 23998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project static bool classof(const LocationContext*) { return true; } 24098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 24198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectpublic: 24298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project static void ProfileCommon(llvm::FoldingSetNodeID &ID, 24398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ContextKind ck, 24498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project AnalysisDeclContext *ctx, 24598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const LocationContext *parent, 24698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const void *data); 24798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}; 24898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 24998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass StackFrameContext : public LocationContext { 25098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // The callsite where this stack frame is established. 25198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const Stmt *CallSite; 25298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 25398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // The parent block of the callsite. 25498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const CFGBlock *Block; 25598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 25698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // The index of the callsite in the CFGBlock. 25798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project unsigned Index; 25898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 25998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project friend class LocationContextManager; 26098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project StackFrameContext(AnalysisDeclContext *ctx, const LocationContext *parent, 26198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const Stmt *s, const CFGBlock *blk, 26298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project unsigned idx) 26398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project : LocationContext(StackFrame, ctx, parent), CallSite(s), 26498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project Block(blk), Index(idx) {} 26598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 26698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectpublic: 26798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ~StackFrameContext() {} 26898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 26998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const Stmt *getCallSite() const { return CallSite; } 27098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 27198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const CFGBlock *getCallSiteBlock() const { return Block; } 27298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 27398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project unsigned getIndex() const { return Index; } 27498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 27598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project void Profile(llvm::FoldingSetNodeID &ID); 27698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 27798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx, 27898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const LocationContext *parent, const Stmt *s, 27998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const CFGBlock *blk, unsigned idx) { 28098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ProfileCommon(ID, StackFrame, ctx, parent, s); 28198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ID.AddPointer(blk); 28298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ID.AddInteger(idx); 28398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 28498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 28598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project static bool classof(const LocationContext *Ctx) { 28698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return Ctx->getKind() == StackFrame; 28798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 28898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}; 28998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 29098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass ScopeContext : public LocationContext { 29198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const Stmt *Enter; 29298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 29398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project friend class LocationContextManager; 29498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent, 29598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const Stmt *s) 29698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project : LocationContext(Scope, ctx, parent), Enter(s) {} 29798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 29898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectpublic: 29998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ~ScopeContext() {} 30098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 30198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project void Profile(llvm::FoldingSetNodeID &ID); 30298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 30398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx, 30498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const LocationContext *parent, const Stmt *s) { 30598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ProfileCommon(ID, Scope, ctx, parent, s); 30698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 30798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 30898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project static bool classof(const LocationContext *Ctx) { 30998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project return Ctx->getKind() == Scope; 31098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project } 31198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project}; 31298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 31398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectclass BlockInvocationContext : public LocationContext { 31498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const BlockDecl *BD; 31598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 31698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project // FIXME: Come up with a more type-safe way to model context-sensitivity. 31798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const void *ContextData; 31898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 31998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project friend class LocationContextManager; 32098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 32198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project BlockInvocationContext(AnalysisDeclContext *ctx, 32298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const LocationContext *parent, 32398913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const BlockDecl *bd, const void *contextData) 32498913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project : LocationContext(Block, ctx, parent), BD(bd), ContextData(contextData) {} 32598913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 32698913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Projectpublic: 32798913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project ~BlockInvocationContext() {} 32898913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 32998913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const BlockDecl *getBlockDecl() const { return BD; } 33098913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 33198913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project const void *getContextData() const { return ContextData; } 33298913fed6520d8849fb2e246be943e04474aefaThe Android Open Source Project 333 void Profile(llvm::FoldingSetNodeID &ID); 334 335 static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx, 336 const LocationContext *parent, const BlockDecl *bd, 337 const void *contextData) { 338 ProfileCommon(ID, Block, ctx, parent, bd); 339 ID.AddPointer(contextData); 340 } 341 342 static bool classof(const LocationContext *Ctx) { 343 return Ctx->getKind() == Block; 344 } 345}; 346 347class LocationContextManager { 348 llvm::FoldingSet<LocationContext> Contexts; 349public: 350 ~LocationContextManager(); 351 352 const StackFrameContext *getStackFrame(AnalysisDeclContext *ctx, 353 const LocationContext *parent, 354 const Stmt *s, 355 const CFGBlock *blk, unsigned idx); 356 357 const ScopeContext *getScope(AnalysisDeclContext *ctx, 358 const LocationContext *parent, 359 const Stmt *s); 360 361 const BlockInvocationContext * 362 getBlockInvocationContext(AnalysisDeclContext *ctx, 363 const LocationContext *parent, 364 const BlockDecl *BD, 365 const void *ContextData); 366 367 /// Discard all previously created LocationContext objects. 368 void clear(); 369private: 370 template <typename LOC, typename DATA> 371 const LOC *getLocationContext(AnalysisDeclContext *ctx, 372 const LocationContext *parent, 373 const DATA *d); 374}; 375 376class AnalysisDeclContextManager { 377 typedef llvm::DenseMap<const Decl*, AnalysisDeclContext*> ContextMap; 378 379 ContextMap Contexts; 380 LocationContextManager LocContexts; 381 CFG::BuildOptions cfgBuildOptions; 382 383public: 384 AnalysisDeclContextManager(bool useUnoptimizedCFG = false, 385 bool addImplicitDtors = false, 386 bool addInitializers = false); 387 388 ~AnalysisDeclContextManager(); 389 390 AnalysisDeclContext *getContext(const Decl *D); 391 392 bool getUseUnoptimizedCFG() const { 393 return !cfgBuildOptions.PruneTriviallyFalseEdges; 394 } 395 396 CFG::BuildOptions &getCFGBuildOptions() { 397 return cfgBuildOptions; 398 } 399 400 const StackFrameContext *getStackFrame(AnalysisDeclContext *Ctx, 401 LocationContext const *Parent, 402 const Stmt *S, 403 const CFGBlock *Blk, 404 unsigned Idx) { 405 return LocContexts.getStackFrame(Ctx, Parent, S, Blk, Idx); 406 } 407 408 // Get the top level stack frame. 409 const StackFrameContext *getStackFrame(const Decl *D) { 410 return LocContexts.getStackFrame(getContext(D), 0, 0, 0, 0); 411 } 412 413 // Get a stack frame with parent. 414 StackFrameContext const *getStackFrame(const Decl *D, 415 LocationContext const *Parent, 416 const Stmt *S, 417 const CFGBlock *Blk, 418 unsigned Idx) { 419 return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx); 420 } 421 422 /// Discard all previously created AnalysisDeclContexts. 423 void clear(); 424 425private: 426 friend class AnalysisDeclContext; 427 428 LocationContextManager &getLocationContextManager() { 429 return LocContexts; 430 } 431}; 432 433} // end clang namespace 434#endif 435