1//===- AnalysisDeclContext.cpp - Analysis context for Path Sens analysis --===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines AnalysisDeclContext, a class that manages the analysis
10// context data for path sensitive analysis.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Analysis/AnalysisDeclContext.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclBase.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/AST/DeclTemplate.h"
21#include "clang/AST/Expr.h"
22#include "clang/AST/LambdaCapture.h"
23#include "clang/AST/ParentMap.h"
24#include "clang/AST/PrettyPrinter.h"
25#include "clang/AST/Stmt.h"
26#include "clang/AST/StmtCXX.h"
27#include "clang/AST/StmtVisitor.h"
28#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
29#include "clang/Analysis/BodyFarm.h"
30#include "clang/Analysis/CFG.h"
31#include "clang/Analysis/CFGStmtMap.h"
32#include "clang/Analysis/Support/BumpVector.h"
33#include "clang/Basic/JsonSupport.h"
34#include "clang/Basic/LLVM.h"
35#include "clang/Basic/SourceLocation.h"
36#include "clang/Basic/SourceManager.h"
37#include "llvm/ADT/DenseMap.h"
38#include "llvm/ADT/FoldingSet.h"
39#include "llvm/ADT/STLExtras.h"
40#include "llvm/ADT/SmallPtrSet.h"
41#include "llvm/ADT/iterator_range.h"
42#include "llvm/Support/Allocator.h"
43#include "llvm/Support/Casting.h"
44#include "llvm/Support/Compiler.h"
45#include "llvm/Support/ErrorHandling.h"
46#include "llvm/Support/SaveAndRestore.h"
47#include "llvm/Support/raw_ostream.h"
48#include <cassert>
49#include <memory>
50
51using namespace clang;
52
53using ManagedAnalysisMap = llvm::DenseMap<const void *, std::unique_ptr<ManagedAnalysis>>;
54
55AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
56                                         const Decl *D,
57                                         const CFG::BuildOptions &Options)
58    : ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {
59  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
60}
61
62AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
63                                         const Decl *D)
64    : ADCMgr(ADCMgr), D(D) {
65  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
66}
67
68AnalysisDeclContextManager::AnalysisDeclContextManager(
69    ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors,
70    bool addInitializers, bool addTemporaryDtors, bool addLifetime,
71    bool addLoopExit, bool addScopes, bool synthesizeBodies,
72    bool addStaticInitBranch, bool addCXXNewAllocator,
73    bool addRichCXXConstructors, bool markElidedCXXConstructors,
74    bool addVirtualBaseBranches, CodeInjector *injector)
75    : Injector(injector), FunctionBodyFarm(ASTCtx, injector),
76      SynthesizeBodies(synthesizeBodies) {
77  cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
78  cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
79  cfgBuildOptions.AddInitializers = addInitializers;
80  cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
81  cfgBuildOptions.AddLifetime = addLifetime;
82  cfgBuildOptions.AddLoopExit = addLoopExit;
83  cfgBuildOptions.AddScopes = addScopes;
84  cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
85  cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
86  cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;
87  cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;
88  cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;
89}
90
91void AnalysisDeclContextManager::clear() { Contexts.clear(); }
92
93Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
94  IsAutosynthesized = false;
95  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
96    Stmt *Body = FD->getBody();
97    if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
98      Body = CoroBody->getBody();
99    if (ADCMgr && ADCMgr->synthesizeBodies()) {
100      Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);
101      if (SynthesizedBody) {
102        Body = SynthesizedBody;
103        IsAutosynthesized = true;
104      }
105    }
106    return Body;
107  }
108  else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
109    Stmt *Body = MD->getBody();
110    if (ADCMgr && ADCMgr->synthesizeBodies()) {
111      Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(MD);
112      if (SynthesizedBody) {
113        Body = SynthesizedBody;
114        IsAutosynthesized = true;
115      }
116    }
117    return Body;
118  } else if (const auto *BD = dyn_cast<BlockDecl>(D))
119    return BD->getBody();
120  else if (const auto *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
121    return FunTmpl->getTemplatedDecl()->getBody();
122
123  llvm_unreachable("unknown code decl");
124}
125
126Stmt *AnalysisDeclContext::getBody() const {
127  bool Tmp;
128  return getBody(Tmp);
129}
130
131bool AnalysisDeclContext::isBodyAutosynthesized() const {
132  bool Tmp;
133  getBody(Tmp);
134  return Tmp;
135}
136
137bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const {
138  bool Tmp;
139  Stmt *Body = getBody(Tmp);
140  return Tmp && Body->getBeginLoc().isValid();
141}
142
143/// Returns true if \param VD is an Objective-C implicit 'self' parameter.
144static bool isSelfDecl(const VarDecl *VD) {
145  return isa<ImplicitParamDecl>(VD) && VD->getName() == "self";
146}
147
148const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
149  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
150    return MD->getSelfDecl();
151  if (const auto *BD = dyn_cast<BlockDecl>(D)) {
152    // See if 'self' was captured by the block.
153    for (const auto &I : BD->captures()) {
154      const VarDecl *VD = I.getVariable();
155      if (isSelfDecl(VD))
156        return dyn_cast<ImplicitParamDecl>(VD);
157    }
158  }
159
160  auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
161  if (!CXXMethod)
162    return nullptr;
163
164  const CXXRecordDecl *parent = CXXMethod->getParent();
165  if (!parent->isLambda())
166    return nullptr;
167
168  for (const auto &LC : parent->captures()) {
169    if (!LC.capturesVariable())
170      continue;
171
172    VarDecl *VD = LC.getCapturedVar();
173    if (isSelfDecl(VD))
174      return dyn_cast<ImplicitParamDecl>(VD);
175  }
176
177  return nullptr;
178}
179
180void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
181  if (!forcedBlkExprs)
182    forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
183  // Default construct an entry for 'stmt'.
184  if (const auto *e = dyn_cast<Expr>(stmt))
185    stmt = e->IgnoreParens();
186  (void) (*forcedBlkExprs)[stmt];
187}
188
189const CFGBlock *
190AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {
191  assert(forcedBlkExprs);
192  if (const auto *e = dyn_cast<Expr>(stmt))
193    stmt = e->IgnoreParens();
194  CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
195    forcedBlkExprs->find(stmt);
196  assert(itr != forcedBlkExprs->end());
197  return itr->second;
198}
199
200/// Add each synthetic statement in the CFG to the parent map, using the
201/// source statement's parent.
202static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
203  if (!TheCFG)
204    return;
205
206  for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(),
207                                    E = TheCFG->synthetic_stmt_end();
208       I != E; ++I) {
209    PM.setParent(I->first, PM.getParent(I->second));
210  }
211}
212
213CFG *AnalysisDeclContext::getCFG() {
214  if (!cfgBuildOptions.PruneTriviallyFalseEdges)
215    return getUnoptimizedCFG();
216
217  if (!builtCFG) {
218    cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
219    // Even when the cfg is not successfully built, we don't
220    // want to try building it again.
221    builtCFG = true;
222
223    if (PM)
224      addParentsForSyntheticStmts(cfg.get(), *PM);
225
226    // The Observer should only observe one build of the CFG.
227    getCFGBuildOptions().Observer = nullptr;
228  }
229  return cfg.get();
230}
231
232CFG *AnalysisDeclContext::getUnoptimizedCFG() {
233  if (!builtCompleteCFG) {
234    SaveAndRestore<bool> NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges,
235                                  false);
236    completeCFG =
237        CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
238    // Even when the cfg is not successfully built, we don't
239    // want to try building it again.
240    builtCompleteCFG = true;
241
242    if (PM)
243      addParentsForSyntheticStmts(completeCFG.get(), *PM);
244
245    // The Observer should only observe one build of the CFG.
246    getCFGBuildOptions().Observer = nullptr;
247  }
248  return completeCFG.get();
249}
250
251CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
252  if (cfgStmtMap)
253    return cfgStmtMap.get();
254
255  if (CFG *c = getCFG()) {
256    cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
257    return cfgStmtMap.get();
258  }
259
260  return nullptr;
261}
262
263CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
264  if (CFA)
265    return CFA.get();
266
267  if (CFG *c = getCFG()) {
268    CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
269    return CFA.get();
270  }
271
272  return nullptr;
273}
274
275void AnalysisDeclContext::dumpCFG(bool ShowColors) {
276  getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
277}
278
279ParentMap &AnalysisDeclContext::getParentMap() {
280  if (!PM) {
281    PM.reset(new ParentMap(getBody()));
282    if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
283      for (const auto *I : C->inits()) {
284        PM->addStmt(I->getInit());
285      }
286    }
287    if (builtCFG)
288      addParentsForSyntheticStmts(getCFG(), *PM);
289    if (builtCompleteCFG)
290      addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);
291  }
292  return *PM;
293}
294
295AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
296  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
297    // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
298    // that has the body.
299    FD->hasBody(FD);
300    D = FD;
301  }
302
303  std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
304  if (!AC)
305    AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
306  return AC.get();
307}
308
309BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; }
310
311const StackFrameContext *
312AnalysisDeclContext::getStackFrame(const LocationContext *ParentLC,
313                                   const Stmt *S, const CFGBlock *Blk,
314                                   unsigned BlockCount, unsigned Index) {
315  return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,
316                                                   BlockCount, Index);
317}
318
319const BlockInvocationContext *AnalysisDeclContext::getBlockInvocationContext(
320    const LocationContext *ParentLC, const BlockDecl *BD, const void *Data) {
321  return getLocationContextManager().getBlockInvocationContext(this, ParentLC,
322                                                               BD, Data);
323}
324
325bool AnalysisDeclContext::isInStdNamespace(const Decl *D) {
326  const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
327  const auto *ND = dyn_cast<NamespaceDecl>(DC);
328  if (!ND)
329    return false;
330
331  while (const DeclContext *Parent = ND->getParent()) {
332    if (!isa<NamespaceDecl>(Parent))
333      break;
334    ND = cast<NamespaceDecl>(Parent);
335  }
336
337  return ND->isStdNamespace();
338}
339
340LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
341  assert(
342      ADCMgr &&
343      "Cannot create LocationContexts without an AnalysisDeclContextManager!");
344  return ADCMgr->getLocationContextManager();
345}
346
347//===----------------------------------------------------------------------===//
348// FoldingSet profiling.
349//===----------------------------------------------------------------------===//
350
351void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
352                                    ContextKind ck,
353                                    AnalysisDeclContext *ctx,
354                                    const LocationContext *parent,
355                                    const void *data) {
356  ID.AddInteger(ck);
357  ID.AddPointer(ctx);
358  ID.AddPointer(parent);
359  ID.AddPointer(data);
360}
361
362void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
363  Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,
364          BlockCount, Index);
365}
366
367void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
368  Profile(ID, getAnalysisDeclContext(), getParent(), BD, Data);
369}
370
371//===----------------------------------------------------------------------===//
372// LocationContext creation.
373//===----------------------------------------------------------------------===//
374
375const StackFrameContext *LocationContextManager::getStackFrame(
376    AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,
377    const CFGBlock *blk, unsigned blockCount, unsigned idx) {
378  llvm::FoldingSetNodeID ID;
379  StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);
380  void *InsertPos;
381  auto *L =
382   cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
383  if (!L) {
384    L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);
385    Contexts.InsertNode(L, InsertPos);
386  }
387  return L;
388}
389
390const BlockInvocationContext *LocationContextManager::getBlockInvocationContext(
391    AnalysisDeclContext *ADC, const LocationContext *ParentLC,
392    const BlockDecl *BD, const void *Data) {
393  llvm::FoldingSetNodeID ID;
394  BlockInvocationContext::Profile(ID, ADC, ParentLC, BD, Data);
395  void *InsertPos;
396  auto *L =
397    cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
398                                                                    InsertPos));
399  if (!L) {
400    L = new BlockInvocationContext(ADC, ParentLC, BD, Data, ++NewID);
401    Contexts.InsertNode(L, InsertPos);
402  }
403  return L;
404}
405
406//===----------------------------------------------------------------------===//
407// LocationContext methods.
408//===----------------------------------------------------------------------===//
409
410const StackFrameContext *LocationContext::getStackFrame() const {
411  const LocationContext *LC = this;
412  while (LC) {
413    if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
414      return SFC;
415    LC = LC->getParent();
416  }
417  return nullptr;
418}
419
420bool LocationContext::inTopFrame() const {
421  return getStackFrame()->inTopFrame();
422}
423
424bool LocationContext::isParentOf(const LocationContext *LC) const {
425  do {
426    const LocationContext *Parent = LC->getParent();
427    if (Parent == this)
428      return true;
429    else
430      LC = Parent;
431  } while (LC);
432
433  return false;
434}
435
436static void printLocation(raw_ostream &Out, const SourceManager &SM,
437                          SourceLocation Loc) {
438  if (Loc.isFileID() && SM.isInMainFile(Loc))
439    Out << SM.getExpansionLineNumber(Loc);
440  else
441    Loc.print(Out, SM);
442}
443
444void LocationContext::dumpStack(raw_ostream &Out) const {
445  ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
446  PrintingPolicy PP(Ctx.getLangOpts());
447  PP.TerseOutput = 1;
448
449  const SourceManager &SM =
450      getAnalysisDeclContext()->getASTContext().getSourceManager();
451
452  unsigned Frame = 0;
453  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
454    switch (LCtx->getKind()) {
455    case StackFrame:
456      Out << "\t#" << Frame << ' ';
457      ++Frame;
458      if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
459        Out << "Calling " << D->getQualifiedNameAsString();
460      else
461        Out << "Calling anonymous code";
462      if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
463        Out << " at line ";
464        printLocation(Out, SM, S->getBeginLoc());
465      }
466      break;
467    case Block:
468      Out << "Invoking block";
469      if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
470        Out << " defined at line ";
471        printLocation(Out, SM, D->getBeginLoc());
472      }
473      break;
474    }
475    Out << '\n';
476  }
477}
478
479void LocationContext::printJson(raw_ostream &Out, const char *NL,
480                                unsigned int Space, bool IsDot,
481                                std::function<void(const LocationContext *)>
482                                    printMoreInfoPerContext) const {
483  ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
484  PrintingPolicy PP(Ctx.getLangOpts());
485  PP.TerseOutput = 1;
486
487  const SourceManager &SM =
488      getAnalysisDeclContext()->getASTContext().getSourceManager();
489
490  unsigned Frame = 0;
491  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
492    Indent(Out, Space, IsDot)
493        << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
494    switch (LCtx->getKind()) {
495    case StackFrame:
496      Out << '#' << Frame << " Call\", \"calling\": \"";
497      ++Frame;
498      if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
499        Out << D->getQualifiedNameAsString();
500      else
501        Out << "anonymous code";
502
503      Out << "\", \"location\": ";
504      if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
505        printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
506      } else {
507        Out << "null";
508      }
509
510      Out << ", \"items\": ";
511      break;
512    case Block:
513      Out << "Invoking block\" ";
514      if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
515        Out << ", \"location\": ";
516        printSourceLocationAsJson(Out, D->getBeginLoc(), SM);
517        Out << ' ';
518      }
519      break;
520    }
521
522    printMoreInfoPerContext(LCtx);
523
524    Out << '}';
525    if (LCtx->getParent())
526      Out << ',';
527    Out << NL;
528  }
529}
530
531LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); }
532
533//===----------------------------------------------------------------------===//
534// Lazily generated map to query the external variables referenced by a Block.
535//===----------------------------------------------------------------------===//
536
537namespace {
538
539class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
540  BumpVector<const VarDecl *> &BEVals;
541  BumpVectorContext &BC;
542  llvm::SmallPtrSet<const VarDecl *, 4> Visited;
543  llvm::SmallPtrSet<const DeclContext *, 4> IgnoredContexts;
544
545public:
546  FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
547                            BumpVectorContext &bc)
548      : BEVals(bevals), BC(bc) {}
549
550  void VisitStmt(Stmt *S) {
551    for (auto *Child : S->children())
552      if (Child)
553        Visit(Child);
554  }
555
556  void VisitDeclRefExpr(DeclRefExpr *DR) {
557    // Non-local variables are also directly modified.
558    if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
559      if (!VD->hasLocalStorage()) {
560        if (Visited.insert(VD).second)
561          BEVals.push_back(VD, BC);
562      }
563    }
564  }
565
566  void VisitBlockExpr(BlockExpr *BR) {
567    // Blocks containing blocks can transitively capture more variables.
568    IgnoredContexts.insert(BR->getBlockDecl());
569    Visit(BR->getBlockDecl()->getBody());
570  }
571
572  void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
573    for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(),
574         et = PE->semantics_end(); it != et; ++it) {
575      Expr *Semantic = *it;
576      if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
577        Semantic = OVE->getSourceExpr();
578      Visit(Semantic);
579    }
580  }
581};
582
583} // namespace
584
585using DeclVec = BumpVector<const VarDecl *>;
586
587static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,
588                                              void *&Vec,
589                                              llvm::BumpPtrAllocator &A) {
590  if (Vec)
591    return (DeclVec*) Vec;
592
593  BumpVectorContext BC(A);
594  DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
595  new (BV) DeclVec(BC, 10);
596
597  // Go through the capture list.
598  for (const auto &CI : BD->captures()) {
599    BV->push_back(CI.getVariable(), BC);
600  }
601
602  // Find the referenced global/static variables.
603  FindBlockDeclRefExprsVals F(*BV, BC);
604  F.Visit(BD->getBody());
605
606  Vec = BV;
607  return BV;
608}
609
610llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
611AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {
612  if (!ReferencedBlockVars)
613    ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
614
615  const DeclVec *V =
616      LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
617  return llvm::make_range(V->begin(), V->end());
618}
619
620std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
621  if (!ManagedAnalyses)
622    ManagedAnalyses = new ManagedAnalysisMap();
623  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
624  return (*M)[tag];
625}
626
627//===----------------------------------------------------------------------===//
628// Cleanup.
629//===----------------------------------------------------------------------===//
630
631ManagedAnalysis::~ManagedAnalysis() = default;
632
633AnalysisDeclContext::~AnalysisDeclContext() {
634  delete forcedBlkExprs;
635  delete ReferencedBlockVars;
636  delete (ManagedAnalysisMap*) ManagedAnalyses;
637}
638
639LocationContext::~LocationContext() = default;
640
641LocationContextManager::~LocationContextManager() {
642  clear();
643}
644
645void LocationContextManager::clear() {
646  for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
647       E = Contexts.end(); I != E; ) {
648    LocationContext *LC = &*I;
649    ++I;
650    delete LC;
651  }
652  Contexts.clear();
653}
654