Coverage Report

Created: 2020-02-25 14:32

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