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