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