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