Coverage Report

Created: 2022-01-22 13:19

/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
60.1k
    : ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {
59
60.1k
  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
60
60.1k
}
61
62
AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
63
                                         const Decl *D)
64
260k
    : ADCMgr(ADCMgr), D(D) {
65
260k
  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
66
260k
}
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.65k
      SynthesizeBodies(synthesizeBodies) {
77
1.65k
  cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
78
1.65k
  cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
79
1.65k
  cfgBuildOptions.AddInitializers = addInitializers;
80
1.65k
  cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
81
1.65k
  cfgBuildOptions.AddLifetime = addLifetime;
82
1.65k
  cfgBuildOptions.AddLoopExit = addLoopExit;
83
1.65k
  cfgBuildOptions.AddScopes = addScopes;
84
1.65k
  cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
85
1.65k
  cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
86
1.65k
  cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;
87
1.65k
  cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;
88
1.65k
  cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;
89
1.65k
}
90
91
34.7k
void AnalysisDeclContextManager::clear() { Contexts.clear(); }
92
93
6.93M
Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
94
6.93M
  IsAutosynthesized = false;
95
6.93M
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
96
6.82M
    Stmt *Body = FD->getBody();
97
6.82M
    if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
98
54
      Body = CoroBody->getBody();
99
6.82M
    if (ADCMgr && 
ADCMgr->synthesizeBodies()6.65M
) {
100
6.65M
      Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);
101
6.65M
      if (SynthesizedBody) {
102
12.5k
        Body = SynthesizedBody;
103
12.5k
        IsAutosynthesized = true;
104
12.5k
      }
105
6.65M
    }
106
6.82M
    return Body;
107
6.82M
  }
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
21.0k
        Body = SynthesizedBody;
114
21.0k
        IsAutosynthesized = true;
115
21.0k
      }
116
100k
    }
117
105k
    return Body;
118
105k
  } else 
if (const auto *6.97k
BD6.97k
= dyn_cast<BlockDecl>(D))
119
6.97k
    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
303k
Stmt *AnalysisDeclContext::getBody() const {
127
303k
  bool Tmp;
128
303k
  return getBody(Tmp);
129
303k
}
130
131
6.56M
bool AnalysisDeclContext::isBodyAutosynthesized() const {
132
6.56M
  bool Tmp;
133
6.56M
  getBody(Tmp);
134
6.56M
  return Tmp;
135
6.56M
}
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.91k
const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
149
5.91k
  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
150
5.37k
    return MD->getSelfDecl();
151
546
  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
522
  auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
161
522
  if (!CXXMethod)
162
495
    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
15.5k
void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
181
15.5k
  if (!forcedBlkExprs)
182
10.6k
    forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
183
  // Default construct an entry for 'stmt'.
184
15.5k
  if (const auto *e = dyn_cast<Expr>(stmt))
185
15.5k
    stmt = e->IgnoreParens();
186
15.5k
  (void) (*forcedBlkExprs)[stmt];
187
15.5k
}
188
189
const CFGBlock *
190
15.5k
AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {
191
15.5k
  assert(forcedBlkExprs);
192
15.5k
  if (const auto *e = dyn_cast<Expr>(stmt))
193
15.5k
    stmt = e->IgnoreParens();
194
15.5k
  CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
195
15.5k
    forcedBlkExprs->find(stmt);
196
15.5k
  assert(itr != forcedBlkExprs->end());
197
0
  return itr->second;
198
15.5k
}
199
200
/// Add each synthetic statement in the CFG to the parent map, using the
201
/// source statement's parent.
202
24.7k
static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
203
24.7k
  if (!TheCFG)
204
0
    return;
205
206
24.7k
  for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(),
207
24.7k
                                    E = TheCFG->synthetic_stmt_end();
208
27.3k
       I != E; 
++I2.62k
) {
209
2.62k
    PM.setParent(I->first, PM.getParent(I->second));
210
2.62k
  }
211
24.7k
}
212
213
1.15M
CFG *AnalysisDeclContext::getCFG() {
214
1.15M
  if (!cfgBuildOptions.PruneTriviallyFalseEdges)
215
0
    return getUnoptimizedCFG();
216
217
1.15M
  if (!builtCFG) {
218
216k
    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
216k
    builtCFG = true;
222
223
216k
    if (PM)
224
0
      addParentsForSyntheticStmts(cfg.get(), *PM);
225
226
    // The Observer should only observe one build of the CFG.
227
216k
    getCFGBuildOptions().Observer = nullptr;
228
216k
  }
229
1.15M
  return cfg.get();
230
1.15M
}
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
174k
CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
252
174k
  if (cfgStmtMap)
