clang  14.0.0git
AnalysisDeclContext.cpp
Go to the documentation of this file.
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 
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"
23 #include "clang/AST/ParentMap.h"
25 #include "clang/AST/Stmt.h"
26 #include "clang/AST/StmtCXX.h"
27 #include "clang/AST/StmtVisitor.h"
30 #include "clang/Analysis/CFG.h"
34 #include "clang/Basic/LLVM.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 
56  const Decl *D,
57  const CFG::BuildOptions &Options)
58  : ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {
59  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
60 }
61 
63  const Decl *D)
64  : ADCMgr(ADCMgr), D(D) {
65  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
66 }
67 
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  SynthesizeBodies(synthesizeBodies) {
77  cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
78  cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
79  cfgBuildOptions.AddInitializers = addInitializers;
80  cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
81  cfgBuildOptions.AddLifetime = addLifetime;
82  cfgBuildOptions.AddLoopExit = addLoopExit;
83  cfgBuildOptions.AddScopes = addScopes;
84  cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
85  cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
86  cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;
87  cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;
88  cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;
89 }
90 
91 void AnalysisDeclContextManager::clear() { Contexts.clear(); }
92 
93 Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
94  IsAutosynthesized = false;
95  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
96  Stmt *Body = FD->getBody();
97  if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
98  Body = CoroBody->getBody();
99  if (ADCMgr && ADCMgr->synthesizeBodies()) {
100  Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);
101  if (SynthesizedBody) {
102  Body = SynthesizedBody;
103  IsAutosynthesized = true;
104  }
105  }
106  return Body;
107  }
108  else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
109  Stmt *Body = MD->getBody();
110  if (ADCMgr && ADCMgr->synthesizeBodies()) {
111  Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(MD);
112  if (SynthesizedBody) {
113  Body = SynthesizedBody;
114  IsAutosynthesized = true;
115  }
116  }
117  return Body;
118  } else if (const auto *BD = dyn_cast<BlockDecl>(D))
119  return BD->getBody();
120  else if (const auto *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
121  return FunTmpl->getTemplatedDecl()->getBody();
122 
123  llvm_unreachable("unknown code decl");
124 }
125 
127  bool Tmp;
128  return getBody(Tmp);
129 }
130 
132  bool Tmp;
133  getBody(Tmp);
134  return Tmp;
135 }
136 
138  bool Tmp;
139  Stmt *Body = getBody(Tmp);
140  return Tmp && Body->getBeginLoc().isValid();
141 }
142 
143 /// Returns true if \param VD is an Objective-C implicit 'self' parameter.
144 static bool isSelfDecl(const VarDecl *VD) {
145  return isa<ImplicitParamDecl>(VD) && VD->getName() == "self";
146 }
147 
149  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
150  return MD->getSelfDecl();
151  if (const auto *BD = dyn_cast<BlockDecl>(D)) {
152  // See if 'self' was captured by the block.
153  for (const auto &I : BD->captures()) {
154  const VarDecl *VD = I.getVariable();
155  if (isSelfDecl(VD))
156  return dyn_cast<ImplicitParamDecl>(VD);
157  }
158  }
159 
160  auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
161  if (!CXXMethod)
162  return nullptr;
163 
164  const CXXRecordDecl *parent = CXXMethod->getParent();
165  if (!parent->isLambda())
166  return nullptr;
167 
168  for (const auto &LC : parent->captures()) {
169  if (!LC.capturesVariable())
170  continue;
171 
172  VarDecl *VD = LC.getCapturedVar();
173  if (isSelfDecl(VD))
174  return dyn_cast<ImplicitParamDecl>(VD);
175  }
176 
177  return nullptr;
178 }
179 
181  if (!forcedBlkExprs)
182  forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
183  // Default construct an entry for 'stmt'.
184  if (const auto *e = dyn_cast<Expr>(stmt))
185  stmt = e->IgnoreParens();
186  (void) (*forcedBlkExprs)[stmt];
187 }
188 
189 const CFGBlock *
191  assert(forcedBlkExprs);
192  if (const auto *e = dyn_cast<Expr>(stmt))
193  stmt = e->IgnoreParens();
194  CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
195  forcedBlkExprs->find(stmt);
196  assert(itr != forcedBlkExprs->end());
197  return itr->second;
198 }
199 
200 /// Add each synthetic statement in the CFG to the parent map, using the
201 /// source statement's parent.
202 static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
203  if (!TheCFG)
204  return;
205 
207  E = TheCFG->synthetic_stmt_end();
208  I != E; ++I) {
209  PM.setParent(I->first, PM.getParent(I->second));
210  }
211 }
212 
214  if (!cfgBuildOptions.PruneTriviallyFalseEdges)
215  return getUnoptimizedCFG();
216 
217  if (!builtCFG) {
218  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  builtCFG = true;
222 
223  if (PM)
224  addParentsForSyntheticStmts(cfg.get(), *PM);
225 
226  // The Observer should only observe one build of the CFG.
227  getCFGBuildOptions().Observer = nullptr;
228  }
229  return cfg.get();
230 }
231 
233  if (!builtCompleteCFG) {
234  SaveAndRestore<bool> NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges,
235  false);
236  completeCFG =
237  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  builtCompleteCFG = true;
241 
242  if (PM)
243  addParentsForSyntheticStmts(completeCFG.get(), *PM);
244 
245  // The Observer should only observe one build of the CFG.
246  getCFGBuildOptions().Observer = nullptr;
247  }
248  return completeCFG.get();
249 }
250 
252  if (cfgStmtMap)
253  return cfgStmtMap.get();
254 
255  if (CFG *c = getCFG()) {
256  cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
257  return cfgStmtMap.get();
258  }
259 
260  return nullptr;
261 }
262 
264  if (CFA)
265  return CFA.get();
266 
267  if (CFG *c = getCFG()) {
268  CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
269  return CFA.get();
270  }
271 
272  return nullptr;
273 }
274 
275 void AnalysisDeclContext::dumpCFG(bool ShowColors) {
276  getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
277 }
278 
280  if (!PM) {
281  PM.reset(new ParentMap(getBody()));
282  if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
283  for (const auto *I : C->inits()) {
284  PM->addStmt(I->getInit());
285  }
286  }
287  if (builtCFG)
289  if (builtCompleteCFG)
291  }
292  return *PM;
293 }
294 
296  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
297  // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
298  // that has the body.
299  FD->hasBody(FD);
300  D = FD;
301  }
302 
303  std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
304  if (!AC)
305  AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
306  return AC.get();
307 }
308 
309 BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; }
310 
311 const StackFrameContext *
313  const Stmt *S, const CFGBlock *Blk,
314  unsigned BlockCount, unsigned Index) {
315  return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,
316  BlockCount, Index);
317 }
318 
320  const LocationContext *ParentLC, const BlockDecl *BD, const void *Data) {
321  return getLocationContextManager().getBlockInvocationContext(this, ParentLC,
322  BD, Data);
323 }
324 
327  const auto *ND = dyn_cast<NamespaceDecl>(DC);
328  if (!ND)
329  return false;
330 
331  while (const DeclContext *Parent = ND->getParent()) {
332  if (!isa<NamespaceDecl>(Parent))
333  break;
334  ND = cast<NamespaceDecl>(Parent);
335  }
336 
337  return ND->isStdNamespace();
338 }
339 
341  std::string Str;
342  llvm::raw_string_ostream OS(Str);
343  const ASTContext &Ctx = D->getASTContext();
344 
345  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
346  OS << FD->getQualifiedNameAsString();
347 
348  // In C++, there are overloads.
349 
350  if (Ctx.getLangOpts().CPlusPlus) {
351  OS << '(';
352  for (const auto &P : FD->parameters()) {
353  if (P != *FD->param_begin())
354  OS << ", ";
355  OS << P->getType().getAsString();
356  }
357  OS << ')';
358  }
359 
360  } else if (isa<BlockDecl>(D)) {
362 
363  if (Loc.isValid()) {
364  OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
365  << ')';
366  }
367 
368  } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
369 
370  // FIXME: copy-pasted from CGDebugInfo.cpp.
371  OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
372  const DeclContext *DC = OMD->getDeclContext();
373  if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
374  OS << OID->getName();
375  } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
376  OS << OID->getName();
377  } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
378  if (OC->IsClassExtension()) {
379  OS << OC->getClassInterface()->getName();
380  } else {
381  OS << OC->getIdentifier()->getNameStart() << '('
382  << OC->getIdentifier()->getNameStart() << ')';
383  }
384  } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
385  OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')';
386  }
387  OS << ' ' << OMD->getSelector().getAsString() << ']';
388  }
389 
390  return OS.str();
391 }
392 
393 LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
394  assert(
395  ADCMgr &&
396  "Cannot create LocationContexts without an AnalysisDeclContextManager!");
397  return ADCMgr->getLocationContextManager();
398 }
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  const void *data) {
409  ID.AddInteger(ck);
410  ID.AddPointer(ctx);
411  ID.AddPointer(parent);
412  ID.AddPointer(data);
413 }
414 
415 void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
416  Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,
417  BlockCount, Index);
418 }
419 
420 void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
421  Profile(ID, getAnalysisDeclContext(), getParent(), BD, Data);
422 }
423 
424 //===----------------------------------------------------------------------===//
425 // LocationContext creation.
426 //===----------------------------------------------------------------------===//
427 
429  AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,
430  const CFGBlock *blk, unsigned blockCount, unsigned idx) {
431  llvm::FoldingSetNodeID ID;
432  StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);
433  void *InsertPos;
434  auto *L =
435  cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
436  if (!L) {
437  L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);
438  Contexts.InsertNode(L, InsertPos);
439  }
440  return L;
441 }
442 
444  AnalysisDeclContext *ADC, const LocationContext *ParentLC,
445  const BlockDecl *BD, const void *Data) {
446  llvm::FoldingSetNodeID ID;
447  BlockInvocationContext::Profile(ID, ADC, ParentLC, BD, Data);
448  void *InsertPos;
449  auto *L =
450  cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
451  InsertPos));
452  if (!L) {
453  L = new BlockInvocationContext(ADC, ParentLC, BD, Data, ++NewID);
454  Contexts.InsertNode(L, InsertPos);
455  }
456  return L;
457 }
458 
459 //===----------------------------------------------------------------------===//
460 // LocationContext methods.
461 //===----------------------------------------------------------------------===//
462 
464  const LocationContext *LC = this;
465  while (LC) {
466  if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
467  return SFC;
468  LC = LC->getParent();
469  }
470  return nullptr;
471 }
472 
474  return getStackFrame()->inTopFrame();
475 }
476 
478  do {
479  const LocationContext *Parent = LC->getParent();
480  if (Parent == this)
481  return true;
482  else
483  LC = Parent;
484  } while (LC);
485 
486  return false;
487 }
488 
489 static void printLocation(raw_ostream &Out, const SourceManager &SM,
490  SourceLocation Loc) {
491  if (Loc.isFileID() && SM.isInMainFile(Loc))
492  Out << SM.getExpansionLineNumber(Loc);
493  else
494  Loc.print(Out, SM);
495 }
496 
497 void LocationContext::dumpStack(raw_ostream &Out) const {
499  PrintingPolicy PP(Ctx.getLangOpts());
500  PP.TerseOutput = 1;
501 
502  const SourceManager &SM =
504 
505  unsigned Frame = 0;
506  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
507  switch (LCtx->getKind()) {
508  case StackFrame:
509  Out << "\t#" << Frame << ' ';
510  ++Frame;
511  if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
512  Out << "Calling " << AnalysisDeclContext::getFunctionName(D);
513  else
514  Out << "Calling anonymous code";
515  if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
516  Out << " at line ";
517  printLocation(Out, SM, S->getBeginLoc());
518  }
519  break;
520  case Block:
521  Out << "Invoking block";
522  if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
523  Out << " defined at line ";
524  printLocation(Out, SM, D->getBeginLoc());
525  }
526  break;
527  }
528  Out << '\n';
529  }
530 }
531 
532 void LocationContext::printJson(raw_ostream &Out, const char *NL,
533  unsigned int Space, bool IsDot,
534  std::function<void(const LocationContext *)>
535  printMoreInfoPerContext) const {
537  PrintingPolicy PP(Ctx.getLangOpts());
538  PP.TerseOutput = 1;
539 
540  const SourceManager &SM =
542 
543  unsigned Frame = 0;
544  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
545  Indent(Out, Space, IsDot)
546  << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
547  switch (LCtx->getKind()) {
548  case StackFrame:
549  Out << '#' << Frame << " Call\", \"calling\": \"";
550  ++Frame;
551  if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
552  Out << D->getQualifiedNameAsString();
553  else
554  Out << "anonymous code";
555 
556  Out << "\", \"location\": ";
557  if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
558  printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
559  } else {
560  Out << "null";
561  }
562 
563  Out << ", \"items\": ";
564  break;
565  case Block:
566  Out << "Invoking block\" ";
567  if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
568  Out << ", \"location\": ";
569  printSourceLocationAsJson(Out, D->getBeginLoc(), SM);
570  Out << ' ';
571  }
572  break;
573  }
574 
575  printMoreInfoPerContext(LCtx);
576 
577  Out << '}';
578  if (LCtx->getParent())
579  Out << ',';
580  Out << NL;
581  }
582 }
583 
584 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>{
594  BumpVectorContext &BC;
597 
598 public:
599  FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
600  BumpVectorContext &bc)
601  : BEVals(bevals), BC(bc) {}
602 
603  void VisitStmt(Stmt *S) {
604  for (auto *Child : S->children())
605  if (Child)
606  Visit(Child);
607  }
608 
609  void VisitDeclRefExpr(DeclRefExpr *DR) {
610  // Non-local variables are also directly modified.
611  if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
612  if (!VD->hasLocalStorage()) {
613  if (Visited.insert(VD).second)
614  BEVals.push_back(VD, BC);
615  }
616  }
617  }
618 
619  void VisitBlockExpr(BlockExpr *BR) {
620  // Blocks containing blocks can transitively capture more variables.
621  IgnoredContexts.insert(BR->getBlockDecl());
622  Visit(BR->getBlockDecl()->getBody());
623  }
624 
625  void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
627  et = PE->semantics_end(); it != et; ++it) {
628  Expr *Semantic = *it;
629  if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
630  Semantic = OVE->getSourceExpr();
631  Visit(Semantic);
632  }
633  }
634 };
635 
636 } // namespace
637 
639 
641  void *&Vec,
642  llvm::BumpPtrAllocator &A) {
643  if (Vec)
644  return (DeclVec*) Vec;
645 
646  BumpVectorContext BC(A);
647  DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
648  new (BV) DeclVec(BC, 10);
649 
650  // Go through the capture list.
651  for (const auto &CI : BD->captures()) {
652  BV->push_back(CI.getVariable(), BC);
653  }
654 
655  // Find the referenced global/static variables.
656  FindBlockDeclRefExprsVals F(*BV, BC);
657  F.Visit(BD->getBody());
658 
659  Vec = BV;
660  return BV;
661 }
662 
663 llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
665  if (!ReferencedBlockVars)
666  ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
667 
668  const DeclVec *V =
669  LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
670  return llvm::make_range(V->begin(), V->end());
671 }
672 
673 std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
674  if (!ManagedAnalyses)
675  ManagedAnalyses = new ManagedAnalysisMap();
676  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
677  return (*M)[tag];
678 }
679 
680 //===----------------------------------------------------------------------===//
681 // Cleanup.
682 //===----------------------------------------------------------------------===//
683 
685 
687  delete forcedBlkExprs;
688  delete ReferencedBlockVars;
689  delete (ManagedAnalysisMap*) ManagedAnalyses;
690 }
691 
693 
695  clear();
696 }
697 
699  for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
700  E = Contexts.end(); I != E; ) {
701  LocationContext *LC = &*I;
702  ++I;
703  delete LC;
704  }
705  Contexts.clear();
706 }
clang::StmtVisitor
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:183
clang::AnalysisDeclContext::getCFGStmtMap
CFGStmtMap * getCFGStmtMap()
Definition: AnalysisDeclContext.cpp:251
clang::LocationContext::printJson
void printJson(raw_ostream &Out, const char *NL="\n", unsigned int Space=0, bool IsDot=false, std::function< void(const LocationContext *)> printMoreInfoPerContext=[](const LocationContext *) {}) const
Prints out the call stack in json format.
Definition: AnalysisDeclContext.cpp:532
CFGReachabilityAnalysis.h
clang::Decl::getASTContext
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:414
clang::AnalysisDeclContext::getASTContext
ASTContext & getASTContext() const
Definition: AnalysisDeclContext.h:104
clang::CFG::synthetic_stmt_iterator
llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator
Definition: CFG.h:1371
clang::AnalysisDeclContext::AnalysisDeclContext
AnalysisDeclContext(AnalysisDeclContextManager *Mgr, const Decl *D)
Definition: AnalysisDeclContext.cpp:62
clang::LocationContextManager::clear
void clear()
Discard all previously created LocationContext objects.
Definition: AnalysisDeclContext.cpp:698
clang::LocationContext
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
Definition: AnalysisDeclContext.h:215
clang::LocationContext::getStackFrame
const StackFrameContext * getStackFrame() const
Definition: AnalysisDeclContext.cpp:463
clang::PseudoObjectExpr::semantics_begin
semantics_iterator semantics_begin()
Definition: Expr.h:6163
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::DeclContext
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1347
clang::PresumedLoc::getLine
unsigned getLine() const
Return the presumed line number of this location.
Definition: SourceLocation.h:339
clang::AnalysisDeclContext::isBodyAutosynthesized
bool isBodyAutosynthesized() const
Definition: AnalysisDeclContext.cpp:131
clang::ast_matchers::stmt
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
Definition: ASTMatchersInternal.cpp:809
AnalysisDeclContext.h
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:88
clang::LocationContextManager
Definition: AnalysisDeclContext.h:383
clang::AnalysisDeclContextManager::synthesizeBodies
bool synthesizeBodies() const
Definition: AnalysisDeclContext.h:461
clang::AnalysisDeclContext
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Definition: AnalysisDeclContext.h:72
clang::AnalysisDeclContext::getSelfDecl
const ImplicitParamDecl * getSelfDecl() const
Definition: AnalysisDeclContext.cpp:148
clang::LocationContext::StackFrame
@ StackFrame
Definition: AnalysisDeclContext.h:217
DeclCXX.h
clang::BlockDecl::getBody
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition: Decl.h:4232
clang::AnalysisDeclContext::getStackFrame
const StackFrameContext * getStackFrame(LocationContext const *ParentLC, const Stmt *S, const CFGBlock *Blk, unsigned BlockCount, unsigned Index)
Obtain a context of the call stack using its parent context.
Definition: AnalysisDeclContext.cpp:312
llvm::SmallPtrSet
Definition: ASTContext.h:82
clang::StackFrameContext
It represents a stack frame of the call stack (based on CallEvent).
Definition: AnalysisDeclContext.h:295
SourceManager.h
clang::CFG::dump
void dump(const LangOptions &LO, bool ShowColors) const
dump - A simple pretty printer of a CFG that outputs to stderr.
Definition: CFG.cpp:5832
clang::SourceManager::getPresumedLoc
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
Definition: SourceManager.cpp:1518
clang::CFG::BuildOptions::MarkElidedCXXConstructors
bool MarkElidedCXXConstructors
Definition: CFG.h:1252
clang::PrintingPolicy
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:59
clang::PseudoObjectExpr::semantics_end
semantics_iterator semantics_end()
Definition: Expr.h:6169
clang::AnalysisDeclContextManager::AnalysisDeclContextManager
AnalysisDeclContextManager(ASTContext &ASTCtx, bool useUnoptimizedCFG=false, bool addImplicitDtors=false, bool addInitializers=false, bool addTemporaryDtors=false, bool addLifetime=false, bool addLoopExit=false, bool addScopes=false, bool synthesizeBodies=false, bool addStaticInitBranches=false, bool addCXXNewAllocator=true, bool addRichCXXConstructors=true, bool markElidedCXXConstructors=true, bool addVirtualBaseBranches=true, CodeInjector *injector=nullptr)
Definition: AnalysisDeclContext.cpp:68
clang::CFGStmtMap::Build
static CFGStmtMap * Build(CFG *C, ParentMap *PM)
Returns a new CFGMap for the given CFG.
Definition: CFGStmtMap.cpp:77
clang::CFG
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition: CFG.h:1225
clang::ASTContext::getSourceManager
SourceManager & getSourceManager()
Definition: ASTContext.h:695
clang::AnalysisDeclContext::getBlockInvocationContext
const BlockInvocationContext * getBlockInvocationContext(const LocationContext *ParentLC, const BlockDecl *BD, const void *Data)
Obtain a context of the block invocation using its parent context.
Definition: AnalysisDeclContext.cpp:319
clang::CFG::BuildOptions::AddRichCXXConstructors
bool AddRichCXXConstructors
Definition: CFG.h:1251
clang::SourceManager
This class handles loading and caching of source files into memory.
Definition: SourceManager.h:626
clang::CFG::BuildOptions::PruneTriviallyFalseEdges
bool PruneTriviallyFalseEdges
Definition: CFG.h:1239
clang::AnalysisDeclContext::dumpCFG
void dumpCFG(bool ShowColors)
Definition: AnalysisDeclContext.cpp:275
Decl.h
DeclObjC.h
clang::AnalysisDeclContext::registerForcedBlockExpression
void registerForcedBlockExpression(const Stmt *stmt)
Definition: AnalysisDeclContext.cpp:180
isSelfDecl
static bool isSelfDecl(const VarDecl *VD)
Returns true if.
Definition: AnalysisDeclContext.cpp:144
clang::BlockDecl::captures
ArrayRef< Capture > captures() const
Definition: Decl.h:4280
clang::CFGBlock
Represents a single basic block in a source-level CFG.
Definition: CFG.h:576
PrettyPrinter.h
clang::CFG::BuildOptions
Definition: CFG.h:1231
clang::StackFrameContext::inTopFrame
bool inTopFrame() const override
Definition: AnalysisDeclContext.h:325
JsonSupport.h
clang::LocationContext::dumpStack
LLVM_DUMP_METHOD void dumpStack(raw_ostream &Out) const
Prints out the call stack.
Definition: AnalysisDeclContext.cpp:497
V
#define V(N, I)
Definition: ASTContext.h:3121
clang::SourceLocation::print
void print(raw_ostream &OS, const SourceManager &SM) const
Definition: SourceLocation.cpp:62
DeclTemplate.h
clang::AnalysisDeclContext::getParentMap
ParentMap & getParentMap()
Definition: AnalysisDeclContext.cpp:279
clang::AnalysisDeclContext::isBodyAutosynthesizedFromModelFile
bool isBodyAutosynthesizedFromModelFile() const
Definition: AnalysisDeclContext.cpp:137
clang::BlockDecl
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4153
clang::LocationContext::getAnalysisDeclContext
AnalysisDeclContext * getAnalysisDeclContext() const
Definition: AnalysisDeclContext.h:241
clang::DeclContext::getEnclosingNamespaceContext
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
Definition: DeclBase.cpp:1798
clang::CFG::buildCFG
static std::unique_ptr< CFG > buildCFG(const Decl *D, Stmt *AST, ASTContext *C, const BuildOptions &BO)
Builds a CFG from an AST.
Definition: CFG.cpp:4990
DeclBase.h
clang::BlockExpr::getBlockDecl
const BlockDecl * getBlockDecl() const
Definition: Expr.h:5977
clang::CFGReverseBlockReachabilityAnalysis
Definition: CFGReachabilityAnalysis.h:31
clang::LocationContext::inTopFrame
virtual bool inTopFrame() const
Definition: AnalysisDeclContext.cpp:473
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:212
clang::CFG::BuildOptions::AddLifetime
bool AddLifetime
Definition: CFG.h:1243
clang::LocationContext::isParentOf
bool isParentOf(const LocationContext *LC) const
Definition: AnalysisDeclContext.cpp:477
clang::BlockInvocationContext
It represents a block invocation (based on BlockCall).
Definition: AnalysisDeclContext.h:349
clang::PseudoObjectExpr
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6095
clang::AnalysisDeclContext::getCFGReachablityAnalysis
CFGReverseBlockReachabilityAnalysis * getCFGReachablityAnalysis()
Definition: AnalysisDeclContext.cpp:263
clang::ParentMap::setParent
void setParent(const Stmt *S, const Stmt *Parent)
Manually sets the parent of S to Parent.
Definition: ParentMap.cpp:127
clang::CFG::BuildOptions::AddVirtualBaseBranches
bool AddVirtualBaseBranches
Definition: CFG.h:1253
clang::DeclRefExpr::getDecl
ValueDecl * getDecl()
Definition: Expr.h:1289
clang::AnalysisDeclContextManager::getBodyFarm
BodyFarm & getBodyFarm()
Definition: AnalysisDeclContext.cpp:309
clang::CFG::synthetic_stmt_begin
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
Definition: CFG.h:1379
clang::LocationContextManager::~LocationContextManager
~LocationContextManager()
Definition: AnalysisDeclContext.cpp:694
clang::ImplicitParamDecl
Definition: Decl.h:1601
Expr.h
ASTContext.h
BumpVector.h
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:876
clang::SourceLocation::isFileID
bool isFileID() const
Definition: SourceLocation.h:104
clang::PresumedLoc::getColumn
unsigned getColumn() const
Return the presumed column number of this location.
Definition: SourceLocation.h:347
clang::AnalysisDeclContext::isInStdNamespace
static bool isInStdNamespace(const Decl *D)
Definition: AnalysisDeclContext.cpp:325
clang::CXXRecordDecl::captures
capture_const_range captures() const
Definition: DeclCXX.h:1059
clang::LocationContextManager::getStackFrame
const StackFrameContext * getStackFrame(AnalysisDeclContext *ADC, const LocationContext *ParentLC, const Stmt *S, const CFGBlock *Block, unsigned BlockCount, unsigned Index)
Obtain a context of the call stack using its parent context.
Definition: AnalysisDeclContext.cpp:428
clang::CFGStmtMap
Definition: CFGStmtMap.h:24
DeclVec
BumpVector< const VarDecl * > DeclVec
Definition: AnalysisDeclContext.cpp:638
clang::PrintingPolicy::TerseOutput
unsigned TerseOutput
Provide a 'terse' output.
Definition: PrettyPrinter.h:221
clang::AnalysisDeclContextManager::getContext
AnalysisDeclContext * getContext(const Decl *D)
Definition: AnalysisDeclContext.cpp:295
CFGStmtMap.h
clang::AnalysisDeclContext::getUnoptimizedCFG
CFG * getUnoptimizedCFG()
Definition: AnalysisDeclContext.cpp:232
clang::CFG::BuildOptions::AddScopes
bool AddScopes
Definition: CFG.h:1246
clang::PseudoObjectExpr::semantics_iterator
Expr *const * semantics_iterator
Definition: Expr.h:6161
clang::LocationContext::Block
@ Block
Definition: AnalysisDeclContext.h:217
clang::printSourceLocationAsJson
void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc, const SourceManager &SM, bool AddBraces=true)
Definition: JsonSupport.h:81
ManagedAnalysisMap
llvm::DenseMap< const void *, std::unique_ptr< ManagedAnalysis > > ManagedAnalysisMap
Definition: AnalysisDeclContext.cpp:53
clang::LocationContext::getParent
const LocationContext * getParent() const
Definition: AnalysisDeclContext.h:243
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:255
clang::ParentMap
Definition: ParentMap.h:20
addParentsForSyntheticStmts
static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM)
Add each synthetic statement in the CFG to the parent map, using the source statement's parent.
Definition: AnalysisDeclContext.cpp:202
SourceLocation.h
clang::Indent
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Definition: JsonSupport.h:20
P
StringRef P
Definition: ASTMatchersInternal.cpp:563
clang::AnalysisDeclContext::getCFGBuildOptions
CFG::BuildOptions & getCFGBuildOptions()
Definition: AnalysisDeclContext.h:110
clang::LocationContext::dump
LLVM_DUMP_METHOD void dump() const
Definition: AnalysisDeclContext.cpp:584
clang::CFG::BuildOptions::AddLoopExit
bool AddLoopExit
Definition: CFG.h:1244
clang::LocationContextManager::getBlockInvocationContext
const BlockInvocationContext * getBlockInvocationContext(AnalysisDeclContext *ADC, const LocationContext *ParentLC, const BlockDecl *BD, const void *Data)
Obtain a context of the block invocation using its parent context.
Definition: AnalysisDeclContext.cpp:443
clang::DeclContext::getParent
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1860
clang::AnalysisDeclContextManager::clear
void clear()
Discard all previously created AnalysisDeclContexts.
Definition: AnalysisDeclContext.cpp:91
clang::BlockExpr
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:5965
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
StmtVisitor.h
LLVM.h
clang::CFG::BuildOptions::AddStaticInitBranches
bool AddStaticInitBranches
Definition: CFG.h:1247
llvm::SaveAndRestore< bool >
clang::BlockInvocationContext::Profile
void Profile(llvm::FoldingSetNodeID &ID) override
Definition: AnalysisDeclContext.cpp:420
clang::ParentMap::getParent
Stmt * getParent(Stmt *) const
Definition: ParentMap.cpp:134
clang::AnalysisDeclContext::getFunctionName
static std::string getFunctionName(const Decl *D)
Definition: AnalysisDeclContext.cpp:340
clang::CFG::synthetic_stmt_end
synthetic_stmt_iterator synthetic_stmt_end() const
Definition: CFG.h:1384
clang::AnalysisDeclContext::getBody
Stmt * getBody() const
Definition: AnalysisDeclContext.cpp:126
clang::BodyFarm
Definition: BodyFarm.h:31
BodyFarm.h
clang::CFG::BuildOptions::AddCXXNewAllocator
bool AddCXXNewAllocator
Definition: CFG.h:1248
clang::CFG::BuildOptions::AddImplicitDtors
bool AddImplicitDtors
Definition: CFG.h:1242
clang::ObjCMethodDecl
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:139
clang::AnalysisDeclContext::getReferencedBlockVars
llvm::iterator_range< referenced_decls_iterator > getReferencedBlockVars(const BlockDecl *BD)
Definition: AnalysisDeclContext.cpp:664
clang::PresumedLoc::isValid
bool isValid() const
Definition: SourceLocation.h:321
LazyInitializeReferencedDecls
static DeclVec * LazyInitializeReferencedDecls(const BlockDecl *BD, void *&Vec, llvm::BumpPtrAllocator &A)
Definition: AnalysisDeclContext.cpp:640
ParentMap.h
clang::Builtin::ID
ID
Definition: Builtins.h:48
clang
Definition: CalledOnceCheck.h:17
printLocation
static void printLocation(raw_ostream &Out, const SourceManager &SM, SourceLocation Loc)
Definition: AnalysisDeclContext.cpp:489
clang::ManagedAnalysis::~ManagedAnalysis
virtual ~ManagedAnalysis()
CFG.h
clang::AnalysisDeclContext::getDecl
const Decl * getDecl() const
Definition: AnalysisDeclContext.h:106
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:69
clang::SourceLocation::isValid
bool isValid() const
Return true if this is a valid SourceLocation object.
Definition: SourceLocation.h:112
clang::LocationContext::ProfileCommon
static void ProfileCommon(llvm::FoldingSetNodeID &ID, ContextKind ck, AnalysisDeclContext *ctx, const LocationContext *parent, const void *data)
Definition: AnalysisDeclContext.cpp:404
s
__device__ __2f16 float bool s
Definition: __clang_hip_libdevice_declares.h:315
clang::AnalysisDeclContext::getBlockForRegisteredExpression
const CFGBlock * getBlockForRegisteredExpression(const Stmt *stmt)
Definition: AnalysisDeclContext.cpp:190
clang::Stmt::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:336
clang::AnalysisDeclContext::~AnalysisDeclContext
~AnalysisDeclContext()
Definition: AnalysisDeclContext.cpp:686
clang::AnalysisDeclContextManager
Definition: AnalysisDeclContext.h:421
clang::LocationContext::ContextKind
ContextKind
Definition: AnalysisDeclContext.h:217
clang::CFG::BuildOptions::forcedBlkExprs
ForcedBlkExprs ** forcedBlkExprs
Definition: CFG.h:1237
LambdaCapture.h
c
__device__ __2f16 float c
Definition: __clang_hip_libdevice_declares.h:315
clang::StackFrameContext::Profile
void Profile(llvm::FoldingSetNodeID &ID) override
Definition: AnalysisDeclContext.cpp:415
clang::BodyFarm::getBody
Stmt * getBody(const FunctionDecl *D)
Factory method for creating bodies for ordinary functions.
Definition: BodyFarm.cpp:668
clang::CodeInjector
CodeInjector is an interface which is responsible for injecting AST of function definitions that may ...
Definition: CodeInjector.h:35
clang::CFG::BuildOptions::Observer
CFGCallback * Observer
Definition: CFG.h:1238
Parent
NodeId Parent
Definition: ASTDiff.cpp:192
Stmt.h
clang::CXXRecordDecl::isLambda
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition: DeclCXX.h:992
clang::AnalysisDeclContext::getCFG
CFG * getCFG()
Definition: AnalysisDeclContext.cpp:213
clang::PresumedLoc
Represents an unpacked "presumed" location which can be presented to the user.
Definition: SourceLocation.h:304
clang::BumpVectorContext
Definition: BumpVector.h:32
clang::Expr
This represents one expression.
Definition: Expr.h:109
SM
#define SM(sm)
Definition: Cuda.cpp:78
clang::CFG::BuildOptions::AddTemporaryDtors
bool AddTemporaryDtors
Definition: CFG.h:1245
clang::CFG::BuildOptions::ForcedBlkExprs
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
Definition: CFG.h:1235
clang::Decl::getLocation
SourceLocation getLocation() const
Definition: DeclBase.h:430
clang::BumpVector::push_back
void push_back(const_reference Elt, BumpVectorContext &C)
Definition: BumpVector.h:159
clang::DeclRefExpr
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1217
clang::LocationContext::getDecl
const Decl * getDecl() const
Definition: AnalysisDeclContext.h:247
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1856
StmtCXX.h
clang::BumpVector
Definition: BumpVector.h:59
clang::LocationContext::~LocationContext
virtual ~LocationContext()
clang::ASTContext::getLangOpts
const LangOptions & getLangOpts() const
Definition: ASTContext.h:765
clang::CFG::BuildOptions::AddInitializers
bool AddInitializers
Definition: CFG.h:1241
clang::Decl::getDeclContext
DeclContext * getDeclContext()
Definition: DeclBase.h:439
clang::NamedDecl::getName
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276