clang  10.0.0svn
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 *, ManagedAnalysis *>;
54 
56  const Decl *d,
57  const CFG::BuildOptions &buildOptions)
58  : Manager(Mgr), D(d), cfgBuildOptions(buildOptions) {
59  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
60 }
61 
63  const Decl *d)
64  : Manager(Mgr), 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 (Manager && Manager->synthesizeBodies()) {
100  Stmt *SynthesizedBody = Manager->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 (Manager && Manager->synthesizeBodies()) {
111  Stmt *SynthesizedBody = Manager->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)
288  addParentsForSyntheticStmts(getCFG(), *PM);
289  if (builtCompleteCFG)
290  addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);
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 CFGBlock *Blk, unsigned BlockCount,
314  unsigned Idx) {
315  return getLocationContextManager().getStackFrame(this, Parent, S, Blk,
316  BlockCount, Idx);
317 }
318 
321  const BlockDecl *BD,
322  const void *ContextData) {
323  return getLocationContextManager().getBlockInvocationContext(this, parent,
324  BD, ContextData);
325 }
326 
329  const auto *ND = dyn_cast<NamespaceDecl>(DC);
330  if (!ND)
331  return false;
332 
333  while (const DeclContext *Parent = ND->getParent()) {
334  if (!isa<NamespaceDecl>(Parent))
335  break;
336  ND = cast<NamespaceDecl>(Parent);
337  }
338 
339  return ND->isStdNamespace();
340 }
341 
342 LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
343  assert(Manager &&
344  "Cannot create LocationContexts without an AnalysisDeclContextManager!");
345  return Manager->getLocationContextManager();
346 }
347 
348 //===----------------------------------------------------------------------===//
349 // FoldingSet profiling.
350 //===----------------------------------------------------------------------===//
351 
352 void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
353  ContextKind ck,
354  AnalysisDeclContext *ctx,
355  const LocationContext *parent,
356  const void *data) {
357  ID.AddInteger(ck);
358  ID.AddPointer(ctx);
359  ID.AddPointer(parent);
360  ID.AddPointer(data);
361 }
362 
363 void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
364  Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,
365  BlockCount, Index);
366 }
367 
368 void ScopeContext::Profile(llvm::FoldingSetNodeID &ID) {
369  Profile(ID, getAnalysisDeclContext(), getParent(), Enter);
370 }
371 
372 void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
373  Profile(ID, getAnalysisDeclContext(), getParent(), BD, ContextData);
374 }
375 
376 //===----------------------------------------------------------------------===//
377 // LocationContext creation.
378 //===----------------------------------------------------------------------===//
379 
380 template <typename LOC, typename DATA>
381 const LOC*
382 LocationContextManager::getLocationContext(AnalysisDeclContext *ctx,
383  const LocationContext *parent,
384  const DATA *d) {
385  llvm::FoldingSetNodeID ID;
386  LOC::Profile(ID, ctx, parent, d);
387  void *InsertPos;
388 
389  LOC *L = cast_or_null<LOC>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
390 
391  if (!L) {
392  L = new LOC(ctx, parent, d, ++NewID);
393  Contexts.InsertNode(L, InsertPos);
394  }
395  return L;
396 }
397 
399  AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,
400  const CFGBlock *blk, unsigned blockCount, unsigned idx) {
401  llvm::FoldingSetNodeID ID;
402  StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);
403  void *InsertPos;
404  auto *L =
405  cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
406  if (!L) {
407  L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);
408  Contexts.InsertNode(L, InsertPos);
409  }
410  return L;
411 }
412 
413 const ScopeContext *
415  const LocationContext *parent,
416  const Stmt *s) {
417  return getLocationContext<ScopeContext, Stmt>(ctx, parent, s);
418 }
419 
422  const LocationContext *parent,
423  const BlockDecl *BD,
424  const void *ContextData) {
425  llvm::FoldingSetNodeID ID;
426  BlockInvocationContext::Profile(ID, ctx, parent, BD, ContextData);
427  void *InsertPos;
428  auto *L =
429  cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
430  InsertPos));
431  if (!L) {
432  L = new BlockInvocationContext(ctx, parent, BD, ContextData, ++NewID);
433  Contexts.InsertNode(L, InsertPos);
434  }
435  return L;
436 }
437 
438 //===----------------------------------------------------------------------===//
439 // LocationContext methods.
440 //===----------------------------------------------------------------------===//
441 
443  const LocationContext *LC = this;
444  while (LC) {
445  if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
446  return SFC;
447  LC = LC->getParent();
448  }
449  return nullptr;
450 }
451 
453  return getStackFrame()->inTopFrame();
454 }
455 
457  do {
458  const LocationContext *Parent = LC->getParent();
459  if (Parent == this)
460  return true;
461  else
462  LC = Parent;
463  } while (LC);
464 
465  return false;
466 }
467 
468 static void printLocation(raw_ostream &Out, const SourceManager &SM,
469  SourceLocation Loc) {
470  if (Loc.isFileID() && SM.isInMainFile(Loc))
471  Out << SM.getExpansionLineNumber(Loc);
472  else
473  Loc.print(Out, SM);
474 }
475 
476 void LocationContext::dumpStack(raw_ostream &Out, const char *NL,
477  std::function<void(const LocationContext *)>
478  printMoreInfoPerContext) const {
479  ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
480  PrintingPolicy PP(Ctx.getLangOpts());
481  PP.TerseOutput = 1;
482 
483  const SourceManager &SM =
484  getAnalysisDeclContext()->getASTContext().getSourceManager();
485 
486  unsigned Frame = 0;
487  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
488  switch (LCtx->getKind()) {
489  case StackFrame:
490  Out << "\t#" << Frame << ' ';
491  ++Frame;
492  if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
493  Out << "Calling " << D->getQualifiedNameAsString();
494  else
495  Out << "Calling anonymous code";
496  if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
497  Out << " at line ";
498  printLocation(Out, SM, S->getBeginLoc());
499  }
500  break;
501  case Scope:
502  Out << "Entering scope";
503  break;
504  case Block:
505  Out << "Invoking block";
506  if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
507  Out << " defined at line ";
508  printLocation(Out, SM, D->getBeginLoc());
509  }
510  break;
511  }
512  Out << NL;
513 
514  printMoreInfoPerContext(LCtx);
515  }
516 }
517 
518 void LocationContext::printJson(raw_ostream &Out, const char *NL,
519  unsigned int Space, bool IsDot,
520  std::function<void(const LocationContext *)>
521  printMoreInfoPerContext) const {
522  ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
523  PrintingPolicy PP(Ctx.getLangOpts());
524  PP.TerseOutput = 1;
525 
526  const SourceManager &SM =
527  getAnalysisDeclContext()->getASTContext().getSourceManager();
528 
529  unsigned Frame = 0;
530  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
531  Indent(Out, Space, IsDot)
532  << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
533  switch (LCtx->getKind()) {
534  case StackFrame:
535  Out << '#' << Frame << " Call\", \"calling\": \"";
536  ++Frame;
537  if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
538  Out << D->getQualifiedNameAsString();
539  else
540  Out << "anonymous code";
541 
542  Out << "\", \"location\": ";
543  if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
544  printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
545  } else {
546  Out << "null";
547  }
548 
549  Out << ", \"items\": ";
550  break;
551  case Scope:
552  Out << "Entering scope\" ";
553  break;
554  case Block:
555  Out << "Invoking block\" ";
556  if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
557  Out << ", \"location\": ";
558  printSourceLocationAsJson(Out, D->getBeginLoc(), SM);
559  Out << ' ';
560  }
561  break;
562  }
563 
564  printMoreInfoPerContext(LCtx);
565 
566  Out << '}';
567  if (LCtx->getParent())
568  Out << ',';
569  Out << NL;
570  }
571 }
572 
573 LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); }
574 
575 //===----------------------------------------------------------------------===//
576 // Lazily generated map to query the external variables referenced by a Block.
577 //===----------------------------------------------------------------------===//
578 
579 namespace {
580 
581 class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
583  BumpVectorContext &BC;
584  llvm::SmallPtrSet<const VarDecl *, 4> Visited;
585  llvm::SmallPtrSet<const DeclContext *, 4> IgnoredContexts;
586 
587 public:
588  FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
589  BumpVectorContext &bc)
590  : BEVals(bevals), BC(bc) {}
591 
592  void VisitStmt(Stmt *S) {
593  for (auto *Child : S->children())
594  if (Child)
595  Visit(Child);
596  }
597 
598  void VisitDeclRefExpr(DeclRefExpr *DR) {
599  // Non-local variables are also directly modified.
600  if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
601  if (!VD->hasLocalStorage()) {
602  if (Visited.insert(VD).second)
603  BEVals.push_back(VD, BC);
604  }
605  }
606  }
607 
608  void VisitBlockExpr(BlockExpr *BR) {
609  // Blocks containing blocks can transitively capture more variables.
610  IgnoredContexts.insert(BR->getBlockDecl());
611  Visit(BR->getBlockDecl()->getBody());
612  }
613 
614  void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
616  et = PE->semantics_end(); it != et; ++it) {
617  Expr *Semantic = *it;
618  if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
619  Semantic = OVE->getSourceExpr();
620  Visit(Semantic);
621  }
622  }
623 };
624 
625 } // namespace
626 
628 
630  void *&Vec,
631  llvm::BumpPtrAllocator &A) {
632  if (Vec)
633  return (DeclVec*) Vec;
634 
635  BumpVectorContext BC(A);
636  DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
637  new (BV) DeclVec(BC, 10);
638 
639  // Go through the capture list.
640  for (const auto &CI : BD->captures()) {
641  BV->push_back(CI.getVariable(), BC);
642  }
643 
644  // Find the referenced global/static variables.
645  FindBlockDeclRefExprsVals F(*BV, BC);
646  F.Visit(BD->getBody());
647 
648  Vec = BV;
649  return BV;
650 }
651 
652 llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
654  if (!ReferencedBlockVars)
655  ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
656 
657  const DeclVec *V =
658  LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
659  return llvm::make_range(V->begin(), V->end());
660 }
661 
662 ManagedAnalysis *&AnalysisDeclContext::getAnalysisImpl(const void *tag) {
663  if (!ManagedAnalyses)
664  ManagedAnalyses = new ManagedAnalysisMap();
665  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
666  return (*M)[tag];
667 }
668 
669 //===----------------------------------------------------------------------===//
670 // Cleanup.
671 //===----------------------------------------------------------------------===//
672 
674 
676  delete forcedBlkExprs;
677  delete ReferencedBlockVars;
678  // Release the managed analyses.
679  if (ManagedAnalyses) {
680  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
681  llvm::DeleteContainerSeconds(*M);
682  delete M;
683  }
684 }
685 
687 
689  clear();
690 }
691 
693  for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
694  E = Contexts.end(); I != E; ) {
695  LocationContext *LC = &*I;
696  ++I;
697  delete LC;
698  }
699  Contexts.clear();
700 }
Defines the clang::ASTContext interface.
const BlockDecl * getBlockDecl() const
Definition: Expr.h:5560
The base class of a hierarchy of objects representing analyses tied to AnalysisDeclContext.
void Profile(llvm::FoldingSetNodeID &ID) override
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
Stmt * getBody() const
Get the body of the Declaration.
Expr *const * semantics_iterator
Definition: Expr.h:5734
Stmt - This represents one statement.
Definition: Stmt.h:66
Defines the SourceManager interface.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
Defines the C++ template declaration subclasses.
Stmt * getParent(Stmt *) const
Definition: ParentMap.cpp:134
Represent a C++ namespace.
Definition: Decl.h:514
capture_const_range captures() const
Definition: DeclCXX.h:1207
bool AddStaticInitBranches
Definition: CFG.h:1247
Represents a variable declaration or definition.
Definition: Decl.h:812
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:37
unsigned TerseOutput
Provide a &#39;terse&#39; output.
bool isParentOf(const LocationContext *LC) const
const StackFrameContext * getStackFrame(AnalysisDeclContext *Ctx, const LocationContext *Parent, const Stmt *S, const CFGBlock *Blk, unsigned BlockCount, unsigned Idx)
void print(raw_ostream &OS, const SourceManager &SM) const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:160
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:274
AnalysisDeclContext contains the context data for the function or method under analysis.
void addStmt(Stmt *S)
Adds and/or updates the parent/child-relations of the complete stmt tree of S.
Definition: ParentMap.cpp:121
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:4002
void setParent(const Stmt *S, const Stmt *Parent)
Manually sets the parent of S to Parent.
Definition: ParentMap.cpp:127
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
Definition: DeclBase.cpp:1762
static bool isInStdNamespace(const Decl *D)
Returns true if the root namespace of the given declaration is the &#39;std&#39; C++ namespace.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
CFGReverseBlockReachabilityAnalysis * getCFGReachablityAnalysis()
CFGCallback * Observer
Definition: CFG.h:1238
child_range children()
Definition: Stmt.cpp:223
virtual bool inTopFrame() const
Return true if the current LocationContext has no caller context.
semantics_iterator semantics_end()
Definition: Expr.h:5742
const LocationContext * getParent() const
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)
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition: DeclCXX.h:1152
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:40
void clear()
Discard all previously created LocationContext objects.
llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator
Definition: CFG.h:1351
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
Definition: CFG.h:1235
NodeId Parent
Definition: ASTDiff.cpp:191
ForcedBlkExprs ** forcedBlkExprs
Definition: CFG.h:1237
Represents a single basic block in a source-level CFG.
Definition: CFG.h:576
AnalysisDeclContext * getContext(const Decl *D)
bool isBodyAutosynthesizedFromModelFile() const
Checks if the body of the Decl is generated by the BodyFarm from a model file.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:3923
const StackFrameContext * getStackFrame(AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s, const CFGBlock *blk, unsigned blockCount, unsigned idx)
This represents one expression.
Definition: Expr.h:108
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
Definition: CFG.h:1225
BumpVector< const VarDecl * > DeclVec
void Profile(llvm::FoldingSetNodeID &ID) override
#define V(N, I)
Definition: ASTContext.h:2913
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:5546
DeclContext * getDeclContext()
Definition: DeclBase.h:438
bool inTopFrame() const override
Return true if the current LocationContext has no caller context.
BodyFarm & getBodyFarm()
Get a reference to {.
const CFGBlock * getBlockForRegisteredExpression(const Stmt *stmt)
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1779
bool isBodyAutosynthesized() const
Checks if the body of the Decl is generated by the BodyFarm.
const ScopeContext * getScope(AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s)
ValueDecl * getDecl()
Definition: Expr.h:1217
CFG::BuildOptions & getCFGBuildOptions()
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
const SourceManager & SM
Definition: Format.cpp:1609
CFG * getUnoptimizedCFG()
Return a version of the CFG without any edges pruned.
const ImplicitParamDecl * getSelfDecl() const
Return the ImplicitParamDecl* associated with &#39;self&#39; if this AnalysisDeclContext wraps an ObjCMethodD...
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:5668
Encodes a location in the source.
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:4824
static void printLocation(raw_ostream &Out, const SourceManager &SM, SourceLocation Loc)
bool PruneTriviallyFalseEdges
Definition: CFG.h:1239
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2068
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:182
bool isStdNamespace() const
Definition: DeclBase.cpp:1073
void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc, const SourceManager &SM, bool AddBraces=true)
Definition: JsonSupport.h:81
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
bool MarkElidedCXXConstructors
Definition: CFG.h:1251
void dumpStack(raw_ostream &Out, const char *NL="\, std::function< void(const LocationContext *)> printMoreInfoPerContext=[](const LocationContext *) {}) const
void push_back(const_reference Elt, BumpVectorContext &C)
Definition: BumpVector.h:159
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
static CFGStmtMap * Build(CFG *C, ParentMap *PM)
Returns a new CFGMap for the given CFG.
Definition: CFGStmtMap.cpp:77
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1271
ArrayRef< Capture > captures() const
Definition: Decl.h:4050
CodeInjector is an interface which is responsible for injecting AST of function definitions that may ...
Definition: CodeInjector.h:35
llvm::iterator_range< referenced_decls_iterator > getReferencedBlockVars(const BlockDecl *BD)
static DeclVec * LazyInitializeReferencedDecls(const BlockDecl *BD, void *&Vec, llvm::BumpPtrAllocator &A)
void Profile(llvm::FoldingSetNodeID &ID) override
semantics_iterator semantics_begin()
Definition: Expr.h:5736
const StackFrameContext * getStackFrame(LocationContext const *Parent, const Stmt *S, const CFGBlock *Blk, unsigned BlockCount, unsigned Idx)
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&#39;s parent...
const StackFrameContext * getStackFrame() const
void printJson(raw_ostream &Out, const char *NL="\, unsigned int Space=0, bool IsDot=false, std::function< void(const LocationContext *)> printMoreInfoPerContext=[](const LocationContext *) {}) const
const BlockInvocationContext * getBlockInvocationContext(AnalysisDeclContext *ctx, const LocationContext *parent, const BlockDecl *BD, const void *ContextData)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
llvm::DenseMap< const void *, ManagedAnalysis * > ManagedAnalysisMap
Defines the clang::SourceLocation class and associated facilities.
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
bool AddVirtualBaseBranches
Definition: CFG.h:1252
synthetic_stmt_iterator synthetic_stmt_end() const
Definition: CFG.h:1364
bool AddRichCXXConstructors
Definition: CFG.h:1250
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:275
void registerForcedBlockExpression(const Stmt *stmt)
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
Definition: CFG.h:1359
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Definition: JsonSupport.h:20
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1141
const BlockInvocationContext * getBlockInvocationContext(const LocationContext *parent, const BlockDecl *BD, const void *ContextData)
void clear()
Discard all previously created AnalysisDeclContexts.
const LangOptions & getLangOpts() const
Definition: ASTContext.h:720
This class handles loading and caching of source files into memory.
AnalysisDeclContext(AnalysisDeclContextManager *Mgr, const Decl *D)
static void ProfileCommon(llvm::FoldingSetNodeID &ID, ContextKind ck, AnalysisDeclContext *ctx, const LocationContext *parent, const void *data)
Defines the LambdaCapture class.