253
170k
    return cfgStmtMap.get();
254
255
4.03k
  if (CFG *c = getCFG()) {
256
4.03k
    cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
257
4.03k
    return cfgStmtMap.get();
258
4.03k
  }
259
260
0
  return nullptr;
261
4.03k
}
262
263
15.5k
CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
264
15.5k
  if (CFA)
265
4.88k
    return CFA.get();
266
267
10.6k
  if (CFG *c = getCFG()) {
268
10.6k
    CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
269
10.6k
    return CFA.get();
270
10.6k
  }
271
272
0
  return nullptr;
273
10.6k
}
274
275
0
void AnalysisDeclContext::dumpCFG(bool ShowColors) {
276
0
  getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
277
0
}
278
279
6.97M
ParentMap &AnalysisDeclContext::getParentMap() {
280
6.97M
  if (!PM) {
281
24.4k
    PM.reset(new ParentMap(getBody()));
282
24.4k
    if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
283
4.68k
      for (const auto *I : C->inits()) {
284
4.68k
        PM->addStmt(I->getInit());
285
4.68k
      }
286
3.34k
    }
287
24.4k
    if (builtCFG)
288
24.3k
      addParentsForSyntheticStmts(getCFG(), *PM);
289
24.4k
    if (builtCompleteCFG)
290
6
      addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);
291
24.4k
  }
292
6.97M
  return *PM;
293
6.97M
}
294
295
363k
AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
296
363k
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
297
    // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
298
    // that has the body.
299
349k
    FD->hasBody(FD);
300
349k
    D = FD;
301
349k
  }
302
303
363k
  std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
304
363k
  if (!AC)
305
60.1k
    AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
306
363k
  return AC.get();
307
363k
}
308
309
6.75M
BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; }
310
311
const StackFrameContext *
312
AnalysisDeclContext::getStackFrame(const LocationContext *ParentLC,
313
                                   const Stmt *S, const CFGBlock *Blk,
314
35.0k
                                   unsigned BlockCount, unsigned Index) {
315
35.0k
  return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,
316
35.0k
                                                   BlockCount, Index);
317
35.0k
}
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
18.1k
bool AnalysisDeclContext::isInStdNamespace(const Decl *D) {
326
18.1k
  const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
327
18.1k
  const auto *ND = dyn_cast<NamespaceDecl>(DC);
328
18.1k
  if (!ND)
329
16.1k
    return false;
330
331
1.99k
  
while (const DeclContext *1.91k
Parent = ND->getParent()) {
332
1.99k
    if (!isa<NamespaceDecl>(Parent))
333
1.91k
      break;
334
78
    ND = cast<NamespaceDecl>(Parent);
335
78
  }
336
337
1.91k
  return ND->isStdNamespace();
338
18.1k
}
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 Str;
391
104
}
392
393
35.1k
LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
394
35.1k
  assert(
395
35.1k
      ADCMgr &&
396
35.1k
      "Cannot create LocationContexts without an AnalysisDeclContextManager!");
397
0
  return ADCMgr->getLocationContextManager();
398
35.1k
}
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
194k
                                    const void *data) {
409
194k
  ID.AddInteger(ck);
410
194k
  ID.AddPointer(ctx);
411
194k
  ID.AddPointer(parent);
412
194k
  ID.AddPointer(data);
413
194k
}
414
415
110k
void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
416
110k
  Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,
417
110k
          BlockCount, Index);
418
110k
}
419
420
100
void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
421
100
  Profile(ID, getAnalysisDeclContext(), getParent(), BD, Data);
422
100
}
423
424
//===----------------------------------------------------------------------===//
425
// LocationContext creation.
426
//===----------------------------------------------------------------------===//
427
428
const StackFrameContext *LocationContextManager::getStackFrame(
429
    AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,
430
83.1k
    const CFGBlock *blk, unsigned blockCount, unsigned idx) {
431
83.1k
  llvm::FoldingSetNodeID ID;
432
83.1k
  StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);
433
83.1k
  void *InsertPos;
434
83.1k
  auto *L =
435
83.1k
   cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
436
83.1k
  if (!L) {
437
26.5k
    L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);
438
26.5k
    Contexts.InsertNode(L, InsertPos);
439
26.5k
  }
440
83.1k
  return L;
