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