11c1057afSEugene Zelenko //===- AnalysisDeclContext.cpp - Analysis context for Path Sens analysis --===//
26f2e6522SChandler Carruth //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66f2e6522SChandler Carruth //
76f2e6522SChandler Carruth //===----------------------------------------------------------------------===//
86f2e6522SChandler Carruth //
91c1057afSEugene Zelenko // This file defines AnalysisDeclContext, a class that manages the analysis
101c1057afSEugene Zelenko // context data for path sensitive analysis.
116f2e6522SChandler Carruth //
126f2e6522SChandler Carruth //===----------------------------------------------------------------------===//
136f2e6522SChandler Carruth
1450657f6bSGeorge Karpenkov #include "clang/Analysis/AnalysisDeclContext.h"
154ab984e7SBenjamin Kramer #include "clang/AST/ASTContext.h"
166f2e6522SChandler Carruth #include "clang/AST/Decl.h"
171c1057afSEugene Zelenko #include "clang/AST/DeclBase.h"
181c1057afSEugene Zelenko #include "clang/AST/DeclCXX.h"
196f2e6522SChandler Carruth #include "clang/AST/DeclObjC.h"
206f2e6522SChandler Carruth #include "clang/AST/DeclTemplate.h"
211c1057afSEugene Zelenko #include "clang/AST/Expr.h"
221c1057afSEugene Zelenko #include "clang/AST/LambdaCapture.h"
236f2e6522SChandler Carruth #include "clang/AST/ParentMap.h"
241c1057afSEugene Zelenko #include "clang/AST/PrettyPrinter.h"
251c1057afSEugene Zelenko #include "clang/AST/Stmt.h"
261c1057afSEugene Zelenko #include "clang/AST/StmtCXX.h"
276f2e6522SChandler Carruth #include "clang/AST/StmtVisitor.h"
283a02247dSChandler Carruth #include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
293d64d6eeSGeorge Karpenkov #include "clang/Analysis/BodyFarm.h"
306f2e6522SChandler Carruth #include "clang/Analysis/CFG.h"
316f2e6522SChandler Carruth #include "clang/Analysis/CFGStmtMap.h"
326f2e6522SChandler Carruth #include "clang/Analysis/Support/BumpVector.h"
339ce37466SCsaba Dabis #include "clang/Basic/JsonSupport.h"
341c1057afSEugene Zelenko #include "clang/Basic/LLVM.h"
351c1057afSEugene Zelenko #include "clang/Basic/SourceLocation.h"
361c1057afSEugene Zelenko #include "clang/Basic/SourceManager.h"
371c1057afSEugene Zelenko #include "llvm/ADT/DenseMap.h"
381c1057afSEugene Zelenko #include "llvm/ADT/FoldingSet.h"
391c1057afSEugene Zelenko #include "llvm/ADT/STLExtras.h"
40616f8022SBenjamin Kramer #include "llvm/ADT/SmallPtrSet.h"
411c1057afSEugene Zelenko #include "llvm/ADT/iterator_range.h"
421c1057afSEugene Zelenko #include "llvm/Support/Allocator.h"
431c1057afSEugene Zelenko #include "llvm/Support/Casting.h"
441c1057afSEugene Zelenko #include "llvm/Support/Compiler.h"
456f2e6522SChandler Carruth #include "llvm/Support/ErrorHandling.h"
463a02247dSChandler Carruth #include "llvm/Support/SaveAndRestore.h"
475553d0d4SChandler Carruth #include "llvm/Support/raw_ostream.h"
481c1057afSEugene Zelenko #include <cassert>
491c1057afSEugene Zelenko #include <memory>
5014f779c4STed Kremenek
516f2e6522SChandler Carruth using namespace clang;
526f2e6522SChandler Carruth
53e265f92bSDavid Blaikie using ManagedAnalysisMap = llvm::DenseMap<const void *, std::unique_ptr<ManagedAnalysis>>;
546f2e6522SChandler Carruth
AnalysisDeclContext(AnalysisDeclContextManager * ADCMgr,const Decl * D,const CFG::BuildOptions & Options)557e1a6ca9SCharusso AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
567e1a6ca9SCharusso const Decl *D,
577e1a6ca9SCharusso const CFG::BuildOptions &Options)
587e1a6ca9SCharusso : ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {
596f2e6522SChandler Carruth cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
606f2e6522SChandler Carruth }
616f2e6522SChandler Carruth
AnalysisDeclContext(AnalysisDeclContextManager * ADCMgr,const Decl * D)627e1a6ca9SCharusso AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
637e1a6ca9SCharusso const Decl *D)
647e1a6ca9SCharusso : ADCMgr(ADCMgr), D(D) {
656f2e6522SChandler Carruth cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
666f2e6522SChandler Carruth }
676f2e6522SChandler Carruth
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)683d64d6eeSGeorge Karpenkov AnalysisDeclContextManager::AnalysisDeclContextManager(
693d64d6eeSGeorge Karpenkov ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors,
703d64d6eeSGeorge Karpenkov bool addInitializers, bool addTemporaryDtors, bool addLifetime,
71debca45eSMaxim Ostapenko bool addLoopExit, bool addScopes, bool synthesizeBodies,
72debca45eSMaxim Ostapenko bool addStaticInitBranch, bool addCXXNewAllocator,
73ff267df0SArtem Dergachev bool addRichCXXConstructors, bool markElidedCXXConstructors,
74192a7474SArtem Dergachev bool addVirtualBaseBranches, CodeInjector *injector)
75050b53b3SGeorge Karpenkov : Injector(injector), FunctionBodyFarm(ASTCtx, injector),
76ed017b63SGeorge Karpenkov SynthesizeBodies(synthesizeBodies) {
776f2e6522SChandler Carruth cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
786f2e6522SChandler Carruth cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
796f2e6522SChandler Carruth cfgBuildOptions.AddInitializers = addInitializers;
806d671cc3SJordan Rose cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
81351c218dSMatthias Gehre cfgBuildOptions.AddLifetime = addLifetime;
82999a25ffSPeter Szecsi cfgBuildOptions.AddLoopExit = addLoopExit;
83debca45eSMaxim Ostapenko cfgBuildOptions.AddScopes = addScopes;
84233c1b0cSTed Kremenek cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
85c9176072SJordan Rose cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
8641ffb307SArtem Dergachev cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;
87ff267df0SArtem Dergachev cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;
88192a7474SArtem Dergachev cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;
896f2e6522SChandler Carruth }
906f2e6522SChandler Carruth
clear()915cb35e16SJustin Lebar void AnalysisDeclContextManager::clear() { Contexts.clear(); }
926f2e6522SChandler Carruth
getBody(bool & IsAutosynthesized) const9300c69a59SAnna Zaks Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
94cc4aaef0SNAKAMURA Takumi IsAutosynthesized = false;
951c1057afSEugene Zelenko if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
9614f779c4STed Kremenek Stmt *Body = FD->getBody();
97da8f9b5bSEric Fiselier if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
98da8f9b5bSEric Fiselier Body = CoroBody->getBody();
997e1a6ca9SCharusso if (ADCMgr && ADCMgr->synthesizeBodies()) {
1007e1a6ca9SCharusso Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);
1017646ebe6SDevin Coughlin if (SynthesizedBody) {
1027646ebe6SDevin Coughlin Body = SynthesizedBody;
10300c69a59SAnna Zaks IsAutosynthesized = true;
10400c69a59SAnna Zaks }
1057646ebe6SDevin Coughlin }
10614f779c4STed Kremenek return Body;
10714f779c4STed Kremenek }
1081c1057afSEugene Zelenko else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
1091a866cd5SJordan Rose Stmt *Body = MD->getBody();
1107e1a6ca9SCharusso if (ADCMgr && ADCMgr->synthesizeBodies()) {
1117e1a6ca9SCharusso Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(MD);
1127646ebe6SDevin Coughlin if (SynthesizedBody) {
1137646ebe6SDevin Coughlin Body = SynthesizedBody;
1141a866cd5SJordan Rose IsAutosynthesized = true;
1151a866cd5SJordan Rose }
1167646ebe6SDevin Coughlin }
1171a866cd5SJordan Rose return Body;
1181c1057afSEugene Zelenko } else if (const auto *BD = dyn_cast<BlockDecl>(D))
1196f2e6522SChandler Carruth return BD->getBody();
1201c1057afSEugene Zelenko else if (const auto *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
1216f2e6522SChandler Carruth return FunTmpl->getTemplatedDecl()->getBody();
1226f2e6522SChandler Carruth
1236f2e6522SChandler Carruth llvm_unreachable("unknown code decl");
1246f2e6522SChandler Carruth }
1256f2e6522SChandler Carruth
getBody() const12600c69a59SAnna Zaks Stmt *AnalysisDeclContext::getBody() const {
12700c69a59SAnna Zaks bool Tmp;
12800c69a59SAnna Zaks return getBody(Tmp);
12900c69a59SAnna Zaks }
13000c69a59SAnna Zaks
isBodyAutosynthesized() const13100c69a59SAnna Zaks bool AnalysisDeclContext::isBodyAutosynthesized() const {
13200c69a59SAnna Zaks bool Tmp;
13300c69a59SAnna Zaks getBody(Tmp);
13400c69a59SAnna Zaks return Tmp;
13500c69a59SAnna Zaks }
13600c69a59SAnna Zaks
isBodyAutosynthesizedFromModelFile() const137eeccb30bSTed Kremenek bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const {
138eeccb30bSTed Kremenek bool Tmp;
139eeccb30bSTed Kremenek Stmt *Body = getBody(Tmp);
140f2ceec48SStephen Kelly return Tmp && Body->getBeginLoc().isValid();
141eeccb30bSTed Kremenek }
142eeccb30bSTed Kremenek
143c289b74bSDevin Coughlin /// Returns true if \param VD is an Objective-C implicit 'self' parameter.
isSelfDecl(const VarDecl * VD)144c289b74bSDevin Coughlin static bool isSelfDecl(const VarDecl *VD) {
145c289b74bSDevin Coughlin return isa<ImplicitParamDecl>(VD) && VD->getName() == "self";
146c289b74bSDevin Coughlin }
147eeccb30bSTed Kremenek
getSelfDecl() const1486f2e6522SChandler Carruth const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
1491c1057afSEugene Zelenko if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
1506f2e6522SChandler Carruth return MD->getSelfDecl();
1511c1057afSEugene Zelenko if (const auto *BD = dyn_cast<BlockDecl>(D)) {
152b39fcfaaSTed Kremenek // See if 'self' was captured by the block.
1539371dd22SAaron Ballman for (const auto &I : BD->captures()) {
1549371dd22SAaron Ballman const VarDecl *VD = I.getVariable();
155c289b74bSDevin Coughlin if (isSelfDecl(VD))
156b39fcfaaSTed Kremenek return dyn_cast<ImplicitParamDecl>(VD);
157b39fcfaaSTed Kremenek }
158b39fcfaaSTed Kremenek }
1596f2e6522SChandler Carruth
1601d405832SDevin Coughlin auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
1611d405832SDevin Coughlin if (!CXXMethod)
1621d405832SDevin Coughlin return nullptr;
1631d405832SDevin Coughlin
1641d405832SDevin Coughlin const CXXRecordDecl *parent = CXXMethod->getParent();
1651d405832SDevin Coughlin if (!parent->isLambda())
1661d405832SDevin Coughlin return nullptr;
1671d405832SDevin Coughlin
1681c1057afSEugene Zelenko for (const auto &LC : parent->captures()) {
1691d405832SDevin Coughlin if (!LC.capturesVariable())
1701d405832SDevin Coughlin continue;
1711d405832SDevin Coughlin
1721d405832SDevin Coughlin VarDecl *VD = LC.getCapturedVar();
173c289b74bSDevin Coughlin if (isSelfDecl(VD))
1741d405832SDevin Coughlin return dyn_cast<ImplicitParamDecl>(VD);
1751d405832SDevin Coughlin }
1761d405832SDevin Coughlin
17725542943SCraig Topper return nullptr;
1786f2e6522SChandler Carruth }
1796f2e6522SChandler Carruth
registerForcedBlockExpression(const Stmt * stmt)1806f2e6522SChandler Carruth void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
1816f2e6522SChandler Carruth if (!forcedBlkExprs)
1826f2e6522SChandler Carruth forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
1836f2e6522SChandler Carruth // Default construct an entry for 'stmt'.
1841c1057afSEugene Zelenko if (const auto *e = dyn_cast<Expr>(stmt))
1856f2e6522SChandler Carruth stmt = e->IgnoreParens();
1866f2e6522SChandler Carruth (void) (*forcedBlkExprs)[stmt];
1876f2e6522SChandler Carruth }
1886f2e6522SChandler Carruth
1896f2e6522SChandler Carruth const CFGBlock *
getBlockForRegisteredExpression(const Stmt * stmt)1906f2e6522SChandler Carruth AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {
1916f2e6522SChandler Carruth assert(forcedBlkExprs);
1921c1057afSEugene Zelenko if (const auto *e = dyn_cast<Expr>(stmt))
1936f2e6522SChandler Carruth stmt = e->IgnoreParens();
1946f2e6522SChandler Carruth CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
1956f2e6522SChandler Carruth forcedBlkExprs->find(stmt);
1966f2e6522SChandler Carruth assert(itr != forcedBlkExprs->end());
1976f2e6522SChandler Carruth return itr->second;
1986f2e6522SChandler Carruth }
1996f2e6522SChandler Carruth
200cf10ea8cSJordan Rose /// Add each synthetic statement in the CFG to the parent map, using the
201cf10ea8cSJordan Rose /// source statement's parent.
addParentsForSyntheticStmts(const CFG * TheCFG,ParentMap & PM)202cf10ea8cSJordan Rose static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
203cf10ea8cSJordan Rose if (!TheCFG)
204cf10ea8cSJordan Rose return;
205cf10ea8cSJordan Rose
206cf10ea8cSJordan Rose for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(),
207cf10ea8cSJordan Rose E = TheCFG->synthetic_stmt_end();
208cf10ea8cSJordan Rose I != E; ++I) {
209cf10ea8cSJordan Rose PM.setParent(I->first, PM.getParent(I->second));
210cf10ea8cSJordan Rose }
211cf10ea8cSJordan Rose }
212cf10ea8cSJordan Rose
getCFG()2136f2e6522SChandler Carruth CFG *AnalysisDeclContext::getCFG() {
2146f2e6522SChandler Carruth if (!cfgBuildOptions.PruneTriviallyFalseEdges)
2156f2e6522SChandler Carruth return getUnoptimizedCFG();
2166f2e6522SChandler Carruth
2176f2e6522SChandler Carruth if (!builtCFG) {
218e90195c0SDavid Blaikie cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
2196f2e6522SChandler Carruth // Even when the cfg is not successfully built, we don't
2206f2e6522SChandler Carruth // want to try building it again.
2216f2e6522SChandler Carruth builtCFG = true;
222cf10ea8cSJordan Rose
223cf10ea8cSJordan Rose if (PM)
224cf10ea8cSJordan Rose addParentsForSyntheticStmts(cfg.get(), *PM);
225e9fa266cSRichard Trieu
226e729d9b5SRichard Trieu // The Observer should only observe one build of the CFG.
22725542943SCraig Topper getCFGBuildOptions().Observer = nullptr;
2286f2e6522SChandler Carruth }
2296f2e6522SChandler Carruth return cfg.get();
2306f2e6522SChandler Carruth }
2316f2e6522SChandler Carruth
getUnoptimizedCFG()2326f2e6522SChandler Carruth CFG *AnalysisDeclContext::getUnoptimizedCFG() {
2336f2e6522SChandler Carruth if (!builtCompleteCFG) {
2346f2e6522SChandler Carruth SaveAndRestore<bool> NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges,
2356f2e6522SChandler Carruth false);
236e90195c0SDavid Blaikie completeCFG =
237e90195c0SDavid Blaikie CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
2386f2e6522SChandler Carruth // Even when the cfg is not successfully built, we don't
2396f2e6522SChandler Carruth // want to try building it again.
2406f2e6522SChandler Carruth builtCompleteCFG = true;
241cf10ea8cSJordan Rose
242cf10ea8cSJordan Rose if (PM)
243cf10ea8cSJordan Rose addParentsForSyntheticStmts(completeCFG.get(), *PM);
244e9fa266cSRichard Trieu
245e729d9b5SRichard Trieu // The Observer should only observe one build of the CFG.
24625542943SCraig Topper getCFGBuildOptions().Observer = nullptr;
2476f2e6522SChandler Carruth }
2486f2e6522SChandler Carruth return completeCFG.get();
2496f2e6522SChandler Carruth }
2506f2e6522SChandler Carruth
getCFGStmtMap()2516f2e6522SChandler Carruth CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
2526f2e6522SChandler Carruth if (cfgStmtMap)
2536f2e6522SChandler Carruth return cfgStmtMap.get();
2546f2e6522SChandler Carruth
2556f2e6522SChandler Carruth if (CFG *c = getCFG()) {
2566f2e6522SChandler Carruth cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
2576f2e6522SChandler Carruth return cfgStmtMap.get();
2586f2e6522SChandler Carruth }
2596f2e6522SChandler Carruth
26025542943SCraig Topper return nullptr;
2616f2e6522SChandler Carruth }
2626f2e6522SChandler Carruth
getCFGReachablityAnalysis()2636f2e6522SChandler Carruth CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
2646f2e6522SChandler Carruth if (CFA)
2656f2e6522SChandler Carruth return CFA.get();
2666f2e6522SChandler Carruth
2676f2e6522SChandler Carruth if (CFG *c = getCFG()) {
2686f2e6522SChandler Carruth CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
2696f2e6522SChandler Carruth return CFA.get();
2706f2e6522SChandler Carruth }
2716f2e6522SChandler Carruth
27225542943SCraig Topper return nullptr;
2736f2e6522SChandler Carruth }
2746f2e6522SChandler Carruth
dumpCFG(bool ShowColors)27572be32afSTed Kremenek void AnalysisDeclContext::dumpCFG(bool ShowColors) {
276bbafb8a7SDavid Blaikie getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
2776f2e6522SChandler Carruth }
2786f2e6522SChandler Carruth
getParentMap()279433b0f54SJordan Rose ParentMap &AnalysisDeclContext::getParentMap() {
280433b0f54SJordan Rose if (!PM) {
281433b0f54SJordan Rose PM.reset(new ParentMap(getBody()));
2821c1057afSEugene Zelenko if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
2830ad78303SAaron Ballman for (const auto *I : C->inits()) {
2840ad78303SAaron Ballman PM->addStmt(I->getInit());
28525bc20f8SJordan Rose }
28625bc20f8SJordan Rose }
287cf10ea8cSJordan Rose if (builtCFG)
288cf10ea8cSJordan Rose addParentsForSyntheticStmts(getCFG(), *PM);
289cf10ea8cSJordan Rose if (builtCompleteCFG)
290cf10ea8cSJordan Rose addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);
29125bc20f8SJordan Rose }
2926f2e6522SChandler Carruth return *PM;
2936f2e6522SChandler Carruth }
2946f2e6522SChandler Carruth
getContext(const Decl * D)2954f8198e7SJordy Rose AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
2961c1057afSEugene Zelenko if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
2973d0ec38cSTed Kremenek // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
2983d0ec38cSTed Kremenek // that has the body.
29914f779c4STed Kremenek FD->hasBody(FD);
30014f779c4STed Kremenek D = FD;
30114f779c4STed Kremenek }
30214f779c4STed Kremenek
3035cb35e16SJustin Lebar std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
3046f2e6522SChandler Carruth if (!AC)
3052b3d49b6SJonas Devlieghere AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
3065cb35e16SJustin Lebar return AC.get();
3076f2e6522SChandler Carruth }
3086f2e6522SChandler Carruth
getBodyFarm()309ed017b63SGeorge Karpenkov BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; }
3103d64d6eeSGeorge Karpenkov
3116f2e6522SChandler Carruth const StackFrameContext *
getStackFrame(const LocationContext * ParentLC,const Stmt * S,const CFGBlock * Blk,unsigned BlockCount,unsigned Index)3127e1a6ca9SCharusso AnalysisDeclContext::getStackFrame(const LocationContext *ParentLC,
3137e1a6ca9SCharusso const Stmt *S, const CFGBlock *Blk,
3147e1a6ca9SCharusso unsigned BlockCount, unsigned Index) {
3157e1a6ca9SCharusso return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,
3167e1a6ca9SCharusso BlockCount, Index);
3176f2e6522SChandler Carruth }
3186f2e6522SChandler Carruth
getBlockInvocationContext(const LocationContext * ParentLC,const BlockDecl * BD,const void * Data)3197e1a6ca9SCharusso const BlockInvocationContext *AnalysisDeclContext::getBlockInvocationContext(
3207e1a6ca9SCharusso const LocationContext *ParentLC, const BlockDecl *BD, const void *Data) {
3217e1a6ca9SCharusso return getLocationContextManager().getBlockInvocationContext(this, ParentLC,
3227e1a6ca9SCharusso BD, Data);
323c3da376fSTed Kremenek }
324c3da376fSTed Kremenek
isInStdNamespace(const Decl * D)3259165df12SDevin Coughlin bool AnalysisDeclContext::isInStdNamespace(const Decl *D) {
3269165df12SDevin Coughlin const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
3271c1057afSEugene Zelenko const auto *ND = dyn_cast<NamespaceDecl>(DC);
3289165df12SDevin Coughlin if (!ND)
3299165df12SDevin Coughlin return false;
3309165df12SDevin Coughlin
3319165df12SDevin Coughlin while (const DeclContext *Parent = ND->getParent()) {
3329165df12SDevin Coughlin if (!isa<NamespaceDecl>(Parent))
3339165df12SDevin Coughlin break;
3349165df12SDevin Coughlin ND = cast<NamespaceDecl>(Parent);
3359165df12SDevin Coughlin }
3369165df12SDevin Coughlin
3379165df12SDevin Coughlin return ND->isStdNamespace();
3389165df12SDevin Coughlin }
3399165df12SDevin Coughlin
getFunctionName(const Decl * D)340d3e14fafSBalazs Benics std::string AnalysisDeclContext::getFunctionName(const Decl *D) {
341d3e14fafSBalazs Benics std::string Str;
342d3e14fafSBalazs Benics llvm::raw_string_ostream OS(Str);
343d3e14fafSBalazs Benics const ASTContext &Ctx = D->getASTContext();
344d3e14fafSBalazs Benics
345d3e14fafSBalazs Benics if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
346d3e14fafSBalazs Benics OS << FD->getQualifiedNameAsString();
347d3e14fafSBalazs Benics
348d3e14fafSBalazs Benics // In C++, there are overloads.
349d3e14fafSBalazs Benics
350d3e14fafSBalazs Benics if (Ctx.getLangOpts().CPlusPlus) {
351d3e14fafSBalazs Benics OS << '(';
352d3e14fafSBalazs Benics for (const auto &P : FD->parameters()) {
353d3e14fafSBalazs Benics if (P != *FD->param_begin())
354d3e14fafSBalazs Benics OS << ", ";
355*cfb81690SNathan James OS << P->getType();
356d3e14fafSBalazs Benics }
357d3e14fafSBalazs Benics OS << ')';
358d3e14fafSBalazs Benics }
359d3e14fafSBalazs Benics
360d3e14fafSBalazs Benics } else if (isa<BlockDecl>(D)) {
361d3e14fafSBalazs Benics PresumedLoc Loc = Ctx.getSourceManager().getPresumedLoc(D->getLocation());
362d3e14fafSBalazs Benics
363d3e14fafSBalazs Benics if (Loc.isValid()) {
364d3e14fafSBalazs Benics OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
365d3e14fafSBalazs Benics << ')';
366d3e14fafSBalazs Benics }
367d3e14fafSBalazs Benics
368d3e14fafSBalazs Benics } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
369d3e14fafSBalazs Benics
370d3e14fafSBalazs Benics // FIXME: copy-pasted from CGDebugInfo.cpp.
371d3e14fafSBalazs Benics OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
372d3e14fafSBalazs Benics const DeclContext *DC = OMD->getDeclContext();
373d3e14fafSBalazs Benics if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
374d3e14fafSBalazs Benics OS << OID->getName();
375d3e14fafSBalazs Benics } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
376d3e14fafSBalazs Benics OS << OID->getName();
377d3e14fafSBalazs Benics } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
378d3e14fafSBalazs Benics if (OC->IsClassExtension()) {
379d3e14fafSBalazs Benics OS << OC->getClassInterface()->getName();
380d3e14fafSBalazs Benics } else {
381d3e14fafSBalazs Benics OS << OC->getIdentifier()->getNameStart() << '('
382d3e14fafSBalazs Benics << OC->getIdentifier()->getNameStart() << ')';
383d3e14fafSBalazs Benics }
384d3e14fafSBalazs Benics } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
385d3e14fafSBalazs Benics OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')';
386d3e14fafSBalazs Benics }
387d3e14fafSBalazs Benics OS << ' ' << OMD->getSelector().getAsString() << ']';
388d3e14fafSBalazs Benics }
389d3e14fafSBalazs Benics
390715c72b4SLogan Smith return Str;
391d3e14fafSBalazs Benics }
392d3e14fafSBalazs Benics
getLocationContextManager()3936f2e6522SChandler Carruth LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
3947e1a6ca9SCharusso assert(
3957e1a6ca9SCharusso ADCMgr &&
3966f2e6522SChandler Carruth "Cannot create LocationContexts without an AnalysisDeclContextManager!");
3977e1a6ca9SCharusso return ADCMgr->getLocationContextManager();
3986f2e6522SChandler Carruth }
3996f2e6522SChandler Carruth
4006f2e6522SChandler Carruth //===----------------------------------------------------------------------===//
4016f2e6522SChandler Carruth // FoldingSet profiling.
4026f2e6522SChandler Carruth //===----------------------------------------------------------------------===//
4036f2e6522SChandler Carruth
ProfileCommon(llvm::FoldingSetNodeID & ID,ContextKind ck,AnalysisDeclContext * ctx,const LocationContext * parent,const void * data)4046f2e6522SChandler Carruth void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
4056f2e6522SChandler Carruth ContextKind ck,
4066f2e6522SChandler Carruth AnalysisDeclContext *ctx,
4076f2e6522SChandler Carruth const LocationContext *parent,
4086f2e6522SChandler Carruth const void *data) {
4096f2e6522SChandler Carruth ID.AddInteger(ck);
4106f2e6522SChandler Carruth ID.AddPointer(ctx);
4116f2e6522SChandler Carruth ID.AddPointer(parent);
4126f2e6522SChandler Carruth ID.AddPointer(data);
4136f2e6522SChandler Carruth }
4146f2e6522SChandler Carruth
Profile(llvm::FoldingSetNodeID & ID)4156f2e6522SChandler Carruth void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
4167740c6d6SCsaba Dabis Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,
4177740c6d6SCsaba Dabis BlockCount, Index);
4186f2e6522SChandler Carruth }
4196f2e6522SChandler Carruth
Profile(llvm::FoldingSetNodeID & ID)4206f2e6522SChandler Carruth void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
4217e1a6ca9SCharusso Profile(ID, getAnalysisDeclContext(), getParent(), BD, Data);
4226f2e6522SChandler Carruth }
4236f2e6522SChandler Carruth
4246f2e6522SChandler Carruth //===----------------------------------------------------------------------===//
4256f2e6522SChandler Carruth // LocationContext creation.
4266f2e6522SChandler Carruth //===----------------------------------------------------------------------===//
4276f2e6522SChandler Carruth
getStackFrame(AnalysisDeclContext * ctx,const LocationContext * parent,const Stmt * s,const CFGBlock * blk,unsigned blockCount,unsigned idx)4287740c6d6SCsaba Dabis const StackFrameContext *LocationContextManager::getStackFrame(
4297740c6d6SCsaba Dabis AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,
4307740c6d6SCsaba Dabis const CFGBlock *blk, unsigned blockCount, unsigned idx) {
4316f2e6522SChandler Carruth llvm::FoldingSetNodeID ID;
4327740c6d6SCsaba Dabis StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);
4336f2e6522SChandler Carruth void *InsertPos;
4341c1057afSEugene Zelenko auto *L =
4356f2e6522SChandler Carruth cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
4366f2e6522SChandler Carruth if (!L) {
4377740c6d6SCsaba Dabis L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);
4386f2e6522SChandler Carruth Contexts.InsertNode(L, InsertPos);
4396f2e6522SChandler Carruth }
4406f2e6522SChandler Carruth return L;
4416f2e6522SChandler Carruth }
4426f2e6522SChandler Carruth
getBlockInvocationContext(AnalysisDeclContext * ADC,const LocationContext * ParentLC,const BlockDecl * BD,const void * Data)4437e1a6ca9SCharusso const BlockInvocationContext *LocationContextManager::getBlockInvocationContext(
4447e1a6ca9SCharusso AnalysisDeclContext *ADC, const LocationContext *ParentLC,
4457e1a6ca9SCharusso const BlockDecl *BD, const void *Data) {
446c3da376fSTed Kremenek llvm::FoldingSetNodeID ID;
4477e1a6ca9SCharusso BlockInvocationContext::Profile(ID, ADC, ParentLC, BD, Data);
448c3da376fSTed Kremenek void *InsertPos;
4491c1057afSEugene Zelenko auto *L =
450c3da376fSTed Kremenek cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
451c3da376fSTed Kremenek InsertPos));
452c3da376fSTed Kremenek if (!L) {
4537e1a6ca9SCharusso L = new BlockInvocationContext(ADC, ParentLC, BD, Data, ++NewID);
454c3da376fSTed Kremenek Contexts.InsertNode(L, InsertPos);
455c3da376fSTed Kremenek }
456c3da376fSTed Kremenek return L;
457c3da376fSTed Kremenek }
458c3da376fSTed Kremenek
4596f2e6522SChandler Carruth //===----------------------------------------------------------------------===//
4606f2e6522SChandler Carruth // LocationContext methods.
4616f2e6522SChandler Carruth //===----------------------------------------------------------------------===//
4626f2e6522SChandler Carruth
getStackFrame() const463dd18b11bSGeorge Karpenkov const StackFrameContext *LocationContext::getStackFrame() const {
4646f2e6522SChandler Carruth const LocationContext *LC = this;
4656f2e6522SChandler Carruth while (LC) {
4661c1057afSEugene Zelenko if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
4676f2e6522SChandler Carruth return SFC;
4686f2e6522SChandler Carruth LC = LC->getParent();
4696f2e6522SChandler Carruth }
47025542943SCraig Topper return nullptr;
4716f2e6522SChandler Carruth }
4726f2e6522SChandler Carruth
inTopFrame() const47344dc91b4SAnna Zaks bool LocationContext::inTopFrame() const {
474dd18b11bSGeorge Karpenkov return getStackFrame()->inTopFrame();
47544dc91b4SAnna Zaks }
47644dc91b4SAnna Zaks
isParentOf(const LocationContext * LC) const4776f2e6522SChandler Carruth bool LocationContext::isParentOf(const LocationContext *LC) const {
4786f2e6522SChandler Carruth do {
4796f2e6522SChandler Carruth const LocationContext *Parent = LC->getParent();
4806f2e6522SChandler Carruth if (Parent == this)
4816f2e6522SChandler Carruth return true;
4826f2e6522SChandler Carruth else
4836f2e6522SChandler Carruth LC = Parent;
4846f2e6522SChandler Carruth } while (LC);
4856f2e6522SChandler Carruth
4866f2e6522SChandler Carruth return false;
4876f2e6522SChandler Carruth }
4886f2e6522SChandler Carruth
printLocation(raw_ostream & Out,const SourceManager & SM,SourceLocation Loc)4899ce37466SCsaba Dabis static void printLocation(raw_ostream &Out, const SourceManager &SM,
4909ce37466SCsaba Dabis SourceLocation Loc) {
4919ce37466SCsaba Dabis if (Loc.isFileID() && SM.isInMainFile(Loc))
4929ce37466SCsaba Dabis Out << SM.getExpansionLineNumber(Loc);
493be073035SArtem Dergachev else
4949ce37466SCsaba Dabis Loc.print(Out, SM);
495be073035SArtem Dergachev }
496be073035SArtem Dergachev
dumpStack(raw_ostream & Out) const4977e1a6ca9SCharusso void LocationContext::dumpStack(raw_ostream &Out) const {
4986fdef11cSJordan Rose ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
4996fdef11cSJordan Rose PrintingPolicy PP(Ctx.getLangOpts());
5006fdef11cSJordan Rose PP.TerseOutput = 1;
5016fdef11cSJordan Rose
502be073035SArtem Dergachev const SourceManager &SM =
503be073035SArtem Dergachev getAnalysisDeclContext()->getASTContext().getSourceManager();
504be073035SArtem Dergachev
5056fdef11cSJordan Rose unsigned Frame = 0;
5066fdef11cSJordan Rose for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
5076fdef11cSJordan Rose switch (LCtx->getKind()) {
5086fdef11cSJordan Rose case StackFrame:
5099ce37466SCsaba Dabis Out << "\t#" << Frame << ' ';
510be073035SArtem Dergachev ++Frame;
5111c1057afSEugene Zelenko if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
512d3e14fafSBalazs Benics Out << "Calling " << AnalysisDeclContext::getFunctionName(D);
513be073035SArtem Dergachev else
5149ce37466SCsaba Dabis Out << "Calling anonymous code";
515be073035SArtem Dergachev if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
5169ce37466SCsaba Dabis Out << " at line ";
5179ce37466SCsaba Dabis printLocation(Out, SM, S->getBeginLoc());
518be073035SArtem Dergachev }
5196fdef11cSJordan Rose break;
5206fdef11cSJordan Rose case Block:
5219ce37466SCsaba Dabis Out << "Invoking block";
522be073035SArtem Dergachev if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
5239ce37466SCsaba Dabis Out << " defined at line ";
5249ce37466SCsaba Dabis printLocation(Out, SM, D->getBeginLoc());
525be073035SArtem Dergachev }
5266fdef11cSJordan Rose break;
5276fdef11cSJordan Rose }
5287e1a6ca9SCharusso Out << '\n';
5296fdef11cSJordan Rose }
5306fdef11cSJordan Rose }
5316fdef11cSJordan Rose
printJson(raw_ostream & Out,const char * NL,unsigned int Space,bool IsDot,std::function<void (const LocationContext *)> printMoreInfoPerContext) const5329ce37466SCsaba Dabis void LocationContext::printJson(raw_ostream &Out, const char *NL,
5339ce37466SCsaba Dabis unsigned int Space, bool IsDot,
5349ce37466SCsaba Dabis std::function<void(const LocationContext *)>
5359ce37466SCsaba Dabis printMoreInfoPerContext) const {
5369ce37466SCsaba Dabis ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
5379ce37466SCsaba Dabis PrintingPolicy PP(Ctx.getLangOpts());
5389ce37466SCsaba Dabis PP.TerseOutput = 1;
5399ce37466SCsaba Dabis
5409ce37466SCsaba Dabis const SourceManager &SM =
5419ce37466SCsaba Dabis getAnalysisDeclContext()->getASTContext().getSourceManager();
5429ce37466SCsaba Dabis
5439ce37466SCsaba Dabis unsigned Frame = 0;
5449ce37466SCsaba Dabis for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
545f9f6cdb1SArtem Dergachev Indent(Out, Space, IsDot)
546f9f6cdb1SArtem Dergachev << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
5479ce37466SCsaba Dabis switch (LCtx->getKind()) {
5489ce37466SCsaba Dabis case StackFrame:
5499ce37466SCsaba Dabis Out << '#' << Frame << " Call\", \"calling\": \"";
5509ce37466SCsaba Dabis ++Frame;
5519ce37466SCsaba Dabis if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
5529ce37466SCsaba Dabis Out << D->getQualifiedNameAsString();
5539ce37466SCsaba Dabis else
5549ce37466SCsaba Dabis Out << "anonymous code";
5559ce37466SCsaba Dabis
556ed035ff8SArtem Dergachev Out << "\", \"location\": ";
5579ce37466SCsaba Dabis if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
558ed035ff8SArtem Dergachev printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
5599ce37466SCsaba Dabis } else {
5609ce37466SCsaba Dabis Out << "null";
561e9c57229SJordan Rose }
562e9c57229SJordan Rose
5639ce37466SCsaba Dabis Out << ", \"items\": ";
5649ce37466SCsaba Dabis break;
5659ce37466SCsaba Dabis case Block:
5669ce37466SCsaba Dabis Out << "Invoking block\" ";
5679ce37466SCsaba Dabis if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
568ed035ff8SArtem Dergachev Out << ", \"location\": ";
569ed035ff8SArtem Dergachev printSourceLocationAsJson(Out, D->getBeginLoc(), SM);
5709ce37466SCsaba Dabis Out << ' ';
5719ce37466SCsaba Dabis }
5729ce37466SCsaba Dabis break;
5739ce37466SCsaba Dabis }
5749ce37466SCsaba Dabis
5759ce37466SCsaba Dabis printMoreInfoPerContext(LCtx);
5769ce37466SCsaba Dabis
5779ce37466SCsaba Dabis Out << '}';
5789ce37466SCsaba Dabis if (LCtx->getParent())
5799ce37466SCsaba Dabis Out << ',';
5809ce37466SCsaba Dabis Out << NL;
5819ce37466SCsaba Dabis }
5829ce37466SCsaba Dabis }
5839ce37466SCsaba Dabis
dump() const5849ce37466SCsaba Dabis LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); }
5859ce37466SCsaba Dabis
5866f2e6522SChandler Carruth //===----------------------------------------------------------------------===//
5876f2e6522SChandler Carruth // Lazily generated map to query the external variables referenced by a Block.
5886f2e6522SChandler Carruth //===----------------------------------------------------------------------===//
5896f2e6522SChandler Carruth
5906f2e6522SChandler Carruth namespace {
5911c1057afSEugene Zelenko
5926f2e6522SChandler Carruth class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
5936f2e6522SChandler Carruth BumpVector<const VarDecl *> &BEVals;
5946f2e6522SChandler Carruth BumpVectorContext &BC;
595616f8022SBenjamin Kramer llvm::SmallPtrSet<const VarDecl *, 4> Visited;
596616f8022SBenjamin Kramer llvm::SmallPtrSet<const DeclContext *, 4> IgnoredContexts;
5971c1057afSEugene Zelenko
5986f2e6522SChandler Carruth public:
FindBlockDeclRefExprsVals(BumpVector<const VarDecl * > & bevals,BumpVectorContext & bc)5996f2e6522SChandler Carruth FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
6006f2e6522SChandler Carruth BumpVectorContext &bc)
6016f2e6522SChandler Carruth : BEVals(bevals), BC(bc) {}
6026f2e6522SChandler Carruth
VisitStmt(Stmt * S)6036f2e6522SChandler Carruth void VisitStmt(Stmt *S) {
6041c1057afSEugene Zelenko for (auto *Child : S->children())
605642f173aSBenjamin Kramer if (Child)
606642f173aSBenjamin Kramer Visit(Child);
6076f2e6522SChandler Carruth }
6086f2e6522SChandler Carruth
VisitDeclRefExpr(DeclRefExpr * DR)609299cfb7aSTed Kremenek void VisitDeclRefExpr(DeclRefExpr *DR) {
6106f2e6522SChandler Carruth // Non-local variables are also directly modified.
6111c1057afSEugene Zelenko if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
6126f2e6522SChandler Carruth if (!VD->hasLocalStorage()) {
61382e95a3cSDavid Blaikie if (Visited.insert(VD).second)
6146f2e6522SChandler Carruth BEVals.push_back(VD, BC);
6156f2e6522SChandler Carruth }
6166f2e6522SChandler Carruth }
6176f2e6522SChandler Carruth }
6186f2e6522SChandler Carruth
VisitBlockExpr(BlockExpr * BR)6196f2e6522SChandler Carruth void VisitBlockExpr(BlockExpr *BR) {
6206f2e6522SChandler Carruth // Blocks containing blocks can transitively capture more variables.
6216f2e6522SChandler Carruth IgnoredContexts.insert(BR->getBlockDecl());
6226f2e6522SChandler Carruth Visit(BR->getBlockDecl()->getBody());
6236f2e6522SChandler Carruth }
624299cfb7aSTed Kremenek
VisitPseudoObjectExpr(PseudoObjectExpr * PE)625299cfb7aSTed Kremenek void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
626299cfb7aSTed Kremenek for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(),
627299cfb7aSTed Kremenek et = PE->semantics_end(); it != et; ++it) {
628299cfb7aSTed Kremenek Expr *Semantic = *it;
6291c1057afSEugene Zelenko if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
630299cfb7aSTed Kremenek Semantic = OVE->getSourceExpr();
631299cfb7aSTed Kremenek Visit(Semantic);
632299cfb7aSTed Kremenek }
633299cfb7aSTed Kremenek }
6346f2e6522SChandler Carruth };
6356f2e6522SChandler Carruth
6361c1057afSEugene Zelenko } // namespace
6371c1057afSEugene Zelenko
6381c1057afSEugene Zelenko using DeclVec = BumpVector<const VarDecl *>;
6396f2e6522SChandler Carruth
LazyInitializeReferencedDecls(const BlockDecl * BD,void * & Vec,llvm::BumpPtrAllocator & A)6406f2e6522SChandler Carruth static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,
6416f2e6522SChandler Carruth void *&Vec,
6426f2e6522SChandler Carruth llvm::BumpPtrAllocator &A) {
6436f2e6522SChandler Carruth if (Vec)
6446f2e6522SChandler Carruth return (DeclVec*) Vec;
6456f2e6522SChandler Carruth
6466f2e6522SChandler Carruth BumpVectorContext BC(A);
6476f2e6522SChandler Carruth DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
6486f2e6522SChandler Carruth new (BV) DeclVec(BC, 10);
6496f2e6522SChandler Carruth
6503e871d8cSTed Kremenek // Go through the capture list.
6519371dd22SAaron Ballman for (const auto &CI : BD->captures()) {
6529371dd22SAaron Ballman BV->push_back(CI.getVariable(), BC);
6533e871d8cSTed Kremenek }
6543e871d8cSTed Kremenek
6553e871d8cSTed Kremenek // Find the referenced global/static variables.
6566f2e6522SChandler Carruth FindBlockDeclRefExprsVals F(*BV, BC);
6576f2e6522SChandler Carruth F.Visit(BD->getBody());
6586f2e6522SChandler Carruth
6596f2e6522SChandler Carruth Vec = BV;
6606f2e6522SChandler Carruth return BV;
6616f2e6522SChandler Carruth }
6626f2e6522SChandler Carruth
663b4ef6683SBenjamin Kramer llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
getReferencedBlockVars(const BlockDecl * BD)6646f2e6522SChandler Carruth AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {
6656f2e6522SChandler Carruth if (!ReferencedBlockVars)
6666f2e6522SChandler Carruth ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
6676f2e6522SChandler Carruth
668b4ef6683SBenjamin Kramer const DeclVec *V =
669b4ef6683SBenjamin Kramer LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
670b4ef6683SBenjamin Kramer return llvm::make_range(V->begin(), V->end());
6716f2e6522SChandler Carruth }
6726f2e6522SChandler Carruth
getAnalysisImpl(const void * tag)673e265f92bSDavid Blaikie std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
6746f2e6522SChandler Carruth if (!ManagedAnalyses)
6756f2e6522SChandler Carruth ManagedAnalyses = new ManagedAnalysisMap();
6766f2e6522SChandler Carruth ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
6776f2e6522SChandler Carruth return (*M)[tag];
6786f2e6522SChandler Carruth }
6796f2e6522SChandler Carruth
6806f2e6522SChandler Carruth //===----------------------------------------------------------------------===//
6816f2e6522SChandler Carruth // Cleanup.
6826f2e6522SChandler Carruth //===----------------------------------------------------------------------===//
6836f2e6522SChandler Carruth
6841c1057afSEugene Zelenko ManagedAnalysis::~ManagedAnalysis() = default;
6856f2e6522SChandler Carruth
~AnalysisDeclContext()6866f2e6522SChandler Carruth AnalysisDeclContext::~AnalysisDeclContext() {
6876f2e6522SChandler Carruth delete forcedBlkExprs;
6886f2e6522SChandler Carruth delete ReferencedBlockVars;
689e265f92bSDavid Blaikie delete (ManagedAnalysisMap*) ManagedAnalyses;
6906f2e6522SChandler Carruth }
6916f2e6522SChandler Carruth
6921c1057afSEugene Zelenko LocationContext::~LocationContext() = default;
6936f2e6522SChandler Carruth
~LocationContextManager()6946f2e6522SChandler Carruth LocationContextManager::~LocationContextManager() {
6956f2e6522SChandler Carruth clear();
6966f2e6522SChandler Carruth }
6976f2e6522SChandler Carruth
clear()6986f2e6522SChandler Carruth void LocationContextManager::clear() {
6996f2e6522SChandler Carruth for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
7006f2e6522SChandler Carruth E = Contexts.end(); I != E; ) {
7016f2e6522SChandler Carruth LocationContext *LC = &*I;
7026f2e6522SChandler Carruth ++I;
7036f2e6522SChandler Carruth delete LC;
7046f2e6522SChandler Carruth }
7056f2e6522SChandler Carruth Contexts.clear();
7066f2e6522SChandler Carruth }
707