brintos

brintos / llvm-project-archived public Read only

0
0
Text · 22.4 KiB · f188fc6 Raw
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