Coverage Report

Created: 2025-09-30 00:56

/home/runner/work/DirectXShaderCompiler/DirectXShaderCompiler/tools/clang/lib/Analysis/AnalysisDeclContext.cpp
Line
Count
Source (jump to first uncovered line)
1
//== AnalysisDeclContext.cpp - Analysis context for Path Sens analysis -*- C++ -*-//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// This file defines AnalysisDeclContext, a class that manages the analysis context
11
// data for path sensitive analysis.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "clang/Analysis/AnalysisContext.h"
16
#include "BodyFarm.h"
17
#include "clang/AST/ASTContext.h"
18
#include "clang/AST/Decl.h"
19
#include "clang/AST/DeclObjC.h"
20
#include "clang/AST/DeclTemplate.h"
21
#include "clang/AST/ParentMap.h"
22
#include "clang/AST/StmtVisitor.h"
23
#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
24
#include "clang/Analysis/Analyses/LiveVariables.h"
25
#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h"
26
#include "clang/Analysis/CFG.h"
27
#include "clang/Analysis/CFGStmtMap.h"
28
#include "clang/Analysis/Support/BumpVector.h"
29
#include "llvm/ADT/SmallPtrSet.h"
30
#include "llvm/Support/ErrorHandling.h"
31
#include "llvm/Support/SaveAndRestore.h"
32
#include "llvm/Support/raw_ostream.h"
33
34
using namespace clang;
35
36
typedef llvm::DenseMap<const void *, ManagedAnalysis *> ManagedAnalysisMap;
37
38
AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
39
                                         const Decl *d,
40
                                         const CFG::BuildOptions &buildOptions)
41
312
  : Manager(Mgr),
42
312
    D(d),
43
312
    cfgBuildOptions(buildOptions),
44
312
    forcedBlkExprs(nullptr),
45
312
    builtCFG(false),
46
312
    builtCompleteCFG(false),
47
312
    ReferencedBlockVars(nullptr),
48
312
    ManagedAnalyses(nullptr)
49
312
{  
50
312
  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
51
312
}
52
53
AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
54
                                         const Decl *d)
55
60.0k
: Manager(Mgr),
56
60.0k
  D(d),
57
60.0k
  forcedBlkExprs(nullptr),
58
60.0k
  builtCFG(false),
59
60.0k
  builtCompleteCFG(false),
60
60.0k
  ReferencedBlockVars(nullptr),
61
60.0k
  ManagedAnalyses(nullptr)
62
60.0k
{  
63
60.0k
  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
64
60.0k
}
65
66
AnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG,
67
                                                       bool addImplicitDtors,
68
                                                       bool addInitializers,
69
                                                       bool addTemporaryDtors,
70
                                                       bool synthesizeBodies,
71
                                                       bool addStaticInitBranch,
72
                                                       bool addCXXNewAllocator,
73
                                                       CodeInjector *injector)
74
312
  : Injector(injector), SynthesizeBodies(synthesizeBodies)
75
312
{
76
312
  cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
77
312
  cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
78
312
  cfgBuildOptions.AddInitializers = addInitializers;
79
312
  cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
80
312
  cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
81
312
  cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
82
312
}
83
84
0
void AnalysisDeclContextManager::clear() {
85
0
  llvm::DeleteContainerSeconds(Contexts);
86
0
}
87
88
0
static BodyFarm &getBodyFarm(ASTContext &C, CodeInjector *injector = nullptr) {
89
0
  static BodyFarm *BF = new BodyFarm(C, injector);
90
0
  return *BF;
91
0
}
92
93
60.2k
Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
94
60.2k
  IsAutosynthesized = false;
95
60.2k
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
96
60.2k
    Stmt *Body = FD->getBody();
97
60.2k
    if (!Body && 
Manager0
&&
Manager->synthesizeBodies()0
) {
98
0
      Body = getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(FD);
99
0
      if (Body)
100
0
        IsAutosynthesized = true;
101
0
    }
102
60.2k
    return Body;
103
60.2k
  }
104
0
  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
105
0
    Stmt *Body = MD->getBody();
106
0
    if (!Body && Manager && Manager->synthesizeBodies()) {
107
0
      Body = getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(MD);
108
0
      if (Body)
109
0
        IsAutosynthesized = true;
110
0
    }
111
0
    return Body;
112
0
  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
