Coverage Report

Created: 2022-07-16 07:03

/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
63.2k
    : ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {
59
63.2k
  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
60
63.2k
}
61
62
AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
63
                                         const Decl *D)
64
275k
    : ADCMgr(ADCMgr), D(D) {
65
275k
  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
66
275k
}
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.74k
      SynthesizeBodies(synthesizeBodies) {
77
1.74k
  cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
78
1.74k
  cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
79
1.74k
  cfgBuildOptions.AddInitializers = addInitializers;
80
1.74k
  cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
81
1.74k
  cfgBuildOptions.AddLifetime = addLifetime;
82
1.74k
  cfgBuildOptions.AddLoopExit = addLoopExit;
83
1.74k
  cfgBuildOptions.AddScopes = addScopes;
84
1.74k
  cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
85
1.74k
  cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
86
1.74k
  cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;
87
1.74k
  cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;
88
1.74k
  cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;
89
1.74k
}
90
91
36.4k
void AnalysisDeclContextManager::clear() { Contexts.clear(); }
92
93
7.26M
Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
94
7.26M
  IsAutosynthesized = false;
95
7.26M
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
96
7.15M
    Stmt *Body = FD->getBody();
97
7.15M
    if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
98
55
      Body = CoroBody->getBody();
99
7.15M
    if (ADCMgr && 
ADCMgr->synthesizeBodies()6.97M
) {
100
6.97M
      Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);
101
6.97M
      if (SynthesizedBody) {
102
109k
        Body = SynthesizedBody;
103
109k
        IsAutosynthesized = true;
104
109k
      }
105
6.97M
    }
106
7.15M
    return Body;
107
7.15M
  }
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 *7.01k
BD7.01k
= dyn_cast<BlockDecl>(D))
119
7.01k
    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
318k
Stmt *AnalysisDeclContext::getBody() const {
127
318k
  bool Tmp;
128
318k
  return getBody(Tmp);
129
318k
}
130
131
6.87M
bool AnalysisDeclContext::isBodyAutosynthesized() const {
132
6.87M
  bool Tmp;
133
6.87M
  getBody(Tmp);
134
6.87M
  return Tmp;
135
6.87M
}
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
16.1k
void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
181
16.1k
  if (!forcedBlkExprs)
182
11.1k
    forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
183
  // Default construct an entry for 'stmt'.
184
16.1k
  if (const auto *e = dyn_cast<Expr>(stmt))
185
16.1k
    stmt = e->IgnoreParens();
186
16.1k
  (void) (*forcedBlkExprs)[stmt];
187
16.1k
}
188
189
const CFGBlock *
190
16.1k
AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {
191
16.1k
  assert(forcedBlkExprs);
192
16.1k
  if (const auto *e = dyn_cast<Expr>(stmt))
193
16.1k
    stmt = e->IgnoreParens();
194
16.1k
  CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
195
16.1k
    forcedBlkExprs->find(stmt);
196
16.1k
  assert(itr != forcedBlkExprs->end());
197
0
  return itr->second;
198
16.1k
}
199
200
/// Add each synthetic statement in the CFG to the parent map, using the
201
/// source statement's parent.
202
25.7k
static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
203
25.7k
  if (!TheCFG)
204
0
    return;
205
206
25.7k
  for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(),
207
25.7k
                                    E = TheCFG->synthetic_stmt_end();
208
28.5k
       I != E; 
++I2.76k
) {
209
2.76k
    PM.setParent(I->first, PM.getParent(I->second));
210
2.76k
  }
211
25.7k
}
212
213
1.18M
CFG *AnalysisDeclContext::getCFG() {
214
1.18M
  if (!cfgBuildOptions.PruneTriviallyFalseEdges)
215
0
    return getUnoptimizedCFG();
216
217
1.18M
  if (!builtCFG) {
218
229k
    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
229k
    builtCFG = true;
222
223
229k
    if (PM)
224
0
      addParentsForSyntheticStmts(cfg.get(), *PM);
225
226
    // The Observer should only observe one build of the CFG.
227
229k
    getCFGBuildOptions().Observer = nullptr;
228
229k
  }
229
1.18M
  return cfg.get();
230
1.18M
}
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
175k
CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
252
175k
  if (cfgStmtMap)
253
171k
    return cfgStmtMap.get();
254
255
4.19k
  if (CFG *c = getCFG()) {
256
4.19k
    cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
257
4.19k
    return cfgStmtMap.get();
258
4.19k
  }
259
260
0
  return nullptr;
261
4.19k
}
262
263
16.1k
CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
264
16.1k
  if (CFA)
265
4.97k
    return CFA.get();
266
267
11.1k
  if (CFG *c = getCFG()) {
268
11.1k
    CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
269
11.1k
    return CFA.get();
270
11.1k
  }
271
272
0
  return nullptr;
