Coverage Report

Created: 2019-07-24 05:18

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