clang  5.0.0
AnalysisDeclContext.cpp
Go to the documentation of this file.
1 //== AnalysisDeclContext.cpp - Analysis context for Path Sens analysis -*- C++ -*-//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines AnalysisDeclContext, a class that manages the analysis context
11 // data for path sensitive analysis.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "BodyFarm.h"
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclObjC.h"
20 #include "clang/AST/DeclTemplate.h"
21 #include "clang/AST/ParentMap.h"
22 #include "clang/AST/StmtVisitor.h"
26 #include "clang/Analysis/CFG.h"
29 #include "llvm/ADT/SmallPtrSet.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/SaveAndRestore.h"
32 #include "llvm/Support/raw_ostream.h"
33 
34 using namespace clang;
35 
36 typedef llvm::DenseMap<const void *, ManagedAnalysis *> ManagedAnalysisMap;
37 
39  const Decl *d,
40  const CFG::BuildOptions &buildOptions)
41  : Manager(Mgr),
42  D(d),
43  cfgBuildOptions(buildOptions),
44  forcedBlkExprs(nullptr),
45  builtCFG(false),
46  builtCompleteCFG(false),
47  ReferencedBlockVars(nullptr),
48  ManagedAnalyses(nullptr)
49 {
50  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
51 }
52 
54  const Decl *d)
55 : Manager(Mgr),
56  D(d),
57  forcedBlkExprs(nullptr),
58  builtCFG(false),
59  builtCompleteCFG(false),
60  ReferencedBlockVars(nullptr),
61  ManagedAnalyses(nullptr)
62 {
63  cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
64 }
65 
67  bool addImplicitDtors,
68  bool addInitializers,
69  bool addTemporaryDtors,
70  bool addLifetime,
71  bool synthesizeBodies,
72  bool addStaticInitBranch,
73  bool addCXXNewAllocator,
74  CodeInjector *injector)
75  : Injector(injector), SynthesizeBodies(synthesizeBodies)
76 {
77  cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
78  cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
79  cfgBuildOptions.AddInitializers = addInitializers;
80  cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
81  cfgBuildOptions.AddLifetime = addLifetime;
82  cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
83  cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
84 }
85 
86 void AnalysisDeclContextManager::clear() { Contexts.clear(); }
87 
88 static BodyFarm &getBodyFarm(ASTContext &C, CodeInjector *injector = nullptr) {
89  static BodyFarm *BF = new BodyFarm(C, injector);
90  return *BF;
91 }
92 
93 Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
94  IsAutosynthesized = false;
95  if (const FunctionDecl *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 =
101  getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(FD);
102  if (SynthesizedBody) {
103  Body = SynthesizedBody;
104  IsAutosynthesized = true;
105  }
106  }
107  return Body;
108  }
109  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
110  Stmt *Body = MD->getBody();
111  if (Manager && Manager->synthesizeBodies()) {
112  Stmt *SynthesizedBody =
113  getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(MD);
114  if (SynthesizedBody) {
115  Body = SynthesizedBody;
116  IsAutosynthesized = true;
117  }
118  }
119  return Body;
120  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
121  return BD->getBody();
122  else if (const FunctionTemplateDecl *FunTmpl
123  = dyn_cast_or_null<FunctionTemplateDecl>(D))
124  return FunTmpl->getTemplatedDecl()->getBody();
125 
126  llvm_unreachable("unknown code decl");
127 }
128 
130  bool Tmp;
131  return getBody(Tmp);
132 }
133 
135  bool Tmp;
136  getBody(Tmp);
137  return Tmp;
138 }
139 
141  bool Tmp;
142  Stmt *Body = getBody(Tmp);
143  return Tmp && Body->getLocStart().isValid();
144 }
145 
146 /// Returns true if \param VD is an Objective-C implicit 'self' parameter.
147 static bool isSelfDecl(const VarDecl *VD) {
148  return isa<ImplicitParamDecl>(VD) && VD->getName() == "self";
149 }
150 
152  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
153  return MD->getSelfDecl();
154  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
155  // See if 'self' was captured by the block.
156  for (const auto &I : BD->captures()) {
157  const VarDecl *VD = I.getVariable();
158  if (isSelfDecl(VD))
159  return dyn_cast<ImplicitParamDecl>(VD);
160  }
161  }
162 
163  auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
164  if (!CXXMethod)
165  return nullptr;
166 
167  const CXXRecordDecl *parent = CXXMethod->getParent();
168  if (!parent->isLambda())
169  return nullptr;
170 
171  for (const LambdaCapture &LC : parent->captures()) {
172  if (!LC.capturesVariable())
173  continue;
174 
175  VarDecl *VD = LC.getCapturedVar();
176  if (isSelfDecl(VD))
177  return dyn_cast<ImplicitParamDecl>(VD);
178  }
179 
180  return nullptr;
181 }
182 
184  if (!forcedBlkExprs)
185  forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
186  // Default construct an entry for 'stmt'.
187  if (const Expr *e = dyn_cast<Expr>(stmt))
188  stmt = e->IgnoreParens();
189  (void) (*forcedBlkExprs)[stmt];
190 }
191 
192 const CFGBlock *
194  assert(forcedBlkExprs);
195  if (const Expr *e = dyn_cast<Expr>(stmt))
196  stmt = e->IgnoreParens();
197  CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
198  forcedBlkExprs->find(stmt);
199  assert(itr != forcedBlkExprs->end());
200  return itr->second;
201 }
202 
203 /// Add each synthetic statement in the CFG to the parent map, using the
204 /// source statement's parent.
205 static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
206  if (!TheCFG)
207  return;
208 
210  E = TheCFG->synthetic_stmt_end();
211  I != E; ++I) {
212  PM.setParent(I->first, PM.getParent(I->second));
213  }
214 }
215 
217  if (!cfgBuildOptions.PruneTriviallyFalseEdges)
218  return getUnoptimizedCFG();
219 
220  if (!builtCFG) {
221  cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
222  // Even when the cfg is not successfully built, we don't
223  // want to try building it again.
224  builtCFG = true;
225 
226  if (PM)
227  addParentsForSyntheticStmts(cfg.get(), *PM);
228 
229  // The Observer should only observe one build of the CFG.
230  getCFGBuildOptions().Observer = nullptr;
231  }
232  return cfg.get();
233 }
234 
236  if (!builtCompleteCFG) {
237  SaveAndRestore<bool> NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges,
238  false);
239  completeCFG =
240  CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
241  // Even when the cfg is not successfully built, we don't
242  // want to try building it again.
243  builtCompleteCFG = true;
244 
245  if (PM)
246  addParentsForSyntheticStmts(completeCFG.get(), *PM);
247 
248  // The Observer should only observe one build of the CFG.
249  getCFGBuildOptions().Observer = nullptr;
250  }
251  return completeCFG.get();
252 }
253 
255  if (cfgStmtMap)
256  return cfgStmtMap.get();
257 
258  if (CFG *c = getCFG()) {
259  cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
260  return cfgStmtMap.get();
261  }
262 
263  return nullptr;
264 }
265 
267  if (CFA)
268  return CFA.get();
269 
270  if (CFG *c = getCFG()) {
271  CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
272  return CFA.get();
273  }
274 
275  return nullptr;
276 }
277 
278 void AnalysisDeclContext::dumpCFG(bool ShowColors) {
279  getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
280 }
281 
283  if (!PM) {
284  PM.reset(new ParentMap(getBody()));
285  if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
286  for (const auto *I : C->inits()) {
287  PM->addStmt(I->getInit());
288  }
289  }
290  if (builtCFG)
292  if (builtCompleteCFG)
294  }
295  return *PM;
296 }
297 
299  if (!PCA)
300  PCA.reset(new PseudoConstantAnalysis(getBody()));
301  return PCA.get();
302 }
303 
305  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
306  // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
307  // that has the body.
308  FD->hasBody(FD);
309  D = FD;
310  }
311 
312  std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
313  if (!AC)
314  AC = llvm::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
315  return AC.get();
316 }
317 
318 const StackFrameContext *
320  const CFGBlock *Blk, unsigned Idx) {
321  return getLocationContextManager().getStackFrame(this, Parent, S, Blk, Idx);
322 }
323 
326  const clang::BlockDecl *BD,
327  const void *ContextData) {
328  return getLocationContextManager().getBlockInvocationContext(this, parent,
329  BD, ContextData);
330 }
331 
334  const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC);
335  if (!ND)
336  return false;
337 
338  while (const DeclContext *Parent = ND->getParent()) {
339  if (!isa<NamespaceDecl>(Parent))
340  break;
341  ND = cast<NamespaceDecl>(Parent);
342  }
343 
344  return ND->isStdNamespace();
345 }
346 
347 LocationContextManager & AnalysisDeclContext::getLocationContextManager() {
348  assert(Manager &&
349  "Cannot create LocationContexts without an AnalysisDeclContextManager!");
350  return Manager->getLocationContextManager();
351 }
352 
353 //===----------------------------------------------------------------------===//
354 // FoldingSet profiling.
355 //===----------------------------------------------------------------------===//
356 
357 void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
358  ContextKind ck,
359  AnalysisDeclContext *ctx,
360  const LocationContext *parent,
361  const void *data) {
362  ID.AddInteger(ck);
363  ID.AddPointer(ctx);
364  ID.AddPointer(parent);
365  ID.AddPointer(data);
366 }
367 
368 void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
369  Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block, Index);
370 }
371 
372 void ScopeContext::Profile(llvm::FoldingSetNodeID &ID) {
373  Profile(ID, getAnalysisDeclContext(), getParent(), Enter);
374 }
375 
376 void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
377  Profile(ID, getAnalysisDeclContext(), getParent(), BD, ContextData);
378 }
379 
380 //===----------------------------------------------------------------------===//
381 // LocationContext creation.
382 //===----------------------------------------------------------------------===//
383 
384 template <typename LOC, typename DATA>
385 const LOC*
386 LocationContextManager::getLocationContext(AnalysisDeclContext *ctx,
387  const LocationContext *parent,
388  const DATA *d) {
389  llvm::FoldingSetNodeID ID;
390  LOC::Profile(ID, ctx, parent, d);
391  void *InsertPos;
392 
393  LOC *L = cast_or_null<LOC>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
394 
395  if (!L) {
396  L = new LOC(ctx, parent, d);
397  Contexts.InsertNode(L, InsertPos);
398  }
399  return L;
400 }
401 
402 const StackFrameContext*
404  const LocationContext *parent,
405  const Stmt *s,
406  const CFGBlock *blk, unsigned idx) {
407  llvm::FoldingSetNodeID ID;
408  StackFrameContext::Profile(ID, ctx, parent, s, blk, idx);
409  void *InsertPos;
410  StackFrameContext *L =
411  cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
412  if (!L) {
413  L = new StackFrameContext(ctx, parent, s, blk, idx);
414  Contexts.InsertNode(L, InsertPos);
415  }
416  return L;
417 }
418 
419 const ScopeContext *
421  const LocationContext *parent,
422  const Stmt *s) {
423  return getLocationContext<ScopeContext, Stmt>(ctx, parent, s);
424 }
425 
428  const LocationContext *parent,
429  const BlockDecl *BD,
430  const void *ContextData) {
431  llvm::FoldingSetNodeID ID;
432  BlockInvocationContext::Profile(ID, ctx, parent, BD, ContextData);
433  void *InsertPos;
435  cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
436  InsertPos));
437  if (!L) {
438  L = new BlockInvocationContext(ctx, parent, BD, ContextData);
439  Contexts.InsertNode(L, InsertPos);
440  }
441  return L;
442 }
443 
444 //===----------------------------------------------------------------------===//
445 // LocationContext methods.
446 //===----------------------------------------------------------------------===//
447 
449  const LocationContext *LC = this;
450  while (LC) {
451  if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC))
452  return SFC;
453  LC = LC->getParent();
454  }
455  return nullptr;
456 }
457 
459  return getCurrentStackFrame()->inTopFrame();
460 }
461 
463  do {
464  const LocationContext *Parent = LC->getParent();
465  if (Parent == this)
466  return true;
467  else
468  LC = Parent;
469  } while (LC);
470 
471  return false;
472 }
473 
474 void LocationContext::dumpStack(raw_ostream &OS, StringRef Indent) const {
476  PrintingPolicy PP(Ctx.getLangOpts());
477  PP.TerseOutput = 1;
478 
479  unsigned Frame = 0;
480  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
481  switch (LCtx->getKind()) {
482  case StackFrame:
483  OS << Indent << '#' << Frame++ << ' ';
484  cast<StackFrameContext>(LCtx)->getDecl()->print(OS, PP);
485  OS << '\n';
486  break;
487  case Scope:
488  OS << Indent << " (scope)\n";
489  break;
490  case Block:
491  OS << Indent << " (block context: "
492  << cast<BlockInvocationContext>(LCtx)->getContextData()
493  << ")\n";
494  break;
495  }
496  }
497 }
498 
499 LLVM_DUMP_METHOD void LocationContext::dumpStack() const {
500  dumpStack(llvm::errs());
501 }
502 
503 //===----------------------------------------------------------------------===//
504 // Lazily generated map to query the external variables referenced by a Block.
505 //===----------------------------------------------------------------------===//
506 
507 namespace {
508 class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
510  BumpVectorContext &BC;
511  llvm::SmallPtrSet<const VarDecl*, 4> Visited;
512  llvm::SmallPtrSet<const DeclContext*, 4> IgnoredContexts;
513 public:
514  FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
515  BumpVectorContext &bc)
516  : BEVals(bevals), BC(bc) {}
517 
518  void VisitStmt(Stmt *S) {
519  for (Stmt *Child : S->children())
520  if (Child)
521  Visit(Child);
522  }
523 
524  void VisitDeclRefExpr(DeclRefExpr *DR) {
525  // Non-local variables are also directly modified.
526  if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
527  if (!VD->hasLocalStorage()) {
528  if (Visited.insert(VD).second)
529  BEVals.push_back(VD, BC);
530  }
531  }
532  }
533 
534  void VisitBlockExpr(BlockExpr *BR) {
535  // Blocks containing blocks can transitively capture more variables.
536  IgnoredContexts.insert(BR->getBlockDecl());
537  Visit(BR->getBlockDecl()->getBody());
538  }
539 
540  void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
542  et = PE->semantics_end(); it != et; ++it) {
543  Expr *Semantic = *it;
544  if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
545  Semantic = OVE->getSourceExpr();
546  Visit(Semantic);
547  }
548  }
549 };
550 } // end anonymous namespace
551 
553 
555  void *&Vec,
556  llvm::BumpPtrAllocator &A) {
557  if (Vec)
558  return (DeclVec*) Vec;
559 
560  BumpVectorContext BC(A);
561  DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
562  new (BV) DeclVec(BC, 10);
563 
564  // Go through the capture list.
565  for (const auto &CI : BD->captures()) {
566  BV->push_back(CI.getVariable(), BC);
567  }
568 
569  // Find the referenced global/static variables.
570  FindBlockDeclRefExprsVals F(*BV, BC);
571  F.Visit(BD->getBody());
572 
573  Vec = BV;
574  return BV;
575 }
576 
577 llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
579  if (!ReferencedBlockVars)
580  ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
581 
582  const DeclVec *V =
583  LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
584  return llvm::make_range(V->begin(), V->end());
585 }
586 
587 ManagedAnalysis *&AnalysisDeclContext::getAnalysisImpl(const void *tag) {
588  if (!ManagedAnalyses)
589  ManagedAnalyses = new ManagedAnalysisMap();
590  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
591  return (*M)[tag];
592 }
593 
594 //===----------------------------------------------------------------------===//
595 // Cleanup.
596 //===----------------------------------------------------------------------===//
597 
599 
601  delete forcedBlkExprs;
602  delete ReferencedBlockVars;
603  // Release the managed analyses.
604  if (ManagedAnalyses) {
605  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
606  llvm::DeleteContainerSeconds(*M);
607  delete M;
608  }
609 }
610 
612 
614 
616  clear();
617 }
618 
620  for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
621  E = Contexts.end(); I != E; ) {
622  LocationContext *LC = &*I;
623  ++I;
624  delete LC;
625  }
626 
627  Contexts.clear();
628 }
629 
Defines the clang::ASTContext interface.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Definition: Decl.h:1618
The base class of a hierarchy of objects representing analyses tied to AnalysisDeclContext.
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:237
BumpVector< const VarDecl * > DeclVec
ASTContext & getASTContext() const
void Profile(llvm::FoldingSetNodeID &ID) override
ArrayRef< Capture > captures() const
Definition: Decl.h:3682
capture_const_range captures() const
Definition: DeclCXX.h:1150
Expr *const * semantics_iterator
Definition: Expr.h:5004
Stmt - This represents one statement.
Definition: Stmt.h:60
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
Definition: ASTMatchers.h:1051
virtual bool inTopFrame() const
Return true if the current LocationContext has no caller context.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:81
Defines the C++ template declaration subclasses.
bool isStdNamespace() const
Definition: DeclBase.cpp:993
NamespaceDecl - Represent a C++ namespace.
Definition: Decl.h:461
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:26
bool AddStaticInitBranches
Definition: CFG.h:798
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2329
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:758
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:113
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:38
const ImplicitParamDecl * getSelfDecl() const
Return the ImplicitParamDecl* associated with 'self' if this AnalysisDeclContext wraps an ObjCMethodD...
unsigned TerseOutput
Provide a 'terse' output.
bool isBodyAutosynthesized() const
Checks if the body of the Decl is generated by the BodyFarm.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:128
synthetic_stmt_iterator synthetic_stmt_end() const
Definition: CFG.h:917
AnalysisDeclContext contains the context data for the function or method under analysis.
AnalysisDeclContext * getAnalysisDeclContext() const
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:3637
AnalysisDeclContextManager(bool useUnoptimizedCFG=false, bool addImplicitDtors=false, bool addInitializers=false, bool addTemporaryDtors=false, bool addLifetime=false, bool synthesizeBodies=false, bool addStaticInitBranches=false, bool addCXXNewAllocator=true, CodeInjector *injector=nullptr)
bool synthesizeBodies() const
Return true if faux bodies should be synthesized for well-known functions.
void setParent(const Stmt *S, const Stmt *Parent)
Manually sets the parent of S to Parent.
Definition: ParentMap.cpp:115
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
Definition: DeclBase.cpp:1642
static bool isInStdNamespace(const Decl *D)
Returns true if the root namespace of the given declaration is the 'std' C++ namespace.
const LangOptions & getLangOpts() const
Definition: ASTContext.h:659
llvm::DenseMap< const void *, ManagedAnalysis * > ManagedAnalysisMap
CFGReverseBlockReachabilityAnalysis * getCFGReachablityAnalysis()
CFGCallback * Observer
Definition: CFG.h:791
child_range children()
Definition: Stmt.cpp:208
semantics_iterator semantics_end()
Definition: Expr.h:5012
bool isParentOf(const LocationContext *LC) const
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:39
const Decl * getDecl() const
void clear()
Discard all previously created LocationContext objects.
detail::InMemoryDirectory::const_iterator I
ForcedBlkExprs ** forcedBlkExprs
Definition: CFG.h:790
CFGBlock - Represents a single basic block in a source-level CFG.
Definition: CFG.h:377
Stmt * getBody() const
Get the body of the Declaration.
AnalysisDeclContext * getContext(const Decl *D)
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
Definition: Decl.h:3557
Expr - This represents one expression.
Definition: Expr.h:105
CFG - Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
Definition: CFG.h:780
void Profile(llvm::FoldingSetNodeID &ID) override
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:4820
DeclContext * getDeclContext()
Definition: DeclBase.h:416
bool inTopFrame() const override
Return true if the current LocationContext has no caller context.
const CFGBlock * getBlockForRegisteredExpression(const Stmt *stmt)
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1294
const ScopeContext * getScope(AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s)
const StackFrameContext * getStackFrame(LocationContext const *Parent, const Stmt *S, const CFGBlock *Blk, unsigned Idx)
ValueDecl * getDecl()
Definition: Expr.h:1038
const StackFrameContext * getStackFrame(AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s, const CFGBlock *blk, unsigned idx)
CFG * getUnoptimizedCFG()
Return a version of the CFG without any edges pruned.
llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator
Definition: CFG.h:904
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
Definition: Expr.h:865
#define false
Definition: stdbool.h:33
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:4938
Stmt * getParent(Stmt *) const
Definition: ParentMap.cpp:122
const StackFrameContext * getCurrentStackFrame() const
bool isValid() const
Return true if this is a valid SourceLocation object.
const std::string ID
static std::unique_ptr< CFG > buildCFG(const Decl *D, Stmt *AST, ASTContext *C, const BuildOptions &BO)
buildCFG - Builds a CFG from an AST.
Definition: CFG.cpp:4016
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:346
bool PruneTriviallyFalseEdges
Definition: CFG.h:792
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1903
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:178
const Decl * getDecl() const
const BlockDecl * getBlockDecl() const
Definition: Expr.h:4834
void push_back(const_reference Elt, BumpVectorContext &C)
Definition: BumpVector.h:154
const LocationContext * getParent() const
CFG::BuildOptions & getCFGBuildOptions()
Return the build options used to construct the CFG.
static CFGStmtMap * Build(CFG *C, ParentMap *PM)
Returns a new CFGMap for the given CFG.
Definition: CFGStmtMap.cpp:78
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1215
CodeInjector is an interface which is responsible for injecting AST of function definitions that may ...
Definition: CodeInjector.h:36
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
detail::InMemoryDirectory::const_iterator E
bool isBodyAutosynthesizedFromModelFile() const
Checks if the body of the Decl is generated by the BodyFarm from a model file.
semantics_iterator semantics_begin()
Definition: Expr.h:5006
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition: DeclCXX.h:1102
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
Definition: CFG.h:789
static bool isSelfDecl(const VarDecl *VD)
Returns true if.
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
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...
PseudoConstantAnalysis * getPseudoConstantAnalysis()
const BlockInvocationContext * getBlockInvocationContext(AnalysisDeclContext *ctx, const LocationContext *parent, const BlockDecl *BD, const void *ContextData)
Represents a C++ struct/union/class.
Definition: DeclCXX.h:267
void registerForcedBlockExpression(const Stmt *stmt)
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:953
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
Definition: CFG.h:912
const BlockInvocationContext * getBlockInvocationContext(const LocationContext *parent, const BlockDecl *BD, const void *ContextData)
void clear()
Discard all previously created AnalysisDeclContexts.
SourceLocation getLocStart() const LLVM_READONLY
Definition: Stmt.cpp:257
void dump(const LangOptions &LO, bool ShowColors) const
dump - A simple pretty printer of a CFG that outputs to stderr.
Definition: CFG.cpp:4662
Declaration of a template function.
Definition: DeclTemplate.h:939
static BodyFarm & getBodyFarm(ASTContext &C, CodeInjector *injector=nullptr)
AnalysisDeclContext(AnalysisDeclContextManager *Mgr, const Decl *D)
static void ProfileCommon(llvm::FoldingSetNodeID &ID, ContextKind ck, AnalysisDeclContext *ctx, const LocationContext *parent, const void *data)
unsigned Indent
The current line's indent.