AnalysisContext.h revision a43df9539644bf1c258e12710cd69d79b0b078cd
1659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- C++ -*-//
243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//                     The LLVM Compiler Infrastructure
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This file is distributed under the University of Illinois Open Source
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// License. See LICENSE.TXT for details.
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//===----------------------------------------------------------------------===//
943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This file defines AnalysisDeclContext, a class that manages the analysis
1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// context data for path sensitive analysis.
1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//===----------------------------------------------------------------------===//
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "clang/AST/Decl.h"
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "clang/AST/Expr.h"
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "clang/Analysis/CFG.h"
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/ADT/OwningPtr.h"
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/ADT/IntrusiveRefCntPtr.h"
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/ADT/FoldingSet.h"
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/ADT/PointerUnion.h"
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/ADT/DenseMap.h"
2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "llvm/Support/Allocator.h"
2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansennamespace clang {
2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Decl;
311c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.orgclass Stmt;
32c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comclass CFGReverseBlockReachabilityAnalysis;
33ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgclass CFGStmtMap;
349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comclass LiveVariables;
3571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgclass ManagedAnalysis;
3671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgclass ParentMap;
3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass PseudoConstantAnalysis;
38659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgclass ImplicitParamDecl;
39659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgclass LocationContextManager;
40a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgclass StackFrameContext;
41659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgclass BlockInvocationContext;
42659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.orgclass AnalysisDeclContextManager;
43ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comclass LocationContext;
44a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansennamespace idx { class TranslationUnit; }
4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org/// The base class of a hierarchy of objects representing analyses tied
4868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org/// to AnalysisDeclContext.
49c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.orgclass ManagedAnalysis {
5068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.orgprotected:
51c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  ManagedAnalysis() {}
52c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.orgpublic:
53bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  virtual ~ManagedAnalysis();
54bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
5568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  // Subclasses need to implement:
5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //  static const void *getTag();
589a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  //
599a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Which returns a fixed pointer address to distinguish classes of
6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // analysis objects.  They also need to implement:
6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //  static [Derived*] create(AnalysisDeclContext &Ctx);
6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  //
6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // which creates the analysis object given an AnalysisDeclContext.
6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
688bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org/// AnalysisDeclContext contains the context data for the function or method
698bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org/// under analysis.
708bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgclass AnalysisDeclContext {
717be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  /// Backpoint to the AnalysisManager object that created this
7241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  /// AnalysisDeclContext. This may be null.
7341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  AnalysisDeclContextManager *Manager;
745a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
755a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  const Decl * const D;
7643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  OwningPtr<CFG> cfg, completeCFG;
7843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  OwningPtr<CFGStmtMap> cfgStmtMap;
7941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
8041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  CFG::BuildOptions cfgBuildOptions;
817be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
825a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org
8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool builtCFG, builtCompleteCFG;
848bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  OwningPtr<ParentMap> PM;
85cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  OwningPtr<PseudoConstantAnalysis> PCA;
86cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  OwningPtr<CFGReverseBlockReachabilityAnalysis> CFA;
87cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
88cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  llvm::BumpPtrAllocator A;
89a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
90a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
917be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
927be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  void *ManagedAnalyses;
937be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
947be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgpublic:
957be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
96355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                  const Decl *D);
97355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
98355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
99355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                  const Decl *D,
100355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                  const CFG::BuildOptions &BuildOptions);
101355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
102355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  ~AnalysisDeclContext();
103355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
10441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  ASTContext &getASTContext() const { return D->getASTContext(); }
10541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  const Decl *getDecl() const { return D; }
1067be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
1077be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  /// Return the build options used to construct the CFG.
10841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  CFG::BuildOptions &getCFGBuildOptions() {
109cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    return cfgBuildOptions;
110cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  }
111cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
112cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  const CFG::BuildOptions &getCFGBuildOptions() const {
113cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    return cfgBuildOptions;
114cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  }
115cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
116355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  /// getAddEHEdges - Return true iff we are adding exceptional edges from
117cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  /// callExprs.  If this is false, then try/catch statements and blocks
118cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  /// reachable from them can appear to be dead in the CFG, analysis passes must
1195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  /// cope with that.
120cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; }
12115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org  bool getUseUnoptimizedCFG() const {
12215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org      return !cfgBuildOptions.PruneTriviallyFalseEdges;
12315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org  }
12415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org  bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
125cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }
126cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
12715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org  void registerForcedBlockExpression(const Stmt *stmt);
12815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org  const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);
12915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org
130355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  Stmt *getBody() const;
131355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  CFG *getCFG();
132cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
133a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  CFGStmtMap *getCFGStmtMap();
13441826e77311db718135ef6517b846933dfd275f3ager@chromium.org
135355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis();
13641826e77311db718135ef6517b846933dfd275f3ager@chromium.org
137a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  /// Return a version of the CFG without any edges pruned.
138a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  CFG *getUnoptimizedCFG();
1397be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
1405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  void dumpCFG(bool ShowColors);
141a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
142355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  /// \brief Returns true if we have built a CFG for this analysis context.
143355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  /// Note that this doesn't correspond to whether or not a valid CFG exists, it
144355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  /// corresponds to whether we *attempted* to build one.
145355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  bool isCFGBuilt() const { return builtCFG; }
146355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
147355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  ParentMap &getParentMap();
148355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  PseudoConstantAnalysis *getPseudoConstantAnalysis();
149355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
150355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  typedef const VarDecl * const * referenced_decls_iterator;
151355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
152355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  std::pair<referenced_decls_iterator, referenced_decls_iterator>
153355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    getReferencedBlockVars(const BlockDecl *BD);
154355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
155355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  /// Return the ImplicitParamDecl* associated with 'self' if this
156355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  /// AnalysisDeclContext wraps an ObjCMethodDecl.  Returns NULL otherwise.
157355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  const ImplicitParamDecl *getSelfDecl() const;
158355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
159355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  const StackFrameContext *getStackFrame(LocationContext const *Parent,
160355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                         const Stmt *S,
161355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                         const CFGBlock *Blk,
162355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                                         unsigned Idx);
163355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
164355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  const BlockInvocationContext *
165355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  getBlockInvocationContext(const LocationContext *parent,
166355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                            const BlockDecl *BD,
167355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org                            const void *ContextData);
168355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
169355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  /// Return the specified analysis object, lazily running the analysis if
170355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  /// necessary.  Return NULL if the analysis could not run.
171355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  template <typename T>
172355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  T *getAnalysis() {
173355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    const void *tag = T::getTag();
174355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    ManagedAnalysis *&data = getAnalysisImpl(tag);
175355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    if (!data) {
176355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org      data = T::create(*this);
177355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    }
178355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    return static_cast<T*>(data);
179355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  }
180355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgprivate:
1810c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  ManagedAnalysis *&getAnalysisImpl(const void* tag);
1827be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
1837be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  LocationContextManager &getLocationContextManager();
1847be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org};
185bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
1867be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgclass LocationContext : public llvm::FoldingSetNode {
1877be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgpublic:
1880c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  enum ContextKind { StackFrame, Scope, Block };
1890c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
1900c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgprivate:
1910c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  ContextKind Kind;
1920c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
1930c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // AnalysisDeclContext can't be const since some methods may modify its
1940c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // member.
1950c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  AnalysisDeclContext *Ctx;
1960c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
1970c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  const LocationContext *Parent;
198bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
1997be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgprotected:
2007be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  LocationContext(ContextKind k, AnalysisDeclContext *ctx,
2017be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org                  const LocationContext *parent)
2027be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    : Kind(k), Ctx(ctx), Parent(parent) {}
2037be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
2047be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.orgpublic:
2057be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  virtual ~LocationContext();
2067be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
2077be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  ContextKind getKind() const { return Kind; }
208bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
2097be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; }
2107be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
2117be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  const LocationContext *getParent() const { return Parent; }
212bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
2137be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  bool isParentOf(const LocationContext *LC) const;
2147be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
2157be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  const Decl *getDecl() const { return getAnalysisDeclContext()->getDecl(); }
2167be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
2177be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  CFG *getCFG() const { return getAnalysisDeclContext()->getCFG(); }
218a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
219bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  template <typename T>
220bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  T *getAnalysis() const {
221bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    return getAnalysisDeclContext()->getAnalysis<T>();
2227be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  }
223bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
2247be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  ParentMap &getParentMap() const {
2257be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    return getAnalysisDeclContext()->getParentMap();
2267be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  }
2277be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
2287be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  const ImplicitParamDecl *getSelfDecl() const {
2297be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    return Ctx->getSelfDecl();
23043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
23183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
23283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  const StackFrameContext *getCurrentStackFrame() const;
23383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
23483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
23583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
23683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  static bool classof(const LocationContext*) { return true; }
23783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
23883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgpublic:
239bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  static void ProfileCommon(llvm::FoldingSetNodeID &ID,
2407d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org                            ContextKind ck,
2415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                            AnalysisDeclContext *ctx,
2427d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org                            const LocationContext *parent,
2435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                            const void *data);
24443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
24543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass StackFrameContext : public LocationContext {
2470c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // The callsite where this stack frame is established.
2480c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  const Stmt *CallSite;
2490c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2500c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // The parent block of the callsite.
2510c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  const CFGBlock *Block;
2520c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2530c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // The index of the callsite in the CFGBlock.
2540c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  unsigned Index;
2550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2560c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  friend class LocationContextManager;
2571044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org  StackFrameContext(AnalysisDeclContext *ctx, const LocationContext *parent,
2581044a4d5f9e933d03cf05a0d7d49d8afccec0879danno@chromium.org                    const Stmt *s, const CFGBlock *blk,
259a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                    unsigned idx)
260a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    : LocationContext(StackFrame, ctx, parent), CallSite(s),
261a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      Block(blk), Index(idx) {}
262a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
263a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgpublic:
264a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ~StackFrameContext() {}
2657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
2667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  const Stmt *getCallSite() const { return CallSite; }
267ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
268a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  const CFGBlock *getCallSiteBlock() const { return Block; }
269a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
270a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  unsigned getIndex() const { return Index; }
271a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
272a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void Profile(llvm::FoldingSetNodeID &ID);
273a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
274a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
275a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                      const LocationContext *parent, const Stmt *s,
276a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                      const CFGBlock *blk, unsigned idx) {
277a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    ProfileCommon(ID, StackFrame, ctx, parent, s);
278a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    ID.AddPointer(blk);
279a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    ID.AddInteger(idx);
280a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
281a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
282a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  static bool classof(const LocationContext *Ctx) {
283a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return Ctx->getKind() == StackFrame;
2848bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  }
285a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org};
2867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
2877028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.orgclass ScopeContext : public LocationContext {
288a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  const Stmt *Enter;
289ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
290a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  friend class LocationContextManager;
2917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent,
2927028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org               const Stmt *s)
2930c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    : LocationContext(Scope, ctx, parent), Enter(s) {}
2940c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2950c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgpublic:
2960c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  ~ScopeContext() {}
2970c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2980c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void Profile(llvm::FoldingSetNodeID &ID);
2990c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3000c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
3010c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org                      const LocationContext *parent, const Stmt *s) {
3020c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    ProfileCommon(ID, Scope, ctx, parent, s);
3037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
3047028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
305a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  static bool classof(const LocationContext *Ctx) {
306a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return Ctx->getKind() == Scope;
307a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
308a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org};
309a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
310a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgclass BlockInvocationContext : public LocationContext {
311a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  const BlockDecl *BD;
312a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
313a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // FIXME: Come up with a more type-safe way to model context-sensitivity.
314a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  const void *ContextData;
315a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
316a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  friend class LocationContextManager;
317a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
318a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  BlockInvocationContext(AnalysisDeclContext *ctx,
3197028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                         const LocationContext *parent,
320a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                         const BlockDecl *bd, const void *contextData)
321a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    : LocationContext(Block, ctx, parent), BD(bd), ContextData(contextData) {}
322a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
323a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgpublic:
324a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ~BlockInvocationContext() {}
325a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
326a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  const BlockDecl *getBlockDecl() const { return BD; }
3277028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
328a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  const void *getContextData() const { return ContextData; }
329a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
330a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void Profile(llvm::FoldingSetNodeID &ID);
331a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
3327028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
333a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                      const LocationContext *parent, const BlockDecl *bd,
334a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                      const void *contextData) {
335a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    ProfileCommon(ID, Block, ctx, parent, bd);
336a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    ID.AddPointer(contextData);
337a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
338a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
3393291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  static bool classof(const LocationContext *Ctx) {
340a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return Ctx->getKind() == Block;
341a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
342a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org};
343a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
344a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgclass LocationContextManager {
345a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  llvm::FoldingSet<LocationContext> Contexts;
346a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgpublic:
3477028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  ~LocationContextManager();
3487028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
349a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  const StackFrameContext *getStackFrame(AnalysisDeclContext *ctx,
350a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                         const LocationContext *parent,
351a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                         const Stmt *s,
352a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                         const CFGBlock *blk, unsigned idx);
353a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
354a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  const ScopeContext *getScope(AnalysisDeclContext *ctx,
355a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                               const LocationContext *parent,
356a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                               const Stmt *s);
3577028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
3587028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  const BlockInvocationContext *
3597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  getBlockInvocationContext(AnalysisDeclContext *ctx,
360a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                            const LocationContext *parent,
361a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                            const BlockDecl *BD,
362a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                            const void *ContextData);
363a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
364a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  /// Discard all previously created LocationContext objects.
365a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void clear();
366a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgprivate:
367a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  template <typename LOC, typename DATA>
368a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  const LOC *getLocationContext(AnalysisDeclContext *ctx,
369a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                const LocationContext *parent,
370a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                const DATA *d);
371a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org};
372a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
373a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgclass AnalysisDeclContextManager {
374a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  typedef llvm::DenseMap<const Decl*, AnalysisDeclContext*> ContextMap;
375a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
376a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  ContextMap Contexts;
377a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  LocationContextManager LocContexts;
378a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  CFG::BuildOptions cfgBuildOptions;
379a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
380a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  /// Flag to indicate whether or not bodies should be synthesized
381a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  /// for well-known functions.
382a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  bool SynthesizeBodies;
3837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
384a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgpublic:
385a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  AnalysisDeclContextManager(bool useUnoptimizedCFG = false,
386a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                             bool addImplicitDtors = false,
387a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                             bool addInitializers = false,
3887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                             bool addTemporaryDtors = false,
3897028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                             bool synthesizeBodies = false);
3907028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
39183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  ~AnalysisDeclContextManager();
392a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
393a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  AnalysisDeclContext *getContext(const Decl *D);
394a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
395a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  bool getUseUnoptimizedCFG() const {
396a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return !cfgBuildOptions.PruneTriviallyFalseEdges;
397a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
398a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
399a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  CFG::BuildOptions &getCFGBuildOptions() {
400a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return cfgBuildOptions;
401a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
402a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
403a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  /// Return true if faux bodies should be synthesized for well-known
404a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  /// functions.
405a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  bool synthesizeBodies() const { return SynthesizeBodies; }
406a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
407ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  const StackFrameContext *getStackFrame(AnalysisDeclContext *Ctx,
408a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                         LocationContext const *Parent,
409a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                         const Stmt *S,
410a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                         const CFGBlock *Blk,
411a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                         unsigned Idx) {
412a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return LocContexts.getStackFrame(Ctx, Parent, S, Blk, Idx);
413a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
414a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
415a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // Get the top level stack frame.
416a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  const StackFrameContext *getStackFrame(const Decl *D) {
417a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return LocContexts.getStackFrame(getContext(D), 0, 0, 0, 0);
418a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
419a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
420a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // Get a stack frame with parent.
421a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  StackFrameContext const *getStackFrame(const Decl *D,
422a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                         LocationContext const *Parent,
423a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                         const Stmt *S,
424a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                         const CFGBlock *Blk,
425a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                         unsigned Idx) {
426a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx);
427a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
428a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
429a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  /// Discard all previously created AnalysisDeclContexts.
430a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void clear();
431a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
432a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgprivate:
433a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  friend class AnalysisDeclContext;
4348bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
435a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  LocationContextManager &getLocationContextManager() {
436a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return LocContexts;
43737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  }
438a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org};
439a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
440a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} // end clang namespace
441a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#endif
442a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org