clang  20.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 
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,
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\": ";
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 }
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3346
NodeId Parent
Definition: ASTDiff.cpp:191
StringRef P
static bool isSelfDecl(const VarDecl *VD)
Returns true if.
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.
static void printLocation(raw_ostream &Out, const SourceManager &SM, SourceLocation Loc)
BumpVector< const VarDecl * > DeclVec
static DeclVec * LazyInitializeReferencedDecls(const BlockDecl *BD, void *&Vec, llvm::BumpPtrAllocator &A)
llvm::DenseMap< const void *, std::unique_ptr< ManagedAnalysis > > ManagedAnalysisMap
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
static char ID
Definition: Arena.cpp:183
#define SM(sm)
Definition: Cuda.cpp:83
const Decl * D
Expr * E
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
llvm::DenseSet< const void * > Visited
Definition: HTMLLogger.cpp:146
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the LambdaCapture class.
bool ShowColors
Definition: Logger.cpp:29
SourceLocation Loc
Definition: SemaObjC.cpp:759
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
const char * Data
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:187
SourceManager & getSourceManager()
Definition: ASTContext.h:721
const LangOptions & getLangOpts() const
Definition: ASTContext.h:797
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)
void clear()
Discard all previously created AnalysisDeclContexts.
AnalysisDeclContext * getContext(const Decl *D)
AnalysisDeclContext contains the context data for the function, method or block under analysis.
static std::string getFunctionName(const Decl *D)
void registerForcedBlockExpression(const Stmt *stmt)
const BlockInvocationContext * getBlockInvocationContext(const LocationContext *ParentLC, const BlockDecl *BD, const void *Data)
Obtain a context of the block invocation using its parent context.
const CFGBlock * getBlockForRegisteredExpression(const Stmt *stmt)
ASTContext & getASTContext() const
CFG::BuildOptions & getCFGBuildOptions()
static bool isInStdNamespace(const Decl *D)
CFGReverseBlockReachabilityAnalysis * getCFGReachablityAnalysis()
const ImplicitParamDecl * getSelfDecl() const
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.
llvm::iterator_range< referenced_decls_iterator > getReferencedBlockVars(const BlockDecl *BD)
const Decl * getDecl() const
AnalysisDeclContext(AnalysisDeclContextManager *Mgr, const Decl *D)
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4472
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:4551
ArrayRef< Capture > captures() const
Definition: Decl.h:4599
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6396
const BlockDecl * getBlockDecl() const
Definition: Expr.h:6408
It represents a block invocation (based on BlockCall).
void Profile(llvm::FoldingSetNodeID &ID) override
Stmt * getBody(const FunctionDecl *D)
Factory method for creating bodies for ordinary functions.
Definition: BodyFarm.cpp:700
void push_back(const_reference Elt, BumpVectorContext &C)
Definition: BumpVector.h:168
Represents a single basic block in a source-level CFG.
Definition: CFG.h:604
static CFGStmtMap * Build(CFG *C, ParentMap *PM)
Returns a new CFGMap for the given CFG.
Definition: CFGStmtMap.cpp:78
bool PruneTriviallyFalseEdges
Definition: CFG.h:1230
bool AddStaticInitBranches
Definition: CFG.h:1238
ForcedBlkExprs ** forcedBlkExprs
Definition: CFG.h:1228
CFGCallback * Observer
Definition: CFG.h:1229
bool AddRichCXXConstructors
Definition: CFG.h:1242
bool AddVirtualBaseBranches
Definition: CFG.h:1244
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
Definition: CFG.h:1226
bool MarkElidedCXXConstructors
Definition: CFG.h:1243
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition: CFG.h:1214
llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator
Definition: CFG.h:1362
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:5236
synthetic_stmt_iterator synthetic_stmt_end() const
Definition: CFG.h:1375
void dump(const LangOptions &LO, bool ShowColors) const
dump - A simple pretty printer of a CFG that outputs to stderr.
Definition: CFG.cpp:6103
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
Definition: CFG.h:1370
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition: DeclCXX.h:1023
capture_const_range captures() const
Definition: DeclCXX.h:1102
CodeInjector is an interface which is responsible for injecting AST of function definitions that may ...
Definition: CodeInjector.h:35
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2090
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
Definition: DeclBase.cpp:2006
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1265
ValueDecl * getDecl()
Definition: Expr.h:1333
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:523
SourceLocation getLocation() const
Definition: DeclBase.h:446
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:438
DeclContext * getDeclContext()
Definition: DeclBase.h:455
This represents one expression.
Definition: Expr.h:110
Represents a function declaration or definition.
Definition: Decl.h:1933
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.
void clear()
Discard all previously created LocationContext objects.
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.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const LocationContext * getParent() const
It might return null.
bool isParentOf(const LocationContext *LC) const
static void ProfileCommon(llvm::FoldingSetNodeID &ID, ContextKind ck, AnalysisDeclContext *ctx, const LocationContext *parent, const void *data)
const Decl * getDecl() const
LLVM_DUMP_METHOD void dumpStack(raw_ostream &Out) const
Prints out the call stack.
LLVM_DUMP_METHOD void dump() const
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
const StackFrameContext * getStackFrame() const
virtual bool inTopFrame() const
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.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
void setParent(const Stmt *S, const Stmt *Parent)
Manually sets the parent of S to Parent.
Definition: ParentMap.cpp:129
Stmt * getParent(Stmt *) const
Definition: ParentMap.cpp:136
Represents an unpacked "presumed" location which can be presented to the user.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6528
semantics_iterator semantics_end()
Definition: Expr.h:6600
semantics_iterator semantics_begin()
Definition: Expr.h:6594
Expr *const * semantics_iterator
Definition: Expr.h:6592
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
void print(raw_ostream &OS, const SourceManager &SM) const
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
It represents a stack frame of the call stack (based on CallEvent).
void Profile(llvm::FoldingSetNodeID &ID) override
bool inTopFrame() const override
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:185
Stmt - This represents one statement.
Definition: Stmt.h:84
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:338
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:668
Represents a variable declaration or definition.
Definition: Decl.h:880
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
The JSON file list parser is used to communicate input to InstallAPI.
void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc, const SourceManager &SM, bool AddBraces=true)
Definition: JsonSupport.h:82
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Definition: JsonSupport.h:21
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned TerseOutput
Provide a 'terse' output.