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