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