1*67e74705SXin Li //== AnalysisDeclContext.cpp - Analysis context for Path Sens analysis -*- C++ -*-//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file defines AnalysisDeclContext, a class that manages the analysis context
11*67e74705SXin Li // data for path sensitive analysis.
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li
15*67e74705SXin Li #include "clang/Analysis/AnalysisContext.h"
16*67e74705SXin Li #include "BodyFarm.h"
17*67e74705SXin Li #include "clang/AST/ASTContext.h"
18*67e74705SXin Li #include "clang/AST/Decl.h"
19*67e74705SXin Li #include "clang/AST/DeclObjC.h"
20*67e74705SXin Li #include "clang/AST/DeclTemplate.h"
21*67e74705SXin Li #include "clang/AST/ParentMap.h"
22*67e74705SXin Li #include "clang/AST/StmtVisitor.h"
23*67e74705SXin Li #include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
24*67e74705SXin Li #include "clang/Analysis/Analyses/LiveVariables.h"
25*67e74705SXin Li #include "clang/Analysis/Analyses/PseudoConstantAnalysis.h"
26*67e74705SXin Li #include "clang/Analysis/CFG.h"
27*67e74705SXin Li #include "clang/Analysis/CFGStmtMap.h"
28*67e74705SXin Li #include "clang/Analysis/Support/BumpVector.h"
29*67e74705SXin Li #include "llvm/ADT/SmallPtrSet.h"
30*67e74705SXin Li #include "llvm/Support/ErrorHandling.h"
31*67e74705SXin Li #include "llvm/Support/SaveAndRestore.h"
32*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
33*67e74705SXin Li
34*67e74705SXin Li using namespace clang;
35*67e74705SXin Li
36*67e74705SXin Li typedef llvm::DenseMap<const void *, ManagedAnalysis *> ManagedAnalysisMap;
37*67e74705SXin Li
AnalysisDeclContext(AnalysisDeclContextManager * Mgr,const Decl * d,const CFG::BuildOptions & buildOptions)38*67e74705SXin Li AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
39*67e74705SXin Li const Decl *d,
40*67e74705SXin Li const CFG::BuildOptions &buildOptions)
41*67e74705SXin Li : Manager(Mgr),
42*67e74705SXin Li D(d),
43*67e74705SXin Li cfgBuildOptions(buildOptions),
44*67e74705SXin Li forcedBlkExprs(nullptr),
45*67e74705SXin Li builtCFG(false),
46*67e74705SXin Li builtCompleteCFG(false),
47*67e74705SXin Li ReferencedBlockVars(nullptr),
48*67e74705SXin Li ManagedAnalyses(nullptr)
49*67e74705SXin Li {
50*67e74705SXin Li cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
51*67e74705SXin Li }
52*67e74705SXin Li
AnalysisDeclContext(AnalysisDeclContextManager * Mgr,const Decl * d)53*67e74705SXin Li AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
54*67e74705SXin Li const Decl *d)
55*67e74705SXin Li : Manager(Mgr),
56*67e74705SXin Li D(d),
57*67e74705SXin Li forcedBlkExprs(nullptr),
58*67e74705SXin Li builtCFG(false),
59*67e74705SXin Li builtCompleteCFG(false),
60*67e74705SXin Li ReferencedBlockVars(nullptr),
61*67e74705SXin Li ManagedAnalyses(nullptr)
62*67e74705SXin Li {
63*67e74705SXin Li cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
64*67e74705SXin Li }
65*67e74705SXin Li
AnalysisDeclContextManager(bool useUnoptimizedCFG,bool addImplicitDtors,bool addInitializers,bool addTemporaryDtors,bool synthesizeBodies,bool addStaticInitBranch,bool addCXXNewAllocator,CodeInjector * injector)66*67e74705SXin Li AnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG,
67*67e74705SXin Li bool addImplicitDtors,
68*67e74705SXin Li bool addInitializers,
69*67e74705SXin Li bool addTemporaryDtors,
70*67e74705SXin Li bool synthesizeBodies,
71*67e74705SXin Li bool addStaticInitBranch,
72*67e74705SXin Li bool addCXXNewAllocator,
73*67e74705SXin Li CodeInjector *injector)
74*67e74705SXin Li : Injector(injector), SynthesizeBodies(synthesizeBodies)
75*67e74705SXin Li {
76*67e74705SXin Li cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
77*67e74705SXin Li cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
78*67e74705SXin Li cfgBuildOptions.AddInitializers = addInitializers;
79*67e74705SXin Li cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
80*67e74705SXin Li cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
81*67e74705SXin Li cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
82*67e74705SXin Li }
83*67e74705SXin Li
clear()84*67e74705SXin Li void AnalysisDeclContextManager::clear() {
85*67e74705SXin Li llvm::DeleteContainerSeconds(Contexts);
86*67e74705SXin Li }
87*67e74705SXin Li
getBodyFarm(ASTContext & C,CodeInjector * injector=nullptr)88*67e74705SXin Li static BodyFarm &getBodyFarm(ASTContext &C, CodeInjector *injector = nullptr) {
89*67e74705SXin Li static BodyFarm *BF = new BodyFarm(C, injector);
90*67e74705SXin Li return *BF;
91*67e74705SXin Li }
92*67e74705SXin Li
getBody(bool & IsAutosynthesized) const93*67e74705SXin Li Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
94*67e74705SXin Li IsAutosynthesized = false;
95*67e74705SXin Li if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
96*67e74705SXin Li Stmt *Body = FD->getBody();
97*67e74705SXin Li if (Manager && Manager->synthesizeBodies()) {
98*67e74705SXin Li Stmt *SynthesizedBody =
99*67e74705SXin Li getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(FD);
100*67e74705SXin Li if (SynthesizedBody) {
101*67e74705SXin Li Body = SynthesizedBody;
102*67e74705SXin Li IsAutosynthesized = true;
103*67e74705SXin Li }
104*67e74705SXin Li }
105*67e74705SXin Li return Body;
106*67e74705SXin Li }
107*67e74705SXin Li else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
108*67e74705SXin Li Stmt *Body = MD->getBody();
109*67e74705SXin Li if (Manager && Manager->synthesizeBodies()) {
110*67e74705SXin Li Stmt *SynthesizedBody =
111*67e74705SXin Li getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(MD);
112*67e74705SXin Li if (SynthesizedBody) {
113*67e74705SXin Li Body = SynthesizedBody;
114*67e74705SXin Li IsAutosynthesized = true;
115*67e74705SXin Li }
116*67e74705SXin Li }
117*67e74705SXin Li return Body;
118*67e74705SXin Li } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
119*67e74705SXin Li return BD->getBody();
120*67e74705SXin Li else if (const FunctionTemplateDecl *FunTmpl
121*67e74705SXin Li = dyn_cast_or_null<FunctionTemplateDecl>(D))
122*67e74705SXin Li return FunTmpl->getTemplatedDecl()->getBody();
123*67e74705SXin Li
124*67e74705SXin Li llvm_unreachable("unknown code decl");
125*67e74705SXin Li }
126*67e74705SXin Li
getBody() const127*67e74705SXin Li Stmt *AnalysisDeclContext::getBody() const {
128*67e74705SXin Li bool Tmp;
129*67e74705SXin Li return getBody(Tmp);
130*67e74705SXin Li }
131*67e74705SXin Li
isBodyAutosynthesized() const132*67e74705SXin Li bool AnalysisDeclContext::isBodyAutosynthesized() const {
133*67e74705SXin Li bool Tmp;
134*67e74705SXin Li getBody(Tmp);
135*67e74705SXin Li return Tmp;
136*67e74705SXin Li }
137*67e74705SXin Li
isBodyAutosynthesizedFromModelFile() const138*67e74705SXin Li bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const {
139*67e74705SXin Li bool Tmp;
140*67e74705SXin Li Stmt *Body = getBody(Tmp);
141*67e74705SXin Li return Tmp && Body->getLocStart().isValid();
142*67e74705SXin Li }
143*67e74705SXin Li
144*67e74705SXin Li /// Returns true if \param VD is an Objective-C implicit 'self' parameter.
isSelfDecl(const VarDecl * VD)145*67e74705SXin Li static bool isSelfDecl(const VarDecl *VD) {
146*67e74705SXin Li return isa<ImplicitParamDecl>(VD) && VD->getName() == "self";
147*67e74705SXin Li }
148*67e74705SXin Li
getSelfDecl() const149*67e74705SXin Li const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
150*67e74705SXin Li if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
151*67e74705SXin Li return MD->getSelfDecl();
152*67e74705SXin Li if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
153*67e74705SXin Li // See if 'self' was captured by the block.
154*67e74705SXin Li for (const auto &I : BD->captures()) {
155*67e74705SXin Li const VarDecl *VD = I.getVariable();
156*67e74705SXin Li if (isSelfDecl(VD))
157*67e74705SXin Li return dyn_cast<ImplicitParamDecl>(VD);
158*67e74705SXin Li }
159*67e74705SXin Li }
160*67e74705SXin Li
161*67e74705SXin Li auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
162*67e74705SXin Li if (!CXXMethod)
163*67e74705SXin Li return nullptr;
164*67e74705SXin Li
165*67e74705SXin Li const CXXRecordDecl *parent = CXXMethod->getParent();
166*67e74705SXin Li if (!parent->isLambda())
167*67e74705SXin Li return nullptr;
168*67e74705SXin Li
169*67e74705SXin Li for (const LambdaCapture &LC : parent->captures()) {
170*67e74705SXin Li if (!LC.capturesVariable())
171*67e74705SXin Li continue;
172*67e74705SXin Li
173*67e74705SXin Li VarDecl *VD = LC.getCapturedVar();
174*67e74705SXin Li if (isSelfDecl(VD))
175*67e74705SXin Li return dyn_cast<ImplicitParamDecl>(VD);
176*67e74705SXin Li }
177*67e74705SXin Li
178*67e74705SXin Li return nullptr;
179*67e74705SXin Li }
180*67e74705SXin Li
registerForcedBlockExpression(const Stmt * stmt)181*67e74705SXin Li void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
182*67e74705SXin Li if (!forcedBlkExprs)
183*67e74705SXin Li forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
184*67e74705SXin Li // Default construct an entry for 'stmt'.
185*67e74705SXin Li if (const Expr *e = dyn_cast<Expr>(stmt))
186*67e74705SXin Li stmt = e->IgnoreParens();
187*67e74705SXin Li (void) (*forcedBlkExprs)[stmt];
188*67e74705SXin Li }
189*67e74705SXin Li
190*67e74705SXin Li const CFGBlock *
getBlockForRegisteredExpression(const Stmt * stmt)191*67e74705SXin Li AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {
192*67e74705SXin Li assert(forcedBlkExprs);
193*67e74705SXin Li if (const Expr *e = dyn_cast<Expr>(stmt))
194*67e74705SXin Li stmt = e->IgnoreParens();
195*67e74705SXin Li CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
196*67e74705SXin Li forcedBlkExprs->find(stmt);
197*67e74705SXin Li assert(itr != forcedBlkExprs->end());
198*67e74705SXin Li return itr->second;
199*67e74705SXin Li }
200*67e74705SXin Li
201*67e74705SXin Li /// Add each synthetic statement in the CFG to the parent map, using the
202*67e74705SXin Li /// source statement's parent.
addParentsForSyntheticStmts(const CFG * TheCFG,ParentMap & PM)203*67e74705SXin Li static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
204*67e74705SXin Li if (!TheCFG)
205*67e74705SXin Li return;
206*67e74705SXin Li
207*67e74705SXin Li for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(),
208*67e74705SXin Li E = TheCFG->synthetic_stmt_end();
209*67e74705SXin Li I != E; ++I) {
210*67e74705SXin Li PM.setParent(I->first, PM.getParent(I->second));
211*67e74705SXin Li }
212*67e74705SXin Li }
213*67e74705SXin Li
getCFG()214*67e74705SXin Li CFG *AnalysisDeclContext::getCFG() {
215*67e74705SXin Li if (!cfgBuildOptions.PruneTriviallyFalseEdges)
216*67e74705SXin Li return getUnoptimizedCFG();
217*67e74705SXin Li
218*67e74705SXin Li if (!builtCFG) {
219*67e74705SXin Li cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
220*67e74705SXin Li // Even when the cfg is not successfully built, we don't
221*67e74705SXin Li // want to try building it again.
222*67e74705SXin Li builtCFG = true;
223*67e74705SXin Li
224*67e74705SXin Li if (PM)
225*67e74705SXin Li addParentsForSyntheticStmts(cfg.get(), *PM);
226*67e74705SXin Li
227*67e74705SXin Li // The Observer should only observe one build of the CFG.
228*67e74705SXin Li getCFGBuildOptions().Observer = nullptr;
229*67e74705SXin Li }
230*67e74705SXin Li return cfg.get();
231*67e74705SXin Li }
232*67e74705SXin Li
getUnoptimizedCFG()233*67e74705SXin Li CFG *AnalysisDeclContext::getUnoptimizedCFG() {
234*67e74705SXin Li if (!builtCompleteCFG) {
235*67e74705SXin Li SaveAndRestore<bool> NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges,
236*67e74705SXin Li false);
237*67e74705SXin Li completeCFG =
238*67e74705SXin Li CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
239*67e74705SXin Li // Even when the cfg is not successfully built, we don't
240*67e74705SXin Li // want to try building it again.
241*67e74705SXin Li builtCompleteCFG = true;
242*67e74705SXin Li
243*67e74705SXin Li if (PM)
244*67e74705SXin Li addParentsForSyntheticStmts(completeCFG.get(), *PM);
245*67e74705SXin Li
246*67e74705SXin Li // The Observer should only observe one build of the CFG.
247*67e74705SXin Li getCFGBuildOptions().Observer = nullptr;
248*67e74705SXin Li }
249*67e74705SXin Li return completeCFG.get();
250*67e74705SXin Li }
251*67e74705SXin Li
getCFGStmtMap()252*67e74705SXin Li CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
253*67e74705SXin Li if (cfgStmtMap)
254*67e74705SXin Li return cfgStmtMap.get();
255*67e74705SXin Li
256*67e74705SXin Li if (CFG *c = getCFG()) {
257*67e74705SXin Li cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
258*67e74705SXin Li return cfgStmtMap.get();
259*67e74705SXin Li }
260*67e74705SXin Li
261*67e74705SXin Li return nullptr;
262*67e74705SXin Li }
263*67e74705SXin Li
getCFGReachablityAnalysis()264*67e74705SXin Li CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
265*67e74705SXin Li if (CFA)
266*67e74705SXin Li return CFA.get();
267*67e74705SXin Li
268*67e74705SXin Li if (CFG *c = getCFG()) {
269*67e74705SXin Li CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
270*67e74705SXin Li return CFA.get();
271*67e74705SXin Li }
272*67e74705SXin Li
273*67e74705SXin Li return nullptr;
274*67e74705SXin Li }
275*67e74705SXin Li
dumpCFG(bool ShowColors)276*67e74705SXin Li void AnalysisDeclContext::dumpCFG(bool ShowColors) {
277*67e74705SXin Li getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
278*67e74705SXin Li }
279*67e74705SXin Li
getParentMap()280*67e74705SXin Li ParentMap &AnalysisDeclContext::getParentMap() {
281*67e74705SXin Li if (!PM) {
282*67e74705SXin Li PM.reset(new ParentMap(getBody()));
283*67e74705SXin Li if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
284*67e74705SXin Li for (const auto *I : C->inits()) {
285*67e74705SXin Li PM->addStmt(I->getInit());
286*67e74705SXin Li }
287*67e74705SXin Li }
288*67e74705SXin Li if (builtCFG)
289*67e74705SXin Li addParentsForSyntheticStmts(getCFG(), *PM);
290*67e74705SXin Li if (builtCompleteCFG)
291*67e74705SXin Li addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);
292*67e74705SXin Li }
293*67e74705SXin Li return *PM;
294*67e74705SXin Li }
295*67e74705SXin Li
getPseudoConstantAnalysis()296*67e74705SXin Li PseudoConstantAnalysis *AnalysisDeclContext::getPseudoConstantAnalysis() {
297*67e74705SXin Li if (!PCA)
298*67e74705SXin Li PCA.reset(new PseudoConstantAnalysis(getBody()));
299*67e74705SXin Li return PCA.get();
300*67e74705SXin Li }
301*67e74705SXin Li
getContext(const Decl * D)302*67e74705SXin Li AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
303*67e74705SXin Li if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
304*67e74705SXin Li // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
305*67e74705SXin Li // that has the body.
306*67e74705SXin Li FD->hasBody(FD);
307*67e74705SXin Li D = FD;
308*67e74705SXin Li }
309*67e74705SXin Li
310*67e74705SXin Li AnalysisDeclContext *&AC = Contexts[D];
311*67e74705SXin Li if (!AC)
312*67e74705SXin Li AC = new AnalysisDeclContext(this, D, cfgBuildOptions);
313*67e74705SXin Li return AC;
314*67e74705SXin Li }
315*67e74705SXin Li
316*67e74705SXin Li const StackFrameContext *
getStackFrame(LocationContext const * Parent,const Stmt * S,const CFGBlock * Blk,unsigned Idx)317*67e74705SXin Li AnalysisDeclContext::getStackFrame(LocationContext const *Parent, const Stmt *S,
318*67e74705SXin Li const CFGBlock *Blk, unsigned Idx) {
319*67e74705SXin Li return getLocationContextManager().getStackFrame(this, Parent, S, Blk, Idx);
320*67e74705SXin Li }
321*67e74705SXin Li
322*67e74705SXin Li const BlockInvocationContext *
getBlockInvocationContext(const LocationContext * parent,const clang::BlockDecl * BD,const void * ContextData)323*67e74705SXin Li AnalysisDeclContext::getBlockInvocationContext(const LocationContext *parent,
324*67e74705SXin Li const clang::BlockDecl *BD,
325*67e74705SXin Li const void *ContextData) {
326*67e74705SXin Li return getLocationContextManager().getBlockInvocationContext(this, parent,
327*67e74705SXin Li BD, ContextData);
328*67e74705SXin Li }
329*67e74705SXin Li
isInStdNamespace(const Decl * D)330*67e74705SXin Li bool AnalysisDeclContext::isInStdNamespace(const Decl *D) {
331*67e74705SXin Li const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
332*67e74705SXin Li const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC);
333*67e74705SXin Li if (!ND)
334*67e74705SXin Li return false;
335*67e74705SXin Li
336*67e74705SXin Li while (const DeclContext *Parent = ND->getParent()) {
337*67e74705SXin Li if (!isa<NamespaceDecl>(Parent))
338*67e74705SXin Li break;
339*67e74705SXin Li ND = cast<NamespaceDecl>(Parent);
340*67e74705SXin Li }
341*67e74705SXin Li
342*67e74705SXin Li return ND->isStdNamespace();
343*67e74705SXin Li }
344*67e74705SXin Li
getLocationContextManager()345*67e74705SXin Li LocationContextManager & AnalysisDeclContext::getLocationContextManager() {
346*67e74705SXin Li assert(Manager &&
347*67e74705SXin Li "Cannot create LocationContexts without an AnalysisDeclContextManager!");
348*67e74705SXin Li return Manager->getLocationContextManager();
349*67e74705SXin Li }
350*67e74705SXin Li
351*67e74705SXin Li //===----------------------------------------------------------------------===//
352*67e74705SXin Li // FoldingSet profiling.
353*67e74705SXin Li //===----------------------------------------------------------------------===//
354*67e74705SXin Li
ProfileCommon(llvm::FoldingSetNodeID & ID,ContextKind ck,AnalysisDeclContext * ctx,const LocationContext * parent,const void * data)355*67e74705SXin Li void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
356*67e74705SXin Li ContextKind ck,
357*67e74705SXin Li AnalysisDeclContext *ctx,
358*67e74705SXin Li const LocationContext *parent,
359*67e74705SXin Li const void *data) {
360*67e74705SXin Li ID.AddInteger(ck);
361*67e74705SXin Li ID.AddPointer(ctx);
362*67e74705SXin Li ID.AddPointer(parent);
363*67e74705SXin Li ID.AddPointer(data);
364*67e74705SXin Li }
365*67e74705SXin Li
Profile(llvm::FoldingSetNodeID & ID)366*67e74705SXin Li void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
367*67e74705SXin Li Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block, Index);
368*67e74705SXin Li }
369*67e74705SXin Li
Profile(llvm::FoldingSetNodeID & ID)370*67e74705SXin Li void ScopeContext::Profile(llvm::FoldingSetNodeID &ID) {
371*67e74705SXin Li Profile(ID, getAnalysisDeclContext(), getParent(), Enter);
372*67e74705SXin Li }
373*67e74705SXin Li
Profile(llvm::FoldingSetNodeID & ID)374*67e74705SXin Li void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
375*67e74705SXin Li Profile(ID, getAnalysisDeclContext(), getParent(), BD, ContextData);
376*67e74705SXin Li }
377*67e74705SXin Li
378*67e74705SXin Li //===----------------------------------------------------------------------===//
379*67e74705SXin Li // LocationContext creation.
380*67e74705SXin Li //===----------------------------------------------------------------------===//
381*67e74705SXin Li
382*67e74705SXin Li template <typename LOC, typename DATA>
383*67e74705SXin Li const LOC*
getLocationContext(AnalysisDeclContext * ctx,const LocationContext * parent,const DATA * d)384*67e74705SXin Li LocationContextManager::getLocationContext(AnalysisDeclContext *ctx,
385*67e74705SXin Li const LocationContext *parent,
386*67e74705SXin Li const DATA *d) {
387*67e74705SXin Li llvm::FoldingSetNodeID ID;
388*67e74705SXin Li LOC::Profile(ID, ctx, parent, d);
389*67e74705SXin Li void *InsertPos;
390*67e74705SXin Li
391*67e74705SXin Li LOC *L = cast_or_null<LOC>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
392*67e74705SXin Li
393*67e74705SXin Li if (!L) {
394*67e74705SXin Li L = new LOC(ctx, parent, d);
395*67e74705SXin Li Contexts.InsertNode(L, InsertPos);
396*67e74705SXin Li }
397*67e74705SXin Li return L;
398*67e74705SXin Li }
399*67e74705SXin Li
400*67e74705SXin Li const StackFrameContext*
getStackFrame(AnalysisDeclContext * ctx,const LocationContext * parent,const Stmt * s,const CFGBlock * blk,unsigned idx)401*67e74705SXin Li LocationContextManager::getStackFrame(AnalysisDeclContext *ctx,
402*67e74705SXin Li const LocationContext *parent,
403*67e74705SXin Li const Stmt *s,
404*67e74705SXin Li const CFGBlock *blk, unsigned idx) {
405*67e74705SXin Li llvm::FoldingSetNodeID ID;
406*67e74705SXin Li StackFrameContext::Profile(ID, ctx, parent, s, blk, idx);
407*67e74705SXin Li void *InsertPos;
408*67e74705SXin Li StackFrameContext *L =
409*67e74705SXin Li cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
410*67e74705SXin Li if (!L) {
411*67e74705SXin Li L = new StackFrameContext(ctx, parent, s, blk, idx);
412*67e74705SXin Li Contexts.InsertNode(L, InsertPos);
413*67e74705SXin Li }
414*67e74705SXin Li return L;
415*67e74705SXin Li }
416*67e74705SXin Li
417*67e74705SXin Li const ScopeContext *
getScope(AnalysisDeclContext * ctx,const LocationContext * parent,const Stmt * s)418*67e74705SXin Li LocationContextManager::getScope(AnalysisDeclContext *ctx,
419*67e74705SXin Li const LocationContext *parent,
420*67e74705SXin Li const Stmt *s) {
421*67e74705SXin Li return getLocationContext<ScopeContext, Stmt>(ctx, parent, s);
422*67e74705SXin Li }
423*67e74705SXin Li
424*67e74705SXin Li const BlockInvocationContext *
getBlockInvocationContext(AnalysisDeclContext * ctx,const LocationContext * parent,const BlockDecl * BD,const void * ContextData)425*67e74705SXin Li LocationContextManager::getBlockInvocationContext(AnalysisDeclContext *ctx,
426*67e74705SXin Li const LocationContext *parent,
427*67e74705SXin Li const BlockDecl *BD,
428*67e74705SXin Li const void *ContextData) {
429*67e74705SXin Li llvm::FoldingSetNodeID ID;
430*67e74705SXin Li BlockInvocationContext::Profile(ID, ctx, parent, BD, ContextData);
431*67e74705SXin Li void *InsertPos;
432*67e74705SXin Li BlockInvocationContext *L =
433*67e74705SXin Li cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
434*67e74705SXin Li InsertPos));
435*67e74705SXin Li if (!L) {
436*67e74705SXin Li L = new BlockInvocationContext(ctx, parent, BD, ContextData);
437*67e74705SXin Li Contexts.InsertNode(L, InsertPos);
438*67e74705SXin Li }
439*67e74705SXin Li return L;
440*67e74705SXin Li }
441*67e74705SXin Li
442*67e74705SXin Li //===----------------------------------------------------------------------===//
443*67e74705SXin Li // LocationContext methods.
444*67e74705SXin Li //===----------------------------------------------------------------------===//
445*67e74705SXin Li
getCurrentStackFrame() const446*67e74705SXin Li const StackFrameContext *LocationContext::getCurrentStackFrame() const {
447*67e74705SXin Li const LocationContext *LC = this;
448*67e74705SXin Li while (LC) {
449*67e74705SXin Li if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC))
450*67e74705SXin Li return SFC;
451*67e74705SXin Li LC = LC->getParent();
452*67e74705SXin Li }
453*67e74705SXin Li return nullptr;
454*67e74705SXin Li }
455*67e74705SXin Li
inTopFrame() const456*67e74705SXin Li bool LocationContext::inTopFrame() const {
457*67e74705SXin Li return getCurrentStackFrame()->inTopFrame();
458*67e74705SXin Li }
459*67e74705SXin Li
isParentOf(const LocationContext * LC) const460*67e74705SXin Li bool LocationContext::isParentOf(const LocationContext *LC) const {
461*67e74705SXin Li do {
462*67e74705SXin Li const LocationContext *Parent = LC->getParent();
463*67e74705SXin Li if (Parent == this)
464*67e74705SXin Li return true;
465*67e74705SXin Li else
466*67e74705SXin Li LC = Parent;
467*67e74705SXin Li } while (LC);
468*67e74705SXin Li
469*67e74705SXin Li return false;
470*67e74705SXin Li }
471*67e74705SXin Li
dumpStack(raw_ostream & OS,StringRef Indent) const472*67e74705SXin Li void LocationContext::dumpStack(raw_ostream &OS, StringRef Indent) const {
473*67e74705SXin Li ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
474*67e74705SXin Li PrintingPolicy PP(Ctx.getLangOpts());
475*67e74705SXin Li PP.TerseOutput = 1;
476*67e74705SXin Li
477*67e74705SXin Li unsigned Frame = 0;
478*67e74705SXin Li for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
479*67e74705SXin Li switch (LCtx->getKind()) {
480*67e74705SXin Li case StackFrame:
481*67e74705SXin Li OS << Indent << '#' << Frame++ << ' ';
482*67e74705SXin Li cast<StackFrameContext>(LCtx)->getDecl()->print(OS, PP);
483*67e74705SXin Li OS << '\n';
484*67e74705SXin Li break;
485*67e74705SXin Li case Scope:
486*67e74705SXin Li OS << Indent << " (scope)\n";
487*67e74705SXin Li break;
488*67e74705SXin Li case Block:
489*67e74705SXin Li OS << Indent << " (block context: "
490*67e74705SXin Li << cast<BlockInvocationContext>(LCtx)->getContextData()
491*67e74705SXin Li << ")\n";
492*67e74705SXin Li break;
493*67e74705SXin Li }
494*67e74705SXin Li }
495*67e74705SXin Li }
496*67e74705SXin Li
dumpStack() const497*67e74705SXin Li LLVM_DUMP_METHOD void LocationContext::dumpStack() const {
498*67e74705SXin Li dumpStack(llvm::errs());
499*67e74705SXin Li }
500*67e74705SXin Li
501*67e74705SXin Li //===----------------------------------------------------------------------===//
502*67e74705SXin Li // Lazily generated map to query the external variables referenced by a Block.
503*67e74705SXin Li //===----------------------------------------------------------------------===//
504*67e74705SXin Li
505*67e74705SXin Li namespace {
506*67e74705SXin Li class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
507*67e74705SXin Li BumpVector<const VarDecl*> &BEVals;
508*67e74705SXin Li BumpVectorContext &BC;
509*67e74705SXin Li llvm::SmallPtrSet<const VarDecl*, 4> Visited;
510*67e74705SXin Li llvm::SmallPtrSet<const DeclContext*, 4> IgnoredContexts;
511*67e74705SXin Li public:
FindBlockDeclRefExprsVals(BumpVector<const VarDecl * > & bevals,BumpVectorContext & bc)512*67e74705SXin Li FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
513*67e74705SXin Li BumpVectorContext &bc)
514*67e74705SXin Li : BEVals(bevals), BC(bc) {}
515*67e74705SXin Li
VisitStmt(Stmt * S)516*67e74705SXin Li void VisitStmt(Stmt *S) {
517*67e74705SXin Li for (Stmt *Child : S->children())
518*67e74705SXin Li if (Child)
519*67e74705SXin Li Visit(Child);
520*67e74705SXin Li }
521*67e74705SXin Li
VisitDeclRefExpr(DeclRefExpr * DR)522*67e74705SXin Li void VisitDeclRefExpr(DeclRefExpr *DR) {
523*67e74705SXin Li // Non-local variables are also directly modified.
524*67e74705SXin Li if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
525*67e74705SXin Li if (!VD->hasLocalStorage()) {
526*67e74705SXin Li if (Visited.insert(VD).second)
527*67e74705SXin Li BEVals.push_back(VD, BC);
528*67e74705SXin Li }
529*67e74705SXin Li }
530*67e74705SXin Li }
531*67e74705SXin Li
VisitBlockExpr(BlockExpr * BR)532*67e74705SXin Li void VisitBlockExpr(BlockExpr *BR) {
533*67e74705SXin Li // Blocks containing blocks can transitively capture more variables.
534*67e74705SXin Li IgnoredContexts.insert(BR->getBlockDecl());
535*67e74705SXin Li Visit(BR->getBlockDecl()->getBody());
536*67e74705SXin Li }
537*67e74705SXin Li
VisitPseudoObjectExpr(PseudoObjectExpr * PE)538*67e74705SXin Li void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
539*67e74705SXin Li for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(),
540*67e74705SXin Li et = PE->semantics_end(); it != et; ++it) {
541*67e74705SXin Li Expr *Semantic = *it;
542*67e74705SXin Li if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
543*67e74705SXin Li Semantic = OVE->getSourceExpr();
544*67e74705SXin Li Visit(Semantic);
545*67e74705SXin Li }
546*67e74705SXin Li }
547*67e74705SXin Li };
548*67e74705SXin Li } // end anonymous namespace
549*67e74705SXin Li
550*67e74705SXin Li typedef BumpVector<const VarDecl*> DeclVec;
551*67e74705SXin Li
LazyInitializeReferencedDecls(const BlockDecl * BD,void * & Vec,llvm::BumpPtrAllocator & A)552*67e74705SXin Li static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,
553*67e74705SXin Li void *&Vec,
554*67e74705SXin Li llvm::BumpPtrAllocator &A) {
555*67e74705SXin Li if (Vec)
556*67e74705SXin Li return (DeclVec*) Vec;
557*67e74705SXin Li
558*67e74705SXin Li BumpVectorContext BC(A);
559*67e74705SXin Li DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
560*67e74705SXin Li new (BV) DeclVec(BC, 10);
561*67e74705SXin Li
562*67e74705SXin Li // Go through the capture list.
563*67e74705SXin Li for (const auto &CI : BD->captures()) {
564*67e74705SXin Li BV->push_back(CI.getVariable(), BC);
565*67e74705SXin Li }
566*67e74705SXin Li
567*67e74705SXin Li // Find the referenced global/static variables.
568*67e74705SXin Li FindBlockDeclRefExprsVals F(*BV, BC);
569*67e74705SXin Li F.Visit(BD->getBody());
570*67e74705SXin Li
571*67e74705SXin Li Vec = BV;
572*67e74705SXin Li return BV;
573*67e74705SXin Li }
574*67e74705SXin Li
575*67e74705SXin Li llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
getReferencedBlockVars(const BlockDecl * BD)576*67e74705SXin Li AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {
577*67e74705SXin Li if (!ReferencedBlockVars)
578*67e74705SXin Li ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
579*67e74705SXin Li
580*67e74705SXin Li const DeclVec *V =
581*67e74705SXin Li LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
582*67e74705SXin Li return llvm::make_range(V->begin(), V->end());
583*67e74705SXin Li }
584*67e74705SXin Li
getAnalysisImpl(const void * tag)585*67e74705SXin Li ManagedAnalysis *&AnalysisDeclContext::getAnalysisImpl(const void *tag) {
586*67e74705SXin Li if (!ManagedAnalyses)
587*67e74705SXin Li ManagedAnalyses = new ManagedAnalysisMap();
588*67e74705SXin Li ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
589*67e74705SXin Li return (*M)[tag];
590*67e74705SXin Li }
591*67e74705SXin Li
592*67e74705SXin Li //===----------------------------------------------------------------------===//
593*67e74705SXin Li // Cleanup.
594*67e74705SXin Li //===----------------------------------------------------------------------===//
595*67e74705SXin Li
~ManagedAnalysis()596*67e74705SXin Li ManagedAnalysis::~ManagedAnalysis() {}
597*67e74705SXin Li
~AnalysisDeclContext()598*67e74705SXin Li AnalysisDeclContext::~AnalysisDeclContext() {
599*67e74705SXin Li delete forcedBlkExprs;
600*67e74705SXin Li delete ReferencedBlockVars;
601*67e74705SXin Li // Release the managed analyses.
602*67e74705SXin Li if (ManagedAnalyses) {
603*67e74705SXin Li ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
604*67e74705SXin Li llvm::DeleteContainerSeconds(*M);
605*67e74705SXin Li delete M;
606*67e74705SXin Li }
607*67e74705SXin Li }
608*67e74705SXin Li
~AnalysisDeclContextManager()609*67e74705SXin Li AnalysisDeclContextManager::~AnalysisDeclContextManager() {
610*67e74705SXin Li llvm::DeleteContainerSeconds(Contexts);
611*67e74705SXin Li }
612*67e74705SXin Li
~LocationContext()613*67e74705SXin Li LocationContext::~LocationContext() {}
614*67e74705SXin Li
~LocationContextManager()615*67e74705SXin Li LocationContextManager::~LocationContextManager() {
616*67e74705SXin Li clear();
617*67e74705SXin Li }
618*67e74705SXin Li
clear()619*67e74705SXin Li void LocationContextManager::clear() {
620*67e74705SXin Li for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
621*67e74705SXin Li E = Contexts.end(); I != E; ) {
622*67e74705SXin Li LocationContext *LC = &*I;
623*67e74705SXin Li ++I;
624*67e74705SXin Li delete LC;
625*67e74705SXin Li }
626*67e74705SXin Li
627*67e74705SXin Li Contexts.clear();
628*67e74705SXin Li }
629*67e74705SXin Li
630