clang  16.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_and_nonnull<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  ValueDecl *VD = LC.getCapturedVar();
173  if (isSelfDecl(dyn_cast<VarDecl>(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 NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges, false);
235  completeCFG =
236  CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
237  // Even when the cfg is not successfully built, we don't
238  // want to try building it again.
239  builtCompleteCFG = true;
240 
241  if (PM)
242  addParentsForSyntheticStmts(completeCFG.get(), *PM);
243 
244  // The Observer should only observe one build of the CFG.
245  getCFGBuildOptions().Observer = nullptr;
246  }
247  return completeCFG.get();
248 }
249 
251  if (cfgStmtMap)
252  return cfgStmtMap.get();
253 
254  if (CFG *c = getCFG()) {
255  cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
256  return cfgStmtMap.get();
257  }
258 
259  return nullptr;
260 }
261 
263  if (CFA)
264  return CFA.get();
265 
266  if (CFG *c = getCFG()) {
267  CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
268  return CFA.get();
269  }
270 
271  return nullptr;
272 }
273 
274 void AnalysisDeclContext::dumpCFG(bool ShowColors) {
275  getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
276 }
277 
279  if (!PM) {
280  PM.reset(new ParentMap(getBody()));
281  if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
282  for (const auto *I : C->inits()) {
283  PM->addStmt(I->getInit());
284  }
285  }
286  if (builtCFG)
288  if (builtCompleteCFG)
290  }
291  return *PM;
292 }
293 
295  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
296  // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
297  // that has the body.
298  FD->hasBody(FD);
299  D = FD;
300  }
301 
302  std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
303  if (!AC)
304  AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
305  return AC.get();
306 }
307 
308 BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; }
309 
310 const StackFrameContext *
312  const Stmt *S, const CFGBlock *Blk,
313  unsigned BlockCount, unsigned Index) {
314  return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,
315  BlockCount, Index);
316 }
317 
319  const LocationContext *ParentLC, const BlockDecl *BD, const void *Data) {
320  return getLocationContextManager().getBlockInvocationContext(this, ParentLC,
321  BD, Data);
322 }
323 
326  const auto *ND = dyn_cast<NamespaceDecl>(DC);
327  if (!ND)
328  return false;
329 
330  while (const DeclContext *Parent = ND->getParent()) {
331  if (!isa<NamespaceDecl>(Parent))
332  break;
333  ND = cast<NamespaceDecl>(Parent);
334  }
335 
336  return ND->isStdNamespace();
337 }
338 
340  std::string Str;
341  llvm::raw_string_ostream OS(Str);
342  const ASTContext &Ctx = D->getASTContext();
343 
344  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
345  OS << FD->getQualifiedNameAsString();
346 
347  // In C++, there are overloads.
348 
349  if (Ctx.getLangOpts().CPlusPlus) {
350  OS << '(';
351  for (const auto &P : FD->parameters()) {
352  if (P != *FD->param_begin())
353  OS << ", ";
354  OS << P->getType();
355  }
356  OS << ')';
357  }
358 
359  } else if (isa<BlockDecl>(D)) {
361 
362  if (Loc.isValid()) {
363  OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
364  << ')';
365  }
366 
367  } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
368 
369  // FIXME: copy-pasted from CGDebugInfo.cpp.
370  OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
371  const DeclContext *DC = OMD->getDeclContext();
372  if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
373  OS << OID->getName();
374  } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
375  OS << OID->getName();
376  } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
377  if (OC->IsClassExtension()) {
378  OS << OC->getClassInterface()->getName();
379  } else {
380  OS << OC->getIdentifier()->getNameStart() << '('
381  << OC->getIdentifier()->getNameStart() << ')';
382  }
383  } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
384  OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')';
385  }
386  OS << ' ' << OMD->getSelector().getAsString() << ']';
387  }
388 
389  return Str;
390 }
391 
392 LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
393  assert(
394  ADCMgr &&
395  "Cannot create LocationContexts without an AnalysisDeclContextManager!");
396  return ADCMgr->getLocationContextManager();
397 }
398 
399 //===----------------------------------------------------------------------===//
400 // FoldingSet profiling.
401 //===----------------------------------------------------------------------===//
402 
403 void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
404  ContextKind ck,
405  AnalysisDeclContext *ctx,
406  const LocationContext *parent,
407  const void *data) {
408  ID.AddInteger(ck);
409  ID.AddPointer(ctx);
410  ID.AddPointer(parent);
411  ID.AddPointer(data);
412 }
413 
414 void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
415  Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,
416  BlockCount, Index);
417 }
418 
419 void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
420  Profile(ID, getAnalysisDeclContext(), getParent(), BD, Data);
421 }
422 
423 //===----------------------------------------------------------------------===//
424 // LocationContext creation.
425 //===----------------------------------------------------------------------===//
426 
428  AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,
429  const CFGBlock *blk, unsigned blockCount, unsigned idx) {
430  llvm::FoldingSetNodeID ID;
431  StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);
432  void *InsertPos;
433  auto *L =
434  cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
435  if (!L) {
436  L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);
437  Contexts.InsertNode(L, InsertPos);
438  }
439  return L;
440 }
441 
443  AnalysisDeclContext *ADC, const LocationContext *ParentLC,
444  const BlockDecl *BD, const void *Data) {
445  llvm::FoldingSetNodeID ID;
446  BlockInvocationContext::Profile(ID, ADC, ParentLC, BD, Data);
447  void *InsertPos;
448  auto *L =
449  cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
450  InsertPos));
451  if (!L) {
452  L = new BlockInvocationContext(ADC, ParentLC, BD, Data, ++NewID);
453  Contexts.InsertNode(L, InsertPos);
454  }
455  return L;
456 }
457 
458 //===----------------------------------------------------------------------===//
459 // LocationContext methods.
460 //===----------------------------------------------------------------------===//
461 
463  const LocationContext *LC = this;
464  while (LC) {
465  if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
466  return SFC;
467  LC = LC->getParent();
468  }
469  return nullptr;
470 }
471 
473  return getStackFrame()->inTopFrame();
474 }
475 
477  do {
478  const LocationContext *Parent = LC->getParent();
479  if (Parent == this)
480  return true;
481  else
482  LC = Parent;
483  } while (LC);
484 
485  return false;
486 }
487 
488 static void printLocation(raw_ostream &Out, const SourceManager &SM,
489  SourceLocation Loc) {
490  if (Loc.isFileID() && SM.isInMainFile(Loc))
491  Out << SM.getExpansionLineNumber(Loc);
492  else
493  Loc.print(Out, SM);
494 }
495 
496 void LocationContext::dumpStack(raw_ostream &Out) const {
498  PrintingPolicy PP(Ctx.getLangOpts());
499  PP.TerseOutput = 1;
500 
501  const SourceManager &SM =
503 
504  unsigned Frame = 0;
505  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
506  switch (LCtx->getKind()) {
507  case StackFrame:
508  Out << "\t#" << Frame << ' ';
509  ++Frame;
510  if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
511  Out << "Calling " << AnalysisDeclContext::getFunctionName(D);
512  else
513  Out << "Calling anonymous code";
514  if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
515  Out << " at line ";
516  printLocation(Out, SM, S->getBeginLoc());
517  }
518  break;
519  case Block:
520  Out << "Invoking block";
521  if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
522  Out << " defined at line ";
523  printLocation(Out, SM, D->getBeginLoc());
524  }
525  break;
526  }
527  Out << '\n';
528  }
529 }
530 
531 void LocationContext::printJson(raw_ostream &Out, const char *NL,
532  unsigned int Space, bool IsDot,
533  std::function<void(const LocationContext *)>
534  printMoreInfoPerContext) const {
536  PrintingPolicy PP(Ctx.getLangOpts());
537  PP.TerseOutput = 1;
538 
539  const SourceManager &SM =
541 
542  unsigned Frame = 0;
543  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
544  Indent(Out, Space, IsDot)
545  << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
546  switch (LCtx->getKind()) {
547  case StackFrame:
548  Out << '#' << Frame << " Call\", \"calling\": \"";
549  ++Frame;
550  if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
551  Out << D->getQualifiedNameAsString();
552  else
553  Out << "anonymous code";
554 
555  Out << "\", \"location\": ";
556  if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
557  printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
558  } else {
559  Out << "null";
560  }
561 
562  Out << ", \"items\": ";
563  break;
564  case Block:
565  Out << "Invoking block\" ";
566  if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
567  Out << ", \"location\": ";
568  printSourceLocationAsJson(Out, D->getBeginLoc(), SM);
569  Out << ' ';
570  }
571  break;
572  }
573 
574  printMoreInfoPerContext(LCtx);
575 
576  Out << '}';
577  if (LCtx->getParent())
578  Out << ',';
579  Out << NL;
580  }
581 }
582 
583 LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); }
584 
585 //===----------------------------------------------------------------------===//
586 // Lazily generated map to query the external variables referenced by a Block.
587 //===----------------------------------------------------------------------===//
588 
589 namespace {
590 
591 class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
593  BumpVectorContext &BC;
596 
597 public:
598  FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
599  BumpVectorContext &bc)
600  : BEVals(bevals), BC(bc) {}
601 
602  void VisitStmt(Stmt *S) {
603  for (auto *Child : S->children())
604  if (Child)
605  Visit(Child);
606  }
607 
608  void VisitDeclRefExpr(DeclRefExpr *DR) {
609  // Non-local variables are also directly modified.
610  if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
611  if (!VD->hasLocalStorage()) {
612  if (Visited.insert(VD).second)
613  BEVals.push_back(VD, BC);
614  }
615  }
616  }
617 
618  void VisitBlockExpr(BlockExpr *BR) {
619  // Blocks containing blocks can transitively capture more variables.
620  IgnoredContexts.insert(BR->getBlockDecl());
621  Visit(BR->getBlockDecl()->getBody());
622  }
623 
624  void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
626  et = PE->semantics_end(); it != et; ++it) {
627  Expr *Semantic = *it;
628  if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
629  Semantic = OVE->getSourceExpr();
630  Visit(Semantic);
631  }
632  }
633 };
634 
635 } // namespace
636 
638 
640  void *&Vec,
641  llvm::BumpPtrAllocator &A) {
642  if (Vec)
643  return (DeclVec*) Vec;
644 
645  BumpVectorContext BC(A);
646  DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
647  new (BV) DeclVec(BC, 10);
648 
649  // Go through the capture list.
650  for (const auto &CI : BD->captures()) {
651  BV->push_back(CI.getVariable(), BC);
652  }
653 
654  // Find the referenced global/static variables.
655  FindBlockDeclRefExprsVals F(*BV, BC);
656  F.Visit(BD->getBody());
657 
658  Vec = BV;
659  return BV;
660 }
661 
662 llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
664  if (!ReferencedBlockVars)
665  ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
666 
667  const DeclVec *V =
668  LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
669  return llvm::make_range(V->begin(), V->end());
670 }
671 
672 std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
673  if (!ManagedAnalyses)
674  ManagedAnalyses = new ManagedAnalysisMap();
675  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
676  return (*M)[tag];
677 }
678 
679 //===----------------------------------------------------------------------===//
680 // Cleanup.
681 //===----------------------------------------------------------------------===//
682 
684 
686  delete forcedBlkExprs;
687  delete ReferencedBlockVars;
688  delete (ManagedAnalysisMap*) ManagedAnalyses;
689 }
690 
692 
694  clear();
695 }
696 
698  for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
699  E = Contexts.end(); I != E; ) {
700  LocationContext *LC = &*I;
701  ++I;
702  delete LC;
703  }
704  Contexts.clear();
705 }
clang::StmtVisitor
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:183
clang::AnalysisDeclContext::getCFGStmtMap
CFGStmtMap * getCFGStmtMap()
Definition: AnalysisDeclContext.cpp:250
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:531
CFGReachabilityAnalysis.h
clang::Decl::getASTContext
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:428
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:1373
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:697
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:462
clang::PseudoObjectExpr::semantics_begin
semantics_iterator semantics_begin()
Definition: Expr.h:6174
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:1389
clang::PresumedLoc::getLine
unsigned getLine() const
Return the presumed line number of this location.
Definition: SourceLocation.h:337
clang::AnalysisDeclContext::isBodyAutosynthesized
bool isBodyAutosynthesized() const
Definition: AnalysisDeclContext.cpp:131
clang::ast_matchers::stmt
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
Definition: ASTMatchersInternal.cpp:811
AnalysisDeclContext.h
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
clang::LocationContextManager
Definition: AnalysisDeclContext.h:387
clang::AnalysisDeclContextManager::synthesizeBodies
bool synthesizeBodies() const
Definition: AnalysisDeclContext.h:465
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:4390
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:311
llvm::SmallPtrSet
Definition: ASTContext.h:55
clang::StackFrameContext
It represents a stack frame of the call stack (based on CallEvent).
Definition: AnalysisDeclContext.h:299
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:6090
clang::SourceManager::getPresumedLoc
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
Definition: SourceManager.cpp:1523
clang::CFG::BuildOptions::MarkElidedCXXConstructors
bool MarkElidedCXXConstructors
Definition: CFG.h:1254
clang::PrintingPolicy
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
clang::PseudoObjectExpr::semantics_end
semantics_iterator semantics_end()
Definition: Expr.h:6180
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:1227
clang::ASTContext::getSourceManager
SourceManager & getSourceManager()
Definition: ASTContext.h:694
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:318
clang::CFG::BuildOptions::AddRichCXXConstructors
bool AddRichCXXConstructors
Definition: CFG.h:1253
clang::SourceManager
This class handles loading and caching of source files into memory.
Definition: SourceManager.h:637
clang::CFG::BuildOptions::PruneTriviallyFalseEdges
bool PruneTriviallyFalseEdges
Definition: CFG.h:1241
clang::AnalysisDeclContext::dumpCFG
void dumpCFG(bool ShowColors)
Definition: AnalysisDeclContext.cpp:274
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:4438
clang::CFGBlock
Represents a single basic block in a source-level CFG.
Definition: CFG.h:578
PrettyPrinter.h
clang::CFG::BuildOptions
Definition: CFG.h:1233
clang::StackFrameContext::inTopFrame
bool inTopFrame() const override
Definition: AnalysisDeclContext.h:329
JsonSupport.h
clang::LocationContext::dumpStack
LLVM_DUMP_METHOD void dumpStack(raw_ostream &Out) const
Prints out the call stack.
Definition: AnalysisDeclContext.cpp:496
V
#define V(N, I)
Definition: ASTContext.h:3208
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:278
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:4311
clang::DeclContext::getEnclosingNamespaceContext
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
Definition: DeclBase.cpp:1847
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:5230
DeclBase.h
clang::BlockExpr::getBlockDecl
const BlockDecl * getBlockDecl() const
Definition: Expr.h:5988
clang::CFGReverseBlockReachabilityAnalysis
Definition: CFGReachabilityAnalysis.h:31
clang::LocationContext::inTopFrame
virtual bool inTopFrame() const
Definition: AnalysisDeclContext.cpp:472
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
clang::CFG::BuildOptions::AddLifetime
bool AddLifetime
Definition: CFG.h:1245
clang::LocationContext::isParentOf
bool isParentOf(const LocationContext *LC) const
Definition: AnalysisDeclContext.cpp:476
clang::BlockInvocationContext
It represents a block invocation (based on BlockCall).
Definition: AnalysisDeclContext.h:353
clang::PseudoObjectExpr
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6106
clang::AnalysisDeclContext::getCFGReachablityAnalysis
CFGReverseBlockReachabilityAnalysis * getCFGReachablityAnalysis()
Definition: AnalysisDeclContext.cpp:262
clang::ParentMap::setParent
void setParent(const Stmt *S, const Stmt *Parent)
Manually sets the parent of S to Parent.
Definition: ParentMap.cpp:129
clang::CFG::BuildOptions::AddVirtualBaseBranches
bool AddVirtualBaseBranches
Definition: CFG.h:1255
clang::DeclRefExpr::getDecl
ValueDecl * getDecl()
Definition: Expr.h:1305
clang::AnalysisDeclContextManager::getBodyFarm
BodyFarm & getBodyFarm()
Definition: AnalysisDeclContext.cpp:308
clang::CFG::synthetic_stmt_begin
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
Definition: CFG.h:1381
clang::LocationContextManager::~LocationContextManager
~LocationContextManager()
Definition: AnalysisDeclContext.cpp:693
clang::ImplicitParamDecl
Definition: Decl.h:1645
Expr.h
ASTContext.h
BumpVector.h
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:906
clang::SourceLocation::isFileID
bool isFileID() const
Definition: SourceLocation.h:102
clang::PresumedLoc::getColumn
unsigned getColumn() const
Return the presumed column number of this location.
Definition: SourceLocation.h:345
clang::AnalysisDeclContext::isInStdNamespace
static bool isInStdNamespace(const Decl *D)
Definition: AnalysisDeclContext.cpp:324
clang::CXXRecordDecl::captures
capture_const_range captures() const
Definition: DeclCXX.h:1068
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:427
clang::CFGStmtMap
Definition: CFGStmtMap.h:24
DeclVec
BumpVector< const VarDecl * > DeclVec
Definition: AnalysisDeclContext.cpp:637
clang::PrintingPolicy::TerseOutput
unsigned TerseOutput
Provide a 'terse' output.
Definition: PrettyPrinter.h:225
clang::AnalysisDeclContextManager::getContext
AnalysisDeclContext * getContext(const Decl *D)
Definition: AnalysisDeclContext.cpp:294
CFGStmtMap.h
clang::AnalysisDeclContext::getUnoptimizedCFG
CFG * getUnoptimizedCFG()
Definition: AnalysisDeclContext.cpp:232
clang::CFG::BuildOptions::AddScopes
bool AddScopes
Definition: CFG.h:1248
clang::PseudoObjectExpr::semantics_iterator
Expr *const * semantics_iterator
Definition: Expr.h:6172
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:82
clang::LocationContext::getAnalysisDeclContext
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
Definition: AnalysisDeclContext.h:244
ManagedAnalysisMap
llvm::DenseMap< const void *, std::unique_ptr< ManagedAnalysis > > ManagedAnalysisMap
Definition: AnalysisDeclContext.cpp:53
clang::LocationContext::getParent
const LocationContext * getParent() const
It might return null.
Definition: AnalysisDeclContext.h:247
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
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:21
P
StringRef P
Definition: ASTMatchersInternal.cpp:564
clang::AnalysisDeclContext::getCFGBuildOptions
CFG::BuildOptions & getCFGBuildOptions()
Definition: AnalysisDeclContext.h:110
clang::LocationContext::dump
LLVM_DUMP_METHOD void dump() const
Definition: AnalysisDeclContext.cpp:583
clang::CFG::BuildOptions::AddLoopExit
bool AddLoopExit
Definition: CFG.h:1246
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:442
clang::ValueDecl
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:701
clang::DeclContext::getParent
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1923
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:5976
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
StmtVisitor.h
LLVM.h
clang::CFG::BuildOptions::AddStaticInitBranches
bool AddStaticInitBranches
Definition: CFG.h:1249
llvm::SaveAndRestore
Definition: LLVM.h:44
clang::BlockInvocationContext::Profile
void Profile(llvm::FoldingSetNodeID &ID) override
Definition: AnalysisDeclContext.cpp:419
clang::ParentMap::getParent
Stmt * getParent(Stmt *) const
Definition: ParentMap.cpp:136
clang::AnalysisDeclContext::getFunctionName
static std::string getFunctionName(const Decl *D)
Definition: AnalysisDeclContext.cpp:339
clang::CFG::synthetic_stmt_end
synthetic_stmt_iterator synthetic_stmt_end() const
Definition: CFG.h:1386
clang::AnalysisDeclContext::getBody
Stmt * getBody() const
Definition: AnalysisDeclContext.cpp:126
clang::BodyFarm
Definition: BodyFarm.h:30
BodyFarm.h
clang::CFG::BuildOptions::AddCXXNewAllocator
bool AddCXXNewAllocator
Definition: CFG.h:1250
clang::CFG::BuildOptions::AddImplicitDtors
bool AddImplicitDtors
Definition: CFG.h:1244
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:663
clang::PresumedLoc::isValid
bool isValid() const
Definition: SourceLocation.h:319
LazyInitializeReferencedDecls
static DeclVec * LazyInitializeReferencedDecls(const BlockDecl *BD, void *&Vec, llvm::BumpPtrAllocator &A)
Definition: AnalysisDeclContext.cpp:639
ParentMap.h
clang::Builtin::ID
ID
Definition: Builtins.h:52
clang
Definition: CalledOnceCheck.h:17
printLocation
static void printLocation(raw_ostream &Out, const SourceManager &SM, SourceLocation Loc)
Definition: AnalysisDeclContext.cpp:488
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:71
clang::SourceLocation::isValid
bool isValid() const
Return true if this is a valid SourceLocation object.
Definition: SourceLocation.h:110
clang::LocationContext::ProfileCommon
static void ProfileCommon(llvm::FoldingSetNodeID &ID, ContextKind ck, AnalysisDeclContext *ctx, const LocationContext *parent, const void *data)
Definition: AnalysisDeclContext.cpp:403
s
__device__ __2f16 float bool s
Definition: __clang_hip_libdevice_declares.h:320
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:685
clang::AnalysisDeclContextManager
Definition: AnalysisDeclContext.h:425
clang::LocationContext::ContextKind
ContextKind
Definition: AnalysisDeclContext.h:217
clang::CFG::BuildOptions::forcedBlkExprs
ForcedBlkExprs ** forcedBlkExprs
Definition: CFG.h:1239
LambdaCapture.h
c
__device__ __2f16 float c
Definition: __clang_hip_libdevice_declares.h:320
clang::StackFrameContext::Profile
void Profile(llvm::FoldingSetNodeID &ID) override
Definition: AnalysisDeclContext.cpp:414
clang::BodyFarm::getBody
Stmt * getBody(const FunctionDecl *D)
Factory method for creating bodies for ordinary functions.
Definition: BodyFarm.cpp:699
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:1240
Parent
NodeId Parent
Definition: ASTDiff.cpp:190
Stmt.h
clang::CXXRecordDecl::isLambda
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition: DeclCXX.h:1000
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:302
clang::BumpVectorContext
Definition: BumpVector.h:32
clang::Expr
This represents one expression.
Definition: Expr.h:109
SM
#define SM(sm)
Definition: Cuda.cpp:79
clang::CFG::BuildOptions::AddTemporaryDtors
bool AddTemporaryDtors
Definition: CFG.h:1247
clang::CFG::BuildOptions::ForcedBlkExprs
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
Definition: CFG.h:1237
clang::Decl::getLocation
SourceLocation getLocation() const
Definition: DeclBase.h:432
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:1233
clang::LocationContext::getDecl
const Decl * getDecl() const
Definition: AnalysisDeclContext.h:251
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1904
StmtCXX.h
clang::BumpVector
Definition: BumpVector.h:59
clang::LocationContext::~LocationContext
virtual ~LocationContext()
clang::ASTContext::getLangOpts
const LangOptions & getLangOpts() const
Definition: ASTContext.h:764
clang::CFG::BuildOptions::AddInitializers
bool AddInitializers
Definition: CFG.h:1243
clang::Decl::getDeclContext
DeclContext * getDeclContext()
Definition: DeclBase.h:441
clang::NamedDecl::getName
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:274