Coverage Report

Created: 2023-05-31 04:38

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Analysis/AnalysisDeclContext.cpp
Line
Count
Source (jump to first uncovered line)
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/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>
50
51
using namespace clang;
52
53
using ManagedAnalysisMap = llvm::DenseMap<const void *, std::unique_ptr<ManagedAnalysis>>;
54
55
AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
56
                                         const Decl *D,
57
                                         const CFG::BuildOptions &Options)
58
64.8k
    : ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {
59
64.8k
  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
60
64.8k
}
61
62
AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
63
                                         const Decl *D)
64
284k
    : ADCMgr(ADCMgr), D(D) {
65
284k
  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
66
284k
}
67
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
1.78k
      SynthesizeBodies(synthesizeBodies) {
77
1.78k
  cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
78
1.78k
  cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
79
1.78k
  cfgBuildOptions.AddInitializers = addInitializers;
80
1.78k
  cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
81
1.78k
  cfgBuildOptions.AddLifetime = addLifetime;
82
1.78k
  cfgBuildOptions.AddLoopExit = addLoopExit;
83
1.78k
  cfgBuildOptions.AddScopes = addScopes;
84
1.78k
  cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
85
1.78k
  cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
86
1.78k
  cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;
87
1.78k
  cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;
88
1.78k
  cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;
89
1.78k
}
90
91
37.3k
void AnalysisDeclContextManager::clear() { Contexts.clear(); }
92
93
7.54M
Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
94
7.54M
  IsAutosynthesized = false;
95
7.54M
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
96
7.43M
    Stmt *Body = FD->getBody();
97
7.43M
    if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
98
69
      Body = CoroBody->getBody();
99
7.43M
    if (ADCMgr && 
ADCMgr->synthesizeBodies()7.25M
) {
100
7.25M
      Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);
101
7.25M
      if (SynthesizedBody) {
102
117k
        Body = SynthesizedBody;
103
117k
        IsAutosynthesized = true;
104
117k
      }
105
7.25M
    }
106
7.43M
    return Body;
107
7.43M
  }
108
113k
  else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
109
105k
    Stmt *Body = MD->getBody();
110
105k
    if (ADCMgr && 
ADCMgr->synthesizeBodies()101k
) {
111
101k
      Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(MD);
112
101k
      if (SynthesizedBody) {
113
21.0k
        Body = SynthesizedBody;
114
21.0k
        IsAutosynthesized = true;
115
21.0k
      }
116
101k
    }
117
105k
    return Body;
118
105k
  } else 
if (const auto *7.18k
BD7.18k
= dyn_cast<BlockDecl>(D))
119
7.18k
    return BD->getBody();
120
0
  else if (const auto *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
121
0
    return FunTmpl->getTemplatedDecl()->getBody();
122
123
0
  llvm_unreachable("unknown code decl");
124
0
}
125
126
327k
Stmt *AnalysisDeclContext::getBody() const {
127
327k
  bool Tmp;
128
327k
  return getBody(Tmp);
129
327k
}
130
131
7.13M
bool AnalysisDeclContext::isBodyAutosynthesized() const {
132
7.13M
  bool Tmp;
133
7.13M
  getBody(Tmp);
134
7.13M
  return Tmp;
135
7.13M
}
136
137
3
bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const {
138
3
  bool Tmp;
139
3
  Stmt *Body = getBody(Tmp);
140
3
  return Tmp && Body->getBeginLoc().isValid();
141
3
}
142
143
/// Returns true if \param VD is an Objective-C implicit 'self' parameter.
144
55
static bool isSelfDecl(const VarDecl *VD) {
145
55
  return isa_and_nonnull<ImplicitParamDecl>(VD) && 
VD->getName() == "self"42
;
146
55
}
147
148
5.99k
const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
149
5.99k
  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
150
5.37k
    return MD->getSelfDecl();
