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