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