151
618
  if (const auto *BD = dyn_cast<BlockDecl>(D)) {
152
    // See if 'self' was captured by the block.
153
37
    for (const auto &I : BD->captures()) {
154
37
      const VarDecl *VD = I.getVariable();
155
37
      if (isSelfDecl(VD))
156
24
        return dyn_cast<ImplicitParamDecl>(VD);
157
37
    }
158
25
  }
159
160
594
  auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
161
594
  if (!CXXMethod)
162
567
    return nullptr;
163
164
27
  const CXXRecordDecl *parent = CXXMethod->getParent();
165
27
  if (!parent->isLambda())
166
9
    return nullptr;
167
168
18
  for (const auto &LC : parent->captures()) {
169
18
    if (!LC.capturesVariable())
170
0
      continue;
171
172
18
    ValueDecl *VD = LC.getCapturedVar();
173
18
    if (isSelfDecl(dyn_cast<VarDecl>(VD)))
174
18
      return dyn_cast<ImplicitParamDecl>(VD);
175
18
  }
176
177
0
  return nullptr;
178
18
}
179
180
14.7k
void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
181
14.7k
  if (!forcedBlkExprs)
182
9.57k
    forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
183
  // Default construct an entry for 'stmt'.
184
14.7k
  if (const auto *e = dyn_cast<Expr>(stmt))
185
14.7k
    stmt = e->IgnoreParens();
186
14.7k
  (void) (*forcedBlkExprs)[stmt];
187
14.7k
}
188
189
const CFGBlock *
190
14.7k
AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {
191
14.7k
  assert(forcedBlkExprs);
192
14.7k
  if (const auto *e = dyn_cast<Expr>(stmt))
193
14.7k
    stmt = e->IgnoreParens();
194
14.7k
  CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
195
14.7k
    forcedBlkExprs->find(stmt);
196
14.7k
  assert(itr != forcedBlkExprs->end());
197
14.7k
  return itr->second;
198
14.7k
}
199
200
/// Add each synthetic statement in the CFG to the parent map, using the
201
/// source statement's parent.
202
26.5k
static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
203
26.5k
  if (!TheCFG)
204
0
    return;
205
206
26.5k
  for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(),
207
26.5k
                                    E = TheCFG->synthetic_stmt_end();
208
29.3k
       I != E; 
++I2.88k
) {
209
2.88k
    PM.setParent(I->first, PM.getParent(I->second));
210
2.88k
  }
211
26.5k
}
212
213
1.21M
CFG *AnalysisDeclContext::getCFG() {
214
1.21M
  if (!cfgBuildOptions.PruneTriviallyFalseEdges)
215
0
    return getUnoptimizedCFG();
216
217
1.21M
  if (!builtCFG) {
218
237k
    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
237k
    builtCFG = true;
222
223
237k
    if (PM)
224
0
      addParentsForSyntheticStmts(cfg.get(), *PM);
225
226
    // The Observer should only observe one build of the CFG.
227
237k
    getCFGBuildOptions().Observer = nullptr;
228
237k
  }
229
1.21M
  return cfg.get();
230
1.21M
}
231
232
389
CFG *AnalysisDeclContext::getUnoptimizedCFG() {
233
389
  if (!builtCompleteCFG) {
234
383
    SaveAndRestore NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges, false);
235
383
    completeCFG =
236
383
        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
383
    builtCompleteCFG = true;
240
241
383
    if (PM)
242
377
      addParentsForSyntheticStmts(completeCFG.get(), *PM);
243
244
    // The Observer should only observe one build of the CFG.
245
383
    getCFGBuildOptions().Observer = nullptr;
246
383
  }
247
389
  return completeCFG.get();
248
389
}
249
250
184k
CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
251
184k
  if (cfgStmtMap)
252
179k
    return cfgStmtMap.get();
253
254
4.80k
  if (CFG *c = getCFG()) {
255
4.80k
    cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
256
4.80k
    return cfgStmtMap.get();
257
4.80k
  }
258
259
0
  return nullptr;
260
4.80k
}
261
262
14.7k
CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
263
14.7k
  if (CFA)
