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