10b57cec5SDimitry Andric //===- AnalysisDeclContext.cpp - Analysis context for Path Sens analysis --===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines AnalysisDeclContext, a class that manages the analysis
100b57cec5SDimitry Andric // context data for path sensitive analysis.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "clang/Analysis/AnalysisDeclContext.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
160b57cec5SDimitry Andric #include "clang/AST/Decl.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclBase.h"
180b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
190b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
200b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
210b57cec5SDimitry Andric #include "clang/AST/Expr.h"
220b57cec5SDimitry Andric #include "clang/AST/LambdaCapture.h"
230b57cec5SDimitry Andric #include "clang/AST/ParentMap.h"
240b57cec5SDimitry Andric #include "clang/AST/PrettyPrinter.h"
250b57cec5SDimitry Andric #include "clang/AST/Stmt.h"
260b57cec5SDimitry Andric #include "clang/AST/StmtCXX.h"
270b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h"
280b57cec5SDimitry Andric #include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
290b57cec5SDimitry Andric #include "clang/Analysis/BodyFarm.h"
300b57cec5SDimitry Andric #include "clang/Analysis/CFG.h"
310b57cec5SDimitry Andric #include "clang/Analysis/CFGStmtMap.h"
320b57cec5SDimitry Andric #include "clang/Analysis/Support/BumpVector.h"
330b57cec5SDimitry Andric #include "clang/Basic/JsonSupport.h"
340b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
350b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
360b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
370b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
380b57cec5SDimitry Andric #include "llvm/ADT/FoldingSet.h"
390b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
400b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
410b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
420b57cec5SDimitry Andric #include "llvm/Support/Allocator.h"
430b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
440b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
450b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
460b57cec5SDimitry Andric #include "llvm/Support/SaveAndRestore.h"
470b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
480b57cec5SDimitry Andric #include <cassert>
490b57cec5SDimitry Andric #include <memory>
500b57cec5SDimitry Andric
510b57cec5SDimitry Andric using namespace clang;
520b57cec5SDimitry Andric
535ffd83dbSDimitry Andric using ManagedAnalysisMap = llvm::DenseMap<const void *, std::unique_ptr<ManagedAnalysis>>;
540b57cec5SDimitry Andric
AnalysisDeclContext(AnalysisDeclContextManager * ADCMgr,const Decl * D,const CFG::BuildOptions & Options)555ffd83dbSDimitry Andric AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
565ffd83dbSDimitry Andric const Decl *D,
575ffd83dbSDimitry Andric const CFG::BuildOptions &Options)
585ffd83dbSDimitry Andric : ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {
590b57cec5SDimitry Andric cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
600b57cec5SDimitry Andric }
610b57cec5SDimitry Andric
AnalysisDeclContext(AnalysisDeclContextManager * ADCMgr,const Decl * D)625ffd83dbSDimitry Andric AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
635ffd83dbSDimitry Andric const Decl *D)
645ffd83dbSDimitry Andric : ADCMgr(ADCMgr), D(D) {
650b57cec5SDimitry Andric cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric
AnalysisDeclContextManager(ASTContext & ASTCtx,bool useUnoptimizedCFG,bool addImplicitDtors,bool addInitializers,bool addTemporaryDtors,bool addLifetime,bool addLoopExit,bool addScopes,bool synthesizeBodies,bool addStaticInitBranch,bool addCXXNewAllocator,bool addRichCXXConstructors,bool markElidedCXXConstructors,bool addVirtualBaseBranches,CodeInjector * injector)680b57cec5SDimitry Andric AnalysisDeclContextManager::AnalysisDeclContextManager(
690b57cec5SDimitry Andric ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors,
700b57cec5SDimitry Andric bool addInitializers, bool addTemporaryDtors, bool addLifetime,
710b57cec5SDimitry Andric bool addLoopExit, bool addScopes, bool synthesizeBodies,
720b57cec5SDimitry Andric bool addStaticInitBranch, bool addCXXNewAllocator,
730b57cec5SDimitry Andric bool addRichCXXConstructors, bool markElidedCXXConstructors,
740b57cec5SDimitry Andric bool addVirtualBaseBranches, CodeInjector *injector)
750b57cec5SDimitry Andric : Injector(injector), FunctionBodyFarm(ASTCtx, injector),
760b57cec5SDimitry Andric SynthesizeBodies(synthesizeBodies) {
770b57cec5SDimitry Andric cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
780b57cec5SDimitry Andric cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
790b57cec5SDimitry Andric cfgBuildOptions.AddInitializers = addInitializers;
800b57cec5SDimitry Andric cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
810b57cec5SDimitry Andric cfgBuildOptions.AddLifetime = addLifetime;
820b57cec5SDimitry Andric cfgBuildOptions.AddLoopExit = addLoopExit;
830b57cec5SDimitry Andric cfgBuildOptions.AddScopes = addScopes;
840b57cec5SDimitry Andric cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
850b57cec5SDimitry Andric cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
860b57cec5SDimitry Andric cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;
870b57cec5SDimitry Andric cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;
880b57cec5SDimitry Andric cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric
clear()910b57cec5SDimitry Andric void AnalysisDeclContextManager::clear() { Contexts.clear(); }
920b57cec5SDimitry Andric
getBody(bool & IsAutosynthesized) const930b57cec5SDimitry Andric Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
940b57cec5SDimitry Andric IsAutosynthesized = false;
950b57cec5SDimitry Andric if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
960b57cec5SDimitry Andric Stmt *Body = FD->getBody();
970b57cec5SDimitry Andric if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
980b57cec5SDimitry Andric Body = CoroBody->getBody();
995ffd83dbSDimitry Andric if (ADCMgr && ADCMgr->synthesizeBodies()) {
1005ffd83dbSDimitry Andric Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);
1010b57cec5SDimitry Andric if (SynthesizedBody) {
1020b57cec5SDimitry Andric Body = SynthesizedBody;
1030b57cec5SDimitry Andric IsAutosynthesized = true;
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric }
1060b57cec5SDimitry Andric return Body;
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
1090b57cec5SDimitry Andric Stmt *Body = MD->getBody();
1105ffd83dbSDimitry Andric if (ADCMgr && ADCMgr->synthesizeBodies()) {
1115ffd83dbSDimitry Andric Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(MD);
1120b57cec5SDimitry Andric if (SynthesizedBody) {
1130b57cec5SDimitry Andric Body = SynthesizedBody;
1140b57cec5SDimitry Andric IsAutosynthesized = true;
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric return Body;
1180b57cec5SDimitry Andric } else if (const auto *BD = dyn_cast<BlockDecl>(D))
1190b57cec5SDimitry Andric return BD->getBody();
1200b57cec5SDimitry Andric else if (const auto *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
1210b57cec5SDimitry Andric return FunTmpl->getTemplatedDecl()->getBody();
1220b57cec5SDimitry Andric
1230b57cec5SDimitry Andric llvm_unreachable("unknown code decl");
1240b57cec5SDimitry Andric }
1250b57cec5SDimitry Andric
getBody() const1260b57cec5SDimitry Andric Stmt *AnalysisDeclContext::getBody() const {
1270b57cec5SDimitry Andric bool Tmp;
1280b57cec5SDimitry Andric return getBody(Tmp);
1290b57cec5SDimitry Andric }
1300b57cec5SDimitry Andric
isBodyAutosynthesized() const1310b57cec5SDimitry Andric bool AnalysisDeclContext::isBodyAutosynthesized() const {
1320b57cec5SDimitry Andric bool Tmp;
1330b57cec5SDimitry Andric getBody(Tmp);
1340b57cec5SDimitry Andric return Tmp;
1350b57cec5SDimitry Andric }
1360b57cec5SDimitry Andric
isBodyAutosynthesizedFromModelFile() const1370b57cec5SDimitry Andric bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const {
1380b57cec5SDimitry Andric bool Tmp;
1390b57cec5SDimitry Andric Stmt *Body = getBody(Tmp);
1400b57cec5SDimitry Andric return Tmp && Body->getBeginLoc().isValid();
1410b57cec5SDimitry Andric }
1420b57cec5SDimitry Andric
1430b57cec5SDimitry Andric /// Returns true if \param VD is an Objective-C implicit 'self' parameter.
isSelfDecl(const VarDecl * VD)1440b57cec5SDimitry Andric static bool isSelfDecl(const VarDecl *VD) {
145*bdd1243dSDimitry Andric return isa_and_nonnull<ImplicitParamDecl>(VD) && VD->getName() == "self";
1460b57cec5SDimitry Andric }
1470b57cec5SDimitry Andric
getSelfDecl() const1480b57cec5SDimitry Andric const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
1490b57cec5SDimitry Andric if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
1500b57cec5SDimitry Andric return MD->getSelfDecl();
1510b57cec5SDimitry Andric if (const auto *BD = dyn_cast<BlockDecl>(D)) {
1520b57cec5SDimitry Andric // See if 'self' was captured by the block.
1530b57cec5SDimitry Andric for (const auto &I : BD->captures()) {
1540b57cec5SDimitry Andric const VarDecl *VD = I.getVariable();
1550b57cec5SDimitry Andric if (isSelfDecl(VD))
1560b57cec5SDimitry Andric return dyn_cast<ImplicitParamDecl>(VD);
1570b57cec5SDimitry Andric }
1580b57cec5SDimitry Andric }
1590b57cec5SDimitry Andric
1600b57cec5SDimitry Andric auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
1610b57cec5SDimitry Andric if (!CXXMethod)
1620b57cec5SDimitry Andric return nullptr;
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric const CXXRecordDecl *parent = CXXMethod->getParent();
1650b57cec5SDimitry Andric if (!parent->isLambda())
1660b57cec5SDimitry Andric return nullptr;
1670b57cec5SDimitry Andric
1680b57cec5SDimitry Andric for (const auto &LC : parent->captures()) {
1690b57cec5SDimitry Andric if (!LC.capturesVariable())
1700b57cec5SDimitry Andric continue;
1710b57cec5SDimitry Andric
172*bdd1243dSDimitry Andric ValueDecl *VD = LC.getCapturedVar();
173*bdd1243dSDimitry Andric if (isSelfDecl(dyn_cast<VarDecl>(VD)))
1740b57cec5SDimitry Andric return dyn_cast<ImplicitParamDecl>(VD);
1750b57cec5SDimitry Andric }
1760b57cec5SDimitry Andric
1770b57cec5SDimitry Andric return nullptr;
1780b57cec5SDimitry Andric }
1790b57cec5SDimitry Andric
registerForcedBlockExpression(const Stmt * stmt)1800b57cec5SDimitry Andric void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
1810b57cec5SDimitry Andric if (!forcedBlkExprs)
1820b57cec5SDimitry Andric forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
1830b57cec5SDimitry Andric // Default construct an entry for 'stmt'.
1840b57cec5SDimitry Andric if (const auto *e = dyn_cast<Expr>(stmt))
1850b57cec5SDimitry Andric stmt = e->IgnoreParens();
1860b57cec5SDimitry Andric (void) (*forcedBlkExprs)[stmt];
1870b57cec5SDimitry Andric }
1880b57cec5SDimitry Andric
1890b57cec5SDimitry Andric const CFGBlock *
getBlockForRegisteredExpression(const Stmt * stmt)1900b57cec5SDimitry Andric AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {
1910b57cec5SDimitry Andric assert(forcedBlkExprs);
1920b57cec5SDimitry Andric if (const auto *e = dyn_cast<Expr>(stmt))
1930b57cec5SDimitry Andric stmt = e->IgnoreParens();
1940b57cec5SDimitry Andric CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
1950b57cec5SDimitry Andric forcedBlkExprs->find(stmt);
1960b57cec5SDimitry Andric assert(itr != forcedBlkExprs->end());
1970b57cec5SDimitry Andric return itr->second;
1980b57cec5SDimitry Andric }
1990b57cec5SDimitry Andric
2000b57cec5SDimitry Andric /// Add each synthetic statement in the CFG to the parent map, using the
2010b57cec5SDimitry Andric /// source statement's parent.
addParentsForSyntheticStmts(const CFG * TheCFG,ParentMap & PM)2020b57cec5SDimitry Andric static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
2030b57cec5SDimitry Andric if (!TheCFG)
2040b57cec5SDimitry Andric return;
2050b57cec5SDimitry Andric
2060b57cec5SDimitry Andric for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(),
2070b57cec5SDimitry Andric E = TheCFG->synthetic_stmt_end();
2080b57cec5SDimitry Andric I != E; ++I) {
2090b57cec5SDimitry Andric PM.setParent(I->first, PM.getParent(I->second));
2100b57cec5SDimitry Andric }
2110b57cec5SDimitry Andric }
2120b57cec5SDimitry Andric
getCFG()2130b57cec5SDimitry Andric CFG *AnalysisDeclContext::getCFG() {
2140b57cec5SDimitry Andric if (!cfgBuildOptions.PruneTriviallyFalseEdges)
2150b57cec5SDimitry Andric return getUnoptimizedCFG();
2160b57cec5SDimitry Andric
2170b57cec5SDimitry Andric if (!builtCFG) {
2180b57cec5SDimitry Andric cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
2190b57cec5SDimitry Andric // Even when the cfg is not successfully built, we don't
2200b57cec5SDimitry Andric // want to try building it again.
2210b57cec5SDimitry Andric builtCFG = true;
2220b57cec5SDimitry Andric
2230b57cec5SDimitry Andric if (PM)
2240b57cec5SDimitry Andric addParentsForSyntheticStmts(cfg.get(), *PM);
2250b57cec5SDimitry Andric
2260b57cec5SDimitry Andric // The Observer should only observe one build of the CFG.
2270b57cec5SDimitry Andric getCFGBuildOptions().Observer = nullptr;
2280b57cec5SDimitry Andric }
2290b57cec5SDimitry Andric return cfg.get();
2300b57cec5SDimitry Andric }
2310b57cec5SDimitry Andric
getUnoptimizedCFG()2320b57cec5SDimitry Andric CFG *AnalysisDeclContext::getUnoptimizedCFG() {
2330b57cec5SDimitry Andric if (!builtCompleteCFG) {
234*bdd1243dSDimitry Andric SaveAndRestore NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges, false);
2350b57cec5SDimitry Andric completeCFG =
2360b57cec5SDimitry Andric CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
2370b57cec5SDimitry Andric // Even when the cfg is not successfully built, we don't
2380b57cec5SDimitry Andric // want to try building it again.
2390b57cec5SDimitry Andric builtCompleteCFG = true;
2400b57cec5SDimitry Andric
2410b57cec5SDimitry Andric if (PM)
2420b57cec5SDimitry Andric addParentsForSyntheticStmts(completeCFG.get(), *PM);
2430b57cec5SDimitry Andric
2440b57cec5SDimitry Andric // The Observer should only observe one build of the CFG.
2450b57cec5SDimitry Andric getCFGBuildOptions().Observer = nullptr;
2460b57cec5SDimitry Andric }
2470b57cec5SDimitry Andric return completeCFG.get();
2480b57cec5SDimitry Andric }
2490b57cec5SDimitry Andric
getCFGStmtMap()2500b57cec5SDimitry Andric CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
2510b57cec5SDimitry Andric if (cfgStmtMap)
2520b57cec5SDimitry Andric return cfgStmtMap.get();
2530b57cec5SDimitry Andric
2540b57cec5SDimitry Andric if (CFG *c = getCFG()) {
2550b57cec5SDimitry Andric cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
2560b57cec5SDimitry Andric return cfgStmtMap.get();
2570b57cec5SDimitry Andric }
2580b57cec5SDimitry Andric
2590b57cec5SDimitry Andric return nullptr;
2600b57cec5SDimitry Andric }
2610b57cec5SDimitry Andric
getCFGReachablityAnalysis()2620b57cec5SDimitry Andric CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
2630b57cec5SDimitry Andric if (CFA)
2640b57cec5SDimitry Andric return CFA.get();
2650b57cec5SDimitry Andric
2660b57cec5SDimitry Andric if (CFG *c = getCFG()) {
2670b57cec5SDimitry Andric CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
2680b57cec5SDimitry Andric return CFA.get();
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andric return nullptr;
2720b57cec5SDimitry Andric }
2730b57cec5SDimitry Andric
dumpCFG(bool ShowColors)2740b57cec5SDimitry Andric void AnalysisDeclContext::dumpCFG(bool ShowColors) {
2750b57cec5SDimitry Andric getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
2760b57cec5SDimitry Andric }
2770b57cec5SDimitry Andric
getParentMap()2780b57cec5SDimitry Andric ParentMap &AnalysisDeclContext::getParentMap() {
2790b57cec5SDimitry Andric if (!PM) {
2800b57cec5SDimitry Andric PM.reset(new ParentMap(getBody()));
2810b57cec5SDimitry Andric if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
2820b57cec5SDimitry Andric for (const auto *I : C->inits()) {
2830b57cec5SDimitry Andric PM->addStmt(I->getInit());
2840b57cec5SDimitry Andric }
2850b57cec5SDimitry Andric }
2860b57cec5SDimitry Andric if (builtCFG)
2870b57cec5SDimitry Andric addParentsForSyntheticStmts(getCFG(), *PM);
2880b57cec5SDimitry Andric if (builtCompleteCFG)
2890b57cec5SDimitry Andric addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);
2900b57cec5SDimitry Andric }
2910b57cec5SDimitry Andric return *PM;
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric
getContext(const Decl * D)2940b57cec5SDimitry Andric AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
2950b57cec5SDimitry Andric if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
2960b57cec5SDimitry Andric // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
2970b57cec5SDimitry Andric // that has the body.
2980b57cec5SDimitry Andric FD->hasBody(FD);
2990b57cec5SDimitry Andric D = FD;
3000b57cec5SDimitry Andric }
3010b57cec5SDimitry Andric
3020b57cec5SDimitry Andric std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
3030b57cec5SDimitry Andric if (!AC)
304a7dea167SDimitry Andric AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
3050b57cec5SDimitry Andric return AC.get();
3060b57cec5SDimitry Andric }
3070b57cec5SDimitry Andric
getBodyFarm()3080b57cec5SDimitry Andric BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; }
3090b57cec5SDimitry Andric
3100b57cec5SDimitry Andric const StackFrameContext *
getStackFrame(const LocationContext * ParentLC,const Stmt * S,const CFGBlock * Blk,unsigned BlockCount,unsigned Index)3115ffd83dbSDimitry Andric AnalysisDeclContext::getStackFrame(const LocationContext *ParentLC,
3125ffd83dbSDimitry Andric const Stmt *S, const CFGBlock *Blk,
3135ffd83dbSDimitry Andric unsigned BlockCount, unsigned Index) {
3145ffd83dbSDimitry Andric return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,
3155ffd83dbSDimitry Andric BlockCount, Index);
3160b57cec5SDimitry Andric }
3170b57cec5SDimitry Andric
getBlockInvocationContext(const LocationContext * ParentLC,const BlockDecl * BD,const void * Data)3185ffd83dbSDimitry Andric const BlockInvocationContext *AnalysisDeclContext::getBlockInvocationContext(
3195ffd83dbSDimitry Andric const LocationContext *ParentLC, const BlockDecl *BD, const void *Data) {
3205ffd83dbSDimitry Andric return getLocationContextManager().getBlockInvocationContext(this, ParentLC,
3215ffd83dbSDimitry Andric BD, Data);
3220b57cec5SDimitry Andric }
3230b57cec5SDimitry Andric
isInStdNamespace(const Decl * D)3240b57cec5SDimitry Andric bool AnalysisDeclContext::isInStdNamespace(const Decl *D) {
3250b57cec5SDimitry Andric const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
3260b57cec5SDimitry Andric const auto *ND = dyn_cast<NamespaceDecl>(DC);
3270b57cec5SDimitry Andric if (!ND)
3280b57cec5SDimitry Andric return false;
3290b57cec5SDimitry Andric
3300b57cec5SDimitry Andric while (const DeclContext *Parent = ND->getParent()) {
3310b57cec5SDimitry Andric if (!isa<NamespaceDecl>(Parent))
3320b57cec5SDimitry Andric break;
3330b57cec5SDimitry Andric ND = cast<NamespaceDecl>(Parent);
3340b57cec5SDimitry Andric }
3350b57cec5SDimitry Andric
3360b57cec5SDimitry Andric return ND->isStdNamespace();
3370b57cec5SDimitry Andric }
3380b57cec5SDimitry Andric
getFunctionName(const Decl * D)339fe6060f1SDimitry Andric std::string AnalysisDeclContext::getFunctionName(const Decl *D) {
340fe6060f1SDimitry Andric std::string Str;
341fe6060f1SDimitry Andric llvm::raw_string_ostream OS(Str);
342fe6060f1SDimitry Andric const ASTContext &Ctx = D->getASTContext();
343fe6060f1SDimitry Andric
344fe6060f1SDimitry Andric if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
345fe6060f1SDimitry Andric OS << FD->getQualifiedNameAsString();
346fe6060f1SDimitry Andric
347fe6060f1SDimitry Andric // In C++, there are overloads.
348fe6060f1SDimitry Andric
349fe6060f1SDimitry Andric if (Ctx.getLangOpts().CPlusPlus) {
350fe6060f1SDimitry Andric OS << '(';
351fe6060f1SDimitry Andric for (const auto &P : FD->parameters()) {
352fe6060f1SDimitry Andric if (P != *FD->param_begin())
353fe6060f1SDimitry Andric OS << ", ";
35481ad6265SDimitry Andric OS << P->getType();
355fe6060f1SDimitry Andric }
356fe6060f1SDimitry Andric OS << ')';
357fe6060f1SDimitry Andric }
358fe6060f1SDimitry Andric
359fe6060f1SDimitry Andric } else if (isa<BlockDecl>(D)) {
360fe6060f1SDimitry Andric PresumedLoc Loc = Ctx.getSourceManager().getPresumedLoc(D->getLocation());
361fe6060f1SDimitry Andric
362fe6060f1SDimitry Andric if (Loc.isValid()) {
363fe6060f1SDimitry Andric OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
364fe6060f1SDimitry Andric << ')';
365fe6060f1SDimitry Andric }
366fe6060f1SDimitry Andric
367fe6060f1SDimitry Andric } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
368fe6060f1SDimitry Andric
369fe6060f1SDimitry Andric // FIXME: copy-pasted from CGDebugInfo.cpp.
370fe6060f1SDimitry Andric OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
371fe6060f1SDimitry Andric const DeclContext *DC = OMD->getDeclContext();
372fe6060f1SDimitry Andric if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
373fe6060f1SDimitry Andric OS << OID->getName();
374fe6060f1SDimitry Andric } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
375fe6060f1SDimitry Andric OS << OID->getName();
376fe6060f1SDimitry Andric } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
377fe6060f1SDimitry Andric if (OC->IsClassExtension()) {
378fe6060f1SDimitry Andric OS << OC->getClassInterface()->getName();
379fe6060f1SDimitry Andric } else {
380fe6060f1SDimitry Andric OS << OC->getIdentifier()->getNameStart() << '('
381fe6060f1SDimitry Andric << OC->getIdentifier()->getNameStart() << ')';
382fe6060f1SDimitry Andric }
383fe6060f1SDimitry Andric } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
384fe6060f1SDimitry Andric OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')';
385fe6060f1SDimitry Andric }
386fe6060f1SDimitry Andric OS << ' ' << OMD->getSelector().getAsString() << ']';
387fe6060f1SDimitry Andric }
388fe6060f1SDimitry Andric
3890eae32dcSDimitry Andric return Str;
390fe6060f1SDimitry Andric }
391fe6060f1SDimitry Andric
getLocationContextManager()3920b57cec5SDimitry Andric LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
3935ffd83dbSDimitry Andric assert(
3945ffd83dbSDimitry Andric ADCMgr &&
3950b57cec5SDimitry Andric "Cannot create LocationContexts without an AnalysisDeclContextManager!");
3965ffd83dbSDimitry Andric return ADCMgr->getLocationContextManager();
3970b57cec5SDimitry Andric }
3980b57cec5SDimitry Andric
3990b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4000b57cec5SDimitry Andric // FoldingSet profiling.
4010b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4020b57cec5SDimitry Andric
ProfileCommon(llvm::FoldingSetNodeID & ID,ContextKind ck,AnalysisDeclContext * ctx,const LocationContext * parent,const void * data)4030b57cec5SDimitry Andric void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
4040b57cec5SDimitry Andric ContextKind ck,
4050b57cec5SDimitry Andric AnalysisDeclContext *ctx,
4060b57cec5SDimitry Andric const LocationContext *parent,
4070b57cec5SDimitry Andric const void *data) {
4080b57cec5SDimitry Andric ID.AddInteger(ck);
4090b57cec5SDimitry Andric ID.AddPointer(ctx);
4100b57cec5SDimitry Andric ID.AddPointer(parent);
4110b57cec5SDimitry Andric ID.AddPointer(data);
4120b57cec5SDimitry Andric }
4130b57cec5SDimitry Andric
Profile(llvm::FoldingSetNodeID & ID)4140b57cec5SDimitry Andric void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
415a7dea167SDimitry Andric Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,
416a7dea167SDimitry Andric BlockCount, Index);
4170b57cec5SDimitry Andric }
4180b57cec5SDimitry Andric
Profile(llvm::FoldingSetNodeID & ID)4190b57cec5SDimitry Andric void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
4205ffd83dbSDimitry Andric Profile(ID, getAnalysisDeclContext(), getParent(), BD, Data);
4210b57cec5SDimitry Andric }
4220b57cec5SDimitry Andric
4230b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4240b57cec5SDimitry Andric // LocationContext creation.
4250b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4260b57cec5SDimitry Andric
getStackFrame(AnalysisDeclContext * ctx,const LocationContext * parent,const Stmt * s,const CFGBlock * blk,unsigned blockCount,unsigned idx)427a7dea167SDimitry Andric const StackFrameContext *LocationContextManager::getStackFrame(
428a7dea167SDimitry Andric AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,
429a7dea167SDimitry Andric const CFGBlock *blk, unsigned blockCount, unsigned idx) {
4300b57cec5SDimitry Andric llvm::FoldingSetNodeID ID;
431a7dea167SDimitry Andric StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);
4320b57cec5SDimitry Andric void *InsertPos;
4330b57cec5SDimitry Andric auto *L =
4340b57cec5SDimitry Andric cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
4350b57cec5SDimitry Andric if (!L) {
436a7dea167SDimitry Andric L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);
4370b57cec5SDimitry Andric Contexts.InsertNode(L, InsertPos);
4380b57cec5SDimitry Andric }
4390b57cec5SDimitry Andric return L;
4400b57cec5SDimitry Andric }
4410b57cec5SDimitry Andric
getBlockInvocationContext(AnalysisDeclContext * ADC,const LocationContext * ParentLC,const BlockDecl * BD,const void * Data)4425ffd83dbSDimitry Andric const BlockInvocationContext *LocationContextManager::getBlockInvocationContext(
4435ffd83dbSDimitry Andric AnalysisDeclContext *ADC, const LocationContext *ParentLC,
4445ffd83dbSDimitry Andric const BlockDecl *BD, const void *Data) {
4450b57cec5SDimitry Andric llvm::FoldingSetNodeID ID;
4465ffd83dbSDimitry Andric BlockInvocationContext::Profile(ID, ADC, ParentLC, BD, Data);
4470b57cec5SDimitry Andric void *InsertPos;
4480b57cec5SDimitry Andric auto *L =
4490b57cec5SDimitry Andric cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
4500b57cec5SDimitry Andric InsertPos));
4510b57cec5SDimitry Andric if (!L) {
4525ffd83dbSDimitry Andric L = new BlockInvocationContext(ADC, ParentLC, BD, Data, ++NewID);
4530b57cec5SDimitry Andric Contexts.InsertNode(L, InsertPos);
4540b57cec5SDimitry Andric }
4550b57cec5SDimitry Andric return L;
4560b57cec5SDimitry Andric }
4570b57cec5SDimitry Andric
4580b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4590b57cec5SDimitry Andric // LocationContext methods.
4600b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4610b57cec5SDimitry Andric
getStackFrame() const4620b57cec5SDimitry Andric const StackFrameContext *LocationContext::getStackFrame() const {
4630b57cec5SDimitry Andric const LocationContext *LC = this;
4640b57cec5SDimitry Andric while (LC) {
4650b57cec5SDimitry Andric if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
4660b57cec5SDimitry Andric return SFC;
4670b57cec5SDimitry Andric LC = LC->getParent();
4680b57cec5SDimitry Andric }
4690b57cec5SDimitry Andric return nullptr;
4700b57cec5SDimitry Andric }
4710b57cec5SDimitry Andric
inTopFrame() const4720b57cec5SDimitry Andric bool LocationContext::inTopFrame() const {
4730b57cec5SDimitry Andric return getStackFrame()->inTopFrame();
4740b57cec5SDimitry Andric }
4750b57cec5SDimitry Andric
isParentOf(const LocationContext * LC) const4760b57cec5SDimitry Andric bool LocationContext::isParentOf(const LocationContext *LC) const {
4770b57cec5SDimitry Andric do {
4780b57cec5SDimitry Andric const LocationContext *Parent = LC->getParent();
4790b57cec5SDimitry Andric if (Parent == this)
4800b57cec5SDimitry Andric return true;
4810b57cec5SDimitry Andric else
4820b57cec5SDimitry Andric LC = Parent;
4830b57cec5SDimitry Andric } while (LC);
4840b57cec5SDimitry Andric
4850b57cec5SDimitry Andric return false;
4860b57cec5SDimitry Andric }
4870b57cec5SDimitry Andric
printLocation(raw_ostream & Out,const SourceManager & SM,SourceLocation Loc)4880b57cec5SDimitry Andric static void printLocation(raw_ostream &Out, const SourceManager &SM,
4890b57cec5SDimitry Andric SourceLocation Loc) {
4900b57cec5SDimitry Andric if (Loc.isFileID() && SM.isInMainFile(Loc))
4910b57cec5SDimitry Andric Out << SM.getExpansionLineNumber(Loc);
4920b57cec5SDimitry Andric else
4930b57cec5SDimitry Andric Loc.print(Out, SM);
4940b57cec5SDimitry Andric }
4950b57cec5SDimitry Andric
dumpStack(raw_ostream & Out) const4965ffd83dbSDimitry Andric void LocationContext::dumpStack(raw_ostream &Out) const {
4970b57cec5SDimitry Andric ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
4980b57cec5SDimitry Andric PrintingPolicy PP(Ctx.getLangOpts());
4990b57cec5SDimitry Andric PP.TerseOutput = 1;
5000b57cec5SDimitry Andric
5010b57cec5SDimitry Andric const SourceManager &SM =
5020b57cec5SDimitry Andric getAnalysisDeclContext()->getASTContext().getSourceManager();
5030b57cec5SDimitry Andric
5040b57cec5SDimitry Andric unsigned Frame = 0;
5050b57cec5SDimitry Andric for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
5060b57cec5SDimitry Andric switch (LCtx->getKind()) {
5070b57cec5SDimitry Andric case StackFrame:
5080b57cec5SDimitry Andric Out << "\t#" << Frame << ' ';
5090b57cec5SDimitry Andric ++Frame;
5100b57cec5SDimitry Andric if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
511fe6060f1SDimitry Andric Out << "Calling " << AnalysisDeclContext::getFunctionName(D);
5120b57cec5SDimitry Andric else
5130b57cec5SDimitry Andric Out << "Calling anonymous code";
5140b57cec5SDimitry Andric if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
5150b57cec5SDimitry Andric Out << " at line ";
5160b57cec5SDimitry Andric printLocation(Out, SM, S->getBeginLoc());
5170b57cec5SDimitry Andric }
5180b57cec5SDimitry Andric break;
5190b57cec5SDimitry Andric case Block:
5200b57cec5SDimitry Andric Out << "Invoking block";
5210b57cec5SDimitry Andric if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
5220b57cec5SDimitry Andric Out << " defined at line ";
5230b57cec5SDimitry Andric printLocation(Out, SM, D->getBeginLoc());
5240b57cec5SDimitry Andric }
5250b57cec5SDimitry Andric break;
5260b57cec5SDimitry Andric }
5275ffd83dbSDimitry Andric Out << '\n';
5280b57cec5SDimitry Andric }
5290b57cec5SDimitry Andric }
5300b57cec5SDimitry Andric
printJson(raw_ostream & Out,const char * NL,unsigned int Space,bool IsDot,std::function<void (const LocationContext *)> printMoreInfoPerContext) const5310b57cec5SDimitry Andric void LocationContext::printJson(raw_ostream &Out, const char *NL,
5320b57cec5SDimitry Andric unsigned int Space, bool IsDot,
5330b57cec5SDimitry Andric std::function<void(const LocationContext *)>
5340b57cec5SDimitry Andric printMoreInfoPerContext) const {
5350b57cec5SDimitry Andric ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
5360b57cec5SDimitry Andric PrintingPolicy PP(Ctx.getLangOpts());
5370b57cec5SDimitry Andric PP.TerseOutput = 1;
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andric const SourceManager &SM =
5400b57cec5SDimitry Andric getAnalysisDeclContext()->getASTContext().getSourceManager();
5410b57cec5SDimitry Andric
5420b57cec5SDimitry Andric unsigned Frame = 0;
5430b57cec5SDimitry Andric for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
5440b57cec5SDimitry Andric Indent(Out, Space, IsDot)
5450b57cec5SDimitry Andric << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
5460b57cec5SDimitry Andric switch (LCtx->getKind()) {
5470b57cec5SDimitry Andric case StackFrame:
5480b57cec5SDimitry Andric Out << '#' << Frame << " Call\", \"calling\": \"";
5490b57cec5SDimitry Andric ++Frame;
5500b57cec5SDimitry Andric if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
5510b57cec5SDimitry Andric Out << D->getQualifiedNameAsString();
5520b57cec5SDimitry Andric else
5530b57cec5SDimitry Andric Out << "anonymous code";
5540b57cec5SDimitry Andric
5550b57cec5SDimitry Andric Out << "\", \"location\": ";
5560b57cec5SDimitry Andric if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
5570b57cec5SDimitry Andric printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
5580b57cec5SDimitry Andric } else {
5590b57cec5SDimitry Andric Out << "null";
5600b57cec5SDimitry Andric }
5610b57cec5SDimitry Andric
5620b57cec5SDimitry Andric Out << ", \"items\": ";
5630b57cec5SDimitry Andric break;
5640b57cec5SDimitry Andric case Block:
5650b57cec5SDimitry Andric Out << "Invoking block\" ";
5660b57cec5SDimitry Andric if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
5670b57cec5SDimitry Andric Out << ", \"location\": ";
5680b57cec5SDimitry Andric printSourceLocationAsJson(Out, D->getBeginLoc(), SM);
5690b57cec5SDimitry Andric Out << ' ';
5700b57cec5SDimitry Andric }
5710b57cec5SDimitry Andric break;
5720b57cec5SDimitry Andric }
5730b57cec5SDimitry Andric
5740b57cec5SDimitry Andric printMoreInfoPerContext(LCtx);
5750b57cec5SDimitry Andric
5760b57cec5SDimitry Andric Out << '}';
5770b57cec5SDimitry Andric if (LCtx->getParent())
5780b57cec5SDimitry Andric Out << ',';
5790b57cec5SDimitry Andric Out << NL;
5800b57cec5SDimitry Andric }
5810b57cec5SDimitry Andric }
5820b57cec5SDimitry Andric
dump() const5830b57cec5SDimitry Andric LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); }
5840b57cec5SDimitry Andric
5850b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5860b57cec5SDimitry Andric // Lazily generated map to query the external variables referenced by a Block.
5870b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5880b57cec5SDimitry Andric
5890b57cec5SDimitry Andric namespace {
5900b57cec5SDimitry Andric
5910b57cec5SDimitry Andric class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
5920b57cec5SDimitry Andric BumpVector<const VarDecl *> &BEVals;
5930b57cec5SDimitry Andric BumpVectorContext &BC;
5940b57cec5SDimitry Andric llvm::SmallPtrSet<const VarDecl *, 4> Visited;
5950b57cec5SDimitry Andric llvm::SmallPtrSet<const DeclContext *, 4> IgnoredContexts;
5960b57cec5SDimitry Andric
5970b57cec5SDimitry Andric public:
FindBlockDeclRefExprsVals(BumpVector<const VarDecl * > & bevals,BumpVectorContext & bc)5980b57cec5SDimitry Andric FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
5990b57cec5SDimitry Andric BumpVectorContext &bc)
6000b57cec5SDimitry Andric : BEVals(bevals), BC(bc) {}
6010b57cec5SDimitry Andric
VisitStmt(Stmt * S)6020b57cec5SDimitry Andric void VisitStmt(Stmt *S) {
6030b57cec5SDimitry Andric for (auto *Child : S->children())
6040b57cec5SDimitry Andric if (Child)
6050b57cec5SDimitry Andric Visit(Child);
6060b57cec5SDimitry Andric }
6070b57cec5SDimitry Andric
VisitDeclRefExpr(DeclRefExpr * DR)6080b57cec5SDimitry Andric void VisitDeclRefExpr(DeclRefExpr *DR) {
6090b57cec5SDimitry Andric // Non-local variables are also directly modified.
6100b57cec5SDimitry Andric if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
6110b57cec5SDimitry Andric if (!VD->hasLocalStorage()) {
6120b57cec5SDimitry Andric if (Visited.insert(VD).second)
6130b57cec5SDimitry Andric BEVals.push_back(VD, BC);
6140b57cec5SDimitry Andric }
6150b57cec5SDimitry Andric }
6160b57cec5SDimitry Andric }
6170b57cec5SDimitry Andric
VisitBlockExpr(BlockExpr * BR)6180b57cec5SDimitry Andric void VisitBlockExpr(BlockExpr *BR) {
6190b57cec5SDimitry Andric // Blocks containing blocks can transitively capture more variables.
6200b57cec5SDimitry Andric IgnoredContexts.insert(BR->getBlockDecl());
6210b57cec5SDimitry Andric Visit(BR->getBlockDecl()->getBody());
6220b57cec5SDimitry Andric }
6230b57cec5SDimitry Andric
VisitPseudoObjectExpr(PseudoObjectExpr * PE)6240b57cec5SDimitry Andric void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
6250b57cec5SDimitry Andric for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(),
6260b57cec5SDimitry Andric et = PE->semantics_end(); it != et; ++it) {
6270b57cec5SDimitry Andric Expr *Semantic = *it;
6280b57cec5SDimitry Andric if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
6290b57cec5SDimitry Andric Semantic = OVE->getSourceExpr();
6300b57cec5SDimitry Andric Visit(Semantic);
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric }
6330b57cec5SDimitry Andric };
6340b57cec5SDimitry Andric
6350b57cec5SDimitry Andric } // namespace
6360b57cec5SDimitry Andric
6370b57cec5SDimitry Andric using DeclVec = BumpVector<const VarDecl *>;
6380b57cec5SDimitry Andric
LazyInitializeReferencedDecls(const BlockDecl * BD,void * & Vec,llvm::BumpPtrAllocator & A)6390b57cec5SDimitry Andric static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,
6400b57cec5SDimitry Andric void *&Vec,
6410b57cec5SDimitry Andric llvm::BumpPtrAllocator &A) {
6420b57cec5SDimitry Andric if (Vec)
6430b57cec5SDimitry Andric return (DeclVec*) Vec;
6440b57cec5SDimitry Andric
6450b57cec5SDimitry Andric BumpVectorContext BC(A);
6460b57cec5SDimitry Andric DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
6470b57cec5SDimitry Andric new (BV) DeclVec(BC, 10);
6480b57cec5SDimitry Andric
6490b57cec5SDimitry Andric // Go through the capture list.
6500b57cec5SDimitry Andric for (const auto &CI : BD->captures()) {
6510b57cec5SDimitry Andric BV->push_back(CI.getVariable(), BC);
6520b57cec5SDimitry Andric }
6530b57cec5SDimitry Andric
6540b57cec5SDimitry Andric // Find the referenced global/static variables.
6550b57cec5SDimitry Andric FindBlockDeclRefExprsVals F(*BV, BC);
6560b57cec5SDimitry Andric F.Visit(BD->getBody());
6570b57cec5SDimitry Andric
6580b57cec5SDimitry Andric Vec = BV;
6590b57cec5SDimitry Andric return BV;
6600b57cec5SDimitry Andric }
6610b57cec5SDimitry Andric
6620b57cec5SDimitry Andric llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
getReferencedBlockVars(const BlockDecl * BD)6630b57cec5SDimitry Andric AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {
6640b57cec5SDimitry Andric if (!ReferencedBlockVars)
6650b57cec5SDimitry Andric ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
6660b57cec5SDimitry Andric
6670b57cec5SDimitry Andric const DeclVec *V =
6680b57cec5SDimitry Andric LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
6690b57cec5SDimitry Andric return llvm::make_range(V->begin(), V->end());
6700b57cec5SDimitry Andric }
6710b57cec5SDimitry Andric
getAnalysisImpl(const void * tag)6725ffd83dbSDimitry Andric std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
6730b57cec5SDimitry Andric if (!ManagedAnalyses)
6740b57cec5SDimitry Andric ManagedAnalyses = new ManagedAnalysisMap();
6750b57cec5SDimitry Andric ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
6760b57cec5SDimitry Andric return (*M)[tag];
6770b57cec5SDimitry Andric }
6780b57cec5SDimitry Andric
6790b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6800b57cec5SDimitry Andric // Cleanup.
6810b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6820b57cec5SDimitry Andric
6830b57cec5SDimitry Andric ManagedAnalysis::~ManagedAnalysis() = default;
6840b57cec5SDimitry Andric
~AnalysisDeclContext()6850b57cec5SDimitry Andric AnalysisDeclContext::~AnalysisDeclContext() {
6860b57cec5SDimitry Andric delete forcedBlkExprs;
6870b57cec5SDimitry Andric delete ReferencedBlockVars;
6885ffd83dbSDimitry Andric delete (ManagedAnalysisMap*) ManagedAnalyses;
6890b57cec5SDimitry Andric }
6900b57cec5SDimitry Andric
6910b57cec5SDimitry Andric LocationContext::~LocationContext() = default;
6920b57cec5SDimitry Andric
~LocationContextManager()6930b57cec5SDimitry Andric LocationContextManager::~LocationContextManager() {
6940b57cec5SDimitry Andric clear();
6950b57cec5SDimitry Andric }
6960b57cec5SDimitry Andric
clear()6970b57cec5SDimitry Andric void LocationContextManager::clear() {
6980b57cec5SDimitry Andric for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
6990b57cec5SDimitry Andric E = Contexts.end(); I != E; ) {
7000b57cec5SDimitry Andric LocationContext *LC = &*I;
7010b57cec5SDimitry Andric ++I;
7020b57cec5SDimitry Andric delete LC;
7030b57cec5SDimitry Andric }
7040b57cec5SDimitry Andric Contexts.clear();
7050b57cec5SDimitry Andric }
706