264
5.19k
    return CFA.get();
265
266
9.57k
  if (CFG *c = getCFG()) {
267
9.57k
    CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
268
9.57k
    return CFA.get();
269
9.57k
  }
270
271
0
  return nullptr;
272
9.57k
}
273
274
0
void AnalysisDeclContext::dumpCFG(bool ShowColors) {
275
0
  getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
276
0
}
277
278
7.89M
ParentMap &AnalysisDeclContext::getParentMap() {
279
7.89M
  if (!PM) {
280
26.2k
    PM.reset(new ParentMap(getBody()));
281
26.2k
    if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
282
4.82k
      for (const auto *I : C->inits()) {
283
4.82k
        PM->addStmt(I->getInit());
284
4.82k
      }
285
3.44k
    }
286
26.2k
    if (builtCFG)
287
26.1k
      addParentsForSyntheticStmts(getCFG(), *PM);
288
26.2k
    if (builtCompleteCFG)
289
6
      addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);
290
26.2k
  }
291
7.89M
  return *PM;
292
7.89M
}
293
294
377k
AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
295
377k
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
296
    // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
297
    // that has the body.
298
362k
    FD->hasBody(FD);
299
362k
    D = FD;
300
362k
  }
301
302
377k
  std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
303
377k
  if (!AC)
304
64.8k
    AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
305
377k
  return AC.get();
306
377k
}
307
308
7.35M
BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; }
309
310
const StackFrameContext *
311
AnalysisDeclContext::getStackFrame(const LocationContext *ParentLC,
312
                                   const Stmt *S, const CFGBlock *Blk,
313
35.0k
                                   unsigned BlockCount, unsigned Index) {
314
35.0k
  return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,
315
35.0k
                                                   BlockCount, Index);
316
35.0k
}
317
318
const BlockInvocationContext *AnalysisDeclContext::getBlockInvocationContext(
319
181
    const LocationContext *ParentLC, const BlockDecl *BD, const void *Data) {
320
181
  return getLocationContextManager().getBlockInvocationContext(this, ParentLC,
321
181
                                                               BD, Data);
322
181
}
323
324
20.3k
bool AnalysisDeclContext::isInStdNamespace(const Decl *D) {
325
20.3k
  const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
326
20.3k
  const auto *ND = dyn_cast<NamespaceDecl>(DC);
327
20.3k
  if (!ND)
328
18.3k
    return false;
329
330
2.06k
  
while (const DeclContext *1.98k
Parent = ND->getParent()) {
331
2.06k
    if (!isa<NamespaceDecl>(Parent))
332
1.98k
      break;
333
78
    ND = cast<NamespaceDecl>(Parent);
334
78
  }
335
336
1.98k
  return ND->isStdNamespace();
337
20.3k
}
338
339
184
std::string AnalysisDeclContext::getFunctionName(const Decl *D) {
340
184
  std::string Str;
341
184
  llvm::raw_string_ostream OS(Str);
342
184
  const ASTContext &Ctx = D->getASTContext();
343
344
184
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
345
90
    OS << FD->getQualifiedNameAsString();
346
347
    // In C++, there are overloads.
348
349
90
    if (Ctx.getLangOpts().CPlusPlus) {
350
72
      OS << '(';
351
72
      for (const auto &P : FD->parameters()) {
352
55
        if (P != *FD->param_begin())
353
12
          OS << ", ";
354
55
        OS << P->getType();
355
55
      }
356
72
      OS << ')';
357
72
    }
358
359
94
  } else if (isa<BlockDecl>(D)) {
360
2
    PresumedLoc Loc = Ctx.getSourceManager().getPresumedLoc(D->getLocation());
361
362
2
    if (Loc.isValid()) {
363
2
      OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
364
2
         << ')';
365
2
    }
366
367
92
  } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
368
369
    // FIXME: copy-pasted from CGDebugInfo.cpp.
