1 //===- AnalysisDeclContext.cpp - Analysis context for Path Sens analysis --===//
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
7 //===----------------------------------------------------------------------===//
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"
51 using namespace clang
;
53 using ManagedAnalysisMap
= llvm::DenseMap
<const void *, std::unique_ptr
<ManagedAnalysis
>>;
55 AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager
*ADCMgr
,
57 const CFG::BuildOptions
&Options
)
58 : ADCMgr(ADCMgr
), D(D
), cfgBuildOptions(Options
) {
59 cfgBuildOptions
.forcedBlkExprs
= &forcedBlkExprs
;
62 AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager
*ADCMgr
,
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;
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;
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 {
131 bool AnalysisDeclContext::isBodyAutosynthesized() const {
137 bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const {
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();
156 return dyn_cast
<ImplicitParamDecl
>(VD
);
160 auto *CXXMethod
= dyn_cast
<CXXMethodDecl
>(D
);
164 const CXXRecordDecl
*parent
= CXXMethod
->getParent();
165 if (!parent
->isLambda())
168 for (const auto &LC
: parent
->captures()) {
169 if (!LC
.capturesVariable())
172 ValueDecl
*VD
= LC
.getCapturedVar();
173 if (isSelfDecl(dyn_cast
<VarDecl
>(VD
)))
174 return dyn_cast
<ImplicitParamDecl
>(VD
);
180 void AnalysisDeclContext::registerForcedBlockExpression(const Stmt
*stmt
) {
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
];
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());
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
) {
206 for (CFG::synthetic_stmt_iterator I
= TheCFG
->synthetic_stmt_begin(),
207 E
= TheCFG
->synthetic_stmt_end();
209 PM
.setParent(I
->first
, PM
.getParent(I
->second
));
213 CFG
*AnalysisDeclContext::getCFG() {
214 if (!cfgBuildOptions
.PruneTriviallyFalseEdges
)
215 return getUnoptimizedCFG();
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.
224 addParentsForSyntheticStmts(cfg
.get(), *PM
);
226 // The Observer should only observe one build of the CFG.
227 getCFGBuildOptions().Observer
= nullptr;
232 CFG
*AnalysisDeclContext::getUnoptimizedCFG() {
233 if (!builtCompleteCFG
) {
234 SaveAndRestore
NotPrune(cfgBuildOptions
.PruneTriviallyFalseEdges
, false);
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;
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() {
252 return cfgStmtMap
.get();
254 if (CFG
*c
= getCFG()) {
255 cfgStmtMap
.reset(CFGStmtMap::Build(c
, &getParentMap()));
256 return cfgStmtMap
.get();
262 CFGReverseBlockReachabilityAnalysis
*AnalysisDeclContext::getCFGReachablityAnalysis() {
266 if (CFG
*c
= getCFG()) {
267 CFA
.reset(new CFGReverseBlockReachabilityAnalysis(*c
));
274 void AnalysisDeclContext::dumpCFG(bool ShowColors
) {
275 getCFG()->dump(getASTContext().getLangOpts(), ShowColors
);
278 ParentMap
&AnalysisDeclContext::getParentMap() {
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());
287 addParentsForSyntheticStmts(getCFG(), *PM
);
288 if (builtCompleteCFG
)
289 addParentsForSyntheticStmts(getUnoptimizedCFG(), *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.
302 std::unique_ptr
<AnalysisDeclContext
> &AC
= Contexts
[D
];
304 AC
= std::make_unique
<AnalysisDeclContext
>(this, D
, cfgBuildOptions
);
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
,
318 const BlockInvocationContext
*AnalysisDeclContext::getBlockInvocationContext(
319 const LocationContext
*ParentLC
, const BlockDecl
*BD
, const void *Data
) {
320 return getLocationContextManager().getBlockInvocationContext(this, ParentLC
,
324 bool AnalysisDeclContext::isInStdNamespace(const Decl
*D
) {
325 const DeclContext
*DC
= D
->getDeclContext()->getEnclosingNamespaceContext();
326 const auto *ND
= dyn_cast
<NamespaceDecl
>(DC
);
330 while (const DeclContext
*Parent
= ND
->getParent()) {
331 if (!isa
<NamespaceDecl
>(Parent
))
333 ND
= cast
<NamespaceDecl
>(Parent
);
336 return ND
->isStdNamespace();
339 std::string
AnalysisDeclContext::getFunctionName(const Decl
*D
) {
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
) {
351 for (const auto &P
: FD
->parameters()) {
352 if (P
!= *FD
->param_begin())
359 } else if (isa
<BlockDecl
>(D
)) {
360 PresumedLoc Loc
= Ctx
.getSourceManager().getPresumedLoc(D
->getLocation());
363 OS
<< "block (line: " << Loc
.getLine() << ", col: " << Loc
.getColumn()
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();
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() << ']';
392 LocationContextManager
&AnalysisDeclContext::getLocationContextManager() {
395 "Cannot create LocationContexts without an AnalysisDeclContextManager!");
396 return ADCMgr
->getLocationContextManager();
399 //===----------------------------------------------------------------------===//
400 // FoldingSet profiling.
401 //===----------------------------------------------------------------------===//
403 void LocationContext::ProfileCommon(llvm::FoldingSetNodeID
&ID
,
405 AnalysisDeclContext
*ctx
,
406 const LocationContext
*parent
,
410 ID
.AddPointer(parent
);
414 void StackFrameContext::Profile(llvm::FoldingSetNodeID
&ID
) {
415 Profile(ID
, getAnalysisDeclContext(), getParent(), CallSite
, Block
,
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
);
434 cast_or_null
<StackFrameContext
>(Contexts
.FindNodeOrInsertPos(ID
, InsertPos
));
436 L
= new StackFrameContext(ctx
, parent
, s
, blk
, blockCount
, idx
, ++NewID
);
437 Contexts
.InsertNode(L
, InsertPos
);
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
);
449 cast_or_null
<BlockInvocationContext
>(Contexts
.FindNodeOrInsertPos(ID
,
452 L
= new BlockInvocationContext(ADC
, ParentLC
, BD
, Data
, ++NewID
);
453 Contexts
.InsertNode(L
, InsertPos
);
458 //===----------------------------------------------------------------------===//
459 // LocationContext methods.
460 //===----------------------------------------------------------------------===//
462 const StackFrameContext
*LocationContext::getStackFrame() const {
463 const LocationContext
*LC
= this;
465 if (const auto *SFC
= dyn_cast
<StackFrameContext
>(LC
))
467 LC
= LC
->getParent();
472 bool LocationContext::inTopFrame() const {
473 return getStackFrame()->inTopFrame();
476 bool LocationContext::isParentOf(const LocationContext
*LC
) const {
478 const LocationContext
*Parent
= LC
->getParent();
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
);
496 void LocationContext::dumpStack(raw_ostream
&Out
) const {
497 ASTContext
&Ctx
= getAnalysisDeclContext()->getASTContext();
498 PrintingPolicy
PP(Ctx
.getLangOpts());
501 const SourceManager
&SM
=
502 getAnalysisDeclContext()->getASTContext().getSourceManager();
505 for (const LocationContext
*LCtx
= this; LCtx
; LCtx
= LCtx
->getParent()) {
506 switch (LCtx
->getKind()) {
508 Out
<< "\t#" << Frame
<< ' ';
510 if (const auto *D
= dyn_cast
<NamedDecl
>(LCtx
->getDecl()))
511 Out
<< "Calling " << AnalysisDeclContext::getFunctionName(D
);
513 Out
<< "Calling anonymous code";
514 if (const Stmt
*S
= cast
<StackFrameContext
>(LCtx
)->getCallSite()) {
516 printLocation(Out
, SM
, S
->getBeginLoc());
520 Out
<< "Invoking block";
521 if (const Decl
*D
= cast
<BlockInvocationContext
>(LCtx
)->getDecl()) {
522 Out
<< " defined at line ";
523 printLocation(Out
, SM
, D
->getBeginLoc());
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());
539 const SourceManager
&SM
=
540 getAnalysisDeclContext()->getASTContext().getSourceManager();
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()) {
548 Out
<< '#' << Frame
<< " Call\", \"calling\": \"";
550 if (const auto *D
= dyn_cast
<NamedDecl
>(LCtx
->getDecl()))
551 Out
<< D
->getQualifiedNameAsString();
553 Out
<< "anonymous code";
555 Out
<< "\", \"location\": ";
556 if (const Stmt
*S
= cast
<StackFrameContext
>(LCtx
)->getCallSite()) {
557 printSourceLocationAsJson(Out
, S
->getBeginLoc(), SM
);
562 Out
<< ", \"items\": ";
565 Out
<< "Invoking block\" ";
566 if (const Decl
*D
= cast
<BlockInvocationContext
>(LCtx
)->getDecl()) {
567 Out
<< ", \"location\": ";
568 printSourceLocationAsJson(Out
, D
->getBeginLoc(), SM
);
574 printMoreInfoPerContext(LCtx
);
577 if (LCtx
->getParent())
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 //===----------------------------------------------------------------------===//
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
;
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())
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();
637 using DeclVec
= BumpVector
<const VarDecl
*>;
639 static DeclVec
* LazyInitializeReferencedDecls(const BlockDecl
*BD
,
641 llvm::BumpPtrAllocator
&A
) {
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());
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*>();
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
;
679 //===----------------------------------------------------------------------===//
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() {
697 void LocationContextManager::clear() {
698 for (llvm::FoldingSet
<LocationContext
>::iterator I
= Contexts
.begin(),
699 E
= Contexts
.end(); I
!= E
; ) {
700 LocationContext
*LC
= &*I
;