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