370
29
    OS << (OMD->isInstanceMethod() ? 
'-'25
:
'+'4
) << '[';
371
29
    const DeclContext *DC = OMD->getDeclContext();
372
29
    if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
373
13
      OS << OID->getName();
374
16
    } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
375
12
      OS << OID->getName();
376
12
    } else 
if (const auto *4
OC4
= dyn_cast<ObjCCategoryDecl>(DC)) {
377
0
      if (OC->IsClassExtension()) {
378
0
        OS << OC->getClassInterface()->getName();
379
0
      } else {
380
0
        OS << OC->getIdentifier()->getNameStart() << '('
381
0
           << OC->getIdentifier()->getNameStart() << ')';
382
0
      }
383
4
    } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
384
0
      OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')';
385
0
    }
386
29
    OS << ' ' << OMD->getSelector().getAsString() << ']';
387
29
  }
388
389
184
  return Str;
390
184
}
391
392
35.2k
LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
393
35.2k
  assert(
394
35.2k
      ADCMgr &&
395
35.2k
      "Cannot create LocationContexts without an AnalysisDeclContextManager!");
396
35.2k
  return ADCMgr->getLocationContextManager();
397
35.2k
}
398
399
//===----------------------------------------------------------------------===//
400
// FoldingSet profiling.
401
//===----------------------------------------------------------------------===//
402
403
void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
404
                                    ContextKind ck,
405
                                    AnalysisDeclContext *ctx,
406
                                    const LocationContext *parent,
407
199k
                                    const void *data) {
408
199k
  ID.AddInteger(ck);
409
199k
  ID.AddPointer(ctx);
410
199k
  ID.AddPointer(parent);
411
199k
  ID.AddPointer(data);
412
199k
}
413
414
113k
void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
415
113k
  Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,
416
113k
          BlockCount, Index);
417
113k
}
418
419
131
void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
420
131
  Profile(ID, getAnalysisDeclContext(), getParent(), BD, Data);
421
131
}
422
423
//===----------------------------------------------------------------------===//
424
// LocationContext creation.
425
//===----------------------------------------------------------------------===//
426
427
const StackFrameContext *LocationContextManager::getStackFrame(
428
    AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,
429
85.6k
    const CFGBlock *blk, unsigned blockCount, unsigned idx) {
430
85.6k
  llvm::FoldingSetNodeID ID;
431
85.6k
  StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);
432
85.6k
  void *InsertPos;
433
85.6k
  auto *L =
434
85.6k
   cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
435
85.6k
  if (!L) {
436
28.6k
    L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);
437
28.6k
    Contexts.InsertNode(L, InsertPos);
438
28.6k
  }
439
85.6k
  return L;
440
85.6k
}
441
442
const BlockInvocationContext *LocationContextManager::getBlockInvocationContext(
443
    AnalysisDeclContext *ADC, const LocationContext *ParentLC,
444
181
    const BlockDecl *BD, const void *Data) {
445
181
  llvm::FoldingSetNodeID ID;
446
181
  BlockInvocationContext::Profile(ID, ADC, ParentLC, BD, Data);
447
181
  void *InsertPos;
448
181
  auto *L =
449
181
    cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
450
181
                                                                    InsertPos));
451
181
  if (!L) {
452
164
    L = new BlockInvocationContext(ADC, ParentLC, BD, Data, ++NewID);
453
164
    Contexts.InsertNode(L, InsertPos);
454
164
  }
455
181
  return L;
