xref: /aosp_15_r20/external/clang/lib/Analysis/AnalysisDeclContext.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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