273
11.1k
}
274
275
0
void AnalysisDeclContext::dumpCFG(bool ShowColors) {
276
0
  getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
277
0
}
278
279
7.58M
ParentMap &AnalysisDeclContext::getParentMap() {
280
7.58M
  if (!PM) {
281
25.4k
    PM.reset(new ParentMap(getBody()));
282
25.4k
    if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
283
4.72k
      for (const auto *I : C->inits()) {
284
4.72k
        PM->addStmt(I->getInit());
285
4.72k
      }
286
3.37k
    }
287
25.4k
    if (builtCFG)
288
25.3k
      addParentsForSyntheticStmts(getCFG(), *PM);
289
25.4k
    if (builtCompleteCFG)
290
6
      addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);
291
25.4k
  }
292
7.58M
  return *PM;
293
7.58M
}
294
295
352k
AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
296
352k
  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
297
    // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
298
    // that has the body.
299
337k
    FD->hasBody(FD);
300
337k
    D = FD;
301
337k
  }
302
303
352k
  std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
304
352k
  if (!AC)
305
63.2k
    AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
306
352k
  return AC.get();
307
352k
}
308
309
7.07M
BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; }
310
311
const StackFrameContext *
312
AnalysisDeclContext::getStackFrame(const LocationContext *ParentLC,
313
                                   const Stmt *S, const CFGBlock *Blk,
314
35.3k
                                   unsigned BlockCount, unsigned Index) {
315
35.3k
  return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,
316
35.3k
                                                   BlockCount, Index);
317
35.3k
}
318
319
const BlockInvocationContext *AnalysisDeclContext::getBlockInvocationContext(
320
172
    const LocationContext *ParentLC, const BlockDecl *BD, const void *Data) {
321
172
  return getLocationContextManager().getBlockInvocationContext(this, ParentLC,
322
172
                                                               BD, Data);
323
172
}
324
325
19.3k
bool AnalysisDeclContext::isInStdNamespace(const Decl *D) {
326
19.3k
  const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
327
19.3k
  const auto *ND = dyn_cast<NamespaceDecl>(DC);
328
19.3k
  if (!ND)
329
17.3k
    return false;
330
331
2.01k
  
while (const DeclContext *1.94k
Parent = ND->getParent()) {
332
2.01k
    if (!isa<NamespaceDecl>(Parent))
333
1.94k
      break;
334
78
    ND = cast<NamespaceDecl>(Parent);
335
78
  }
336
337
1.94k
  return ND->isStdNamespace();
338
19.3k
}
339
340
184
std::string AnalysisDeclContext::getFunctionName(const Decl *D) {
341
184
  std::string Str;
342
184
  llvm::raw_string_ostream OS(Str);
343
184
  const ASTContext &Ctx = D->getASTContext();
344
345
184
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
346
90
    OS << FD->getQualifiedNameAsString();
347
348
    // In C++, there are overloads.
349
350
90
    if (Ctx.getLangOpts().CPlusPlus) {
351
72
      OS << '(';
352
72
      for (const auto &P : FD->parameters()) {
353
55
        if (P != *FD->param_begin())
354
12
          OS << ", ";
355
55
        OS << P->getType();
356
55
      }
357
72
      OS << ')';
358
72
    }
359
360
94
  } 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
92
  } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
369
370
    // FIXME: copy-pasted from CGDebugInfo.cpp.
371
29
    OS << (OMD->isInstanceMethod() ? 
'-'25
:
'+'4
) << '[';
372
29
    const DeclContext *DC = OMD->getDeclContext();
373
29
    if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
374
13
      OS << OID->getName();
375
16
    } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
376
12
      OS << OID->getName();
377
12
    } 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
29
    OS << ' ' << OMD->getSelector().getAsString() << ']';
388
29
  }
389
390
184
  return Str;
391
184
}
392
393
35.5k
LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
394
35.5k
  assert(
395
35.5k
      ADCMgr &&
396
35.5k
      "Cannot create LocationContexts without an AnalysisDeclContextManager!");
397
0
  return ADCMgr->getLocationContextManager();
398
35.5k
}
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
193k
                                    const void *data) {
409
193k
  ID.AddInteger(ck);
410
193k
  ID.AddPointer(ctx);
411
193k
  ID.AddPointer(parent);
412
193k
  ID.AddPointer(data);
413
193k
}
414
415
109k
void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
416
109k
  Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,
417
109k
          BlockCount, Index);
418
109k
}
419
420
74
void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
421
74
  Profile(ID, getAnalysisDeclContext(), getParent(), BD, Data);
422
74
}
423
424
//===----------------------------------------------------------------------===//
425
// LocationContext creation.
426
//===----------------------------------------------------------------------===//
427
428
const StackFrameContext *LocationContextManager::getStackFrame(
429
    AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,
430
84.0k
    const CFGBlock *blk, unsigned blockCount, unsigned idx) {
431
84.0k
  llvm::FoldingSetNodeID ID;
432
84.0k
  StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);
433
84.0k
  void *InsertPos;
434
84.0k
  auto *L =