456
181
}
457
458
//===----------------------------------------------------------------------===//
459
// LocationContext methods.
460
//===----------------------------------------------------------------------===//
461
462
9.47M
const StackFrameContext *LocationContext::getStackFrame() const {
463
9.47M
  const LocationContext *LC = this;
464
9.47M
  while (LC) {
465
9.47M
    if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
466
9.47M
      return SFC;
467
748
    LC = LC->getParent();
468
748
  }
469
0
  return nullptr;
470
9.47M
}
471
472
0
bool LocationContext::inTopFrame() const {
473
0
  return getStackFrame()->inTopFrame();
474
0
}
475
476
1.20M
bool LocationContext::isParentOf(const LocationContext *LC) const {
477
2.12M
  do {
478
2.12M
    const LocationContext *Parent = LC->getParent();
479
2.12M
    if (Parent == this)
480
484k
      return true;
481
1.64M
    else
482
1.64M
      LC = Parent;
483
2.12M
  } while (
LC1.64M
);
484
485
719k
  return false;
486
1.20M
}
487
488
static void printLocation(raw_ostream &Out, const SourceManager &SM,
489
0
                          SourceLocation Loc) {
490
0
  if (Loc.isFileID() && SM.isInMainFile(Loc))
491
0
    Out << SM.getExpansionLineNumber(Loc);
492
0
  else
493
0
    Loc.print(Out, SM);
494
0
}
495
496
0
void LocationContext::dumpStack(raw_ostream &Out) const {
497
0
  ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
498
0
  PrintingPolicy PP(Ctx.getLangOpts());
499
0
  PP.TerseOutput = 1;
500
501
0
  const SourceManager &SM =
502
0
      getAnalysisDeclContext()->getASTContext().getSourceManager();
503
504
0
  unsigned Frame = 0;
505
0
  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
506
0
    switch (LCtx->getKind()) {
507
0
    case StackFrame:
508
0
      Out << "\t#" << Frame << ' ';
509
0
      ++Frame;
510
0
      if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
511
0
        Out << "Calling " << AnalysisDeclContext::getFunctionName(D);
512
0
      else
513
0
        Out << "Calling anonymous code";
514
0
      if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
515
0
        Out << " at line ";
516
0
        printLocation(Out, SM, S->getBeginLoc());
517
0
      }
518
0
      break;
519
0
    case Block:
520
0
      Out << "Invoking block";
521
0
      if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
522
0
        Out << " defined at line ";
523
0
        printLocation(Out, SM, D->getBeginLoc());
524
0
      }
525
0
      break;
526
0
    }
527
0
    Out << '\n';
528
0
  }
529
0
}
530
531
void LocationContext::printJson(raw_ostream &Out, const char *NL,
532
                                unsigned int Space, bool IsDot,
533
                                std::function<void(const LocationContext *)>
534
151
                                    printMoreInfoPerContext) const {
535
151
  ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
536
151
  PrintingPolicy PP(Ctx.getLangOpts());
537
151
  PP.TerseOutput = 1;
538
539
151
  const SourceManager &SM =
540
151
      getAnalysisDeclContext()->getASTContext().getSourceManager();
541
542
151
  unsigned Frame = 0;
543
322
  for (const LocationContext *LCtx = this; LCtx; 
LCtx = LCtx->getParent()171
) {
544
171
    Indent(Out, Space, IsDot)
545
171
        << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
546
171
    switch (LCtx->getKind()) {
547
171
    case StackFrame:
548
171
      Out << '#' << Frame << " Call\", \"calling\": \"";
549
171
      ++Frame;
550
171
      if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
551
171
        Out << D->getQualifiedNameAsString();
552
0
      else
553
0
        Out << "anonymous code";
554
555
171
      Out << "\", \"location\": ";
556
171
      if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
557
19
        printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
558
152
      } else {
559
152
        Out << "null";
560
152
      }
561
562
171
      Out << ", \"items\": ";
563
171
      break;
564
0
    case Block:
565
0
      Out << "Invoking block\" ";
566
0
      if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
567
0
        Out << ", \"location\": ";
568
0
        printSourceLocationAsJson(Out, D->getBeginLoc(), SM);
569
0
        Out << ' ';
570
0
      }
571
0
      break;
572
171
    }
573
574
171
    printMoreInfoPerContext(LCtx);
575
576
171
    Out << '}';
577
171
    if (LCtx->getParent())
578
20
      Out << ',';
579
171
    Out << NL;
580
171
  }