113
0
    return BD->getBody();
114
0
  else if (const FunctionTemplateDecl *FunTmpl
115
0
           = dyn_cast_or_null<FunctionTemplateDecl>(D))
116
0
    return FunTmpl->getTemplatedDecl()->getBody();
117
118
60.2k
  
llvm_unreachable0
("unknown code decl");
119
60.2k
}
120
121
60.2k
Stmt *AnalysisDeclContext::getBody() const {
122
60.2k
  bool Tmp;
123
60.2k
  return getBody(Tmp);
124
60.2k
}
125
126
0
bool AnalysisDeclContext::isBodyAutosynthesized() const {
127
0
  bool Tmp;
128
0
  getBody(Tmp);
129
0
  return Tmp;
130
0
}
131
132
0
bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const {
133
0
  bool Tmp;
134
0
  Stmt *Body = getBody(Tmp);
135
0
  return Tmp && Body->getLocStart().isValid();
136
0
}
137
138
139
0
const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
140
0
  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
141
0
    return MD->getSelfDecl();
142
0
  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
143
    // See if 'self' was captured by the block.
144
0
    for (const auto &I : BD->captures()) {
145
0
      const VarDecl *VD = I.getVariable();
146
0
      if (VD->getName() == "self")
147
0
        return dyn_cast<ImplicitParamDecl>(VD);
148
0
    }    
149
0
  }
150
151
0
  return nullptr;
152
0
}
153
154
1.35k
void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
155
1.35k
  if (!forcedBlkExprs)
156
360
    forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
157
  // Default construct an entry for 'stmt'.
158
1.35k
  if (const Expr *e = dyn_cast<Expr>(stmt))
159
1.35k
    stmt = e->IgnoreParens();
160
1.35k
  (void) (*forcedBlkExprs)[stmt];
161
1.35k
}
162
163
const CFGBlock *
164
1.35k
AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {
165
1.35k
  assert(forcedBlkExprs);
166
1.35k
  if (const Expr *e = dyn_cast<Expr>(stmt))
167
1.35k
    stmt = e->IgnoreParens();
168
1.35k
  CFG::BuildOptions::ForcedBlkExprs::const_iterator itr = 
169
1.35k
    forcedBlkExprs->find(stmt);
170
1.35k
  assert(itr != forcedBlkExprs->end());
171
1.35k
  return itr->second;
172
1.35k
}
173
174
/// Add each synthetic statement in the CFG to the parent map, using the
175
/// source statement's parent.
176
0
static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
177
0
  if (!TheCFG)
178
0
    return;
179
180
0
  for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(),
181
0
                                    E = TheCFG->synthetic_stmt_end();
182
0
       I != E; ++I) {
183
0
    PM.setParent(I->first, PM.getParent(I->second));
184
0
  }
185
0
}
186
187
125k
CFG *AnalysisDeclContext::getCFG() {
188
125k
  if (!cfgBuildOptions.PruneTriviallyFalseEdges)
189
0
    return getUnoptimizedCFG();
190
191
125k
  if (!builtCFG) {
192
60.2k
    cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
193
    // Even when the cfg is not successfully built, we don't
194
    // want to try building it again.
195
60.2k
    builtCFG = true;
196
197
60.2k
    if (PM)
198
0
      addParentsForSyntheticStmts(cfg.get(), *PM);
199
200
    // The Observer should only observe one build of the CFG.
201
60.2k
    getCFGBuildOptions().Observer = nullptr;
202
60.2k
  }
203
125k
  return cfg.get();
204
125k
}
205
206
0
CFG *AnalysisDeclContext::getUnoptimizedCFG() {
207
0
  if (!builtCompleteCFG) {
208
0
    SaveAndRestore<bool> NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges,
209
0
                                  false);
210
0
    completeCFG =
211
0
        CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
212
    // Even when the cfg is not successfully built, we don't
213
    // want to try building it again.
214
0
    builtCompleteCFG = true;
215
216
0
    if (PM)
217
0
      addParentsForSyntheticStmts(completeCFG.get(), *PM);
218
219
    // The Observer should only observe one build of the CFG.
220
0
    getCFGBuildOptions().Observer = nullptr;
221
0
  }
222
0
  return completeCFG.get();
223
0
}
224
225
0
CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
226
0
  if (cfgStmtMap)