435
84.0k
   cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
436
84.0k
  if (!L) {
437
27.1k
    L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);
438
27.1k
    Contexts.InsertNode(L, InsertPos);
439
27.1k
  }
440
84.0k
  return L;
441
84.0k
}
442
443
const BlockInvocationContext *LocationContextManager::getBlockInvocationContext(
444
    AnalysisDeclContext *ADC, const LocationContext *ParentLC,
445
172
    const BlockDecl *BD, const void *Data) {
446
172
  llvm::FoldingSetNodeID ID;
447
172
  BlockInvocationContext::Profile(ID, ADC, ParentLC, BD, Data);
448
172
  void *InsertPos;
449
172
  auto *L =
450
172
    cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
451
172
                                                                    InsertPos));
452
172
  if (!L) {
453
155
    L = new BlockInvocationContext(ADC, ParentLC, BD, Data, ++NewID);
454
155
    Contexts.InsertNode(L, InsertPos);
455
155
  }
456
172
  return L;
457
172
}
458
459
//===----------------------------------------------------------------------===//
460
// LocationContext methods.
461
//===----------------------------------------------------------------------===//
462
463
8.98M
const StackFrameContext *LocationContext::getStackFrame() const {
464
8.98M
  const LocationContext *LC = this;
465
8.98M
  while (LC) {
466
8.98M
    if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
467
8.98M
      return SFC;
468
713
    LC = LC->getParent();
469
713
  }
470
0
  return nullptr;
471
8.98M
}
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
151
                                    printMoreInfoPerContext) const {
536
151
  ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
537
151
  PrintingPolicy PP(Ctx.getLangOpts());
538
151
  PP.TerseOutput = 1;
539
540
151
  const SourceManager &SM =
541
151
      getAnalysisDeclContext()->getASTContext().getSourceManager();
542
543
151
  unsigned Frame = 0;
544
322
  for (const LocationContext *LCtx = this; LCtx; 
LCtx = LCtx->getParent()171
) {
545
171
    Indent(Out, Space, IsDot)
546
171
        << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
547
171
    switch (LCtx->getKind()) {
548
171
    case StackFrame:
549
171
      Out << '#' << Frame << " Call\", \"calling\": \"";
550
171
      ++Frame;
551
171
      if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
552
171
        Out << D->getQualifiedNameAsString();
553
0
      else
554
0
        Out << "anonymous code";
555
556
171
      Out << "\", \"location\": ";
557
171
      if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
558
19
        printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
559
152
      } else {
560
152
        Out << "null";
561
152
      }
562
563
171
      Out << ", \"items\": ";
564
171
      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
171
    }
574
575
171
    printMoreInfoPerContext(LCtx);
576
577
171
    Out << '}';
578
171
    if (LCtx->getParent())
579
20
      Out << ',';
580
171
    Out << NL;
581
171
  }
582
151
}
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
406
      : 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
803
                                              llvm::BumpPtrAllocator &A) {
643
803
  if (Vec)
644
397
    return (DeclVec*) Vec;
645
646
406
  BumpVectorContext BC(A);
647
406
  DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
648
406
  new (BV) DeclVec(BC, 10);
649
650
  // Go through the capture list.
651
406
  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
406
  FindBlockDeclRefExprsVals F(*BV, BC);
657
406
  F.Visit(BD->getBody());
658
659
406
  Vec = BV;
660
406
  return BV;
661
803
}
662
663
llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
664
803
AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {
665
803
  if (!ReferencedBlockVars)
666
358
    ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
667
668
803
  const DeclVec *V =
669
803
      LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
670
803
  return llvm::make_range(V->begin(), V->end());
671
803
}
672
673
2.21M
std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
674
2.21M
  if (!ManagedAnalyses)
675
30.9k
    ManagedAnalyses = new ManagedAnalysisMap();
676
2.21M
  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
677
2.21M
  return (*M)[tag];
678
2.21M
}
679
680
//===----------------------------------------------------------------------===//
681
// Cleanup.
682
//===----------------------------------------------------------------------===//
683
684
68.7k
ManagedAnalysis::~ManagedAnalysis() = default;
685
686
338k
AnalysisDeclContext::~AnalysisDeclContext() {
687
338k
  delete forcedBlkExprs;
688
338k
  delete ReferencedBlockVars;
689
338k
  delete (ManagedAnalysisMap*) ManagedAnalyses;
690
338k
}
691
692
27.3k
LocationContext::~LocationContext() = default;
693
694
1.74k
LocationContextManager::~LocationContextManager() {
695
1.74k
  clear();
696
1.74k
}
697
698
1.74k
void LocationContextManager::clear() {
699
1.74k
  for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
700
29.0k
       E = Contexts.end(); I != E; ) {
701
27.3k
    LocationContext *LC = &*I;
702
27.3k
    ++I;
703
27.3k
    delete LC;
704
27.3k
  }
705
1.74k
  Contexts.clear();
706
1.74k
}