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