1234287Sdim//== AnalysisDeclContext.cpp - Analysis context for Path Sens analysis -*- C++ -*-//
2234287Sdim//
3234287Sdim//                     The LLVM Compiler Infrastructure
4234287Sdim//
5234287Sdim// This file is distributed under the University of Illinois Open Source
6234287Sdim// License. See LICENSE.TXT for details.
7234287Sdim//
8234287Sdim//===----------------------------------------------------------------------===//
9234287Sdim//
10234287Sdim// This file defines AnalysisDeclContext, a class that manages the analysis context
11234287Sdim// data for path sensitive analysis.
12234287Sdim//
13234287Sdim//===----------------------------------------------------------------------===//
14234287Sdim
15249423Sdim#include "clang/Analysis/AnalysisContext.h"
16249423Sdim#include "BodyFarm.h"
17239462Sdim#include "clang/AST/ASTContext.h"
18234287Sdim#include "clang/AST/Decl.h"
19234287Sdim#include "clang/AST/DeclObjC.h"
20234287Sdim#include "clang/AST/DeclTemplate.h"
21234287Sdim#include "clang/AST/ParentMap.h"
22234287Sdim#include "clang/AST/StmtVisitor.h"
23249423Sdim#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
24234287Sdim#include "clang/Analysis/Analyses/LiveVariables.h"
25234287Sdim#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h"
26234287Sdim#include "clang/Analysis/CFG.h"
27234287Sdim#include "clang/Analysis/CFGStmtMap.h"
28234287Sdim#include "clang/Analysis/Support/BumpVector.h"
29234287Sdim#include "llvm/ADT/SmallPtrSet.h"
30234287Sdim#include "llvm/Support/ErrorHandling.h"
31249423Sdim#include "llvm/Support/raw_ostream.h"
32249423Sdim#include "llvm/Support/SaveAndRestore.h"
33234287Sdim
34234287Sdimusing namespace clang;
35234287Sdim
36234287Sdimtypedef llvm::DenseMap<const void *, ManagedAnalysis *> ManagedAnalysisMap;
37234287Sdim
38234287SdimAnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
39243830Sdim                                         const Decl *d,
40243830Sdim                                         const CFG::BuildOptions &buildOptions)
41234287Sdim  : Manager(Mgr),
42234287Sdim    D(d),
43234287Sdim    cfgBuildOptions(buildOptions),
44234287Sdim    forcedBlkExprs(0),
45234287Sdim    builtCFG(false),
46234287Sdim    builtCompleteCFG(false),
47234287Sdim    ReferencedBlockVars(0),
48234287Sdim    ManagedAnalyses(0)
49234287Sdim{
50234287Sdim  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
51234287Sdim}
52234287Sdim
53234287SdimAnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
54243830Sdim                                         const Decl *d)
55234287Sdim: Manager(Mgr),
56234287Sdim  D(d),
57234287Sdim  forcedBlkExprs(0),
58234287Sdim  builtCFG(false),
59234287Sdim  builtCompleteCFG(false),
60234287Sdim  ReferencedBlockVars(0),
61234287Sdim  ManagedAnalyses(0)
62234287Sdim{
63234287Sdim  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
64234287Sdim}
65234287Sdim
66234287SdimAnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG,
67243830Sdim                                                       bool addImplicitDtors,
68243830Sdim                                                       bool addInitializers,
69243830Sdim                                                       bool addTemporaryDtors,
70249423Sdim                                                       bool synthesizeBodies,
71249423Sdim                                                       bool addStaticInitBranch)
72243830Sdim  : SynthesizeBodies(synthesizeBodies)
73243830Sdim{
74234287Sdim  cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
75234287Sdim  cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
76234287Sdim  cfgBuildOptions.AddInitializers = addInitializers;
77243830Sdim  cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
78249423Sdim  cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
79234287Sdim}
80234287Sdim
81234287Sdimvoid AnalysisDeclContextManager::clear() {
82234287Sdim  for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I)
83234287Sdim    delete I->second;
84234287Sdim  Contexts.clear();
85234287Sdim}
86234287Sdim
87243830Sdimstatic BodyFarm &getBodyFarm(ASTContext &C) {
88243830Sdim  static BodyFarm *BF = new BodyFarm(C);
89243830Sdim  return *BF;
90243830Sdim}
91243830Sdim
92249423SdimStmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
93249423Sdim  IsAutosynthesized = false;
94243830Sdim  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
95243830Sdim    Stmt *Body = FD->getBody();
96249423Sdim    if (!Body && Manager && Manager->synthesizeBodies()) {
97249423Sdim      IsAutosynthesized = true;
98243830Sdim      return getBodyFarm(getASTContext()).getBody(FD);
99249423Sdim    }
100243830Sdim    return Body;
101243830Sdim  }
102234287Sdim  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
103234287Sdim    return MD->getBody();
104234287Sdim  else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
105234287Sdim    return BD->getBody();
106234287Sdim  else if (const FunctionTemplateDecl *FunTmpl
107234287Sdim           = dyn_cast_or_null<FunctionTemplateDecl>(D))
108234287Sdim    return FunTmpl->getTemplatedDecl()->getBody();
109234287Sdim
110234287Sdim  llvm_unreachable("unknown code decl");
111234287Sdim}
112234287Sdim
113249423SdimStmt *AnalysisDeclContext::getBody() const {
114249423Sdim  bool Tmp;
115249423Sdim  return getBody(Tmp);
116249423Sdim}
117249423Sdim
118249423Sdimbool AnalysisDeclContext::isBodyAutosynthesized() const {
119249423Sdim  bool Tmp;
120249423Sdim  getBody(Tmp);
121249423Sdim  return Tmp;
122249423Sdim}
123249423Sdim
124234287Sdimconst ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
125234287Sdim  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
126234287Sdim    return MD->getSelfDecl();
127234287Sdim  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
128234287Sdim    // See if 'self' was captured by the block.
129234287Sdim    for (BlockDecl::capture_const_iterator it = BD->capture_begin(),
130234287Sdim         et = BD->capture_end(); it != et; ++it) {
131234287Sdim      const VarDecl *VD = it->getVariable();
132234287Sdim      if (VD->getName() == "self")
133234287Sdim        return dyn_cast<ImplicitParamDecl>(VD);
134234287Sdim    }
135234287Sdim  }
136234287Sdim
137234287Sdim  return NULL;
138234287Sdim}
139234287Sdim
140234287Sdimvoid AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
141234287Sdim  if (!forcedBlkExprs)
142234287Sdim    forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
143234287Sdim  // Default construct an entry for 'stmt'.
144234287Sdim  if (const Expr *e = dyn_cast<Expr>(stmt))
145234287Sdim    stmt = e->IgnoreParens();
146234287Sdim  (void) (*forcedBlkExprs)[stmt];
147234287Sdim}
148234287Sdim
149234287Sdimconst CFGBlock *
150234287SdimAnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {
151234287Sdim  assert(forcedBlkExprs);
152234287Sdim  if (const Expr *e = dyn_cast<Expr>(stmt))
153234287Sdim    stmt = e->IgnoreParens();
154234287Sdim  CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
155234287Sdim    forcedBlkExprs->find(stmt);
156234287Sdim  assert(itr != forcedBlkExprs->end());
157234287Sdim  return itr->second;
158234287Sdim}
159234287Sdim
160263508Sdim/// Add each synthetic statement in the CFG to the parent map, using the
161263508Sdim/// source statement's parent.
162263508Sdimstatic void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
163263508Sdim  if (!TheCFG)
164263508Sdim    return;
165263508Sdim
166263508Sdim  for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(),
167263508Sdim                                    E = TheCFG->synthetic_stmt_end();
168263508Sdim       I != E; ++I) {
169263508Sdim    PM.setParent(I->first, PM.getParent(I->second));
170263508Sdim  }
171263508Sdim}
172263508Sdim
173234287SdimCFG *AnalysisDeclContext::getCFG() {
174234287Sdim  if (!cfgBuildOptions.PruneTriviallyFalseEdges)
175234287Sdim    return getUnoptimizedCFG();
176234287Sdim
177234287Sdim  if (!builtCFG) {
178234287Sdim    cfg.reset(CFG::buildCFG(D, getBody(),
179234287Sdim                            &D->getASTContext(), cfgBuildOptions));
180234287Sdim    // Even when the cfg is not successfully built, we don't
181234287Sdim    // want to try building it again.
182234287Sdim    builtCFG = true;
183263508Sdim
184263508Sdim    if (PM)
185263508Sdim      addParentsForSyntheticStmts(cfg.get(), *PM);
186234287Sdim  }
187234287Sdim  return cfg.get();
188234287Sdim}
189234287Sdim
190234287SdimCFG *AnalysisDeclContext::getUnoptimizedCFG() {
191234287Sdim  if (!builtCompleteCFG) {
192234287Sdim    SaveAndRestore<bool> NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges,
193234287Sdim                                  false);
194234287Sdim    completeCFG.reset(CFG::buildCFG(D, getBody(), &D->getASTContext(),
195234287Sdim                                    cfgBuildOptions));
196234287Sdim    // Even when the cfg is not successfully built, we don't
197234287Sdim    // want to try building it again.
198234287Sdim    builtCompleteCFG = true;
199263508Sdim
200263508Sdim    if (PM)
201263508Sdim      addParentsForSyntheticStmts(completeCFG.get(), *PM);
202234287Sdim  }
203234287Sdim  return completeCFG.get();
204234287Sdim}
205234287Sdim
206234287SdimCFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
207234287Sdim  if (cfgStmtMap)
208234287Sdim    return cfgStmtMap.get();
209234287Sdim
210234287Sdim  if (CFG *c = getCFG()) {
211234287Sdim    cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
212234287Sdim    return cfgStmtMap.get();
213234287Sdim  }
214234287Sdim
215234287Sdim  return 0;
216234287Sdim}
217234287Sdim
218234287SdimCFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
219234287Sdim  if (CFA)
220234287Sdim    return CFA.get();
221234287Sdim
222234287Sdim  if (CFG *c = getCFG()) {
223234287Sdim    CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
224234287Sdim    return CFA.get();
225234287Sdim  }
226234287Sdim
227234287Sdim  return 0;
228234287Sdim}
229234287Sdim
230234287Sdimvoid AnalysisDeclContext::dumpCFG(bool ShowColors) {
231234287Sdim    getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
232234287Sdim}
233234287Sdim
234234287SdimParentMap &AnalysisDeclContext::getParentMap() {
235239462Sdim  if (!PM) {
236234287Sdim    PM.reset(new ParentMap(getBody()));
237239462Sdim    if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
238239462Sdim      for (CXXConstructorDecl::init_const_iterator I = C->init_begin(),
239239462Sdim                                                   E = C->init_end();
240239462Sdim           I != E; ++I) {
241239462Sdim        PM->addStmt((*I)->getInit());
242239462Sdim      }
243239462Sdim    }
244263508Sdim    if (builtCFG)
245263508Sdim      addParentsForSyntheticStmts(getCFG(), *PM);
246263508Sdim    if (builtCompleteCFG)
247263508Sdim      addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);
248239462Sdim  }
249234287Sdim  return *PM;
250234287Sdim}
251234287Sdim
252234287SdimPseudoConstantAnalysis *AnalysisDeclContext::getPseudoConstantAnalysis() {
253234287Sdim  if (!PCA)
254234287Sdim    PCA.reset(new PseudoConstantAnalysis(getBody()));
255234287Sdim  return PCA.get();
256234287Sdim}
257234287Sdim
258239462SdimAnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
259243830Sdim  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
260243830Sdim    // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
261243830Sdim    // that has the body.
262243830Sdim    FD->hasBody(FD);
263243830Sdim    D = FD;
264243830Sdim  }
265243830Sdim
266234287Sdim  AnalysisDeclContext *&AC = Contexts[D];
267234287Sdim  if (!AC)
268239462Sdim    AC = new AnalysisDeclContext(this, D, cfgBuildOptions);
269234287Sdim  return AC;
270234287Sdim}
271234287Sdim
272234287Sdimconst StackFrameContext *
273234287SdimAnalysisDeclContext::getStackFrame(LocationContext const *Parent, const Stmt *S,
274234287Sdim                               const CFGBlock *Blk, unsigned Idx) {
275234287Sdim  return getLocationContextManager().getStackFrame(this, Parent, S, Blk, Idx);
276234287Sdim}
277234287Sdim
278239462Sdimconst BlockInvocationContext *
279239462SdimAnalysisDeclContext::getBlockInvocationContext(const LocationContext *parent,
280239462Sdim                                               const clang::BlockDecl *BD,
281239462Sdim                                               const void *ContextData) {
282239462Sdim  return getLocationContextManager().getBlockInvocationContext(this, parent,
283239462Sdim                                                               BD, ContextData);
284239462Sdim}
285239462Sdim
286234287SdimLocationContextManager & AnalysisDeclContext::getLocationContextManager() {
287234287Sdim  assert(Manager &&
288234287Sdim         "Cannot create LocationContexts without an AnalysisDeclContextManager!");
289234287Sdim  return Manager->getLocationContextManager();
290234287Sdim}
291234287Sdim
292234287Sdim//===----------------------------------------------------------------------===//
293234287Sdim// FoldingSet profiling.
294234287Sdim//===----------------------------------------------------------------------===//
295234287Sdim
296234287Sdimvoid LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
297234287Sdim                                    ContextKind ck,
298234287Sdim                                    AnalysisDeclContext *ctx,
299234287Sdim                                    const LocationContext *parent,
300234287Sdim                                    const void *data) {
301234287Sdim  ID.AddInteger(ck);
302234287Sdim  ID.AddPointer(ctx);
303234287Sdim  ID.AddPointer(parent);
304234287Sdim  ID.AddPointer(data);
305234287Sdim}
306234287Sdim
307234287Sdimvoid StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
308234287Sdim  Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block, Index);
309234287Sdim}
310234287Sdim
311234287Sdimvoid ScopeContext::Profile(llvm::FoldingSetNodeID &ID) {
312234287Sdim  Profile(ID, getAnalysisDeclContext(), getParent(), Enter);
313234287Sdim}
314234287Sdim
315234287Sdimvoid BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
316239462Sdim  Profile(ID, getAnalysisDeclContext(), getParent(), BD, ContextData);
317234287Sdim}
318234287Sdim
319234287Sdim//===----------------------------------------------------------------------===//
320234287Sdim// LocationContext creation.
321234287Sdim//===----------------------------------------------------------------------===//
322234287Sdim
323234287Sdimtemplate <typename LOC, typename DATA>
324234287Sdimconst LOC*
325234287SdimLocationContextManager::getLocationContext(AnalysisDeclContext *ctx,
326234287Sdim                                           const LocationContext *parent,
327234287Sdim                                           const DATA *d) {
328234287Sdim  llvm::FoldingSetNodeID ID;
329234287Sdim  LOC::Profile(ID, ctx, parent, d);
330234287Sdim  void *InsertPos;
331234287Sdim
332234287Sdim  LOC *L = cast_or_null<LOC>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
333234287Sdim
334234287Sdim  if (!L) {
335234287Sdim    L = new LOC(ctx, parent, d);
336234287Sdim    Contexts.InsertNode(L, InsertPos);
337234287Sdim  }
338234287Sdim  return L;
339234287Sdim}
340234287Sdim
341234287Sdimconst StackFrameContext*
342234287SdimLocationContextManager::getStackFrame(AnalysisDeclContext *ctx,
343234287Sdim                                      const LocationContext *parent,
344234287Sdim                                      const Stmt *s,
345234287Sdim                                      const CFGBlock *blk, unsigned idx) {
346234287Sdim  llvm::FoldingSetNodeID ID;
347234287Sdim  StackFrameContext::Profile(ID, ctx, parent, s, blk, idx);
348234287Sdim  void *InsertPos;
349234287Sdim  StackFrameContext *L =
350234287Sdim   cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
351234287Sdim  if (!L) {
352234287Sdim    L = new StackFrameContext(ctx, parent, s, blk, idx);
353234287Sdim    Contexts.InsertNode(L, InsertPos);
354234287Sdim  }
355234287Sdim  return L;
356234287Sdim}
357234287Sdim
358234287Sdimconst ScopeContext *
359234287SdimLocationContextManager::getScope(AnalysisDeclContext *ctx,
360234287Sdim                                 const LocationContext *parent,
361234287Sdim                                 const Stmt *s) {
362234287Sdim  return getLocationContext<ScopeContext, Stmt>(ctx, parent, s);
363234287Sdim}
364234287Sdim
365239462Sdimconst BlockInvocationContext *
366239462SdimLocationContextManager::getBlockInvocationContext(AnalysisDeclContext *ctx,
367239462Sdim                                                  const LocationContext *parent,
368239462Sdim                                                  const BlockDecl *BD,
369239462Sdim                                                  const void *ContextData) {
370239462Sdim  llvm::FoldingSetNodeID ID;
371239462Sdim  BlockInvocationContext::Profile(ID, ctx, parent, BD, ContextData);
372239462Sdim  void *InsertPos;
373239462Sdim  BlockInvocationContext *L =
374239462Sdim    cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
375239462Sdim                                                                    InsertPos));
376239462Sdim  if (!L) {
377239462Sdim    L = new BlockInvocationContext(ctx, parent, BD, ContextData);
378239462Sdim    Contexts.InsertNode(L, InsertPos);
379239462Sdim  }
380239462Sdim  return L;
381239462Sdim}
382239462Sdim
383234287Sdim//===----------------------------------------------------------------------===//
384234287Sdim// LocationContext methods.
385234287Sdim//===----------------------------------------------------------------------===//
386234287Sdim
387234287Sdimconst StackFrameContext *LocationContext::getCurrentStackFrame() const {
388234287Sdim  const LocationContext *LC = this;
389234287Sdim  while (LC) {
390234287Sdim    if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC))
391234287Sdim      return SFC;
392234287Sdim    LC = LC->getParent();
393234287Sdim  }
394234287Sdim  return NULL;
395234287Sdim}
396234287Sdim
397243830Sdimbool LocationContext::inTopFrame() const {
398243830Sdim  return getCurrentStackFrame()->inTopFrame();
399243830Sdim}
400243830Sdim
401234287Sdimbool LocationContext::isParentOf(const LocationContext *LC) const {
402234287Sdim  do {
403234287Sdim    const LocationContext *Parent = LC->getParent();
404234287Sdim    if (Parent == this)
405234287Sdim      return true;
406234287Sdim    else
407234287Sdim      LC = Parent;
408234287Sdim  } while (LC);
409234287Sdim
410234287Sdim  return false;
411234287Sdim}
412234287Sdim
413263508Sdimvoid LocationContext::dumpStack(raw_ostream &OS, StringRef Indent) const {
414249423Sdim  ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
415249423Sdim  PrintingPolicy PP(Ctx.getLangOpts());
416249423Sdim  PP.TerseOutput = 1;
417249423Sdim
418249423Sdim  unsigned Frame = 0;
419249423Sdim  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
420249423Sdim    switch (LCtx->getKind()) {
421249423Sdim    case StackFrame:
422263508Sdim      OS << Indent << '#' << Frame++ << ' ';
423263508Sdim      cast<StackFrameContext>(LCtx)->getDecl()->print(OS, PP);
424263508Sdim      OS << '\n';
425249423Sdim      break;
426249423Sdim    case Scope:
427263508Sdim      OS << Indent << "    (scope)\n";
428249423Sdim      break;
429249423Sdim    case Block:
430263508Sdim      OS << Indent << "    (block context: "
431249423Sdim                   << cast<BlockInvocationContext>(LCtx)->getContextData()
432249423Sdim                   << ")\n";
433249423Sdim      break;
434249423Sdim    }
435249423Sdim  }
436249423Sdim}
437249423Sdim
438263508Sdimvoid LocationContext::dumpStack() const {
439263508Sdim  dumpStack(llvm::errs());
440263508Sdim}
441263508Sdim
442234287Sdim//===----------------------------------------------------------------------===//
443234287Sdim// Lazily generated map to query the external variables referenced by a Block.
444234287Sdim//===----------------------------------------------------------------------===//
445234287Sdim
446234287Sdimnamespace {
447234287Sdimclass FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
448234287Sdim  BumpVector<const VarDecl*> &BEVals;
449234287Sdim  BumpVectorContext &BC;
450234287Sdim  llvm::SmallPtrSet<const VarDecl*, 4> Visited;
451234287Sdim  llvm::SmallPtrSet<const DeclContext*, 4> IgnoredContexts;
452234287Sdimpublic:
453234287Sdim  FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
454234287Sdim                            BumpVectorContext &bc)
455234287Sdim  : BEVals(bevals), BC(bc) {}
456234287Sdim
457234287Sdim  bool IsTrackedDecl(const VarDecl *VD) {
458234287Sdim    const DeclContext *DC = VD->getDeclContext();
459234287Sdim    return IgnoredContexts.count(DC) == 0;
460234287Sdim  }
461234287Sdim
462234287Sdim  void VisitStmt(Stmt *S) {
463234287Sdim    for (Stmt::child_range I = S->children(); I; ++I)
464234287Sdim      if (Stmt *child = *I)
465234287Sdim        Visit(child);
466234287Sdim  }
467234287Sdim
468234287Sdim  void VisitDeclRefExpr(DeclRefExpr *DR) {
469234287Sdim    // Non-local variables are also directly modified.
470234287Sdim    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
471234287Sdim      if (!VD->hasLocalStorage()) {
472234287Sdim        if (Visited.insert(VD))
473234287Sdim          BEVals.push_back(VD, BC);
474234287Sdim      }
475234287Sdim    }
476234287Sdim  }
477234287Sdim
478234287Sdim  void VisitBlockExpr(BlockExpr *BR) {
479234287Sdim    // Blocks containing blocks can transitively capture more variables.
480234287Sdim    IgnoredContexts.insert(BR->getBlockDecl());
481234287Sdim    Visit(BR->getBlockDecl()->getBody());
482234287Sdim  }
483234287Sdim
484234287Sdim  void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
485234287Sdim    for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(),
486234287Sdim         et = PE->semantics_end(); it != et; ++it) {
487234287Sdim      Expr *Semantic = *it;
488234287Sdim      if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
489234287Sdim        Semantic = OVE->getSourceExpr();
490234287Sdim      Visit(Semantic);
491234287Sdim    }
492234287Sdim  }
493234287Sdim};
494234287Sdim} // end anonymous namespace
495234287Sdim
496234287Sdimtypedef BumpVector<const VarDecl*> DeclVec;
497234287Sdim
498234287Sdimstatic DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,
499234287Sdim                                              void *&Vec,
500234287Sdim                                              llvm::BumpPtrAllocator &A) {
501234287Sdim  if (Vec)
502234287Sdim    return (DeclVec*) Vec;
503234287Sdim
504234287Sdim  BumpVectorContext BC(A);
505234287Sdim  DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
506234287Sdim  new (BV) DeclVec(BC, 10);
507234287Sdim
508249423Sdim  // Go through the capture list.
509249423Sdim  for (BlockDecl::capture_const_iterator CI = BD->capture_begin(),
510249423Sdim       CE = BD->capture_end(); CI != CE; ++CI) {
511249423Sdim    BV->push_back(CI->getVariable(), BC);
512249423Sdim  }
513249423Sdim
514249423Sdim  // Find the referenced global/static variables.
515234287Sdim  FindBlockDeclRefExprsVals F(*BV, BC);
516234287Sdim  F.Visit(BD->getBody());
517234287Sdim
518234287Sdim  Vec = BV;
519234287Sdim  return BV;
520234287Sdim}
521234287Sdim
522234287Sdimstd::pair<AnalysisDeclContext::referenced_decls_iterator,
523234287Sdim          AnalysisDeclContext::referenced_decls_iterator>
524234287SdimAnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {
525234287Sdim  if (!ReferencedBlockVars)
526234287Sdim    ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
527234287Sdim
528234287Sdim  DeclVec *V = LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
529234287Sdim  return std::make_pair(V->begin(), V->end());
530234287Sdim}
531234287Sdim
532234287SdimManagedAnalysis *&AnalysisDeclContext::getAnalysisImpl(const void *tag) {
533234287Sdim  if (!ManagedAnalyses)
534234287Sdim    ManagedAnalyses = new ManagedAnalysisMap();
535234287Sdim  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
536234287Sdim  return (*M)[tag];
537234287Sdim}
538234287Sdim
539234287Sdim//===----------------------------------------------------------------------===//
540234287Sdim// Cleanup.
541234287Sdim//===----------------------------------------------------------------------===//
542234287Sdim
543234287SdimManagedAnalysis::~ManagedAnalysis() {}
544234287Sdim
545234287SdimAnalysisDeclContext::~AnalysisDeclContext() {
546234287Sdim  delete forcedBlkExprs;
547234287Sdim  delete ReferencedBlockVars;
548234287Sdim  // Release the managed analyses.
549234287Sdim  if (ManagedAnalyses) {
550234287Sdim    ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
551234287Sdim    for (ManagedAnalysisMap::iterator I = M->begin(), E = M->end(); I!=E; ++I)
552234287Sdim      delete I->second;
553234287Sdim    delete M;
554234287Sdim  }
555234287Sdim}
556234287Sdim
557234287SdimAnalysisDeclContextManager::~AnalysisDeclContextManager() {
558234287Sdim  for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I)
559234287Sdim    delete I->second;
560234287Sdim}
561234287Sdim
562234287SdimLocationContext::~LocationContext() {}
563234287Sdim
564234287SdimLocationContextManager::~LocationContextManager() {
565234287Sdim  clear();
566234287Sdim}
567234287Sdim
568234287Sdimvoid LocationContextManager::clear() {
569234287Sdim  for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
570234287Sdim       E = Contexts.end(); I != E; ) {
571234287Sdim    LocationContext *LC = &*I;
572234287Sdim    ++I;
573234287Sdim    delete LC;
574234287Sdim  }
575234287Sdim
576234287Sdim  Contexts.clear();
577234287Sdim}
578234287Sdim
579