Coverage Report

Created: 2021-08-24 07:12

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