1234287Sdim//== AnalysisDeclContext.cpp - Analysis context for Path Sens analysis -*- C++ -*-// 2234287Sdim// 3234287Sdim// The LLVM Compiler Infrastructure 4234287Sdim// 5234287Sdim// This file is distributed under the University of Illinois Open Source 6234287Sdim// License. See LICENSE.TXT for details. 7234287Sdim// 8234287Sdim//===----------------------------------------------------------------------===// 9234287Sdim// 10234287Sdim// This file defines AnalysisDeclContext, a class that manages the analysis context 11234287Sdim// data for path sensitive analysis. 12234287Sdim// 13234287Sdim//===----------------------------------------------------------------------===// 14234287Sdim 15249423Sdim#include "clang/Analysis/AnalysisContext.h" 16249423Sdim#include "BodyFarm.h" 17239462Sdim#include "clang/AST/ASTContext.h" 18234287Sdim#include "clang/AST/Decl.h" 19234287Sdim#include "clang/AST/DeclObjC.h" 20234287Sdim#include "clang/AST/DeclTemplate.h" 21234287Sdim#include "clang/AST/ParentMap.h" 22234287Sdim#include "clang/AST/StmtVisitor.h" 23249423Sdim#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h" 24234287Sdim#include "clang/Analysis/Analyses/LiveVariables.h" 25234287Sdim#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h" 26234287Sdim#include "clang/Analysis/CFG.h" 27234287Sdim#include "clang/Analysis/CFGStmtMap.h" 28234287Sdim#include "clang/Analysis/Support/BumpVector.h" 29234287Sdim#include "llvm/ADT/SmallPtrSet.h" 30234287Sdim#include "llvm/Support/ErrorHandling.h" 31249423Sdim#include "llvm/Support/raw_ostream.h" 32249423Sdim#include "llvm/Support/SaveAndRestore.h" 33234287Sdim 34234287Sdimusing namespace clang; 35234287Sdim 36234287Sdimtypedef llvm::DenseMap<const void *, ManagedAnalysis *> ManagedAnalysisMap; 37234287Sdim 38234287SdimAnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr, 39243830Sdim const Decl *d, 40243830Sdim const CFG::BuildOptions &buildOptions) 41234287Sdim : Manager(Mgr), 42234287Sdim D(d), 43234287Sdim cfgBuildOptions(buildOptions), 44234287Sdim forcedBlkExprs(0), 45234287Sdim builtCFG(false), 46234287Sdim builtCompleteCFG(false), 47234287Sdim ReferencedBlockVars(0), 48234287Sdim ManagedAnalyses(0) 49234287Sdim{ 50234287Sdim cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs; 51234287Sdim} 52234287Sdim 53234287SdimAnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr, 54243830Sdim const Decl *d) 55234287Sdim: Manager(Mgr), 56234287Sdim D(d), 57234287Sdim forcedBlkExprs(0), 58234287Sdim builtCFG(false), 59234287Sdim builtCompleteCFG(false), 60234287Sdim ReferencedBlockVars(0), 61234287Sdim ManagedAnalyses(0) 62234287Sdim{ 63234287Sdim cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs; 64234287Sdim} 65234287Sdim 66234287SdimAnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG, 67243830Sdim bool addImplicitDtors, 68243830Sdim bool addInitializers, 69243830Sdim bool addTemporaryDtors, 70249423Sdim bool synthesizeBodies, 71249423Sdim bool addStaticInitBranch) 72243830Sdim : SynthesizeBodies(synthesizeBodies) 73243830Sdim{ 74234287Sdim cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG; 75234287Sdim cfgBuildOptions.AddImplicitDtors = addImplicitDtors; 76234287Sdim cfgBuildOptions.AddInitializers = addInitializers; 77243830Sdim cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors; 78249423Sdim cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch; 79234287Sdim} 80234287Sdim 81234287Sdimvoid AnalysisDeclContextManager::clear() { 82234287Sdim for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I) 83234287Sdim delete I->second; 84234287Sdim Contexts.clear(); 85234287Sdim} 86234287Sdim 87243830Sdimstatic BodyFarm &getBodyFarm(ASTContext &C) { 88243830Sdim static BodyFarm *BF = new BodyFarm(C); 89243830Sdim return *BF; 90243830Sdim} 91243830Sdim 92249423SdimStmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const { 93249423Sdim IsAutosynthesized = false; 94243830Sdim if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 95243830Sdim Stmt *Body = FD->getBody(); 96249423Sdim if (!Body && Manager && Manager->synthesizeBodies()) { 97249423Sdim IsAutosynthesized = true; 98243830Sdim return getBodyFarm(getASTContext()).getBody(FD); 99249423Sdim } 100243830Sdim return Body; 101243830Sdim } 102234287Sdim else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 103234287Sdim return MD->getBody(); 104234287Sdim else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 105234287Sdim return BD->getBody(); 106234287Sdim else if (const FunctionTemplateDecl *FunTmpl 107234287Sdim = dyn_cast_or_null<FunctionTemplateDecl>(D)) 108234287Sdim return FunTmpl->getTemplatedDecl()->getBody(); 109234287Sdim 110234287Sdim llvm_unreachable("unknown code decl"); 111234287Sdim} 112234287Sdim 113249423SdimStmt *AnalysisDeclContext::getBody() const { 114249423Sdim bool Tmp; 115249423Sdim return getBody(Tmp); 116249423Sdim} 117249423Sdim 118249423Sdimbool AnalysisDeclContext::isBodyAutosynthesized() const { 119249423Sdim bool Tmp; 120249423Sdim getBody(Tmp); 121249423Sdim return Tmp; 122249423Sdim} 123249423Sdim 124234287Sdimconst ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const { 125234287Sdim if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 126234287Sdim return MD->getSelfDecl(); 127234287Sdim if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) { 128234287Sdim // See if 'self' was captured by the block. 129234287Sdim for (BlockDecl::capture_const_iterator it = BD->capture_begin(), 130234287Sdim et = BD->capture_end(); it != et; ++it) { 131234287Sdim const VarDecl *VD = it->getVariable(); 132234287Sdim if (VD->getName() == "self") 133234287Sdim return dyn_cast<ImplicitParamDecl>(VD); 134234287Sdim } 135234287Sdim } 136234287Sdim 137234287Sdim return NULL; 138234287Sdim} 139234287Sdim 140234287Sdimvoid AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) { 141234287Sdim if (!forcedBlkExprs) 142234287Sdim forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs(); 143234287Sdim // Default construct an entry for 'stmt'. 144234287Sdim if (const Expr *e = dyn_cast<Expr>(stmt)) 145234287Sdim stmt = e->IgnoreParens(); 146234287Sdim (void) (*forcedBlkExprs)[stmt]; 147234287Sdim} 148234287Sdim 149234287Sdimconst CFGBlock * 150234287SdimAnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) { 151234287Sdim assert(forcedBlkExprs); 152234287Sdim if (const Expr *e = dyn_cast<Expr>(stmt)) 153234287Sdim stmt = e->IgnoreParens(); 154234287Sdim CFG::BuildOptions::ForcedBlkExprs::const_iterator itr = 155234287Sdim forcedBlkExprs->find(stmt); 156234287Sdim assert(itr != forcedBlkExprs->end()); 157234287Sdim return itr->second; 158234287Sdim} 159234287Sdim 160234287SdimCFG *AnalysisDeclContext::getCFG() { 161234287Sdim if (!cfgBuildOptions.PruneTriviallyFalseEdges) 162234287Sdim return getUnoptimizedCFG(); 163234287Sdim 164234287Sdim if (!builtCFG) { 165234287Sdim cfg.reset(CFG::buildCFG(D, getBody(), 166234287Sdim &D->getASTContext(), cfgBuildOptions)); 167234287Sdim // Even when the cfg is not successfully built, we don't 168234287Sdim // want to try building it again. 169234287Sdim builtCFG = true; 170234287Sdim } 171234287Sdim return cfg.get(); 172234287Sdim} 173234287Sdim 174234287SdimCFG *AnalysisDeclContext::getUnoptimizedCFG() { 175234287Sdim if (!builtCompleteCFG) { 176234287Sdim SaveAndRestore<bool> NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges, 177234287Sdim false); 178234287Sdim completeCFG.reset(CFG::buildCFG(D, getBody(), &D->getASTContext(), 179234287Sdim cfgBuildOptions)); 180234287Sdim // Even when the cfg is not successfully built, we don't 181234287Sdim // want to try building it again. 182234287Sdim builtCompleteCFG = true; 183234287Sdim } 184234287Sdim return completeCFG.get(); 185234287Sdim} 186234287Sdim 187234287SdimCFGStmtMap *AnalysisDeclContext::getCFGStmtMap() { 188234287Sdim if (cfgStmtMap) 189234287Sdim return cfgStmtMap.get(); 190234287Sdim 191234287Sdim if (CFG *c = getCFG()) { 192234287Sdim cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap())); 193234287Sdim return cfgStmtMap.get(); 194234287Sdim } 195234287Sdim 196234287Sdim return 0; 197234287Sdim} 198234287Sdim 199234287SdimCFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() { 200234287Sdim if (CFA) 201234287Sdim return CFA.get(); 202234287Sdim 203234287Sdim if (CFG *c = getCFG()) { 204234287Sdim CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c)); 205234287Sdim return CFA.get(); 206234287Sdim } 207234287Sdim 208234287Sdim return 0; 209234287Sdim} 210234287Sdim 211234287Sdimvoid AnalysisDeclContext::dumpCFG(bool ShowColors) { 212234287Sdim getCFG()->dump(getASTContext().getLangOpts(), ShowColors); 213234287Sdim} 214234287Sdim 215234287SdimParentMap &AnalysisDeclContext::getParentMap() { 216239462Sdim if (!PM) { 217234287Sdim PM.reset(new ParentMap(getBody())); 218239462Sdim if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(getDecl())) { 219239462Sdim for (CXXConstructorDecl::init_const_iterator I = C->init_begin(), 220239462Sdim E = C->init_end(); 221239462Sdim I != E; ++I) { 222239462Sdim PM->addStmt((*I)->getInit()); 223239462Sdim } 224239462Sdim } 225239462Sdim } 226234287Sdim return *PM; 227234287Sdim} 228234287Sdim 229234287SdimPseudoConstantAnalysis *AnalysisDeclContext::getPseudoConstantAnalysis() { 230234287Sdim if (!PCA) 231234287Sdim PCA.reset(new PseudoConstantAnalysis(getBody())); 232234287Sdim return PCA.get(); 233234287Sdim} 234234287Sdim 235239462SdimAnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) { 236243830Sdim if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 237243830Sdim // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl 238243830Sdim // that has the body. 239243830Sdim FD->hasBody(FD); 240243830Sdim D = FD; 241243830Sdim } 242243830Sdim 243234287Sdim AnalysisDeclContext *&AC = Contexts[D]; 244234287Sdim if (!AC) 245239462Sdim AC = new AnalysisDeclContext(this, D, cfgBuildOptions); 246234287Sdim return AC; 247234287Sdim} 248234287Sdim 249234287Sdimconst StackFrameContext * 250234287SdimAnalysisDeclContext::getStackFrame(LocationContext const *Parent, const Stmt *S, 251234287Sdim const CFGBlock *Blk, unsigned Idx) { 252234287Sdim return getLocationContextManager().getStackFrame(this, Parent, S, Blk, Idx); 253234287Sdim} 254234287Sdim 255239462Sdimconst BlockInvocationContext * 256239462SdimAnalysisDeclContext::getBlockInvocationContext(const LocationContext *parent, 257239462Sdim const clang::BlockDecl *BD, 258239462Sdim const void *ContextData) { 259239462Sdim return getLocationContextManager().getBlockInvocationContext(this, parent, 260239462Sdim BD, ContextData); 261239462Sdim} 262239462Sdim 263234287SdimLocationContextManager & AnalysisDeclContext::getLocationContextManager() { 264234287Sdim assert(Manager && 265234287Sdim "Cannot create LocationContexts without an AnalysisDeclContextManager!"); 266234287Sdim return Manager->getLocationContextManager(); 267234287Sdim} 268234287Sdim 269234287Sdim//===----------------------------------------------------------------------===// 270234287Sdim// FoldingSet profiling. 271234287Sdim//===----------------------------------------------------------------------===// 272234287Sdim 273234287Sdimvoid LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID, 274234287Sdim ContextKind ck, 275234287Sdim AnalysisDeclContext *ctx, 276234287Sdim const LocationContext *parent, 277234287Sdim const void *data) { 278234287Sdim ID.AddInteger(ck); 279234287Sdim ID.AddPointer(ctx); 280234287Sdim ID.AddPointer(parent); 281234287Sdim ID.AddPointer(data); 282234287Sdim} 283234287Sdim 284234287Sdimvoid StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) { 285234287Sdim Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block, Index); 286234287Sdim} 287234287Sdim 288234287Sdimvoid ScopeContext::Profile(llvm::FoldingSetNodeID &ID) { 289234287Sdim Profile(ID, getAnalysisDeclContext(), getParent(), Enter); 290234287Sdim} 291234287Sdim 292234287Sdimvoid BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) { 293239462Sdim Profile(ID, getAnalysisDeclContext(), getParent(), BD, ContextData); 294234287Sdim} 295234287Sdim 296234287Sdim//===----------------------------------------------------------------------===// 297234287Sdim// LocationContext creation. 298234287Sdim//===----------------------------------------------------------------------===// 299234287Sdim 300234287Sdimtemplate <typename LOC, typename DATA> 301234287Sdimconst LOC* 302234287SdimLocationContextManager::getLocationContext(AnalysisDeclContext *ctx, 303234287Sdim const LocationContext *parent, 304234287Sdim const DATA *d) { 305234287Sdim llvm::FoldingSetNodeID ID; 306234287Sdim LOC::Profile(ID, ctx, parent, d); 307234287Sdim void *InsertPos; 308234287Sdim 309234287Sdim LOC *L = cast_or_null<LOC>(Contexts.FindNodeOrInsertPos(ID, InsertPos)); 310234287Sdim 311234287Sdim if (!L) { 312234287Sdim L = new LOC(ctx, parent, d); 313234287Sdim Contexts.InsertNode(L, InsertPos); 314234287Sdim } 315234287Sdim return L; 316234287Sdim} 317234287Sdim 318234287Sdimconst StackFrameContext* 319234287SdimLocationContextManager::getStackFrame(AnalysisDeclContext *ctx, 320234287Sdim const LocationContext *parent, 321234287Sdim const Stmt *s, 322234287Sdim const CFGBlock *blk, unsigned idx) { 323234287Sdim llvm::FoldingSetNodeID ID; 324234287Sdim StackFrameContext::Profile(ID, ctx, parent, s, blk, idx); 325234287Sdim void *InsertPos; 326234287Sdim StackFrameContext *L = 327234287Sdim cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos)); 328234287Sdim if (!L) { 329234287Sdim L = new StackFrameContext(ctx, parent, s, blk, idx); 330234287Sdim Contexts.InsertNode(L, InsertPos); 331234287Sdim } 332234287Sdim return L; 333234287Sdim} 334234287Sdim 335234287Sdimconst ScopeContext * 336234287SdimLocationContextManager::getScope(AnalysisDeclContext *ctx, 337234287Sdim const LocationContext *parent, 338234287Sdim const Stmt *s) { 339234287Sdim return getLocationContext<ScopeContext, Stmt>(ctx, parent, s); 340234287Sdim} 341234287Sdim 342239462Sdimconst BlockInvocationContext * 343239462SdimLocationContextManager::getBlockInvocationContext(AnalysisDeclContext *ctx, 344239462Sdim const LocationContext *parent, 345239462Sdim const BlockDecl *BD, 346239462Sdim const void *ContextData) { 347239462Sdim llvm::FoldingSetNodeID ID; 348239462Sdim BlockInvocationContext::Profile(ID, ctx, parent, BD, ContextData); 349239462Sdim void *InsertPos; 350239462Sdim BlockInvocationContext *L = 351239462Sdim cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID, 352239462Sdim InsertPos)); 353239462Sdim if (!L) { 354239462Sdim L = new BlockInvocationContext(ctx, parent, BD, ContextData); 355239462Sdim Contexts.InsertNode(L, InsertPos); 356239462Sdim } 357239462Sdim return L; 358239462Sdim} 359239462Sdim 360234287Sdim//===----------------------------------------------------------------------===// 361234287Sdim// LocationContext methods. 362234287Sdim//===----------------------------------------------------------------------===// 363234287Sdim 364234287Sdimconst StackFrameContext *LocationContext::getCurrentStackFrame() const { 365234287Sdim const LocationContext *LC = this; 366234287Sdim while (LC) { 367234287Sdim if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) 368234287Sdim return SFC; 369234287Sdim LC = LC->getParent(); 370234287Sdim } 371234287Sdim return NULL; 372234287Sdim} 373234287Sdim 374243830Sdimbool LocationContext::inTopFrame() const { 375243830Sdim return getCurrentStackFrame()->inTopFrame(); 376243830Sdim} 377243830Sdim 378234287Sdimbool LocationContext::isParentOf(const LocationContext *LC) const { 379234287Sdim do { 380234287Sdim const LocationContext *Parent = LC->getParent(); 381234287Sdim if (Parent == this) 382234287Sdim return true; 383234287Sdim else 384234287Sdim LC = Parent; 385234287Sdim } while (LC); 386234287Sdim 387234287Sdim return false; 388234287Sdim} 389234287Sdim 390249423Sdimvoid LocationContext::dumpStack() const { 391249423Sdim ASTContext &Ctx = getAnalysisDeclContext()->getASTContext(); 392249423Sdim PrintingPolicy PP(Ctx.getLangOpts()); 393249423Sdim PP.TerseOutput = 1; 394249423Sdim 395249423Sdim unsigned Frame = 0; 396249423Sdim for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) { 397249423Sdim switch (LCtx->getKind()) { 398249423Sdim case StackFrame: 399249423Sdim llvm::errs() << '#' << Frame++ << ' '; 400249423Sdim cast<StackFrameContext>(LCtx)->getDecl()->print(llvm::errs(), PP); 401249423Sdim llvm::errs() << '\n'; 402249423Sdim break; 403249423Sdim case Scope: 404249423Sdim llvm::errs() << " (scope)\n"; 405249423Sdim break; 406249423Sdim case Block: 407249423Sdim llvm::errs() << " (block context: " 408249423Sdim << cast<BlockInvocationContext>(LCtx)->getContextData() 409249423Sdim << ")\n"; 410249423Sdim break; 411249423Sdim } 412249423Sdim } 413249423Sdim} 414249423Sdim 415234287Sdim//===----------------------------------------------------------------------===// 416234287Sdim// Lazily generated map to query the external variables referenced by a Block. 417234287Sdim//===----------------------------------------------------------------------===// 418234287Sdim 419234287Sdimnamespace { 420234287Sdimclass FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{ 421234287Sdim BumpVector<const VarDecl*> &BEVals; 422234287Sdim BumpVectorContext &BC; 423234287Sdim llvm::SmallPtrSet<const VarDecl*, 4> Visited; 424234287Sdim llvm::SmallPtrSet<const DeclContext*, 4> IgnoredContexts; 425234287Sdimpublic: 426234287Sdim FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals, 427234287Sdim BumpVectorContext &bc) 428234287Sdim : BEVals(bevals), BC(bc) {} 429234287Sdim 430234287Sdim bool IsTrackedDecl(const VarDecl *VD) { 431234287Sdim const DeclContext *DC = VD->getDeclContext(); 432234287Sdim return IgnoredContexts.count(DC) == 0; 433234287Sdim } 434234287Sdim 435234287Sdim void VisitStmt(Stmt *S) { 436234287Sdim for (Stmt::child_range I = S->children(); I; ++I) 437234287Sdim if (Stmt *child = *I) 438234287Sdim Visit(child); 439234287Sdim } 440234287Sdim 441234287Sdim void VisitDeclRefExpr(DeclRefExpr *DR) { 442234287Sdim // Non-local variables are also directly modified. 443234287Sdim if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) { 444234287Sdim if (!VD->hasLocalStorage()) { 445234287Sdim if (Visited.insert(VD)) 446234287Sdim BEVals.push_back(VD, BC); 447234287Sdim } 448234287Sdim } 449234287Sdim } 450234287Sdim 451234287Sdim void VisitBlockExpr(BlockExpr *BR) { 452234287Sdim // Blocks containing blocks can transitively capture more variables. 453234287Sdim IgnoredContexts.insert(BR->getBlockDecl()); 454234287Sdim Visit(BR->getBlockDecl()->getBody()); 455234287Sdim } 456234287Sdim 457234287Sdim void VisitPseudoObjectExpr(PseudoObjectExpr *PE) { 458234287Sdim for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(), 459234287Sdim et = PE->semantics_end(); it != et; ++it) { 460234287Sdim Expr *Semantic = *it; 461234287Sdim if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Semantic)) 462234287Sdim Semantic = OVE->getSourceExpr(); 463234287Sdim Visit(Semantic); 464234287Sdim } 465234287Sdim } 466234287Sdim}; 467234287Sdim} // end anonymous namespace 468234287Sdim 469234287Sdimtypedef BumpVector<const VarDecl*> DeclVec; 470234287Sdim 471234287Sdimstatic DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD, 472234287Sdim void *&Vec, 473234287Sdim llvm::BumpPtrAllocator &A) { 474234287Sdim if (Vec) 475234287Sdim return (DeclVec*) Vec; 476234287Sdim 477234287Sdim BumpVectorContext BC(A); 478234287Sdim DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>(); 479234287Sdim new (BV) DeclVec(BC, 10); 480234287Sdim 481249423Sdim // Go through the capture list. 482249423Sdim for (BlockDecl::capture_const_iterator CI = BD->capture_begin(), 483249423Sdim CE = BD->capture_end(); CI != CE; ++CI) { 484249423Sdim BV->push_back(CI->getVariable(), BC); 485249423Sdim } 486249423Sdim 487249423Sdim // Find the referenced global/static variables. 488234287Sdim FindBlockDeclRefExprsVals F(*BV, BC); 489234287Sdim F.Visit(BD->getBody()); 490234287Sdim 491234287Sdim Vec = BV; 492234287Sdim return BV; 493234287Sdim} 494234287Sdim 495234287Sdimstd::pair<AnalysisDeclContext::referenced_decls_iterator, 496234287Sdim AnalysisDeclContext::referenced_decls_iterator> 497234287SdimAnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) { 498234287Sdim if (!ReferencedBlockVars) 499234287Sdim ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>(); 500234287Sdim 501234287Sdim DeclVec *V = LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A); 502234287Sdim return std::make_pair(V->begin(), V->end()); 503234287Sdim} 504234287Sdim 505234287SdimManagedAnalysis *&AnalysisDeclContext::getAnalysisImpl(const void *tag) { 506234287Sdim if (!ManagedAnalyses) 507234287Sdim ManagedAnalyses = new ManagedAnalysisMap(); 508234287Sdim ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses; 509234287Sdim return (*M)[tag]; 510234287Sdim} 511234287Sdim 512234287Sdim//===----------------------------------------------------------------------===// 513234287Sdim// Cleanup. 514234287Sdim//===----------------------------------------------------------------------===// 515234287Sdim 516234287SdimManagedAnalysis::~ManagedAnalysis() {} 517234287Sdim 518234287SdimAnalysisDeclContext::~AnalysisDeclContext() { 519234287Sdim delete forcedBlkExprs; 520234287Sdim delete ReferencedBlockVars; 521234287Sdim // Release the managed analyses. 522234287Sdim if (ManagedAnalyses) { 523234287Sdim ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses; 524234287Sdim for (ManagedAnalysisMap::iterator I = M->begin(), E = M->end(); I!=E; ++I) 525234287Sdim delete I->second; 526234287Sdim delete M; 527234287Sdim } 528234287Sdim} 529234287Sdim 530234287SdimAnalysisDeclContextManager::~AnalysisDeclContextManager() { 531234287Sdim for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I) 532234287Sdim delete I->second; 533234287Sdim} 534234287Sdim 535234287SdimLocationContext::~LocationContext() {} 536234287Sdim 537234287SdimLocationContextManager::~LocationContextManager() { 538234287Sdim clear(); 539234287Sdim} 540234287Sdim 541234287Sdimvoid LocationContextManager::clear() { 542234287Sdim for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(), 543234287Sdim E = Contexts.end(); I != E; ) { 544234287Sdim LocationContext *LC = &*I; 545234287Sdim ++I; 546234287Sdim delete LC; 547234287Sdim } 548234287Sdim 549234287Sdim Contexts.clear(); 550234287Sdim} 551234287Sdim 552