clang  3.9.0
CFG.h
Go to the documentation of this file.
1 //===--- CFG.h - Classes for representing and building CFGs------*- 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 the CFG and CFGBuilder classes for representing and
11 // building Control-Flow Graphs (CFGs) from ASTs.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_ANALYSIS_CFG_H
16 #define LLVM_CLANG_ANALYSIS_CFG_H
17 
18 #include "clang/AST/Stmt.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/GraphTraits.h"
23 #include "llvm/ADT/Optional.h"
24 #include "llvm/ADT/PointerIntPair.h"
25 #include "llvm/Support/Allocator.h"
26 #include "llvm/Support/Casting.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include <bitset>
29 #include <cassert>
30 #include <iterator>
31 #include <memory>
32 
33 namespace clang {
34  class CXXDestructorDecl;
35  class Decl;
36  class Stmt;
37  class Expr;
38  class FieldDecl;
39  class VarDecl;
40  class CXXCtorInitializer;
41  class CXXBaseSpecifier;
42  class CXXBindTemporaryExpr;
43  class CFG;
44  class PrinterHelper;
45  class LangOptions;
46  class ASTContext;
47  class CXXRecordDecl;
48  class CXXDeleteExpr;
49  class CXXNewExpr;
50  class BinaryOperator;
51 
52 /// CFGElement - Represents a top-level expression in a basic block.
53 class CFGElement {
54 public:
55  enum Kind {
56  // main kind
60  // dtor kind
68  };
69 
70 protected:
71  // The int bits are used to mark the kind.
72  llvm::PointerIntPair<void *, 2> Data1;
73  llvm::PointerIntPair<void *, 2> Data2;
74 
75  CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr)
76  : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
77  Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
78  assert(getKind() == kind);
79  }
80 
82 public:
83 
84  /// \brief Convert to the specified CFGElement type, asserting that this
85  /// CFGElement is of the desired type.
86  template<typename T>
87  T castAs() const {
88  assert(T::isKind(*this));
89  T t;
90  CFGElement& e = t;
91  e = *this;
92  return t;
93  }
94 
95  /// \brief Convert to the specified CFGElement type, returning None if this
96  /// CFGElement is not of the desired type.
97  template<typename T>
98  Optional<T> getAs() const {
99  if (!T::isKind(*this))
100  return None;
101  T t;
102  CFGElement& e = t;
103  e = *this;
104  return t;
105  }
106 
107  Kind getKind() const {
108  unsigned x = Data2.getInt();
109  x <<= 2;
110  x |= Data1.getInt();
111  return (Kind) x;
112  }
113 };
114 
115 class CFGStmt : public CFGElement {
116 public:
118 
119  const Stmt *getStmt() const {
120  return static_cast<const Stmt *>(Data1.getPointer());
121  }
122 
123 private:
124  friend class CFGElement;
125  CFGStmt() {}
126  static bool isKind(const CFGElement &E) {
127  return E.getKind() == Statement;
128  }
129 };
130 
131 /// CFGInitializer - Represents C++ base or member initializer from
132 /// constructor's initialization list.
133 class CFGInitializer : public CFGElement {
134 public:
136  : CFGElement(Initializer, initializer) {}
137 
139  return static_cast<CXXCtorInitializer*>(Data1.getPointer());
140  }
141 
142 private:
143  friend class CFGElement;
144  CFGInitializer() {}
145  static bool isKind(const CFGElement &E) {
146  return E.getKind() == Initializer;
147  }
148 };
149 
150 /// CFGNewAllocator - Represents C++ allocator call.
151 class CFGNewAllocator : public CFGElement {
152 public:
153  explicit CFGNewAllocator(const CXXNewExpr *S)
154  : CFGElement(NewAllocator, S) {}
155 
156  // Get the new expression.
157  const CXXNewExpr *getAllocatorExpr() const {
158  return static_cast<CXXNewExpr *>(Data1.getPointer());
159  }
160 
161 private:
162  friend class CFGElement;
163  CFGNewAllocator() {}
164  static bool isKind(const CFGElement &elem) {
165  return elem.getKind() == NewAllocator;
166  }
167 };
168 
169 /// CFGImplicitDtor - Represents C++ object destructor implicitly generated
170 /// by compiler on various occasions.
171 class CFGImplicitDtor : public CFGElement {
172 protected:
174  CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr)
175  : CFGElement(kind, data1, data2) {
176  assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
177  }
178 
179 public:
180  const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const;
181  bool isNoReturn(ASTContext &astContext) const;
182 
183 private:
184  friend class CFGElement;
185  static bool isKind(const CFGElement &E) {
186  Kind kind = E.getKind();
187  return kind >= DTOR_BEGIN && kind <= DTOR_END;
188  }
189 };
190 
191 /// CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated
192 /// for automatic object or temporary bound to const reference at the point
193 /// of leaving its local scope.
195 public:
196  CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt)
197  : CFGImplicitDtor(AutomaticObjectDtor, var, stmt) {}
198 
199  const VarDecl *getVarDecl() const {
200  return static_cast<VarDecl*>(Data1.getPointer());
201  }
202 
203  // Get statement end of which triggered the destructor call.
204  const Stmt *getTriggerStmt() const {
205  return static_cast<Stmt*>(Data2.getPointer());
206  }
207 
208 private:
209  friend class CFGElement;
211  static bool isKind(const CFGElement &elem) {
212  return elem.getKind() == AutomaticObjectDtor;
213  }
214 };
215 
216 /// CFGDeleteDtor - Represents C++ object destructor generated
217 /// from a call to delete.
219 public:
221  : CFGImplicitDtor(DeleteDtor, RD, DE) {}
222 
224  return static_cast<CXXRecordDecl*>(Data1.getPointer());
225  }
226 
227  // Get Delete expression which triggered the destructor call.
228  const CXXDeleteExpr *getDeleteExpr() const {
229  return static_cast<CXXDeleteExpr *>(Data2.getPointer());
230  }
231 
232 private:
233  friend class CFGElement;
234  CFGDeleteDtor() {}
235  static bool isKind(const CFGElement &elem) {
236  return elem.getKind() == DeleteDtor;
237  }
238 };
239 
240 /// CFGBaseDtor - Represents C++ object destructor implicitly generated for
241 /// base object in destructor.
242 class CFGBaseDtor : public CFGImplicitDtor {
243 public:
245  : CFGImplicitDtor(BaseDtor, base) {}
246 
248  return static_cast<const CXXBaseSpecifier*>(Data1.getPointer());
249  }
250 
251 private:
252  friend class CFGElement;
253  CFGBaseDtor() {}
254  static bool isKind(const CFGElement &E) {
255  return E.getKind() == BaseDtor;
256  }
257 };
258 
259 /// CFGMemberDtor - Represents C++ object destructor implicitly generated for
260 /// member object in destructor.
262 public:
263  CFGMemberDtor(const FieldDecl *field)
264  : CFGImplicitDtor(MemberDtor, field, nullptr) {}
265 
266  const FieldDecl *getFieldDecl() const {
267  return static_cast<const FieldDecl*>(Data1.getPointer());
268  }
269 
270 private:
271  friend class CFGElement;
272  CFGMemberDtor() {}
273  static bool isKind(const CFGElement &E) {
274  return E.getKind() == MemberDtor;
275  }
276 };
277 
278 /// CFGTemporaryDtor - Represents C++ object destructor implicitly generated
279 /// at the end of full expression for temporary object.
281 public:
283  : CFGImplicitDtor(TemporaryDtor, expr, nullptr) {}
284 
286  return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer());
287  }
288 
289 private:
290  friend class CFGElement;
291  CFGTemporaryDtor() {}
292  static bool isKind(const CFGElement &E) {
293  return E.getKind() == TemporaryDtor;
294  }
295 };
296 
297 /// CFGTerminator - Represents CFGBlock terminator statement.
298 ///
299 /// TemporaryDtorsBranch bit is set to true if the terminator marks a branch
300 /// in control flow of destructors of temporaries. In this case terminator
301 /// statement is the same statement that branches control flow in evaluation
302 /// of matching full expression.
304  llvm::PointerIntPair<Stmt *, 1> Data;
305 public:
307  CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false)
308  : Data(S, TemporaryDtorsBranch) {}
309 
310  Stmt *getStmt() { return Data.getPointer(); }
311  const Stmt *getStmt() const { return Data.getPointer(); }
312 
313  bool isTemporaryDtorsBranch() const { return Data.getInt(); }
314 
315  operator Stmt *() { return getStmt(); }
316  operator const Stmt *() const { return getStmt(); }
317 
318  Stmt *operator->() { return getStmt(); }
319  const Stmt *operator->() const { return getStmt(); }
320 
321  Stmt &operator*() { return *getStmt(); }
322  const Stmt &operator*() const { return *getStmt(); }
323 
324  explicit operator bool() const { return getStmt(); }
325 };
326 
327 /// CFGBlock - Represents a single basic block in a source-level CFG.
328 /// It consists of:
329 ///
330 /// (1) A set of statements/expressions (which may contain subexpressions).
331 /// (2) A "terminator" statement (not in the set of statements).
332 /// (3) A list of successors and predecessors.
333 ///
334 /// Terminator: The terminator represents the type of control-flow that occurs
335 /// at the end of the basic block. The terminator is a Stmt* referring to an
336 /// AST node that has control-flow: if-statements, breaks, loops, etc.
337 /// If the control-flow is conditional, the condition expression will appear
338 /// within the set of statements in the block (usually the last statement).
339 ///
340 /// Predecessors: the order in the set of predecessors is arbitrary.
341 ///
342 /// Successors: the order in the set of successors is NOT arbitrary. We
343 /// currently have the following orderings based on the terminator:
344 ///
345 /// Terminator Successor Ordering
346 /// -----------------------------------------------------
347 /// if Then Block; Else Block
348 /// ? operator LHS expression; RHS expression
349 /// &&, || expression that uses result of && or ||, RHS
350 ///
351 /// But note that any of that may be NULL in case of optimized-out edges.
352 ///
353 class CFGBlock {
354  class ElementList {
355  typedef BumpVector<CFGElement> ImplTy;
356  ImplTy Impl;
357  public:
358  ElementList(BumpVectorContext &C) : Impl(C, 4) {}
359 
360  typedef std::reverse_iterator<ImplTy::iterator> iterator;
361  typedef std::reverse_iterator<ImplTy::const_iterator> const_iterator;
364  typedef ImplTy::const_reference const_reference;
365 
366  void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); }
367  reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E,
368  BumpVectorContext &C) {
369  return Impl.insert(I, Cnt, E, C);
370  }
371 
372  const_reference front() const { return Impl.back(); }
373  const_reference back() const { return Impl.front(); }
374 
375  iterator begin() { return Impl.rbegin(); }
376  iterator end() { return Impl.rend(); }
377  const_iterator begin() const { return Impl.rbegin(); }
378  const_iterator end() const { return Impl.rend(); }
379  reverse_iterator rbegin() { return Impl.begin(); }
380  reverse_iterator rend() { return Impl.end(); }
381  const_reverse_iterator rbegin() const { return Impl.begin(); }
382  const_reverse_iterator rend() const { return Impl.end(); }
383 
384  CFGElement operator[](size_t i) const {
385  assert(i < Impl.size());
386  return Impl[Impl.size() - 1 - i];
387  }
388 
389  size_t size() const { return Impl.size(); }
390  bool empty() const { return Impl.empty(); }
391  };
392 
393  /// Stmts - The set of statements in the basic block.
394  ElementList Elements;
395 
396  /// Label - An (optional) label that prefixes the executable
397  /// statements in the block. When this variable is non-NULL, it is
398  /// either an instance of LabelStmt, SwitchCase or CXXCatchStmt.
399  Stmt *Label;
400 
401  /// Terminator - The terminator for a basic block that
402  /// indicates the type of control-flow that occurs between a block
403  /// and its successors.
404  CFGTerminator Terminator;
405 
406  /// LoopTarget - Some blocks are used to represent the "loop edge" to
407  /// the start of a loop from within the loop body. This Stmt* will be
408  /// refer to the loop statement for such blocks (and be null otherwise).
409  const Stmt *LoopTarget;
410 
411  /// BlockID - A numerical ID assigned to a CFGBlock during construction
412  /// of the CFG.
413  unsigned BlockID;
414 
415 public:
416  /// This class represents a potential adjacent block in the CFG. It encodes
417  /// whether or not the block is actually reachable, or can be proved to be
418  /// trivially unreachable. For some cases it allows one to encode scenarios
419  /// where a block was substituted because the original (now alternate) block
420  /// is unreachable.
422  enum Kind {
423  AB_Normal,
424  AB_Unreachable,
425  AB_Alternate
426  };
427 
428  CFGBlock *ReachableBlock;
429  llvm::PointerIntPair<CFGBlock*, 2> UnreachableBlock;
430 
431  public:
432  /// Construct an AdjacentBlock with a possibly unreachable block.
433  AdjacentBlock(CFGBlock *B, bool IsReachable);
434 
435  /// Construct an AdjacentBlock with a reachable block and an alternate
436  /// unreachable block.
437  AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock);
438 
439  /// Get the reachable block, if one exists.
441  return ReachableBlock;
442  }
443 
444  /// Get the potentially unreachable block.
446  return UnreachableBlock.getPointer();
447  }
448 
449  /// Provide an implicit conversion to CFGBlock* so that
450  /// AdjacentBlock can be substituted for CFGBlock*.
451  operator CFGBlock*() const {
452  return getReachableBlock();
453  }
454 
455  CFGBlock& operator *() const {
456  return *getReachableBlock();
457  }
458 
460  return getReachableBlock();
461  }
462 
463  bool isReachable() const {
464  Kind K = (Kind) UnreachableBlock.getInt();
465  return K == AB_Normal || K == AB_Alternate;
466  }
467  };
468 
469 private:
470  /// Predecessors/Successors - Keep track of the predecessor / successor
471  /// CFG blocks.
472  typedef BumpVector<AdjacentBlock> AdjacentBlocks;
473  AdjacentBlocks Preds;
474  AdjacentBlocks Succs;
475 
476  /// NoReturn - This bit is set when the basic block contains a function call
477  /// or implicit destructor that is attributed as 'noreturn'. In that case,
478  /// control cannot technically ever proceed past this block. All such blocks
479  /// will have a single immediate successor: the exit block. This allows them
480  /// to be easily reached from the exit block and using this bit quickly
481  /// recognized without scanning the contents of the block.
482  ///
483  /// Optimization Note: This bit could be profitably folded with Terminator's
484  /// storage if the memory usage of CFGBlock becomes an issue.
485  unsigned HasNoReturnElement : 1;
486 
487  /// Parent - The parent CFG that owns this CFGBlock.
488  CFG *Parent;
489 
490 public:
491  explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
492  : Elements(C), Label(nullptr), Terminator(nullptr), LoopTarget(nullptr),
493  BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false),
494  Parent(parent) {}
495 
496  // Statement iterators
497  typedef ElementList::iterator iterator;
498  typedef ElementList::const_iterator const_iterator;
501 
502  CFGElement front() const { return Elements.front(); }
503  CFGElement back() const { return Elements.back(); }
504 
505  iterator begin() { return Elements.begin(); }
506  iterator end() { return Elements.end(); }
507  const_iterator begin() const { return Elements.begin(); }
508  const_iterator end() const { return Elements.end(); }
509 
510  reverse_iterator rbegin() { return Elements.rbegin(); }
511  reverse_iterator rend() { return Elements.rend(); }
512  const_reverse_iterator rbegin() const { return Elements.rbegin(); }
513  const_reverse_iterator rend() const { return Elements.rend(); }
514 
515  unsigned size() const { return Elements.size(); }
516  bool empty() const { return Elements.empty(); }
517 
518  CFGElement operator[](size_t i) const { return Elements[i]; }
519 
520  // CFG iterators
525 
530 
531  pred_iterator pred_begin() { return Preds.begin(); }
532  pred_iterator pred_end() { return Preds.end(); }
533  const_pred_iterator pred_begin() const { return Preds.begin(); }
534  const_pred_iterator pred_end() const { return Preds.end(); }
535 
537  pred_reverse_iterator pred_rend() { return Preds.rend(); }
538  const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); }
539  const_pred_reverse_iterator pred_rend() const { return Preds.rend(); }
540 
541  succ_iterator succ_begin() { return Succs.begin(); }
542  succ_iterator succ_end() { return Succs.end(); }
543  const_succ_iterator succ_begin() const { return Succs.begin(); }
544  const_succ_iterator succ_end() const { return Succs.end(); }
545 
547  succ_reverse_iterator succ_rend() { return Succs.rend(); }
548  const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); }
549  const_succ_reverse_iterator succ_rend() const { return Succs.rend(); }
550 
551  unsigned succ_size() const { return Succs.size(); }
552  bool succ_empty() const { return Succs.empty(); }
553 
554  unsigned pred_size() const { return Preds.size(); }
555  bool pred_empty() const { return Preds.empty(); }
556 
557 
559  public:
563  }
564 
567  };
568 
569  static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src,
570  const CFGBlock *Dst);
571 
572  template <typename IMPL, bool IsPred>
574  private:
575  IMPL I, E;
576  const FilterOptions F;
577  const CFGBlock *From;
578  public:
579  explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e,
580  const CFGBlock *from,
581  const FilterOptions &f)
582  : I(i), E(e), F(f), From(from) {
583  while (hasMore() && Filter(*I))
584  ++I;
585  }
586 
587  bool hasMore() const { return I != E; }
588 
590  do { ++I; } while (hasMore() && Filter(*I));
591  return *this;
592  }
593 
594  const CFGBlock *operator*() const { return *I; }
595  private:
596  bool Filter(const CFGBlock *To) {
597  return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To);
598  }
599  };
600 
601  typedef FilteredCFGBlockIterator<const_pred_iterator, true>
603 
606 
608  return filtered_pred_iterator(pred_begin(), pred_end(), this, f);
609  }
610 
612  return filtered_succ_iterator(succ_begin(), succ_end(), this, f);
613  }
614 
615  // Manipulation of block contents
616 
617  void setTerminator(CFGTerminator Term) { Terminator = Term; }
618  void setLabel(Stmt *Statement) { Label = Statement; }
619  void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
620  void setHasNoReturnElement() { HasNoReturnElement = true; }
621 
622  CFGTerminator getTerminator() { return Terminator; }
623  const CFGTerminator getTerminator() const { return Terminator; }
624 
625  Stmt *getTerminatorCondition(bool StripParens = true);
626 
627  const Stmt *getTerminatorCondition(bool StripParens = true) const {
628  return const_cast<CFGBlock*>(this)->getTerminatorCondition(StripParens);
629  }
630 
631  const Stmt *getLoopTarget() const { return LoopTarget; }
632 
633  Stmt *getLabel() { return Label; }
634  const Stmt *getLabel() const { return Label; }
635 
636  bool hasNoReturnElement() const { return HasNoReturnElement; }
637 
638  unsigned getBlockID() const { return BlockID; }
639 
640  CFG *getParent() const { return Parent; }
641 
642  void dump() const;
643 
644  void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const;
645  void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO,
646  bool ShowColors) const;
647  void printTerminator(raw_ostream &OS, const LangOptions &LO) const;
648  void printAsOperand(raw_ostream &OS, bool /*PrintType*/) {
649  OS << "BB#" << getBlockID();
650  }
651 
652  /// Adds a (potentially unreachable) successor block to the current block.
653  void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C);
654 
655  void appendStmt(Stmt *statement, BumpVectorContext &C) {
656  Elements.push_back(CFGStmt(statement), C);
657  }
658 
660  BumpVectorContext &C) {
661  Elements.push_back(CFGInitializer(initializer), C);
662  }
663 
665  BumpVectorContext &C) {
666  Elements.push_back(CFGNewAllocator(NE), C);
667  }
668 
670  Elements.push_back(CFGBaseDtor(BS), C);
671  }
672 
674  Elements.push_back(CFGMemberDtor(FD), C);
675  }
676 
678  Elements.push_back(CFGTemporaryDtor(E), C);
679  }
680 
682  Elements.push_back(CFGAutomaticObjDtor(VD, S), C);
683  }
684 
686  Elements.push_back(CFGDeleteDtor(RD, DE), C);
687  }
688 
689  // Destructors must be inserted in reversed order. So insertion is in two
690  // steps. First we prepare space for some number of elements, then we insert
691  // the elements beginning at the last position in prepared space.
693  BumpVectorContext &C) {
694  return iterator(Elements.insert(I.base(), Cnt,
695  CFGAutomaticObjDtor(nullptr, nullptr), C));
696  }
698  *I = CFGAutomaticObjDtor(VD, S);
699  return ++I;
700  }
701 };
702 
703 /// \brief CFGCallback defines methods that should be called when a logical
704 /// operator error is found when building the CFG.
705 class CFGCallback {
706 public:
708  virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {}
709  virtual void compareBitwiseEquality(const BinaryOperator *B,
710  bool isAlwaysTrue) {}
711  virtual ~CFGCallback() {}
712 };
713 
714 /// CFG - Represents a source-level, intra-procedural CFG that represents the
715 /// control-flow of a Stmt. The Stmt can represent an entire function body,
716 /// or a single expression. A CFG will always contain one empty block that
717 /// represents the Exit point of the CFG. A CFG will also contain a designated
718 /// Entry block. The CFG solely represents control-flow; it consists of
719 /// CFGBlocks which are simply containers of Stmt*'s in the AST the CFG
720 /// was constructed from.
721 class CFG {
722 public:
723  //===--------------------------------------------------------------------===//
724  // CFG Construction & Manipulation.
725  //===--------------------------------------------------------------------===//
726 
727  class BuildOptions {
728  std::bitset<Stmt::lastStmtConstant> alwaysAddMask;
729  public:
730  typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs;
741 
742  bool alwaysAdd(const Stmt *stmt) const {
743  return alwaysAddMask[stmt->getStmtClass()];
744  }
745 
746  BuildOptions &setAlwaysAdd(Stmt::StmtClass stmtClass, bool val = true) {
747  alwaysAddMask[stmtClass] = val;
748  return *this;
749  }
750 
752  alwaysAddMask.set();
753  return *this;
754  }
755 
757  : forcedBlkExprs(nullptr), Observer(nullptr),
762  };
763 
764  /// \brief Provides a custom implementation of the iterator class to have the
765  /// same interface as Function::iterator - iterator returns CFGBlock
766  /// (not a pointer to CFGBlock).
768  public:
771  typedef value_type* pointer;
773 
774  graph_iterator(const ImplTy &i) : I(i) {}
775 
776  bool operator==(const graph_iterator &X) const { return I == X.I; }
777  bool operator!=(const graph_iterator &X) const { return I != X.I; }
778 
779  reference operator*() const { return **I; }
780  pointer operator->() const { return *I; }
781  operator CFGBlock* () { return *I; }
782 
783  graph_iterator &operator++() { ++I; return *this; }
784  graph_iterator &operator--() { --I; return *this; }
785 
786  private:
787  ImplTy I;
788  };
789 
791  public:
792  typedef const CFGBlock value_type;
794  typedef value_type* pointer;
796 
797  const_graph_iterator(const ImplTy &i) : I(i) {}
798 
799  bool operator==(const const_graph_iterator &X) const { return I == X.I; }
800  bool operator!=(const const_graph_iterator &X) const { return I != X.I; }
801 
802  reference operator*() const { return **I; }
803  pointer operator->() const { return *I; }
804  operator CFGBlock* () const { return *I; }
805 
806  const_graph_iterator &operator++() { ++I; return *this; }
807  const_graph_iterator &operator--() { --I; return *this; }
808 
809  private:
810  ImplTy I;
811  };
812 
813  /// buildCFG - Builds a CFG from an AST.
814  static std::unique_ptr<CFG> buildCFG(const Decl *D, Stmt *AST, ASTContext *C,
815  const BuildOptions &BO);
816 
817  /// createBlock - Create a new block in the CFG. The CFG owns the block;
818  /// the caller should not directly free it.
820 
821  /// setEntry - Set the entry block of the CFG. This is typically used
822  /// only during CFG construction. Most CFG clients expect that the
823  /// entry block has no predecessors and contains no statements.
824  void setEntry(CFGBlock *B) { Entry = B; }
825 
826  /// setIndirectGotoBlock - Set the block used for indirect goto jumps.
827  /// This is typically used only during CFG construction.
828  void setIndirectGotoBlock(CFGBlock *B) { IndirectGotoBlock = B; }
829 
830  //===--------------------------------------------------------------------===//
831  // Block Iterators
832  //===--------------------------------------------------------------------===//
833 
837  typedef std::reverse_iterator<iterator> reverse_iterator;
838  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
839 
840  CFGBlock & front() { return *Blocks.front(); }
841  CFGBlock & back() { return *Blocks.back(); }
842 
843  iterator begin() { return Blocks.begin(); }
844  iterator end() { return Blocks.end(); }
845  const_iterator begin() const { return Blocks.begin(); }
846  const_iterator end() const { return Blocks.end(); }
847 
849  graph_iterator nodes_end() { return graph_iterator(Blocks.end()); }
851  return const_graph_iterator(Blocks.begin());
852  }
854  return const_graph_iterator(Blocks.end());
855  }
856 
857  reverse_iterator rbegin() { return Blocks.rbegin(); }
858  reverse_iterator rend() { return Blocks.rend(); }
859  const_reverse_iterator rbegin() const { return Blocks.rbegin(); }
860  const_reverse_iterator rend() const { return Blocks.rend(); }
861 
862  CFGBlock & getEntry() { return *Entry; }
863  const CFGBlock & getEntry() const { return *Entry; }
864  CFGBlock & getExit() { return *Exit; }
865  const CFGBlock & getExit() const { return *Exit; }
866 
867  CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; }
868  const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; }
869 
870  typedef std::vector<const CFGBlock*>::const_iterator try_block_iterator;
872  return TryDispatchBlocks.begin();
873  }
875  return TryDispatchBlocks.end();
876  }
877 
878  void addTryDispatchBlock(const CFGBlock *block) {
879  TryDispatchBlocks.push_back(block);
880  }
881 
882  /// Records a synthetic DeclStmt and the DeclStmt it was constructed from.
883  ///
884  /// The CFG uses synthetic DeclStmts when a single AST DeclStmt contains
885  /// multiple decls.
886  void addSyntheticDeclStmt(const DeclStmt *Synthetic,
887  const DeclStmt *Source) {
888  assert(Synthetic->isSingleDecl() && "Can handle single declarations only");
889  assert(Synthetic != Source && "Don't include original DeclStmts in map");
890  assert(!SyntheticDeclStmts.count(Synthetic) && "Already in map");
891  SyntheticDeclStmts[Synthetic] = Source;
892  }
893 
894  typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator
896 
897  /// Iterates over synthetic DeclStmts in the CFG.
898  ///
899  /// Each element is a (synthetic statement, source statement) pair.
900  ///
901  /// \sa addSyntheticDeclStmt
903  return SyntheticDeclStmts.begin();
904  }
905 
906  /// \sa synthetic_stmt_begin
908  return SyntheticDeclStmts.end();
909  }
910 
911  //===--------------------------------------------------------------------===//
912  // Member templates useful for various batch operations over CFGs.
913  //===--------------------------------------------------------------------===//
914 
915  template <typename CALLBACK>
916  void VisitBlockStmts(CALLBACK& O) const {
917  for (const_iterator I=begin(), E=end(); I != E; ++I)
918  for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end();
919  BI != BE; ++BI) {
920  if (Optional<CFGStmt> stmt = BI->getAs<CFGStmt>())
921  O(const_cast<Stmt*>(stmt->getStmt()));
922  }
923  }
924 
925  //===--------------------------------------------------------------------===//
926  // CFG Introspection.
927  //===--------------------------------------------------------------------===//
928 
929  /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which
930  /// start at 0).
931  unsigned getNumBlockIDs() const { return NumBlockIDs; }
932 
933  /// size - Return the total number of CFGBlocks within the CFG
934  /// This is simply a renaming of the getNumBlockIDs(). This is necessary
935  /// because the dominator implementation needs such an interface.
936  unsigned size() const { return NumBlockIDs; }
937 
938  //===--------------------------------------------------------------------===//
939  // CFG Debugging: Pretty-Printing and Visualization.
940  //===--------------------------------------------------------------------===//
941 
942  void viewCFG(const LangOptions &LO) const;
943  void print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const;
944  void dump(const LangOptions &LO, bool ShowColors) const;
945 
946  //===--------------------------------------------------------------------===//
947  // Internal: constructors and data.
948  //===--------------------------------------------------------------------===//
949 
950  CFG()
951  : Entry(nullptr), Exit(nullptr), IndirectGotoBlock(nullptr), NumBlockIDs(0),
952  Blocks(BlkBVC, 10) {}
953 
954  llvm::BumpPtrAllocator& getAllocator() {
955  return BlkBVC.getAllocator();
956  }
957 
959  return BlkBVC;
960  }
961 
962 private:
963  CFGBlock *Entry;
964  CFGBlock *Exit;
965  CFGBlock* IndirectGotoBlock; // Special block to contain collective dispatch
966  // for indirect gotos
967  unsigned NumBlockIDs;
968 
969  BumpVectorContext BlkBVC;
970 
971  CFGBlockListTy Blocks;
972 
973  /// C++ 'try' statements are modeled with an indirect dispatch block.
974  /// This is the collection of such blocks present in the CFG.
975  std::vector<const CFGBlock *> TryDispatchBlocks;
976 
977  /// Collects DeclStmts synthesized for this CFG and maps each one back to its
978  /// source DeclStmt.
979  llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts;
980 };
981 } // end namespace clang
982 
983 //===----------------------------------------------------------------------===//
984 // GraphTraits specializations for CFG basic block graphs (source-level CFGs)
985 //===----------------------------------------------------------------------===//
986 
987 namespace llvm {
988 
989 /// Implement simplify_type for CFGTerminator, so that we can dyn_cast from
990 /// CFGTerminator to a specific Stmt class.
991 template <> struct simplify_type< ::clang::CFGTerminator> {
992  typedef ::clang::Stmt *SimpleType;
994  return Val.getStmt();
995  }
996 };
997 
998 // Traits for: CFGBlock
999 
1000 template <> struct GraphTraits< ::clang::CFGBlock *> {
1001  typedef ::clang::CFGBlock NodeType;
1002  typedef ::clang::CFGBlock::succ_iterator ChildIteratorType;
1003 
1005  { return BB; }
1006 
1008  { return N->succ_begin(); }
1009 
1011  { return N->succ_end(); }
1012 };
1013 
1014 template <> struct GraphTraits< const ::clang::CFGBlock *> {
1015  typedef const ::clang::CFGBlock NodeType;
1016  typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType;
1017 
1018  static NodeType* getEntryNode(const clang::CFGBlock *BB)
1019  { return BB; }
1020 
1021  static inline ChildIteratorType child_begin(NodeType* N)
1022  { return N->succ_begin(); }
1023 
1024  static inline ChildIteratorType child_end(NodeType* N)
1025  { return N->succ_end(); }
1026 };
1027 
1028 template <> struct GraphTraits<Inverse< ::clang::CFGBlock*> > {
1029  typedef ::clang::CFGBlock NodeType;
1030  typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
1031 
1032  static NodeType *getEntryNode(Inverse< ::clang::CFGBlock*> G)
1033  { return G.Graph; }
1034 
1036  { return N->pred_begin(); }
1037 
1039  { return N->pred_end(); }
1040 };
1041 
1042 template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
1043  typedef const ::clang::CFGBlock NodeType;
1044  typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
1045 
1046  static NodeType *getEntryNode(Inverse<const ::clang::CFGBlock*> G)
1047  { return G.Graph; }
1048 
1049  static inline ChildIteratorType child_begin(NodeType* N)
1050  { return N->pred_begin(); }
1051 
1052  static inline ChildIteratorType child_end(NodeType* N)
1053  { return N->pred_end(); }
1054 };
1055 
1056 // Traits for: CFG
1057 
1058 template <> struct GraphTraits< ::clang::CFG* >
1059  : public GraphTraits< ::clang::CFGBlock *> {
1060 
1061  typedef ::clang::CFG::graph_iterator nodes_iterator;
1062 
1063  static NodeType *getEntryNode(::clang::CFG* F) { return &F->getEntry(); }
1064  static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();}
1065  static nodes_iterator nodes_end(::clang::CFG* F) { return F->nodes_end(); }
1066  static unsigned size(::clang::CFG* F) { return F->size(); }
1067 };
1068 
1069 template <> struct GraphTraits<const ::clang::CFG* >
1070  : public GraphTraits<const ::clang::CFGBlock *> {
1071 
1072  typedef ::clang::CFG::const_graph_iterator nodes_iterator;
1073 
1074  static NodeType *getEntryNode( const ::clang::CFG* F) {
1075  return &F->getEntry();
1076  }
1077  static nodes_iterator nodes_begin( const ::clang::CFG* F) {
1078  return F->nodes_begin();
1079  }
1080  static nodes_iterator nodes_end( const ::clang::CFG* F) {
1081  return F->nodes_end();
1082  }
1083  static unsigned size(const ::clang::CFG* F) {
1084  return F->size();
1085  }
1086 };
1087 
1088 template <> struct GraphTraits<Inverse< ::clang::CFG*> >
1089  : public GraphTraits<Inverse< ::clang::CFGBlock*> > {
1090 
1091  typedef ::clang::CFG::graph_iterator nodes_iterator;
1092 
1093  static NodeType *getEntryNode( ::clang::CFG* F) { return &F->getExit(); }
1094  static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();}
1095  static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); }
1096 };
1097 
1098 template <> struct GraphTraits<Inverse<const ::clang::CFG*> >
1099  : public GraphTraits<Inverse<const ::clang::CFGBlock*> > {
1100 
1101  typedef ::clang::CFG::const_graph_iterator nodes_iterator;
1102 
1103  static NodeType *getEntryNode(const ::clang::CFG* F) { return &F->getExit(); }
1104  static nodes_iterator nodes_begin(const ::clang::CFG* F) {
1105  return F->nodes_begin();
1106  }
1107  static nodes_iterator nodes_end(const ::clang::CFG* F) {
1108  return F->nodes_end();
1109  }
1110 };
1111 } // end llvm namespace
1112 
1113 #endif // LLVM_CLANG_ANALYSIS_CFG_H
FilteredCFGBlockIterator< const_pred_iterator, true > filtered_pred_iterator
Definition: CFG.h:602
void setIndirectGotoBlock(CFGBlock *B)
setIndirectGotoBlock - Set the block used for indirect goto jumps.
Definition: CFG.h:828
const_pred_reverse_iterator pred_rend() const
Definition: CFG.h:539
CFGNewAllocator - Represents C++ allocator call.
Definition: CFG.h:151
succ_reverse_iterator succ_rbegin()
Definition: CFG.h:546
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
Definition: ASTMatchers.h:1367
const CXXNewExpr * getAllocatorExpr() const
Definition: CFG.h:157
pred_iterator pred_end()
Definition: CFG.h:532
Stmt * operator->()
Definition: CFG.h:318
CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
Definition: CFG.h:491
CFGElement operator[](size_t i) const
Definition: CFG.h:518
iterator end()
Definition: BumpVector.h:91
ElementList::const_reverse_iterator const_reverse_iterator
Definition: CFG.h:500
iterator begin()
Definition: BumpVector.h:89
succ_iterator succ_begin()
Definition: CFG.h:541
ElementList::reverse_iterator reverse_iterator
Definition: CFG.h:499
reference back()
Definition: BumpVector.h:119
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
Definition: ASTMatchers.h:985
CFGBlock & getEntry()
Definition: CFG.h:862
static NodeType * getEntryNode(Inverse< const ::clang::CFGBlock * > G)
Definition: CFG.h:1046
CFGStmt(Stmt *S)
Definition: CFG.h:117
CFGDeleteDtor(const CXXRecordDecl *RD, const CXXDeleteExpr *DE)
Definition: CFG.h:220
reference operator*() const
Definition: CFG.h:802
CFG * getParent() const
Definition: CFG.h:640
void appendNewAllocator(CXXNewExpr *NE, BumpVectorContext &C)
Definition: CFG.h:664
CFGNewAllocator(const CXXNewExpr *S)
Definition: CFG.h:153
graph_iterator & operator++()
Definition: CFG.h:783
const CFGBlock value_type
Definition: CFG.h:792
CFGBlockListTy::iterator iterator
Definition: CFG.h:835
llvm::BumpPtrAllocator & getAllocator()
Definition: CFG.h:954
bool isReachable() const
Definition: CFG.h:463
const CFGBlock * operator*() const
Definition: CFG.h:594
CFGDeleteDtor - Represents C++ object destructor generated from a call to delete. ...
Definition: CFG.h:218
iterator begin()
Definition: CFG.h:505
static unsigned size(const ::clang::CFG *F)
Definition: CFG.h:1083
const CXXDeleteExpr * getDeleteExpr() const
Definition: CFG.h:228
const CFGBlock & getEntry() const
Definition: CFG.h:863
BumpVector< CFGBlock * >::const_iterator ImplTy
Definition: CFG.h:795
CFGElement back() const
Definition: CFG.h:503
std::reverse_iterator< iterator > reverse_iterator
Definition: BumpVector.h:81
unsigned IgnoreDefaultsWithCoveredEnums
Definition: CFG.h:566
bool AddStaticInitBranches
Definition: CFG.h:738
const_pred_iterator pred_end() const
Definition: CFG.h:534
bool pred_empty() const
Definition: CFG.h:555
::clang::CFGBlock::const_pred_iterator ChildIteratorType
Definition: CFG.h:1030
void print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const
print - A simple pretty printer of a CFG that outputs to an ostream.
Definition: CFG.cpp:4532
llvm::BumpPtrAllocator & getAllocator()
Definition: BumpVector.h:54
const FieldDecl * getFieldDecl() const
Definition: CFG.h:266
reverse_iterator rbegin()
Definition: BumpVector.h:95
CFGBlock * getReachableBlock() const
Get the reachable block, if one exists.
Definition: CFG.h:440
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:768
bool succ_empty() const
Definition: CFG.h:552
graph_iterator(const ImplTy &i)
Definition: CFG.h:774
void printTerminator(raw_ostream &OS, const LangOptions &LO) const
printTerminator - A simple pretty printer of the terminator of a CFGBlock.
Definition: CFG.cpp:4573
typedefconst::clang::CFGBlock NodeType
Definition: CFG.h:1015
static ChildIteratorType child_end(NodeType *N)
Definition: CFG.h:1024
unsigned succ_size() const
Definition: CFG.h:551
graph_iterator nodes_begin()
Definition: CFG.h:848
AdjacentBlocks::iterator succ_iterator
Definition: CFG.h:526
reference operator*() const
Definition: CFG.h:779
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
void setLoopTarget(const Stmt *loopTarget)
Definition: CFG.h:619
::clang::CFG::graph_iterator nodes_iterator
Definition: CFG.h:1091
synthetic_stmt_iterator synthetic_stmt_end() const
Definition: CFG.h:907
const_graph_iterator nodes_end() const
Definition: CFG.h:853
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
Definition: Decl.h:2293
const Stmt * getLabel() const
Definition: CFG.h:634
iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S)
Definition: CFG.h:697
CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated for automatic object or t...
Definition: CFG.h:194
void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C)
Definition: CFG.h:681
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type...
Definition: CFG.h:87
CFGBlock * operator->() const
Definition: CFG.h:459
CFGBlock & back()
Definition: CFG.h:841
void setTerminator(CFGTerminator Term)
Definition: CFG.h:617
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
static unsigned size(::clang::CFG *F)
Definition: CFG.h:1066
iterator end()
Definition: CFG.h:844
const Stmt & operator*() const
Definition: CFG.h:322
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
Definition: CFG.h:285
static nodes_iterator nodes_end(const ::clang::CFG *F)
Definition: CFG.h:1080
const Stmt * getLoopTarget() const
Definition: CFG.h:631
std::vector< const CFGBlock * >::const_iterator try_block_iterator
Definition: CFG.h:870
CFGBlock * getPossiblyUnreachableBlock() const
Get the potentially unreachable block.
Definition: CFG.h:445
BumpVector< CFGBlock * > CFGBlockListTy
Definition: CFG.h:834
const_graph_iterator & operator++()
Definition: CFG.h:806
static NodeType * getEntryNode(const clang::CFGBlock *BB)
Definition: CFG.h:1018
const_iterator begin() const
Definition: CFG.h:845
bool AddCXXDefaultInitExprInCtors
Definition: CFG.h:740
const VarDecl * getVarDecl() const
Definition: CFG.h:199
unsigned size() const
size - Return the total number of CFGBlocks within the CFG This is simply a renaming of the getNumBlo...
Definition: CFG.h:936
unsigned pred_size() const
Definition: CFG.h:554
static nodes_iterator nodes_begin(const ::clang::CFG *F)
Definition: CFG.h:1077
CFGCallback * Observer
Definition: CFG.h:732
ElementList::const_iterator const_iterator
Definition: CFG.h:498
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:2897
Provides a custom implementation of the iterator class to have the same interface as Function::iterat...
Definition: CFG.h:767
bool empty() const
Definition: BumpVector.h:100
graph_iterator nodes_end()
Definition: CFG.h:849
FilteredCFGBlockIterator(const IMPL &i, const IMPL &e, const CFGBlock *from, const FilterOptions &f)
Definition: CFG.h:579
::clang::CFGBlock::succ_iterator ChildIteratorType
Definition: CFG.h:1002
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1119
static ChildIteratorType child_begin(NodeType *N)
Definition: CFG.h:1007
static NodeType * getEntryNode(const ::clang::CFG *F)
Definition: CFG.h:1074
detail::InMemoryDirectory::const_iterator I
const Stmt * getTriggerStmt() const
Definition: CFG.h:204
reverse_iterator rend()
Definition: CFG.h:511
filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const
Definition: CFG.h:607
AdjacentBlocks::reverse_iterator succ_reverse_iterator
Definition: CFG.h:528
const_succ_iterator succ_begin() const
Definition: CFG.h:543
static nodes_iterator nodes_begin(::clang::CFG *F)
Definition: CFG.h:1064
static nodes_iterator nodes_begin(::clang::CFG *F)
Definition: CFG.h:1094
ForcedBlkExprs ** forcedBlkExprs
Definition: CFG.h:731
const Stmt * getStmt() const
Definition: CFG.h:311
AdjacentBlocks::iterator pred_iterator
Definition: CFG.h:521
static ChildIteratorType child_end(NodeType *N)
Definition: CFG.h:1052
reverse_iterator rend()
Definition: BumpVector.h:97
void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C)
Definition: CFG.h:669
CFGBlock - Represents a single basic block in a source-level CFG.
Definition: CFG.h:353
static ChildIteratorType child_begin(NodeType *N)
Definition: CFG.h:1021
CFG()
Definition: CFG.h:950
bool alwaysAdd(const Stmt *stmt) const
Definition: CFG.h:742
bool operator==(const const_graph_iterator &X) const
Definition: CFG.h:799
friend class ASTContext
Definition: Type.h:4178
Stmt * getTerminatorCondition(bool StripParens=true)
Definition: CFG.cpp:4579
bool isNoReturn(ASTContext &astContext) const
Definition: CFG.cpp:3947
void VisitBlockStmts(CALLBACK &O) const
Definition: CFG.h:916
static NodeType * getEntryNode(Inverse< ::clang::CFGBlock * > G)
Definition: CFG.h:1032
CFG - Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
Definition: CFG.h:721
static NodeType * getEntryNode(::clang::CFG *F)
Definition: CFG.h:1093
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2414
CXXCtorInitializer * getInitializer() const
Definition: CFG.h:138
const CXXRecordDecl * getCXXRecordDecl() const
Definition: CFG.h:223
#define bool
Definition: stdbool.h:31
static NodeType * getEntryNode(const ::clang::CFG *F)
Definition: CFG.h:1103
static ChildIteratorType child_begin(NodeType *N)
Definition: CFG.h:1035
static SimpleType getSimplifiedValue(::clang::CFGTerminator Val)
Definition: CFG.h:993
::clang::CFG::graph_iterator nodes_iterator
Definition: CFG.h:1061
bool operator==(const graph_iterator &X) const
Definition: CFG.h:776
void dump() const
Definition: CFG.cpp:4559
AdjacentBlocks::const_iterator const_pred_iterator
Definition: CFG.h:522
unsigned getBlockID() const
Definition: CFG.h:638
const_iterator end() const
Definition: CFG.h:846
const_iterator begin() const
Definition: CFG.h:507
CFGBaseDtor - Represents C++ object destructor implicitly generated for base object in destructor...
Definition: CFG.h:242
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: BumpVector.h:80
const_graph_iterator(const ImplTy &i)
Definition: CFG.h:797
void viewCFG(const LangOptions &LO) const
Definition: CFG.cpp:4653
void addTryDispatchBlock(const CFGBlock *block)
Definition: CFG.h:878
Stmt & operator*()
Definition: CFG.h:321
reverse_iterator rbegin()
Definition: CFG.h:510
ElementList::iterator iterator
Definition: CFG.h:497
const_pred_iterator pred_begin() const
Definition: CFG.h:533
llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator
Definition: CFG.h:895
static ChildIteratorType child_begin(NodeType *N)
Definition: CFG.h:1049
static ChildIteratorType child_end(NodeType *N)
Definition: CFG.h:1010
const_reverse_iterator rbegin() const
Definition: CFG.h:512
void appendStmt(Stmt *statement, BumpVectorContext &C)
Definition: CFG.h:655
bool hasNoReturnElement() const
Definition: CFG.h:636
CFGElement front() const
Definition: CFG.h:502
CFGBlock & front()
Definition: CFG.h:840
CFGTerminator getTerminator()
Definition: CFG.h:622
#define false
Definition: stdbool.h:33
CFGImplicitDtor(Kind kind, const void *data1, const void *data2=nullptr)
Definition: CFG.h:174
pred_reverse_iterator pred_rend()
Definition: CFG.h:537
BuildOptions & setAlwaysAdd(Stmt::StmtClass stmtClass, bool val=true)
Definition: CFG.h:746
Stmt * getLabel()
Definition: CFG.h:633
::clang::CFG::const_graph_iterator nodes_iterator
Definition: CFG.h:1072
reverse_iterator rbegin()
Definition: CFG.h:857
::clang::CFG::const_graph_iterator nodes_iterator
Definition: CFG.h:1101
BumpVector< CFGBlock * >::iterator ImplTy
Definition: CFG.h:772
const Stmt * operator->() const
Definition: CFG.h:319
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
Definition: ExprCXX.h:1804
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl. ...
Definition: Stmt.h:457
void setLabel(Stmt *Statement)
Definition: CFG.h:618
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:3888
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Definition: Stmt.h:443
bool PruneTriviallyFalseEdges
Definition: CFG.h:733
bool isTemporaryDtorsBranch() const
Definition: CFG.h:313
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: CFG.h:838
virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue)
Definition: CFG.h:708
const Stmt * getStmt() const
Definition: CFG.h:119
succ_reverse_iterator succ_rend()
Definition: CFG.h:547
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
Definition: CFG.cpp:3895
llvm::PointerIntPair< void *, 2 > Data1
Definition: CFG.h:72
BumpVectorContext & getBumpVectorContext()
Definition: CFG.h:958
iterator begin()
Definition: CFG.h:843
succ_iterator succ_end()
Definition: CFG.h:542
BuildOptions & setAllAlwaysAdd()
Definition: CFG.h:751
const_graph_iterator nodes_begin() const
Definition: CFG.h:850
void print(raw_ostream &OS, const CFG *cfg, const LangOptions &LO, bool ShowColors) const
print - A simple pretty printer of a CFGBlock that outputs to an ostream.
Definition: CFG.cpp:4565
AdjacentBlocks::const_iterator const_succ_iterator
Definition: CFG.h:527
FilteredCFGBlockIterator & operator++()
Definition: CFG.h:589
static nodes_iterator nodes_end(::clang::CFG *F)
Definition: CFG.h:1065
const_pred_reverse_iterator pred_rbegin() const
Definition: CFG.h:538
::clang::CFGBlock::const_pred_iterator ChildIteratorType
Definition: CFG.h:1044
pred_iterator pred_begin()
Definition: CFG.h:531
AdjacentBlocks::reverse_iterator pred_reverse_iterator
Definition: CFG.h:523
llvm::PointerIntPair< void *, 2 > Data2
Definition: CFG.h:73
CFGBlockListTy::const_iterator const_iterator
Definition: CFG.h:836
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
Definition: ExprCXX.h:2008
static nodes_iterator nodes_begin(const ::clang::CFG *F)
Definition: CFG.h:1104
CFGTerminator(Stmt *S, bool TemporaryDtorsBranch=false)
Definition: CFG.h:307
iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt, BumpVectorContext &C)
Definition: CFG.h:692
CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt)
Definition: CFG.h:196
virtual void compareBitwiseEquality(const BinaryOperator *B, bool isAlwaysTrue)
Definition: CFG.h:709
const_iterator end() const
Definition: CFG.h:508
pointer operator->() const
Definition: CFG.h:780
void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C)
Definition: CFG.h:685
unsigned size() const
Definition: CFG.h:515
const_succ_reverse_iterator succ_rend() const
Definition: CFG.h:549
detail::InMemoryDirectory::const_iterator E
void appendMemberDtor(FieldDecl *FD, BumpVectorContext &C)
Definition: CFG.h:673
try_block_iterator try_blocks_end() const
Definition: CFG.h:874
void appendInitializer(CXXCtorInitializer *initializer, BumpVectorContext &C)
Definition: CFG.h:659
value_type & reference
Definition: CFG.h:770
This class represents a potential adjacent block in the CFG.
Definition: CFG.h:421
reverse_iterator rend()
Definition: CFG.h:858
CFGInitializer(CXXCtorInitializer *initializer)
Definition: CFG.h:135
Stmt * getStmt()
Definition: CFG.h:310
bool operator!=(const graph_iterator &X) const
Definition: CFG.h:777
pred_reverse_iterator pred_rbegin()
Definition: CFG.h:536
reference front()
Definition: BumpVector.h:112
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
Definition: CFG.h:730
CFGBlock * getIndirectGotoBlock()
Definition: CFG.h:867
Represents a C++ base or member initializer.
Definition: DeclCXX.h:1922
bool operator!=(const const_graph_iterator &X) const
Definition: CFG.h:800
::clang::CFGBlock::const_succ_iterator ChildIteratorType
Definition: CFG.h:1016
try_block_iterator try_blocks_begin() const
Definition: CFG.h:871
const_reverse_iterator rbegin() const
Definition: CFG.h:859
static ChildIteratorType child_end(NodeType *N)
Definition: CFG.h:1038
Represents a base class of a C++ class.
Definition: DeclCXX.h:159
static NodeType * getEntryNode(::clang::CFG *F)
Definition: CFG.h:1063
CFGElement(Kind kind, const void *Ptr1, const void *Ptr2=nullptr)
Definition: CFG.h:75
unsigned IgnoreNullPredecessors
Definition: CFG.h:565
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:12171
void setHasNoReturnElement()
Definition: CFG.h:620
CFGMemberDtor(const FieldDecl *field)
Definition: CFG.h:263
size_type size() const
Definition: BumpVector.h:101
const_graph_iterator & operator--()
Definition: CFG.h:807
Defines the clang::SourceLocation class and associated facilities.
AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator
Definition: CFG.h:524
const_reverse_iterator rend() const
Definition: CFG.h:860
void printAsOperand(raw_ostream &OS, bool)
Definition: CFG.h:648
Represents a C++ struct/union/class.
Definition: DeclCXX.h:263
pointer operator->() const
Definition: CFG.h:803
CFGCallback defines methods that should be called when a logical operator error is found when buildin...
Definition: CFG.h:705
static nodes_iterator nodes_end(const ::clang::CFG *F)
Definition: CFG.h:1107
CFGImplicitDtor - Represents C++ object destructor implicitly generated by compiler on various occasi...
Definition: CFG.h:171
Kind getKind() const
Definition: CFG.h:107
static NodeType * getEntryNode(::clang::CFGBlock *BB)
Definition: CFG.h:1004
CFGElement - Represents a top-level expression in a basic block.
Definition: CFG.h:53
void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C)
Adds a (potentially unreachable) successor block to the current block.
Definition: CFG.cpp:3967
const_reverse_iterator rend() const
Definition: CFG.h:513
AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator
Definition: CFG.h:529
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:43
CFGTerminator - Represents CFGBlock terminator statement.
Definition: CFG.h:303
CFGMemberDtor - Represents C++ object destructor implicitly generated for member object in destructor...
Definition: CFG.h:261
const CFGElement * const_iterator
Definition: BumpVector.h:78
AdjacentBlock(CFGBlock *B, bool IsReachable)
Construct an AdjacentBlock with a possibly unreachable block.
Definition: CFG.cpp:3957
graph_iterator & operator--()
Definition: CFG.h:784
void appendTemporaryDtor(CXXBindTemporaryExpr *E, BumpVectorContext &C)
Definition: CFG.h:677
FilteredCFGBlockIterator< const_succ_iterator, false > filtered_succ_iterator
Definition: CFG.h:605
CFGBlock & operator*() const
Definition: CFG.h:455
const Stmt * getTerminatorCondition(bool StripParens=true) const
Definition: CFG.h:627
const_succ_iterator succ_end() const
Definition: CFG.h:544
const CFGElement & const_reference
Definition: BumpVector.h:84
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
Definition: CFG.h:902
CFGBaseDtor(const CXXBaseSpecifier *base)
Definition: CFG.h:244
CFGInitializer - Represents C++ base or member initializer from constructor's initialization list...
Definition: CFG.h:133
value_type * pointer
Definition: CFG.h:771
#define true
Definition: stdbool.h:32
bool empty() const
Definition: CFG.h:516
const CFGTerminator getTerminator() const
Definition: CFG.h:623
CFGTemporaryDtor(CXXBindTemporaryExpr *expr)
Definition: CFG.h:282
iterator end()
Definition: CFG.h:506
CFGBlock * createBlock()
createBlock - Create a new block in the CFG.
Definition: CFG.cpp:3871
const CXXBaseSpecifier * getBaseSpecifier() const
Definition: CFG.h:247
const CFGBlock & getExit() const
Definition: CFG.h:865
unsigned getNumBlockIDs() const
getNumBlockIDs - Returns the total number of BlockIDs allocated (which start at 0).
Definition: CFG.h:931
void setEntry(CFGBlock *B)
setEntry - Set the entry block of the CFG.
Definition: CFG.h:824
std::reverse_iterator< iterator > reverse_iterator
Definition: CFG.h:837
void addSyntheticDeclStmt(const DeclStmt *Synthetic, const DeclStmt *Source)
Records a synthetic DeclStmt and the DeclStmt it was constructed from.
Definition: CFG.h:886
void dump(const LangOptions &LO, bool ShowColors) const
dump - A simple pretty printer of a CFG that outputs to stderr.
Definition: CFG.cpp:4527
CFGTemporaryDtor - Represents C++ object destructor implicitly generated at the end of full expressio...
Definition: CFG.h:280
static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src, const CFGBlock *Dst)
Definition: CFG.cpp:3978
static nodes_iterator nodes_end(::clang::CFG *F)
Definition: CFG.h:1095
const_succ_reverse_iterator succ_rbegin() const
Definition: CFG.h:548
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
Definition: CFG.h:98
const CFGBlock * getIndirectGotoBlock() const
Definition: CFG.h:868
filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const
Definition: CFG.h:611
virtual ~CFGCallback()
Definition: CFG.h:711
CFGBlock & getExit()
Definition: CFG.h:864