[DFAJumpThreading] Remove incoming StartBlock from all phis when unfolding select...
[llvm-project.git] / clang / lib / Analysis / AnalysisDeclContext.cpp
blobd3a1a993711fbf57be41ff85b2cc6e9fe2508880
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.
12 //===----------------------------------------------------------------------===//
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/Casting.h"
44 #include "llvm/Support/Compiler.h"
45 #include "llvm/Support/ErrorHandling.h"
46 #include "llvm/Support/SaveAndRestore.h"
47 #include "llvm/Support/raw_ostream.h"
48 #include <cassert>
49 #include <memory>
51 using namespace clang;
53 using ManagedAnalysisMap = llvm::DenseMap<const void *, std::unique_ptr<ManagedAnalysis>>;
55 AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
56 const Decl *D,
57 const CFG::BuildOptions &Options)
58 : ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {
59 cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
62 AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
63 const Decl *D)
64 : ADCMgr(ADCMgr), D(D) {
65 cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
68 AnalysisDeclContextManager::AnalysisDeclContextManager(
69 ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors,
70 bool addInitializers, bool addTemporaryDtors, bool addLifetime,
71 bool addLoopExit, bool addScopes, bool synthesizeBodies,
72 bool addStaticInitBranch, bool addCXXNewAllocator,
73 bool addRichCXXConstructors, bool markElidedCXXConstructors,
74 bool addVirtualBaseBranches, CodeInjector *injector)
75 : Injector(injector), FunctionBodyFarm(ASTCtx, injector),
76 SynthesizeBodies(synthesizeBodies) {
77 cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
78 cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
79 cfgBuildOptions.AddInitializers = addInitializers;
80 cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
81 cfgBuildOptions.AddLifetime = addLifetime;
82 cfgBuildOptions.AddLoopExit = addLoopExit;
83 cfgBuildOptions.AddScopes = addScopes;
84 cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
85 cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
86 cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;
87 cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;
88 cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;
91 void AnalysisDeclContextManager::clear() { Contexts.clear(); }
93 Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
94 IsAutosynthesized = false;
95 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
96 Stmt *Body = FD->getBody();
97 if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
98 Body = CoroBody->getBody();
99 if (ADCMgr && ADCMgr->synthesizeBodies()) {
100 Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);
101 if (SynthesizedBody) {
102 Body = SynthesizedBody;
103 IsAutosynthesized = true;
106 return Body;
108 else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
109 Stmt *Body = MD->getBody();
110 if (ADCMgr && ADCMgr->synthesizeBodies()) {
111 Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(MD);
112 if (SynthesizedBody) {
113 Body = SynthesizedBody;
114 IsAutosynthesized = true;
117 return Body;
118 } else if (const auto *BD = dyn_cast<BlockDecl>(D))
119 return BD->getBody();
120 else if (const auto *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
121 return FunTmpl->getTemplatedDecl()->getBody();
123 llvm_unreachable("unknown code decl");
126 Stmt *AnalysisDeclContext::getBody() const {
127 bool Tmp;
128 return getBody(Tmp);
131 bool AnalysisDeclContext::isBodyAutosynthesized() const {
132 bool Tmp;
133 getBody(Tmp);
134 return Tmp;
137 bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const {
138 bool Tmp;
139 Stmt *Body = getBody(Tmp);
140 return Tmp && Body->getBeginLoc().isValid();
143 /// Returns true if \param VD is an Objective-C implicit 'self' parameter.
144 static bool isSelfDecl(const VarDecl *VD) {
145 return isa_and_nonnull<ImplicitParamDecl>(VD) && VD->getName() == "self";
148 const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
149 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
150 return MD->getSelfDecl();
151 if (const auto *BD = dyn_cast<BlockDecl>(D)) {
152 // See if 'self' was captured by the block.
153 for (const auto &I : BD->captures()) {
154 const VarDecl *VD = I.getVariable();
155 if (isSelfDecl(VD))
156 return dyn_cast<ImplicitParamDecl>(VD);
160 auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
161 if (!CXXMethod)
162 return nullptr;
164 const CXXRecordDecl *parent = CXXMethod->getParent();
165 if (!parent->isLambda())
166 return nullptr;
168 for (const auto &LC : parent->captures()) {
169 if (!LC.capturesVariable())
170 continue;
172 ValueDecl *VD = LC.getCapturedVar();
173 if (isSelfDecl(dyn_cast<VarDecl>(VD)))
174 return dyn_cast<ImplicitParamDecl>(VD);
177 return nullptr;
180 void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
181 if (!forcedBlkExprs)
182 forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
183 // Default construct an entry for 'stmt'.
184 if (const auto *e = dyn_cast<Expr>(stmt))
185 stmt = e->IgnoreParens();
186 (void) (*forcedBlkExprs)[stmt];
189 const CFGBlock *
190 AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {
191 assert(forcedBlkExprs);
192 if (const auto *e = dyn_cast<Expr>(stmt))
193 stmt = e->IgnoreParens();
194 CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
195 forcedBlkExprs->find(stmt);
196 assert(itr != forcedBlkExprs->end());
197 return itr->second;
200 /// Add each synthetic statement in the CFG to the parent map, using the
201 /// source statement's parent.
202 static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
203 if (!TheCFG)
204 return;
206 for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(),
207 E = TheCFG->synthetic_stmt_end();
208 I != E; ++I) {
209 PM.setParent(I->first, PM.getParent(I->second));
213 CFG *AnalysisDeclContext::getCFG() {
214 if (!cfgBuildOptions.PruneTriviallyFalseEdges)
215 return getUnoptimizedCFG();
217 if (!builtCFG) {
218 cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
219 // Even when the cfg is not successfully built, we don't
220 // want to try building it again.
221 builtCFG = true;
223 if (PM)
224 addParentsForSyntheticStmts(cfg.get(), *PM);
226 // The Observer should only observe one build of the CFG.
227 getCFGBuildOptions().Observer = nullptr;
229 return cfg.get();
232 CFG *AnalysisDeclContext::getUnoptimizedCFG() {
233 if (!builtCompleteCFG) {
234 SaveAndRestore NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges, false);
235 completeCFG =
236 CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
237 // Even when the cfg is not successfully built, we don't
238 // want to try building it again.
239 builtCompleteCFG = true;
241 if (PM)
242 addParentsForSyntheticStmts(completeCFG.get(), *PM);
244 // The Observer should only observe one build of the CFG.
245 getCFGBuildOptions().Observer = nullptr;
247 return completeCFG.get();
250 CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
251 if (cfgStmtMap)
252 return cfgStmtMap.get();
254 if (CFG *c = getCFG()) {
255 cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
256 return cfgStmtMap.get();
259 return nullptr;
262 CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
263 if (CFA)
264 return CFA.get();
266 if (CFG *c = getCFG()) {
267 CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
268 return CFA.get();
271 return nullptr;
274 void AnalysisDeclContext::dumpCFG(bool ShowColors) {
275 getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
278 ParentMap &AnalysisDeclContext::getParentMap() {
279 if (!PM) {
280 PM.reset(new ParentMap(getBody()));
281 if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
282 for (const auto *I : C->inits()) {
283 PM->addStmt(I->getInit());
286 if (builtCFG)
287 addParentsForSyntheticStmts(getCFG(), *PM);
288 if (builtCompleteCFG)
289 addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);
291 return *PM;
294 AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
295 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
296 // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
297 // that has the body.
298 FD->hasBody(FD);
299 D = FD;
302 std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
303 if (!AC)
304 AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
305 return AC.get();
308 BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; }
310 const StackFrameContext *
311 AnalysisDeclContext::getStackFrame(const LocationContext *ParentLC,
312 const Stmt *S, const CFGBlock *Blk,
313 unsigned BlockCount, unsigned Index) {
314 return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,
315 BlockCount, Index);
318 const BlockInvocationContext *AnalysisDeclContext::getBlockInvocationContext(
319 const LocationContext *ParentLC, const BlockDecl *BD, const void *Data) {
320 return getLocationContextManager().getBlockInvocationContext(this, ParentLC,
321 BD, Data);
324 bool AnalysisDeclContext::isInStdNamespace(const Decl *D) {
325 const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
326 const auto *ND = dyn_cast<NamespaceDecl>(DC);
327 if (!ND)
328 return false;
330 while (const DeclContext *Parent = ND->getParent()) {
331 if (!isa<NamespaceDecl>(Parent))
332 break;
333 ND = cast<NamespaceDecl>(Parent);
336 return ND->isStdNamespace();
339 std::string AnalysisDeclContext::getFunctionName(const Decl *D) {
340 std::string Str;
341 llvm::raw_string_ostream OS(Str);
342 const ASTContext &Ctx = D->getASTContext();
344 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
345 OS << FD->getQualifiedNameAsString();
347 // In C++, there are overloads.
349 if (Ctx.getLangOpts().CPlusPlus) {
350 OS << '(';
351 for (const auto &P : FD->parameters()) {
352 if (P != *FD->param_begin())
353 OS << ", ";
354 OS << P->getType();
356 OS << ')';
359 } else if (isa<BlockDecl>(D)) {
360 PresumedLoc Loc = Ctx.getSourceManager().getPresumedLoc(D->getLocation());
362 if (Loc.isValid()) {
363 OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
364 << ')';
367 } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
369 // FIXME: copy-pasted from CGDebugInfo.cpp.
370 OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
371 const DeclContext *DC = OMD->getDeclContext();
372 if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
373 OS << OID->getName();
374 } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
375 OS << OID->getName();
376 } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
377 if (OC->IsClassExtension()) {
378 OS << OC->getClassInterface()->getName();
379 } else {
380 OS << OC->getIdentifier()->getNameStart() << '('
381 << OC->getIdentifier()->getNameStart() << ')';
383 } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
384 OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')';
386 OS << ' ' << OMD->getSelector().getAsString() << ']';
389 return Str;
392 LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
393 assert(
394 ADCMgr &&
395 "Cannot create LocationContexts without an AnalysisDeclContextManager!");
396 return ADCMgr->getLocationContextManager();
399 //===----------------------------------------------------------------------===//
400 // FoldingSet profiling.
401 //===----------------------------------------------------------------------===//
403 void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
404 ContextKind ck,
405 AnalysisDeclContext *ctx,
406 const LocationContext *parent,
407 const void *data) {
408 ID.AddInteger(ck);
409 ID.AddPointer(ctx);
410 ID.AddPointer(parent);
411 ID.AddPointer(data);
414 void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
415 Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,
416 BlockCount, Index);
419 void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
420 Profile(ID, getAnalysisDeclContext(), getParent(), BD, Data);
423 //===----------------------------------------------------------------------===//
424 // LocationContext creation.
425 //===----------------------------------------------------------------------===//
427 const StackFrameContext *LocationContextManager::getStackFrame(
428 AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,
429 const CFGBlock *blk, unsigned blockCount, unsigned idx) {
430 llvm::FoldingSetNodeID ID;
431 StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);
432 void *InsertPos;
433 auto *L =
434 cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
435 if (!L) {
436 L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);
437 Contexts.InsertNode(L, InsertPos);
439 return L;
442 const BlockInvocationContext *LocationContextManager::getBlockInvocationContext(
443 AnalysisDeclContext *ADC, const LocationContext *ParentLC,
444 const BlockDecl *BD, const void *Data) {
445 llvm::FoldingSetNodeID ID;
446 BlockInvocationContext::Profile(ID, ADC, ParentLC, BD, Data);
447 void *InsertPos;
448 auto *L =
449 cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
450 InsertPos));
451 if (!L) {
452 L = new BlockInvocationContext(ADC, ParentLC, BD, Data, ++NewID);
453 Contexts.InsertNode(L, InsertPos);
455 return L;
458 //===----------------------------------------------------------------------===//
459 // LocationContext methods.
460 //===----------------------------------------------------------------------===//
462 const StackFrameContext *LocationContext::getStackFrame() const {
463 const LocationContext *LC = this;
464 while (LC) {
465 if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
466 return SFC;
467 LC = LC->getParent();
469 return nullptr;
472 bool LocationContext::inTopFrame() const {
473 return getStackFrame()->inTopFrame();
476 bool LocationContext::isParentOf(const LocationContext *LC) const {
477 do {
478 const LocationContext *Parent = LC->getParent();
479 if (Parent == this)
480 return true;
481 else
482 LC = Parent;
483 } while (LC);
485 return false;
488 static void printLocation(raw_ostream &Out, const SourceManager &SM,
489 SourceLocation Loc) {
490 if (Loc.isFileID() && SM.isInMainFile(Loc))
491 Out << SM.getExpansionLineNumber(Loc);
492 else
493 Loc.print(Out, SM);
496 void LocationContext::dumpStack(raw_ostream &Out) const {
497 ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
498 PrintingPolicy PP(Ctx.getLangOpts());
499 PP.TerseOutput = 1;
501 const SourceManager &SM =
502 getAnalysisDeclContext()->getASTContext().getSourceManager();
504 unsigned Frame = 0;
505 for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
506 switch (LCtx->getKind()) {
507 case StackFrame:
508 Out << "\t#" << Frame << ' ';
509 ++Frame;
510 if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
511 Out << "Calling " << AnalysisDeclContext::getFunctionName(D);
512 else
513 Out << "Calling anonymous code";
514 if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
515 Out << " at line ";
516 printLocation(Out, SM, S->getBeginLoc());
518 break;
519 case Block:
520 Out << "Invoking block";
521 if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
522 Out << " defined at line ";
523 printLocation(Out, SM, D->getBeginLoc());
525 break;
527 Out << '\n';
531 void LocationContext::printJson(raw_ostream &Out, const char *NL,
532 unsigned int Space, bool IsDot,
533 std::function<void(const LocationContext *)>
534 printMoreInfoPerContext) const {
535 ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
536 PrintingPolicy PP(Ctx.getLangOpts());
537 PP.TerseOutput = 1;
539 const SourceManager &SM =
540 getAnalysisDeclContext()->getASTContext().getSourceManager();
542 unsigned Frame = 0;
543 for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
544 Indent(Out, Space, IsDot)
545 << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
546 switch (LCtx->getKind()) {
547 case StackFrame:
548 Out << '#' << Frame << " Call\", \"calling\": \"";
549 ++Frame;
550 if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
551 Out << D->getQualifiedNameAsString();
552 else
553 Out << "anonymous code";
555 Out << "\", \"location\": ";
556 if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
557 printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
558 } else {
559 Out << "null";
562 Out << ", \"items\": ";
563 break;
564 case Block:
565 Out << "Invoking block\" ";
566 if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
567 Out << ", \"location\": ";
568 printSourceLocationAsJson(Out, D->getBeginLoc(), SM);
569 Out << ' ';
571 break;
574 printMoreInfoPerContext(LCtx);
576 Out << '}';
577 if (LCtx->getParent())
578 Out << ',';
579 Out << NL;
583 LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); }
585 //===----------------------------------------------------------------------===//
586 // Lazily generated map to query the external variables referenced by a Block.
587 //===----------------------------------------------------------------------===//
589 namespace {
591 class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
592 BumpVector<const VarDecl *> &BEVals;
593 BumpVectorContext &BC;
594 llvm::SmallPtrSet<const VarDecl *, 4> Visited;
595 llvm::SmallPtrSet<const DeclContext *, 4> IgnoredContexts;
597 public:
598 FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
599 BumpVectorContext &bc)
600 : BEVals(bevals), BC(bc) {}
602 void VisitStmt(Stmt *S) {
603 for (auto *Child : S->children())
604 if (Child)
605 Visit(Child);
608 void VisitDeclRefExpr(DeclRefExpr *DR) {
609 // Non-local variables are also directly modified.
610 if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
611 if (!VD->hasLocalStorage()) {
612 if (Visited.insert(VD).second)
613 BEVals.push_back(VD, BC);
618 void VisitBlockExpr(BlockExpr *BR) {
619 // Blocks containing blocks can transitively capture more variables.
620 IgnoredContexts.insert(BR->getBlockDecl());
621 Visit(BR->getBlockDecl()->getBody());
624 void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
625 for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(),
626 et = PE->semantics_end(); it != et; ++it) {
627 Expr *Semantic = *it;
628 if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
629 Semantic = OVE->getSourceExpr();
630 Visit(Semantic);
635 } // namespace
637 using DeclVec = BumpVector<const VarDecl *>;
639 static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,
640 void *&Vec,
641 llvm::BumpPtrAllocator &A) {
642 if (Vec)
643 return (DeclVec*) Vec;
645 BumpVectorContext BC(A);
646 DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
647 new (BV) DeclVec(BC, 10);
649 // Go through the capture list.
650 for (const auto &CI : BD->captures()) {
651 BV->push_back(CI.getVariable(), BC);
654 // Find the referenced global/static variables.
655 FindBlockDeclRefExprsVals F(*BV, BC);
656 F.Visit(BD->getBody());
658 Vec = BV;
659 return BV;
662 llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
663 AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {
664 if (!ReferencedBlockVars)
665 ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
667 const DeclVec *V =
668 LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
669 return llvm::make_range(V->begin(), V->end());
672 std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
673 if (!ManagedAnalyses)
674 ManagedAnalyses = new ManagedAnalysisMap();
675 ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
676 return (*M)[tag];
679 //===----------------------------------------------------------------------===//
680 // Cleanup.
681 //===----------------------------------------------------------------------===//
683 ManagedAnalysis::~ManagedAnalysis() = default;
685 AnalysisDeclContext::~AnalysisDeclContext() {
686 delete forcedBlkExprs;
687 delete ReferencedBlockVars;
688 delete (ManagedAnalysisMap*) ManagedAnalyses;
691 LocationContext::~LocationContext() = default;
693 LocationContextManager::~LocationContextManager() {
694 clear();
697 void LocationContextManager::clear() {
698 for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
699 E = Contexts.end(); I != E; ) {
700 LocationContext *LC = &*I;
701 ++I;
702 delete LC;
704 Contexts.clear();