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