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