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