227
0
    return cfgStmtMap.get();
228
  
229
0
  if (CFG *c = getCFG()) {
230
0
    cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
231
0
    return cfgStmtMap.get();
232
0
  }
233
234
0
  return nullptr;
235
0
}
236
237
1.35k
CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
238
1.35k
  if (CFA)
239
998
    return CFA.get();
240
  
241
360
  if (CFG *c = getCFG()) {
242
360
    CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
243
360
    return CFA.get();
244
360
  }
245
246
0
  return nullptr;
247
360
}
248
249
0
void AnalysisDeclContext::dumpCFG(bool ShowColors) {
250
0
    getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
251
0
}
252
253
0
ParentMap &AnalysisDeclContext::getParentMap() {
254
0
  if (!PM) {
255
0
    PM.reset(new ParentMap(getBody()));
256
0
    if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
257
0
      for (const auto *I : C->inits()) {
258
0
        PM->addStmt(I->getInit());
259
0
      }
260
0
    }
261
0
    if (builtCFG)
262
0
      addParentsForSyntheticStmts(getCFG(), *PM);
263
0
    if (builtCompleteCFG)
264
0
      addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);
265
0
  }
266
0
  return *PM;
267
0
}
268
269
0
PseudoConstantAnalysis *AnalysisDeclContext::getPseudoConstantAnalysis() {
270
0
  if (!PCA)
271
0
    PCA.reset(new PseudoConstantAnalysis(getBody()));
272
0
  return PCA.get();
273
0
}
274
275
312
AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
276
312
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
277
    // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
278
    // that has the body.
279
312
    FD->hasBody(FD);
280
312
    D = FD;
281
312
  }
282
283
312
  AnalysisDeclContext *&AC = Contexts[D];
284
312
  if (!AC)
285
312
    AC = new AnalysisDeclContext(this, D, cfgBuildOptions);
286
312
  return AC;
287
312
}
288
289
const StackFrameContext *
290
AnalysisDeclContext::getStackFrame(LocationContext const *Parent, const Stmt *S,
291
0
                               const CFGBlock *Blk, unsigned Idx) {
292
0
  return getLocationContextManager().getStackFrame(this, Parent, S, Blk, Idx);
293
0
}
294
295
const BlockInvocationContext *
296
AnalysisDeclContext::getBlockInvocationContext(const LocationContext *parent,
297
                                               const clang::BlockDecl *BD,
298
0
                                               const void *ContextData) {
299
0
  return getLocationContextManager().getBlockInvocationContext(this, parent,
300
0
                                                               BD, ContextData);
301
0
}
302
303
0
LocationContextManager & AnalysisDeclContext::getLocationContextManager() {
304
0
  assert(Manager &&
305
0
         "Cannot create LocationContexts without an AnalysisDeclContextManager!");
306
0
  return Manager->getLocationContextManager();  
307
0
}
308
309
//===----------------------------------------------------------------------===//
310
// FoldingSet profiling.
311
//===----------------------------------------------------------------------===//
312
313
void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
314
                                    ContextKind ck,
315
                                    AnalysisDeclContext *ctx,
316
                                    const LocationContext *parent,
317
0
                                    const void *data) {
318
0
  ID.AddInteger(ck);
319
0
  ID.AddPointer(ctx);
320
0
  ID.AddPointer(parent);
321
0
  ID.AddPointer(data);
322
0
}
323
324
0
void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
325
0
  Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block, Index);
326
0
}
327
328
0
void ScopeContext::Profile(llvm::FoldingSetNodeID &ID) {
329
0
  Profile(ID, getAnalysisDeclContext(), getParent(), Enter);
330
0
}
331
332
0
void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
333
0
  Profile(ID, getAnalysisDeclContext(), getParent(), BD, ContextData);