581
151
}
582
583
0
LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); }
584
585
//===----------------------------------------------------------------------===//
586
// Lazily generated map to query the external variables referenced by a Block.
587
//===----------------------------------------------------------------------===//
588
589
namespace {
590
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;
596
597
public:
598
  FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
599
                            BumpVectorContext &bc)
600
418
      : BEVals(bevals), BC(bc) {}
601
602
1.94k
  void VisitStmt(Stmt *S) {
603
1.94k
    for (auto *Child : S->children())
604
2.09k
      if (Child)
605
2.09k
        Visit(Child);
606
1.94k
  }
607
608
573
  void VisitDeclRefExpr(DeclRefExpr *DR) {
609
    // Non-local variables are also directly modified.
610
573
    if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
611
433
      if (!VD->hasLocalStorage()) {
612
42
        if (Visited.insert(VD).second)
613
42
          BEVals.push_back(VD, BC);
614
42
      }
615
433
    }
616
573
  }
617
618
20
  void VisitBlockExpr(BlockExpr *BR) {
619
    // Blocks containing blocks can transitively capture more variables.
620
20
    IgnoredContexts.insert(BR->getBlockDecl());
621
20
    Visit(BR->getBlockDecl()->getBody());
622
20
  }
623
624
2
  void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
625
2
    for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(),
626
6
         et = PE->semantics_end(); it != et; 
++it4
) {
627
4
      Expr *Semantic = *it;
628
4
      if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
629
2
        Semantic = OVE->getSourceExpr();
630
4
      Visit(Semantic);
631
4
    }
632
2
  }
633
};
634
635
} // namespace
636
637
using DeclVec = BumpVector<const VarDecl *>;
638
639
static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,
640
                                              void *&Vec,
641
827
                                              llvm::BumpPtrAllocator &A) {
642
827
  if (Vec)
643
409
    return (DeclVec*) Vec;
644
645
418
  BumpVectorContext BC(A);
646
418
  DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
647
418
  new (BV) DeclVec(BC, 10);
648
649
  // Go through the capture list.
650
418
  for (const auto &CI : BD->captures()) {
651
297
    BV->push_back(CI.getVariable(), BC);
652
297
  }
653
654
  // Find the referenced global/static variables.
655
418
  FindBlockDeclRefExprsVals F(*BV, BC);
656
418
  F.Visit(BD->getBody());
657
658
418
  Vec = BV;
659
418
  return BV;
660
827
}
661
662
llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
663
827
AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {
664
827
  if (!ReferencedBlockVars)
665
369
    ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
666
667
827
  const DeclVec *V =
668
827
      LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
669
827
  return llvm::make_range(V->begin(), V->end());
670
827
}
671
672
2.32M
std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
673
2.32M
  if (!ManagedAnalyses)
674
31.8k
    ManagedAnalyses = new ManagedAnalysisMap();
675
2.32M
  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
676
2.32M
  return (*M)[tag];
677
2.32M
}
678
679
//===----------------------------------------------------------------------===//
680
// Cleanup.
681
//===----------------------------------------------------------------------===//
682
683
71.1k
ManagedAnalysis::~ManagedAnalysis() = default;
684
685
349k
AnalysisDeclContext::~AnalysisDeclContext() {
686
349k
  delete forcedBlkExprs;
687
349k
  delete ReferencedBlockVars;
688
349k
  delete (ManagedAnalysisMap*) ManagedAnalyses;
689
349k
}
690
691
28.8k
LocationContext::~LocationContext() = default;
692
693
1.78k
LocationContextManager::~LocationContextManager() {
694
1.78k
  clear();
695
1.78k
}
696
697
1.78k
void LocationContextManager::clear() {
698
1.78k
  for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
699
30.5k
       E = Contexts.end(); I != E; ) {
700
28.8k
    LocationContext *LC = &*I;
701
28.8k
    ++I;
702
28.8k
    delete LC;
703
28.8k
  }
704
1.78k
  Contexts.clear();
705
1.78k
}