441
83.1k
}
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.78M
const StackFrameContext *LocationContext::getStackFrame() const {
464
7.78M
  const LocationContext *LC = this;
465
7.78M
  while (LC) {
466
7.78M
    if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
467
7.78M
      return SFC;
468
705
    LC = LC->getParent();
469
705
  }
470
0
  return nullptr;
471
7.78M
}
472
473
0
bool LocationContext::inTopFrame() const {
474
0
  return getStackFrame()->inTopFrame();
475
0
}
476
477
1.23M
bool LocationContext::isParentOf(const LocationContext *LC) const {
478
2.19M
  do {
479
2.19M
    const LocationContext *Parent = LC->getParent();
480
2.19M
    if (Parent == this)
481
491k
      return true;
482
1.70M
    else
483
1.70M
      LC = Parent;
484
2.19M
  } while (
LC1.70M
);
485
486
738k
  return false;
487
1.23M
}
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
135
                                    printMoreInfoPerContext) const {
536
135
  ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
537
135
  PrintingPolicy PP(Ctx.getLangOpts());
538
135
  PP.TerseOutput = 1;
539
540
135
  const SourceManager &SM =
541
135
      getAnalysisDeclContext()->getASTContext().getSourceManager();
542
543
135
  unsigned Frame = 0;
544
290
  for (const LocationContext *LCtx = this; LCtx; 
LCtx = LCtx->getParent()155
) {
545
155
    Indent(Out, Space, IsDot)
546
155
        << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
547
155
    switch (LCtx->getKind()) {
548
155
    case StackFrame:
549
155
      Out << '#' << Frame << " Call\", \"calling\": \"";
550
155
      ++Frame;
551
155
      if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
552
155
        Out << D->getQualifiedNameAsString();
553
0
      else
554
0
        Out << "anonymous code";
555
556
155
      Out << "\", \"location\": ";
557
155
      if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
558
19
        printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
559
136
      } else {
560
136
        Out << "null";
561
136
      }
562
563
155
      Out << ", \"items\": ";
564
155
      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
155
    }
574
575
155
    printMoreInfoPerContext(LCtx);
576
577
155
    Out << '}';
578
155
    if (LCtx->getParent())
579
20
      Out << ',';
580
155
    Out << NL;
581
155
  }
582
135
}
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
404
      : BEVals(bevals), BC(bc) {}
602
603
1.88k
  void VisitStmt(Stmt *S) {
604
1.88k
    for (auto *Child : S->children())
605
2.03k
      if (Child)
606
2.03k
        Visit(Child);
607
1.88k
  }
608
609
553
  void VisitDeclRefExpr(DeclRefExpr *DR) {
610
    // Non-local variables are also directly modified.
611
553
    if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
612
421
      if (!VD->hasLocalStorage()) {
613
42
        if (Visited.insert(VD).second)
614
42
          BEVals.push_back(VD, BC);
615
42
      }
616
421
    }
617
553
  }
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
799
                                              llvm::BumpPtrAllocator &A) {
643
799
  if (Vec)
644
395
    return (DeclVec*) Vec;
645
646
404
  BumpVectorContext BC(A);
647
404
  DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
648
404
  new (BV) DeclVec(BC, 10);
649
650
  // Go through the capture list.
651
404
  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
404
  FindBlockDeclRefExprsVals F(*BV, BC);
657
404
  F.Visit(BD->getBody());
658
659
404
  Vec = BV;
660
404
  return BV;
661
799
}
662
663
llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
664
799
AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {
665
799
  if (!ReferencedBlockVars)
666
356
    ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
667
668
799
  const DeclVec *V =
669
799
      LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
670
799
  return llvm::make_range(V->begin(), V->end());
671
799
}
672
673
1.65M
std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
674
1.65M
  if (!ManagedAnalyses)
675
29.8k
    ManagedAnalyses = new ManagedAnalysisMap();
676
1.65M
  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
677
1.65M
  return (*M)[tag];
678
1.65M
}
679
680
//===----------------------------------------------------------------------===//
681
// Cleanup.
682
//===----------------------------------------------------------------------===//
683
684
66.2k
ManagedAnalysis::~ManagedAnalysis() = default;
685
686
320k
AnalysisDeclContext::~AnalysisDeclContext() {
687
320k
  delete forcedBlkExprs;
688
320k
  delete ReferencedBlockVars;
689
320k
  delete (ManagedAnalysisMap*) ManagedAnalyses;
690
320k
}
691
692
26.7k
LocationContext::~LocationContext() = default;
693
694
1.65k
LocationContextManager::~LocationContextManager() {
695
1.65k
  clear();
696
1.65k
}
697
698
1.65k
void LocationContextManager::clear() {
699
1.65k
  for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
700
28.4k
       E = Contexts.end(); I != E; ) {
701
26.7k
    LocationContext *LC = &*I;
702
26.7k
    ++I;
703
26.7k
    delete LC;
704
26.7k
  }
705
1.65k
  Contexts.clear();
706
1.65k
}