xref: /freebsd-src/contrib/llvm-project/clang/lib/Analysis/AnalysisDeclContext.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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