334
0
}
335
336
//===----------------------------------------------------------------------===//
337
// LocationContext creation.
338
//===----------------------------------------------------------------------===//
339
340
template <typename LOC, typename DATA>
341
const LOC*
342
LocationContextManager::getLocationContext(AnalysisDeclContext *ctx,
343
                                           const LocationContext *parent,
344
0
                                           const DATA *d) {
345
0
  llvm::FoldingSetNodeID ID;
346
0
  LOC::Profile(ID, ctx, parent, d);
347
0
  void *InsertPos;
348
349
0
  LOC *L = cast_or_null<LOC>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
350
351
0
  if (!L) {
352
0
    L = new LOC(ctx, parent, d);
353
0
    Contexts.InsertNode(L, InsertPos);
354
0
  }
355
0
  return L;
356
0
}
357
358
const StackFrameContext*
359
LocationContextManager::getStackFrame(AnalysisDeclContext *ctx,
360
                                      const LocationContext *parent,
361
                                      const Stmt *s,
362
0
                                      const CFGBlock *blk, unsigned idx) {
363
0
  llvm::FoldingSetNodeID ID;
364
0
  StackFrameContext::Profile(ID, ctx, parent, s, blk, idx);
365
0
  void *InsertPos;
366
0
  StackFrameContext *L =
367
0
   cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
368
0
  if (!L) {
369
0
    L = new StackFrameContext(ctx, parent, s, blk, idx);
370
0
    Contexts.InsertNode(L, InsertPos);
371
0
  }
372
0
  return L;
373
0
}
374
375
const ScopeContext *
376
LocationContextManager::getScope(AnalysisDeclContext *ctx,
377
                                 const LocationContext *parent,
378
0
                                 const Stmt *s) {
379
0
  return getLocationContext<ScopeContext, Stmt>(ctx, parent, s);
380
0
}
381
382
const BlockInvocationContext *
383
LocationContextManager::getBlockInvocationContext(AnalysisDeclContext *ctx,
384
                                                  const LocationContext *parent,
385
                                                  const BlockDecl *BD,
386
0
                                                  const void *ContextData) {
387
0
  llvm::FoldingSetNodeID ID;
388
0
  BlockInvocationContext::Profile(ID, ctx, parent, BD, ContextData);
389
0
  void *InsertPos;
390
0
  BlockInvocationContext *L =
391
0
    cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
392
0
                                                                    InsertPos));
393
0
  if (!L) {
394
0
    L = new BlockInvocationContext(ctx, parent, BD, ContextData);
395
0
    Contexts.InsertNode(L, InsertPos);
396
0
  }
397
0
  return L;
398
0
}
399
400
//===----------------------------------------------------------------------===//
401
// LocationContext methods.
402
//===----------------------------------------------------------------------===//
403
404
0
const StackFrameContext *LocationContext::getCurrentStackFrame() const {
405
0
  const LocationContext *LC = this;
406
0
  while (LC) {
407
0
    if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC))
408
0
      return SFC;
409
0
    LC = LC->getParent();
410
0
  }
411
0
  return nullptr;
412
0
}
413
414
0
bool LocationContext::inTopFrame() const {
415
0
  return getCurrentStackFrame()->inTopFrame();
416
0
}
417
418
0
bool LocationContext::isParentOf(const LocationContext *LC) const {
419
0
  do {
420
0
    const LocationContext *Parent = LC->getParent();
421
0
    if (Parent == this)
422
0
      return true;
423
0
    else
424
0
      LC = Parent;
425
0
  } while (LC);
426
427
0
  return false;
428
0
}
429
430
0
void LocationContext::dumpStack(raw_ostream &OS, StringRef Indent) const {
431
0
  ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
432
0
  PrintingPolicy PP(Ctx.getLangOpts());
433
0
  PP.TerseOutput = 1;
434
435
0
  unsigned Frame = 0;
436
0
  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
437
0
    switch (LCtx->getKind()) {
438
0
    case StackFrame:
439
0
      OS << Indent << '#' << Frame++ << ' ';
440
0
      cast<StackFrameContext>(LCtx)->getDecl()->print(OS, PP);
441
0
      OS << '\n';
442
0
      break;
443
0
    case Scope:
444
0
      OS << Indent << "    (scope)\n";
445
0
      break;
446
0
    case Block:
447
0
      OS << Indent << "    (block context: "
448
0
                   << cast<BlockInvocationContext>(LCtx)->getContextData()
449
0
                   << ")\n";
450
0
      break;
451
0
    }
452
0
  }
453
0
}
454
455
0
LLVM_DUMP_METHOD void LocationContext::dumpStack() const {
456
0
  dumpStack(llvm::errs());
457
0
}
458
459
//===----------------------------------------------------------------------===//
460
// Lazily generated map to query the external variables referenced by a Block.
461
//===----------------------------------------------------------------------===//
462
463
namespace {
464
class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
465
  BumpVector<const VarDecl*> &BEVals;
466
  BumpVectorContext &BC;
467
  llvm::SmallPtrSet<const VarDecl*, 4> Visited;
468
  llvm::SmallPtrSet<const DeclContext*, 4> IgnoredContexts;
469
public:
470
  FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
471
                            BumpVectorContext &bc)
