Path: blob/main/contrib/llvm-project/clang/lib/Analysis/AnalysisDeclContext.cpp
35233 views
//===- AnalysisDeclContext.cpp - Analysis context for Path Sens analysis --===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file defines AnalysisDeclContext, a class that manages the analysis9// context data for path sensitive analysis.10//11//===----------------------------------------------------------------------===//1213#include "clang/Analysis/AnalysisDeclContext.h"14#include "clang/AST/ASTContext.h"15#include "clang/AST/Decl.h"16#include "clang/AST/DeclBase.h"17#include "clang/AST/DeclCXX.h"18#include "clang/AST/DeclObjC.h"19#include "clang/AST/DeclTemplate.h"20#include "clang/AST/Expr.h"21#include "clang/AST/LambdaCapture.h"22#include "clang/AST/ParentMap.h"23#include "clang/AST/PrettyPrinter.h"24#include "clang/AST/Stmt.h"25#include "clang/AST/StmtCXX.h"26#include "clang/AST/StmtVisitor.h"27#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"28#include "clang/Analysis/BodyFarm.h"29#include "clang/Analysis/CFG.h"30#include "clang/Analysis/CFGStmtMap.h"31#include "clang/Analysis/Support/BumpVector.h"32#include "clang/Basic/JsonSupport.h"33#include "clang/Basic/LLVM.h"34#include "clang/Basic/SourceLocation.h"35#include "clang/Basic/SourceManager.h"36#include "llvm/ADT/DenseMap.h"37#include "llvm/ADT/FoldingSet.h"38#include "llvm/ADT/STLExtras.h"39#include "llvm/ADT/SmallPtrSet.h"40#include "llvm/ADT/iterator_range.h"41#include "llvm/Support/Allocator.h"42#include "llvm/Support/Casting.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>4950using namespace clang;5152using ManagedAnalysisMap = llvm::DenseMap<const void *, std::unique_ptr<ManagedAnalysis>>;5354AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,55const Decl *D,56const CFG::BuildOptions &Options)57: ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {58cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;59}6061AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,62const Decl *D)63: ADCMgr(ADCMgr), D(D) {64cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;65}6667AnalysisDeclContextManager::AnalysisDeclContextManager(68ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors,69bool addInitializers, bool addTemporaryDtors, bool addLifetime,70bool addLoopExit, bool addScopes, bool synthesizeBodies,71bool addStaticInitBranch, bool addCXXNewAllocator,72bool addRichCXXConstructors, bool markElidedCXXConstructors,73bool addVirtualBaseBranches, CodeInjector *injector)74: Injector(injector), FunctionBodyFarm(ASTCtx, injector),75SynthesizeBodies(synthesizeBodies) {76cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;77cfgBuildOptions.AddImplicitDtors = addImplicitDtors;78cfgBuildOptions.AddInitializers = addInitializers;79cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;80cfgBuildOptions.AddLifetime = addLifetime;81cfgBuildOptions.AddLoopExit = addLoopExit;82cfgBuildOptions.AddScopes = addScopes;83cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;84cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;85cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;86cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;87cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;88}8990void AnalysisDeclContextManager::clear() { Contexts.clear(); }9192Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {93IsAutosynthesized = false;94if (const auto *FD = dyn_cast<FunctionDecl>(D)) {95Stmt *Body = FD->getBody();96if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))97Body = CoroBody->getBody();98if (ADCMgr && ADCMgr->synthesizeBodies()) {99Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);100if (SynthesizedBody) {101Body = SynthesizedBody;102IsAutosynthesized = true;103}104}105return Body;106}107else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {108Stmt *Body = MD->getBody();109if (ADCMgr && ADCMgr->synthesizeBodies()) {110Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(MD);111if (SynthesizedBody) {112Body = SynthesizedBody;113IsAutosynthesized = true;114}115}116return Body;117} else if (const auto *BD = dyn_cast<BlockDecl>(D))118return BD->getBody();119else if (const auto *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))120return FunTmpl->getTemplatedDecl()->getBody();121122llvm_unreachable("unknown code decl");123}124125Stmt *AnalysisDeclContext::getBody() const {126bool Tmp;127return getBody(Tmp);128}129130bool AnalysisDeclContext::isBodyAutosynthesized() const {131bool Tmp;132getBody(Tmp);133return Tmp;134}135136bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const {137bool Tmp;138Stmt *Body = getBody(Tmp);139return Tmp && Body->getBeginLoc().isValid();140}141142/// Returns true if \param VD is an Objective-C implicit 'self' parameter.143static bool isSelfDecl(const VarDecl *VD) {144return isa_and_nonnull<ImplicitParamDecl>(VD) && VD->getName() == "self";145}146147const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {148if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))149return MD->getSelfDecl();150if (const auto *BD = dyn_cast<BlockDecl>(D)) {151// See if 'self' was captured by the block.152for (const auto &I : BD->captures()) {153const VarDecl *VD = I.getVariable();154if (isSelfDecl(VD))155return dyn_cast<ImplicitParamDecl>(VD);156}157}158159auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);160if (!CXXMethod)161return nullptr;162163const CXXRecordDecl *parent = CXXMethod->getParent();164if (!parent->isLambda())165return nullptr;166167for (const auto &LC : parent->captures()) {168if (!LC.capturesVariable())169continue;170171ValueDecl *VD = LC.getCapturedVar();172if (isSelfDecl(dyn_cast<VarDecl>(VD)))173return dyn_cast<ImplicitParamDecl>(VD);174}175176return nullptr;177}178179void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {180if (!forcedBlkExprs)181forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();182// Default construct an entry for 'stmt'.183if (const auto *e = dyn_cast<Expr>(stmt))184stmt = e->IgnoreParens();185(void) (*forcedBlkExprs)[stmt];186}187188const CFGBlock *189AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {190assert(forcedBlkExprs);191if (const auto *e = dyn_cast<Expr>(stmt))192stmt = e->IgnoreParens();193CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =194forcedBlkExprs->find(stmt);195assert(itr != forcedBlkExprs->end());196return itr->second;197}198199/// Add each synthetic statement in the CFG to the parent map, using the200/// source statement's parent.201static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {202if (!TheCFG)203return;204205for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(),206E = TheCFG->synthetic_stmt_end();207I != E; ++I) {208PM.setParent(I->first, PM.getParent(I->second));209}210}211212CFG *AnalysisDeclContext::getCFG() {213if (!cfgBuildOptions.PruneTriviallyFalseEdges)214return getUnoptimizedCFG();215216if (!builtCFG) {217cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);218// Even when the cfg is not successfully built, we don't219// want to try building it again.220builtCFG = true;221222if (PM)223addParentsForSyntheticStmts(cfg.get(), *PM);224225// The Observer should only observe one build of the CFG.226getCFGBuildOptions().Observer = nullptr;227}228return cfg.get();229}230231CFG *AnalysisDeclContext::getUnoptimizedCFG() {232if (!builtCompleteCFG) {233SaveAndRestore NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges, false);234completeCFG =235CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);236// Even when the cfg is not successfully built, we don't237// want to try building it again.238builtCompleteCFG = true;239240if (PM)241addParentsForSyntheticStmts(completeCFG.get(), *PM);242243// The Observer should only observe one build of the CFG.244getCFGBuildOptions().Observer = nullptr;245}246return completeCFG.get();247}248249CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {250if (cfgStmtMap)251return cfgStmtMap.get();252253if (CFG *c = getCFG()) {254cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));255return cfgStmtMap.get();256}257258return nullptr;259}260261CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {262if (CFA)263return CFA.get();264265if (CFG *c = getCFG()) {266CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));267return CFA.get();268}269270return nullptr;271}272273void AnalysisDeclContext::dumpCFG(bool ShowColors) {274getCFG()->dump(getASTContext().getLangOpts(), ShowColors);275}276277ParentMap &AnalysisDeclContext::getParentMap() {278if (!PM) {279PM.reset(new ParentMap(getBody()));280if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {281for (const auto *I : C->inits()) {282PM->addStmt(I->getInit());283}284}285if (builtCFG)286addParentsForSyntheticStmts(getCFG(), *PM);287if (builtCompleteCFG)288addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);289}290return *PM;291}292293AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {294if (const auto *FD = dyn_cast<FunctionDecl>(D)) {295// Calling 'hasBody' replaces 'FD' in place with the FunctionDecl296// that has the body.297FD->hasBody(FD);298D = FD;299}300301std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];302if (!AC)303AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);304return AC.get();305}306307BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; }308309const StackFrameContext *310AnalysisDeclContext::getStackFrame(const LocationContext *ParentLC,311const Stmt *S, const CFGBlock *Blk,312unsigned BlockCount, unsigned Index) {313return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,314BlockCount, Index);315}316317const BlockInvocationContext *AnalysisDeclContext::getBlockInvocationContext(318const LocationContext *ParentLC, const BlockDecl *BD, const void *Data) {319return getLocationContextManager().getBlockInvocationContext(this, ParentLC,320BD, Data);321}322323bool AnalysisDeclContext::isInStdNamespace(const Decl *D) {324const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();325const auto *ND = dyn_cast<NamespaceDecl>(DC);326if (!ND)327return false;328329while (const DeclContext *Parent = ND->getParent()) {330if (!isa<NamespaceDecl>(Parent))331break;332ND = cast<NamespaceDecl>(Parent);333}334335return ND->isStdNamespace();336}337338std::string AnalysisDeclContext::getFunctionName(const Decl *D) {339std::string Str;340llvm::raw_string_ostream OS(Str);341const ASTContext &Ctx = D->getASTContext();342343if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {344OS << FD->getQualifiedNameAsString();345346// In C++, there are overloads.347348if (Ctx.getLangOpts().CPlusPlus) {349OS << '(';350for (const auto &P : FD->parameters()) {351if (P != *FD->param_begin())352OS << ", ";353OS << P->getType();354}355OS << ')';356}357358} else if (isa<BlockDecl>(D)) {359PresumedLoc Loc = Ctx.getSourceManager().getPresumedLoc(D->getLocation());360361if (Loc.isValid()) {362OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()363<< ')';364}365366} else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {367368// FIXME: copy-pasted from CGDebugInfo.cpp.369OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';370const DeclContext *DC = OMD->getDeclContext();371if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {372OS << OID->getName();373} else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {374OS << OID->getName();375} else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {376if (OC->IsClassExtension()) {377OS << OC->getClassInterface()->getName();378} else {379OS << OC->getIdentifier()->getNameStart() << '('380<< OC->getIdentifier()->getNameStart() << ')';381}382} else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {383OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')';384}385OS << ' ' << OMD->getSelector().getAsString() << ']';386}387388return Str;389}390391LocationContextManager &AnalysisDeclContext::getLocationContextManager() {392assert(393ADCMgr &&394"Cannot create LocationContexts without an AnalysisDeclContextManager!");395return ADCMgr->getLocationContextManager();396}397398//===----------------------------------------------------------------------===//399// FoldingSet profiling.400//===----------------------------------------------------------------------===//401402void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,403ContextKind ck,404AnalysisDeclContext *ctx,405const LocationContext *parent,406const void *data) {407ID.AddInteger(ck);408ID.AddPointer(ctx);409ID.AddPointer(parent);410ID.AddPointer(data);411}412413void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {414Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,415BlockCount, Index);416}417418void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {419Profile(ID, getAnalysisDeclContext(), getParent(), BD, Data);420}421422//===----------------------------------------------------------------------===//423// LocationContext creation.424//===----------------------------------------------------------------------===//425426const StackFrameContext *LocationContextManager::getStackFrame(427AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,428const CFGBlock *blk, unsigned blockCount, unsigned idx) {429llvm::FoldingSetNodeID ID;430StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);431void *InsertPos;432auto *L =433cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));434if (!L) {435L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);436Contexts.InsertNode(L, InsertPos);437}438return L;439}440441const BlockInvocationContext *LocationContextManager::getBlockInvocationContext(442AnalysisDeclContext *ADC, const LocationContext *ParentLC,443const BlockDecl *BD, const void *Data) {444llvm::FoldingSetNodeID ID;445BlockInvocationContext::Profile(ID, ADC, ParentLC, BD, Data);446void *InsertPos;447auto *L =448cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,449InsertPos));450if (!L) {451L = new BlockInvocationContext(ADC, ParentLC, BD, Data, ++NewID);452Contexts.InsertNode(L, InsertPos);453}454return L;455}456457//===----------------------------------------------------------------------===//458// LocationContext methods.459//===----------------------------------------------------------------------===//460461const StackFrameContext *LocationContext::getStackFrame() const {462const LocationContext *LC = this;463while (LC) {464if (const auto *SFC = dyn_cast<StackFrameContext>(LC))465return SFC;466LC = LC->getParent();467}468return nullptr;469}470471bool LocationContext::inTopFrame() const {472return getStackFrame()->inTopFrame();473}474475bool LocationContext::isParentOf(const LocationContext *LC) const {476do {477const LocationContext *Parent = LC->getParent();478if (Parent == this)479return true;480else481LC = Parent;482} while (LC);483484return false;485}486487static void printLocation(raw_ostream &Out, const SourceManager &SM,488SourceLocation Loc) {489if (Loc.isFileID() && SM.isInMainFile(Loc))490Out << SM.getExpansionLineNumber(Loc);491else492Loc.print(Out, SM);493}494495void LocationContext::dumpStack(raw_ostream &Out) const {496ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();497PrintingPolicy PP(Ctx.getLangOpts());498PP.TerseOutput = 1;499500const SourceManager &SM =501getAnalysisDeclContext()->getASTContext().getSourceManager();502503unsigned Frame = 0;504for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {505switch (LCtx->getKind()) {506case StackFrame:507Out << "\t#" << Frame << ' ';508++Frame;509if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))510Out << "Calling " << AnalysisDeclContext::getFunctionName(D);511else512Out << "Calling anonymous code";513if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {514Out << " at line ";515printLocation(Out, SM, S->getBeginLoc());516}517break;518case Block:519Out << "Invoking block";520if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {521Out << " defined at line ";522printLocation(Out, SM, D->getBeginLoc());523}524break;525}526Out << '\n';527}528}529530void LocationContext::printJson(raw_ostream &Out, const char *NL,531unsigned int Space, bool IsDot,532std::function<void(const LocationContext *)>533printMoreInfoPerContext) const {534ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();535PrintingPolicy PP(Ctx.getLangOpts());536PP.TerseOutput = 1;537538const SourceManager &SM =539getAnalysisDeclContext()->getASTContext().getSourceManager();540541unsigned Frame = 0;542for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {543Indent(Out, Space, IsDot)544<< "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";545switch (LCtx->getKind()) {546case StackFrame:547Out << '#' << Frame << " Call\", \"calling\": \"";548++Frame;549if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))550Out << D->getQualifiedNameAsString();551else552Out << "anonymous code";553554Out << "\", \"location\": ";555if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {556printSourceLocationAsJson(Out, S->getBeginLoc(), SM);557} else {558Out << "null";559}560561Out << ", \"items\": ";562break;563case Block:564Out << "Invoking block\" ";565if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {566Out << ", \"location\": ";567printSourceLocationAsJson(Out, D->getBeginLoc(), SM);568Out << ' ';569}570break;571}572573printMoreInfoPerContext(LCtx);574575Out << '}';576if (LCtx->getParent())577Out << ',';578Out << NL;579}580}581582LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); }583584//===----------------------------------------------------------------------===//585// Lazily generated map to query the external variables referenced by a Block.586//===----------------------------------------------------------------------===//587588namespace {589590class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{591BumpVector<const VarDecl *> &BEVals;592BumpVectorContext &BC;593llvm::SmallPtrSet<const VarDecl *, 4> Visited;594llvm::SmallPtrSet<const DeclContext *, 4> IgnoredContexts;595596public:597FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,598BumpVectorContext &bc)599: BEVals(bevals), BC(bc) {}600601void VisitStmt(Stmt *S) {602for (auto *Child : S->children())603if (Child)604Visit(Child);605}606607void VisitDeclRefExpr(DeclRefExpr *DR) {608// Non-local variables are also directly modified.609if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {610if (!VD->hasLocalStorage()) {611if (Visited.insert(VD).second)612BEVals.push_back(VD, BC);613}614}615}616617void VisitBlockExpr(BlockExpr *BR) {618// Blocks containing blocks can transitively capture more variables.619IgnoredContexts.insert(BR->getBlockDecl());620Visit(BR->getBlockDecl()->getBody());621}622623void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {624for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(),625et = PE->semantics_end(); it != et; ++it) {626Expr *Semantic = *it;627if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))628Semantic = OVE->getSourceExpr();629Visit(Semantic);630}631}632};633634} // namespace635636using DeclVec = BumpVector<const VarDecl *>;637638static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,639void *&Vec,640llvm::BumpPtrAllocator &A) {641if (Vec)642return (DeclVec*) Vec;643644BumpVectorContext BC(A);645DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();646new (BV) DeclVec(BC, 10);647648// Go through the capture list.649for (const auto &CI : BD->captures()) {650BV->push_back(CI.getVariable(), BC);651}652653// Find the referenced global/static variables.654FindBlockDeclRefExprsVals F(*BV, BC);655F.Visit(BD->getBody());656657Vec = BV;658return BV;659}660661llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>662AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {663if (!ReferencedBlockVars)664ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();665666const DeclVec *V =667LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);668return llvm::make_range(V->begin(), V->end());669}670671std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {672if (!ManagedAnalyses)673ManagedAnalyses = new ManagedAnalysisMap();674ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;675return (*M)[tag];676}677678//===----------------------------------------------------------------------===//679// Cleanup.680//===----------------------------------------------------------------------===//681682ManagedAnalysis::~ManagedAnalysis() = default;683684AnalysisDeclContext::~AnalysisDeclContext() {685delete forcedBlkExprs;686delete ReferencedBlockVars;687delete (ManagedAnalysisMap*) ManagedAnalyses;688}689690LocationContext::~LocationContext() = default;691692LocationContextManager::~LocationContextManager() {693clear();694}695696void LocationContextManager::clear() {697for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),698E = Contexts.end(); I != E; ) {699LocationContext *LC = &*I;700++I;701delete LC;702}703Contexts.clear();704}705706707