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