clang  9.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 = llvm::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 Idx) {
314  return getLocationContextManager().getStackFrame(this, Parent, S, Blk, Idx);
315 }
316 
319  const BlockDecl *BD,
320  const void *ContextData) {
321  return getLocationContextManager().getBlockInvocationContext(this, parent,
322  BD, ContextData);
323 }
324 
327  const auto *ND = dyn_cast<NamespaceDecl>(DC);
328  if (!ND)
329  return false;
330 
331  while (const DeclContext *Parent = ND->getParent()) {
332  if (!isa<NamespaceDecl>(Parent))
333  break;
334  ND = cast<NamespaceDecl>(Parent);
335  }
336 
337  return ND->isStdNamespace();
338 }
339 
340 LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
341  assert(Manager &&
342  "Cannot create LocationContexts without an AnalysisDeclContextManager!");
343  return Manager->getLocationContextManager();
344 }
345 
346 //===----------------------------------------------------------------------===//
347 // FoldingSet profiling.
348 //===----------------------------------------------------------------------===//
349 
350 void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
351  ContextKind ck,
352  AnalysisDeclContext *ctx,
353  const LocationContext *parent,
354  const void *data) {
355  ID.AddInteger(ck);
356  ID.AddPointer(ctx);
357  ID.AddPointer(parent);
358  ID.AddPointer(data);
359 }
360 
361 void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
362  Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block, Index);
363 }
364 
365 void ScopeContext::Profile(llvm::FoldingSetNodeID &ID) {
366  Profile(ID, getAnalysisDeclContext(), getParent(), Enter);
367 }
368 
369 void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
370  Profile(ID, getAnalysisDeclContext(), getParent(), BD, ContextData);
371 }
372 
373 //===----------------------------------------------------------------------===//
374 // LocationContext creation.
375 //===----------------------------------------------------------------------===//
376 
377 template <typename LOC, typename DATA>
378 const LOC*
379 LocationContextManager::getLocationContext(AnalysisDeclContext *ctx,
380  const LocationContext *parent,
381  const DATA *d) {
382  llvm::FoldingSetNodeID ID;
383  LOC::Profile(ID, ctx, parent, d);
384  void *InsertPos;
385 
386  LOC *L = cast_or_null<LOC>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
387 
388  if (!L) {
389  L = new LOC(ctx, parent, d, ++NewID);
390  Contexts.InsertNode(L, InsertPos);
391  }
392  return L;
393 }
394 
395 const StackFrameContext*
397  const LocationContext *parent,
398  const Stmt *s,
399  const CFGBlock *blk, unsigned idx) {
400  llvm::FoldingSetNodeID ID;
401  StackFrameContext::Profile(ID, ctx, parent, s, blk, idx);
402  void *InsertPos;
403  auto *L =
404  cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
405  if (!L) {
406  L = new StackFrameContext(ctx, parent, s, blk, idx, ++NewID);
407  Contexts.InsertNode(L, InsertPos);
408  }
409  return L;
410 }
411 
412 const ScopeContext *
414  const LocationContext *parent,
415  const Stmt *s) {
416  return getLocationContext<ScopeContext, Stmt>(ctx, parent, s);
417 }
418 
421  const LocationContext *parent,
422  const BlockDecl *BD,
423  const void *ContextData) {
424  llvm::FoldingSetNodeID ID;
425  BlockInvocationContext::Profile(ID, ctx, parent, BD, ContextData);
426  void *InsertPos;
427  auto *L =
428  cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
429  InsertPos));
430  if (!L) {
431  L = new BlockInvocationContext(ctx, parent, BD, ContextData, ++NewID);
432  Contexts.InsertNode(L, InsertPos);
433  }
434  return L;
435 }
436 
437 //===----------------------------------------------------------------------===//
438 // LocationContext methods.
439 //===----------------------------------------------------------------------===//
440 
442  const LocationContext *LC = this;
443  while (LC) {
444  if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
445  return SFC;
446  LC = LC->getParent();
447  }
448  return nullptr;
449 }
450 
452  return getStackFrame()->inTopFrame();
453 }
454 
456  do {
457  const LocationContext *Parent = LC->getParent();
458  if (Parent == this)
459  return true;
460  else
461  LC = Parent;
462  } while (LC);
463 
464  return false;
465 }
466 
467 static void printLocation(raw_ostream &Out, const SourceManager &SM,
468  SourceLocation Loc) {
469  if (Loc.isFileID() && SM.isInMainFile(Loc))
470  Out << SM.getExpansionLineNumber(Loc);
471  else
472  Loc.print(Out, SM);
473 }
474 
475 void LocationContext::dumpStack(raw_ostream &Out, const char *NL,
476  std::function<void(const LocationContext *)>
477  printMoreInfoPerContext) const {
478  ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
479  PrintingPolicy PP(Ctx.getLangOpts());
480  PP.TerseOutput = 1;
481 
482  const SourceManager &SM =
483  getAnalysisDeclContext()->getASTContext().getSourceManager();
484 
485  unsigned Frame = 0;
486  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
487  switch (LCtx->getKind()) {
488  case StackFrame:
489  Out << "\t#" << Frame << ' ';
490  ++Frame;
491  if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
492  Out << "Calling " << D->getQualifiedNameAsString();
493  else
494  Out << "Calling anonymous code";
495  if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
496  Out << " at line ";
497  printLocation(Out, SM, S->getBeginLoc());
498  }
499  break;
500  case Scope:
501  Out << "Entering scope";
502  break;
503  case Block:
504  Out << "Invoking block";
505  if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
506  Out << " defined at line ";
507  printLocation(Out, SM, D->getBeginLoc());
508  }
509  break;
510  }
511  Out << NL;
512 
513  printMoreInfoPerContext(LCtx);
514  }
515 }
516 
517 void LocationContext::printJson(raw_ostream &Out, const char *NL,
518  unsigned int Space, bool IsDot,
519  std::function<void(const LocationContext *)>
520  printMoreInfoPerContext) const {
521  ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
522  PrintingPolicy PP(Ctx.getLangOpts());
523  PP.TerseOutput = 1;
524 
525  const SourceManager &SM =
526  getAnalysisDeclContext()->getASTContext().getSourceManager();
527 
528  unsigned Frame = 0;
529  for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
530  Indent(Out, Space, IsDot)
531  << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
532  switch (LCtx->getKind()) {
533  case StackFrame:
534  Out << '#' << Frame << " Call\", \"calling\": \"";
535  ++Frame;
536  if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
537  Out << D->getQualifiedNameAsString();
538  else
539  Out << "anonymous code";
540 
541  Out << "\", \"location\": ";
542  if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
543  printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
544  } else {
545  Out << "null";
546  }
547 
548  Out << ", \"items\": ";
549  break;
550  case Scope:
551  Out << "Entering scope\" ";
552  break;
553  case Block:
554  Out << "Invoking block\" ";
555  if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
556  Out << ", \"location\": ";
557  printSourceLocationAsJson(Out, D->getBeginLoc(), SM);
558  Out << ' ';
559  }
560  break;
561  }
562 
563  printMoreInfoPerContext(LCtx);
564 
565  Out << '}';
566  if (LCtx->getParent())
567  Out << ',';
568  Out << NL;
569  }
570 }
571 
572 LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); }
573 
574 //===----------------------------------------------------------------------===//
575 // Lazily generated map to query the external variables referenced by a Block.
576 //===----------------------------------------------------------------------===//
577 
578 namespace {
579 
580 class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
582  BumpVectorContext &BC;
583  llvm::SmallPtrSet<const VarDecl *, 4> Visited;
584  llvm::SmallPtrSet<const DeclContext *, 4> IgnoredContexts;
585 
586 public:
587  FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
588  BumpVectorContext &bc)
589  : BEVals(bevals), BC(bc) {}
590 
591  void VisitStmt(Stmt *S) {
592  for (auto *Child : S->children())
593  if (Child)
594  Visit(Child);
595  }
596 
597  void VisitDeclRefExpr(DeclRefExpr *DR) {
598  // Non-local variables are also directly modified.
599  if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
600  if (!VD->hasLocalStorage()) {
601  if (Visited.insert(VD).second)
602  BEVals.push_back(VD, BC);
603  }
604  }
605  }
606 
607  void VisitBlockExpr(BlockExpr *BR) {
608  // Blocks containing blocks can transitively capture more variables.
609  IgnoredContexts.insert(BR->getBlockDecl());
610  Visit(BR->getBlockDecl()->getBody());
611  }
612 
613  void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
615  et = PE->semantics_end(); it != et; ++it) {
616  Expr *Semantic = *it;
617  if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
618  Semantic = OVE->getSourceExpr();
619  Visit(Semantic);
620  }
621  }
622 };
623 
624 } // namespace
625 
627 
629  void *&Vec,
630  llvm::BumpPtrAllocator &A) {
631  if (Vec)
632  return (DeclVec*) Vec;
633 
634  BumpVectorContext BC(A);
635  DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
636  new (BV) DeclVec(BC, 10);
637 
638  // Go through the capture list.
639  for (const auto &CI : BD->captures()) {
640  BV->push_back(CI.getVariable(), BC);
641  }
642 
643  // Find the referenced global/static variables.
644  FindBlockDeclRefExprsVals F(*BV, BC);
645  F.Visit(BD->getBody());
646 
647  Vec = BV;
648  return BV;
649 }
650 
651 llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
653  if (!ReferencedBlockVars)
654  ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
655 
656  const DeclVec *V =
657  LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
658  return llvm::make_range(V->begin(), V->end());
659 }
660 
661 ManagedAnalysis *&AnalysisDeclContext::getAnalysisImpl(const void *tag) {
662  if (!ManagedAnalyses)
663  ManagedAnalyses = new ManagedAnalysisMap();
664  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
665  return (*M)[tag];
666 }
667 
668 //===----------------------------------------------------------------------===//
669 // Cleanup.
670 //===----------------------------------------------------------------------===//
671 
673 
675  delete forcedBlkExprs;
676  delete ReferencedBlockVars;
677  // Release the managed analyses.
678  if (ManagedAnalyses) {
679  ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
680  llvm::DeleteContainerSeconds(*M);
681  delete M;
682  }
683 }
684 
686 
688  clear();
689 }
690 
692  for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
693  E = Contexts.end(); I != E; ) {
694  LocationContext *LC = &*I;
695  ++I;
696  delete LC;
697  }
698  Contexts.clear();
699 }
Defines the clang::ASTContext interface.
const BlockDecl * getBlockDecl() const
Definition: Expr.h:5555
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:5729
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:1253
bool AddStaticInitBranches
Definition: CFG.h:1057
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
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:154
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:263
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:3994
c
Definition: emmintrin.h:306
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:1755
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:1048
child_range children()
Definition: Stmt.cpp:212
virtual bool inTopFrame() const
Return true if the current LocationContext has no caller context.
semantics_iterator semantics_end()
Definition: Expr.h:5737
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:1198
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:1161
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
Definition: CFG.h:1045
NodeId Parent
Definition: ASTDiff.cpp:191
const StackFrameContext * getStackFrame(AnalysisDeclContext *Ctx, LocationContext const *Parent, const Stmt *S, const CFGBlock *Blk, unsigned Idx)
ForcedBlkExprs ** forcedBlkExprs
Definition: CFG.h:1047
Represents a single basic block in a source-level CFG.
Definition: CFG.h:570
AnalysisDeclContext * getContext(const Decl *D)
__v2du d
Definition: emmintrin.h:413
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:3915
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:1035
BumpVector< const VarDecl * > DeclVec
void Profile(llvm::FoldingSetNodeID &ID) override
#define V(N, I)
Definition: ASTContext.h:2907
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:5541
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)
const StackFrameContext * getStackFrame(LocationContext const *Parent, const Stmt *S, const CFGBlock *Blk, unsigned Idx)
ValueDecl * getDecl()
Definition: Expr.h:1217
CFG::BuildOptions & getCFGBuildOptions()
const StackFrameContext * getStackFrame(AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s, const CFGBlock *blk, unsigned idx)
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
const SourceManager & SM
Definition: Format.cpp:1572
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:5663
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:4788
static void printLocation(raw_ostream &Out, const SourceManager &SM, SourceLocation Loc)
bool PruneTriviallyFalseEdges
Definition: CFG.h:1049
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2114
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:182
bool isStdNamespace() const
Definition: DeclBase.cpp:1066
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:1061
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:4042
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:5731
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:300
bool AddVirtualBaseBranches
Definition: CFG.h:1062
synthetic_stmt_iterator synthetic_stmt_end() const
Definition: CFG.h:1174
bool AddRichCXXConstructors
Definition: CFG.h:1060
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:1169
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:710
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.