472
0
  : BEVals(bevals), BC(bc) {}
473
474
0
  void VisitStmt(Stmt *S) {
475
0
    for (Stmt *Child : S->children())
476
0
      if (Child)
477
0
        Visit(Child);
478
0
  }
479
480
0
  void VisitDeclRefExpr(DeclRefExpr *DR) {
481
    // Non-local variables are also directly modified.
482
0
    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
483
0
      if (!VD->hasLocalStorage()) {
484
0
        if (Visited.insert(VD).second)
485
0
          BEVals.push_back(VD, BC);
486
0
      }
487
0
    }
488
0
  }
489
490
0
  void VisitBlockExpr(BlockExpr *BR) {
491
    // Blocks containing blocks can transitively capture more variables.
492
0
    IgnoredContexts.insert(BR->getBlockDecl());
493
0
    Visit(BR->getBlockDecl()->getBody());
494
0
  }
495
  
496
0
  void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
497
0
    for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(), 
498
0
         et = PE->semantics_end(); it != et; ++it) {
499
0
      Expr *Semantic = *it;
500
0
      if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
501
0
        Semantic = OVE->getSourceExpr();
502
0
      Visit(Semantic);
503
0
    }
504
0
  }
505
};
506
} // end anonymous namespace
507
508
typedef BumpVector<const VarDecl*> DeclVec;
509
510
static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,
511
                                              void *&Vec,
512
0
                                              llvm::BumpPtrAllocator &A) {
513
0
  if (Vec)
514
0
    return (DeclVec*) Vec;
515
516
0
  BumpVectorContext BC(A);
517
0
  DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
518
0
  new (BV) DeclVec(BC, 10);
519
520
  // Go through the capture list.
521
0
  for (const auto &CI : BD->captures()) {
522
0
    BV->push_back(CI.getVariable(), BC);
523
0
  }
524
525
  // Find the referenced global/static variables.
526
0
  FindBlockDeclRefExprsVals F(*BV, BC);
527
0
  F.Visit(BD->getBody());
528
529
0
  Vec = BV;
530
0
  return BV;
531
0
}
532
533
llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
534
0
AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {
535
0
  if (!ReferencedBlockVars)
536
0
    ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
537
538
0
  const DeclVec *V =
539
0
      LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
540
0
  return llvm::make_range(V->begin(), V->end());
541
0
}
542
543
25.8k
ManagedAnalysis *&AnalysisDeclContext::getAnalysisImpl(const void *tag) {
544
25.8k
  if (!ManagedAnalyses)
545
25.8k
    ManagedAnalyses = new ManagedAnalysisMap();
546
25.8k
  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
547
25.8k
  return (*M)[tag];
548
25.8k
}
549
550
//===----------------------------------------------------------------------===//
551
// Cleanup.
552
//===----------------------------------------------------------------------===//
553
554
26.1k
ManagedAnalysis::~ManagedAnalysis() {}
555
556
60.3k
AnalysisDeclContext::~AnalysisDeclContext() {
557
60.3k
  delete forcedBlkExprs;
558
60.3k
  delete ReferencedBlockVars;
559
  // Release the managed analyses.
560
60.3k
  if (ManagedAnalyses) {
561
25.8k
    ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
562
25.8k
    llvm::DeleteContainerSeconds(*M);
563
25.8k
    delete M;
564
25.8k
  }
565
60.3k
}
566
567
312
AnalysisDeclContextManager::~AnalysisDeclContextManager() {
568
312
  llvm::DeleteContainerSeconds(Contexts);
569
312
}
570
571
0
LocationContext::~LocationContext() {}
572
573
312
LocationContextManager::~LocationContextManager() {
574
312
  clear();
575
312
}
576
577
312
void LocationContextManager::clear() {
578
312
  for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
579
312
       E = Contexts.end(); I != E; ) {
580
0
    LocationContext *LC = &*I;
581
0
    ++I;
582
0
    delete LC;
583
0
  }
584
585
312
  Contexts.clear();
586
312
}
587