clang  16.0.0git
CFG.h
Go to the documentation of this file.
1 //===- CFG.h - Classes for representing and building CFGs -------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the CFG and CFGBuilder classes for representing and
10 // building Control-Flow Graphs (CFGs) from ASTs.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_ANALYSIS_CFG_H
15 #define LLVM_CLANG_ANALYSIS_CFG_H
16 
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/AST/ExprObjC.h"
21 #include "clang/Basic/LLVM.h"
22 #include "llvm/ADT/DenseMap.h"
23 #include "llvm/ADT/GraphTraits.h"
24 #include "llvm/ADT/None.h"
25 #include "llvm/ADT/Optional.h"
26 #include "llvm/ADT/PointerIntPair.h"
27 #include "llvm/ADT/iterator_range.h"
28 #include "llvm/Support/Allocator.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include <bitset>
31 #include <cassert>
32 #include <cstddef>
33 #include <iterator>
34 #include <memory>
35 #include <vector>
36 
37 namespace clang {
38 
39 class ASTContext;
40 class BinaryOperator;
41 class CFG;
42 class CXXBaseSpecifier;
43 class CXXBindTemporaryExpr;
44 class CXXCtorInitializer;
45 class CXXDeleteExpr;
46 class CXXDestructorDecl;
47 class CXXNewExpr;
48 class CXXRecordDecl;
49 class Decl;
50 class FieldDecl;
51 class LangOptions;
52 class VarDecl;
53 
54 /// Represents a top-level expression in a basic block.
55 class CFGElement {
56 public:
57  enum Kind {
58  // main kind
65  // stmt kind
71  // dtor kind
79  };
80 
81 protected:
82  // The int bits are used to mark the kind.
83  llvm::PointerIntPair<void *, 2> Data1;
84  llvm::PointerIntPair<void *, 2> Data2;
85 
86  CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr)
87  : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
88  Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
89  assert(getKind() == kind);
90  }
91 
92  CFGElement() = default;
93 
94 public:
95  /// Convert to the specified CFGElement type, asserting that this
96  /// CFGElement is of the desired type.
97  template<typename T>
98  T castAs() const {
99  assert(T::isKind(*this));
100  T t;
101  CFGElement& e = t;
102  e = *this;
103  return t;
104  }
105 
106  /// Convert to the specified CFGElement type, returning None if this
107  /// CFGElement is not of the desired type.
108  template<typename T>
109  Optional<T> getAs() const {
110  if (!T::isKind(*this))
111  return std::nullopt;
112  T t;
113  CFGElement& e = t;
114  e = *this;
115  return t;
116  }
117 
118  Kind getKind() const {
119  unsigned x = Data2.getInt();
120  x <<= 2;
121  x |= Data1.getInt();
122  return (Kind) x;
123  }
124 
125  void dumpToStream(llvm::raw_ostream &OS) const;
126 
127  void dump() const {
128  dumpToStream(llvm::errs());
129  }
130 };
131 
132 class CFGStmt : public CFGElement {
133 public:
134  explicit CFGStmt(const Stmt *S, Kind K = Statement) : CFGElement(K, S) {
135  assert(isKind(*this));
136  }
137 
138  const Stmt *getStmt() const {
139  return static_cast<const Stmt *>(Data1.getPointer());
140  }
141 
142 private:
143  friend class CFGElement;
144 
145  static bool isKind(const CFGElement &E) {
146  return E.getKind() >= STMT_BEGIN && E.getKind() <= STMT_END;
147  }
148 
149 protected:
150  CFGStmt() = default;
151 };
152 
153 /// Represents C++ constructor call. Maintains information necessary to figure
154 /// out what memory is being initialized by the constructor expression. For now
155 /// this is only used by the analyzer's CFG.
156 class CFGConstructor : public CFGStmt {
157 public:
158  explicit CFGConstructor(const CXXConstructExpr *CE,
159  const ConstructionContext *C)
160  : CFGStmt(CE, Constructor) {
161  assert(C);
162  Data2.setPointer(const_cast<ConstructionContext *>(C));
163  }
164 
166  return static_cast<ConstructionContext *>(Data2.getPointer());
167  }
168 
169 private:
170  friend class CFGElement;
171 
172  CFGConstructor() = default;
173 
174  static bool isKind(const CFGElement &E) {
175  return E.getKind() == Constructor;
176  }
177 };
178 
179 /// Represents a function call that returns a C++ object by value. This, like
180 /// constructor, requires a construction context in order to understand the
181 /// storage of the returned object . In C such tracking is not necessary because
182 /// no additional effort is required for destroying the object or modeling copy
183 /// elision. Like CFGConstructor, this element is for now only used by the
184 /// analyzer's CFG.
186 public:
187  /// Returns true when call expression \p CE needs to be represented
188  /// by CFGCXXRecordTypedCall, as opposed to a regular CFGStmt.
189  static bool isCXXRecordTypedCall(const Expr *E) {
190  assert(isa<CallExpr>(E) || isa<ObjCMessageExpr>(E));
191  // There is no such thing as reference-type expression. If the function
192  // returns a reference, it'll return the respective lvalue or xvalue
193  // instead, and we're only interested in objects.
194  return !E->isGLValue() &&
196  }
197 
198  explicit CFGCXXRecordTypedCall(const Expr *E, const ConstructionContext *C)
200  assert(isCXXRecordTypedCall(E));
201  assert(C && (isa<TemporaryObjectConstructionContext>(C) ||
202  // These are possible in C++17 due to mandatory copy elision.
203  isa<ReturnedValueConstructionContext>(C) ||
204  isa<VariableConstructionContext>(C) ||
205  isa<ConstructorInitializerConstructionContext>(C) ||
206  isa<ArgumentConstructionContext>(C) ||
207  isa<LambdaCaptureConstructionContext>(C)));
208  Data2.setPointer(const_cast<ConstructionContext *>(C));
209  }
210 
212  return static_cast<ConstructionContext *>(Data2.getPointer());
213  }
214 
215 private:
216  friend class CFGElement;
217 
218  CFGCXXRecordTypedCall() = default;
219 
220  static bool isKind(const CFGElement &E) {
221  return E.getKind() == CXXRecordTypedCall;
222  }
223 };
224 
225 /// Represents C++ base or member initializer from constructor's initialization
226 /// list.
227 class CFGInitializer : public CFGElement {
228 public:
229  explicit CFGInitializer(const CXXCtorInitializer *initializer)
230  : CFGElement(Initializer, initializer) {}
231 
233  return static_cast<CXXCtorInitializer*>(Data1.getPointer());
234  }
235 
236 private:
237  friend class CFGElement;
238 
239  CFGInitializer() = default;
240 
241  static bool isKind(const CFGElement &E) {
242  return E.getKind() == Initializer;
243  }
244 };
245 
246 /// Represents C++ allocator call.
247 class CFGNewAllocator : public CFGElement {
248 public:
249  explicit CFGNewAllocator(const CXXNewExpr *S)
250  : CFGElement(NewAllocator, S) {}
251 
252  // Get the new expression.
253  const CXXNewExpr *getAllocatorExpr() const {
254  return static_cast<CXXNewExpr *>(Data1.getPointer());
255  }
256 
257 private:
258  friend class CFGElement;
259 
260  CFGNewAllocator() = default;
261 
262  static bool isKind(const CFGElement &elem) {
263  return elem.getKind() == NewAllocator;
264  }
265 };
266 
267 /// Represents the point where a loop ends.
268 /// This element is only produced when building the CFG for the static
269 /// analyzer and hidden behind the 'cfg-loopexit' analyzer config flag.
270 ///
271 /// Note: a loop exit element can be reached even when the loop body was never
272 /// entered.
273 class CFGLoopExit : public CFGElement {
274 public:
275  explicit CFGLoopExit(const Stmt *stmt) : CFGElement(LoopExit, stmt) {}
276 
277  const Stmt *getLoopStmt() const {
278  return static_cast<Stmt *>(Data1.getPointer());
279  }
280 
281 private:
282  friend class CFGElement;
283 
284  CFGLoopExit() = default;
285 
286  static bool isKind(const CFGElement &elem) {
287  return elem.getKind() == LoopExit;
288  }
289 };
290 
291 /// Represents the point where the lifetime of an automatic object ends
292 class CFGLifetimeEnds : public CFGElement {
293 public:
294  explicit CFGLifetimeEnds(const VarDecl *var, const Stmt *stmt)
296 
297  const VarDecl *getVarDecl() const {
298  return static_cast<VarDecl *>(Data1.getPointer());
299  }
300 
301  const Stmt *getTriggerStmt() const {
302  return static_cast<Stmt *>(Data2.getPointer());
303  }
304 
305 private:
306  friend class CFGElement;
307 
308  CFGLifetimeEnds() = default;
309 
310  static bool isKind(const CFGElement &elem) {
311  return elem.getKind() == LifetimeEnds;
312  }
313 };
314 
315 /// Represents beginning of a scope implicitly generated
316 /// by the compiler on encountering a CompoundStmt
317 class CFGScopeBegin : public CFGElement {
318 public:
320  CFGScopeBegin(const VarDecl *VD, const Stmt *S)
321  : CFGElement(ScopeBegin, VD, S) {}
322 
323  // Get statement that triggered a new scope.
324  const Stmt *getTriggerStmt() const {
325  return static_cast<Stmt*>(Data2.getPointer());
326  }
327 
328  // Get VD that triggered a new scope.
329  const VarDecl *getVarDecl() const {
330  return static_cast<VarDecl *>(Data1.getPointer());
331  }
332 
333 private:
334  friend class CFGElement;
335  static bool isKind(const CFGElement &E) {
336  Kind kind = E.getKind();
337  return kind == ScopeBegin;
338  }
339 };
340 
341 /// Represents end of a scope implicitly generated by
342 /// the compiler after the last Stmt in a CompoundStmt's body
343 class CFGScopeEnd : public CFGElement {
344 public:
346  CFGScopeEnd(const VarDecl *VD, const Stmt *S) : CFGElement(ScopeEnd, VD, S) {}
347 
348  const VarDecl *getVarDecl() const {
349  return static_cast<VarDecl *>(Data1.getPointer());
350  }
351 
352  const Stmt *getTriggerStmt() const {
353  return static_cast<Stmt *>(Data2.getPointer());
354  }
355 
356 private:
357  friend class CFGElement;
358  static bool isKind(const CFGElement &E) {
359  Kind kind = E.getKind();
360  return kind == ScopeEnd;
361  }
362 };
363 
364 /// Represents C++ object destructor implicitly generated by compiler on various
365 /// occasions.
366 class CFGImplicitDtor : public CFGElement {
367 protected:
368  CFGImplicitDtor() = default;
369 
370  CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr)
371  : CFGElement(kind, data1, data2) {
372  assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
373  }
374 
375 public:
376  const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const;
377  bool isNoReturn(ASTContext &astContext) const;
378 
379 private:
380  friend class CFGElement;
381 
382  static bool isKind(const CFGElement &E) {
383  Kind kind = E.getKind();
384  return kind >= DTOR_BEGIN && kind <= DTOR_END;
385  }
386 };
387 
388 /// Represents C++ object destructor implicitly generated for automatic object
389 /// or temporary bound to const reference at the point of leaving its local
390 /// scope.
392 public:
395 
396  const VarDecl *getVarDecl() const {
397  return static_cast<VarDecl*>(Data1.getPointer());
398  }
399 
400  // Get statement end of which triggered the destructor call.
401  const Stmt *getTriggerStmt() const {
402  return static_cast<Stmt*>(Data2.getPointer());
403  }
404 
405 private:
406  friend class CFGElement;
407 
408  CFGAutomaticObjDtor() = default;
409 
410  static bool isKind(const CFGElement &elem) {
411  return elem.getKind() == AutomaticObjectDtor;
412  }
413 };
414 
415 /// Represents C++ object destructor generated from a call to delete.
417 public:
419  : CFGImplicitDtor(DeleteDtor, RD, DE) {}
420 
422  return static_cast<CXXRecordDecl*>(Data1.getPointer());
423  }
424 
425  // Get Delete expression which triggered the destructor call.
426  const CXXDeleteExpr *getDeleteExpr() const {
427  return static_cast<CXXDeleteExpr *>(Data2.getPointer());
428  }
429 
430 private:
431  friend class CFGElement;
432 
433  CFGDeleteDtor() = default;
434 
435  static bool isKind(const CFGElement &elem) {
436  return elem.getKind() == DeleteDtor;
437  }
438 };
439 
440 /// Represents C++ object destructor implicitly generated for base object in
441 /// destructor.
442 class CFGBaseDtor : public CFGImplicitDtor {
443 public:
445  : CFGImplicitDtor(BaseDtor, base) {}
446 
448  return static_cast<const CXXBaseSpecifier*>(Data1.getPointer());
449  }
450 
451 private:
452  friend class CFGElement;
453 
454  CFGBaseDtor() = default;
455 
456  static bool isKind(const CFGElement &E) {
457  return E.getKind() == BaseDtor;
458  }
459 };
460 
461 /// Represents C++ object destructor implicitly generated for member object in
462 /// destructor.
464 public:
465  CFGMemberDtor(const FieldDecl *field)
466  : CFGImplicitDtor(MemberDtor, field, nullptr) {}
467 
468  const FieldDecl *getFieldDecl() const {
469  return static_cast<const FieldDecl*>(Data1.getPointer());
470  }
471 
472 private:
473  friend class CFGElement;
474 
475  CFGMemberDtor() = default;
476 
477  static bool isKind(const CFGElement &E) {
478  return E.getKind() == MemberDtor;
479  }
480 };
481 
482 /// Represents C++ object destructor implicitly generated at the end of full
483 /// expression for temporary object.
485 public:
487  : CFGImplicitDtor(TemporaryDtor, expr, nullptr) {}
488 
490  return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer());
491  }
492 
493 private:
494  friend class CFGElement;
495 
496  CFGTemporaryDtor() = default;
497 
498  static bool isKind(const CFGElement &E) {
499  return E.getKind() == TemporaryDtor;
500  }
501 };
502 
503 /// Represents CFGBlock terminator statement.
504 ///
506 public:
507  enum Kind {
508  /// A branch that corresponds to a statement in the code,
509  /// such as an if-statement.
511  /// A branch in control flow of destructors of temporaries. In this case
512  /// terminator statement is the same statement that branches control flow
513  /// in evaluation of matching full expression.
515  /// A shortcut around virtual base initializers. It gets taken when
516  /// virtual base classes have already been initialized by the constructor
517  /// of the most derived class while we're in the base class.
519 
520  /// Number of different kinds, for assertions. We subtract 1 so that
521  /// to keep receiving compiler warnings when we don't cover all enum values
522  /// in a switch.
524  };
525 
526 private:
527  static constexpr int KindBits = 2;
528  static_assert((1 << KindBits) > NumKindsMinusOne,
529  "Not enough room for kind!");
530  llvm::PointerIntPair<Stmt *, KindBits> Data;
531 
532 public:
533  CFGTerminator() { assert(!isValid()); }
534  CFGTerminator(Stmt *S, Kind K = StmtBranch) : Data(S, K) {}
535 
536  bool isValid() const { return Data.getOpaqueValue() != nullptr; }
537  Stmt *getStmt() { return Data.getPointer(); }
538  const Stmt *getStmt() const { return Data.getPointer(); }
539  Kind getKind() const { return static_cast<Kind>(Data.getInt()); }
540 
541  bool isStmtBranch() const {
542  return getKind() == StmtBranch;
543  }
544  bool isTemporaryDtorsBranch() const {
545  return getKind() == TemporaryDtorsBranch;
546  }
547  bool isVirtualBaseBranch() const {
548  return getKind() == VirtualBaseBranch;
549  }
550 };
551 
552 /// Represents a single basic block in a source-level CFG.
553 /// It consists of:
554 ///
555 /// (1) A set of statements/expressions (which may contain subexpressions).
556 /// (2) A "terminator" statement (not in the set of statements).
557 /// (3) A list of successors and predecessors.
558 ///
559 /// Terminator: The terminator represents the type of control-flow that occurs
560 /// at the end of the basic block. The terminator is a Stmt* referring to an
561 /// AST node that has control-flow: if-statements, breaks, loops, etc.
562 /// If the control-flow is conditional, the condition expression will appear
563 /// within the set of statements in the block (usually the last statement).
564 ///
565 /// Predecessors: the order in the set of predecessors is arbitrary.
566 ///
567 /// Successors: the order in the set of successors is NOT arbitrary. We
568 /// currently have the following orderings based on the terminator:
569 ///
570 /// Terminator | Successor Ordering
571 /// ------------------|------------------------------------
572 /// if | Then Block; Else Block
573 /// ? operator | LHS expression; RHS expression
574 /// logical and/or | expression that consumes the op, RHS
575 /// vbase inits | already handled by the most derived class; not yet
576 ///
577 /// But note that any of that may be NULL in case of optimized-out edges.
578 class CFGBlock {
579  class ElementList {
580  using ImplTy = BumpVector<CFGElement>;
581 
582  ImplTy Impl;
583 
584  public:
585  ElementList(BumpVectorContext &C) : Impl(C, 4) {}
586 
587  using iterator = std::reverse_iterator<ImplTy::iterator>;
588  using const_iterator = std::reverse_iterator<ImplTy::const_iterator>;
591  using const_reference = ImplTy::const_reference;
592 
593  void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); }
594 
595  reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E,
596  BumpVectorContext &C) {
597  return Impl.insert(I, Cnt, E, C);
598  }
599 
600  const_reference front() const { return Impl.back(); }
601  const_reference back() const { return Impl.front(); }
602 
603  iterator begin() { return Impl.rbegin(); }
604  iterator end() { return Impl.rend(); }
605  const_iterator begin() const { return Impl.rbegin(); }
606  const_iterator end() const { return Impl.rend(); }
607  reverse_iterator rbegin() { return Impl.begin(); }
608  reverse_iterator rend() { return Impl.end(); }
609  const_reverse_iterator rbegin() const { return Impl.begin(); }
610  const_reverse_iterator rend() const { return Impl.end(); }
611 
612  CFGElement operator[](size_t i) const {
613  assert(i < Impl.size());
614  return Impl[Impl.size() - 1 - i];
615  }
616 
617  size_t size() const { return Impl.size(); }
618  bool empty() const { return Impl.empty(); }
619  };
620 
621  /// A convenience class for comparing CFGElements, since methods of CFGBlock
622  /// like operator[] return CFGElements by value. This is practically a wrapper
623  /// around a (CFGBlock, Index) pair.
624  template <bool IsConst> class ElementRefImpl {
625 
626  template <bool IsOtherConst> friend class ElementRefImpl;
627 
628  using CFGBlockPtr =
629  std::conditional_t<IsConst, const CFGBlock *, CFGBlock *>;
630 
631  using CFGElementPtr =
632  std::conditional_t<IsConst, const CFGElement *, CFGElement *>;
633 
634  protected:
635  CFGBlockPtr Parent;
636  size_t Index;
637 
638  public:
639  ElementRefImpl(CFGBlockPtr Parent, size_t Index)
640  : Parent(Parent), Index(Index) {}
641 
642  template <bool IsOtherConst>
643  ElementRefImpl(ElementRefImpl<IsOtherConst> Other)
644  : ElementRefImpl(Other.Parent, Other.Index) {}
645 
646  size_t getIndexInBlock() const { return Index; }
647 
648  CFGBlockPtr getParent() { return Parent; }
649  CFGBlockPtr getParent() const { return Parent; }
650 
651  bool operator<(ElementRefImpl Other) const {
652  return std::make_pair(Parent, Index) <
653  std::make_pair(Other.Parent, Other.Index);
654  }
655 
656  bool operator==(ElementRefImpl Other) const {
657  return Parent == Other.Parent && Index == Other.Index;
658  }
659 
660  bool operator!=(ElementRefImpl Other) const { return !(*this == Other); }
661  CFGElement operator*() const { return (*Parent)[Index]; }
662  CFGElementPtr operator->() const { return &*(Parent->begin() + Index); }
663 
664  void dumpToStream(llvm::raw_ostream &OS) const {
665  OS << getIndexInBlock() + 1 << ": ";
666  (*this)->dumpToStream(OS);
667  }
668 
669  void dump() const {
670  dumpToStream(llvm::errs());
671  }
672  };
673 
674  template <bool IsReverse, bool IsConst> class ElementRefIterator {
675 
676  template <bool IsOtherReverse, bool IsOtherConst>
677  friend class ElementRefIterator;
678 
679  using CFGBlockRef =
680  std::conditional_t<IsConst, const CFGBlock *, CFGBlock *>;
681 
682  using UnderlayingIteratorTy = std::conditional_t<
683  IsConst,
684  std::conditional_t<IsReverse, ElementList::const_reverse_iterator,
685  ElementList::const_iterator>,
686  std::conditional_t<IsReverse, ElementList::reverse_iterator,
687  ElementList::iterator>>;
688 
689  using IteratorTraits = typename std::iterator_traits<UnderlayingIteratorTy>;
690  using ElementRef = typename CFGBlock::ElementRefImpl<IsConst>;
691 
692  public:
693  using difference_type = typename IteratorTraits::difference_type;
694  using value_type = ElementRef;
695  using pointer = ElementRef *;
696  using iterator_category = typename IteratorTraits::iterator_category;
697 
698  private:
699  CFGBlockRef Parent;
700  UnderlayingIteratorTy Pos;
701 
702  public:
703  ElementRefIterator(CFGBlockRef Parent, UnderlayingIteratorTy Pos)
704  : Parent(Parent), Pos(Pos) {}
705 
706  template <bool IsOtherConst>
707  ElementRefIterator(ElementRefIterator<false, IsOtherConst> E)
708  : ElementRefIterator(E.Parent, E.Pos.base()) {}
709 
710  template <bool IsOtherConst>
711  ElementRefIterator(ElementRefIterator<true, IsOtherConst> E)
712  : ElementRefIterator(E.Parent, std::make_reverse_iterator(E.Pos)) {}
713 
714  bool operator<(ElementRefIterator Other) const {
715  assert(Parent == Other.Parent);
716  return Pos < Other.Pos;
717  }
718 
719  bool operator==(ElementRefIterator Other) const {
720  return Parent == Other.Parent && Pos == Other.Pos;
721  }
722 
723  bool operator!=(ElementRefIterator Other) const {
724  return !(*this == Other);
725  }
726 
727  private:
728  template <bool IsOtherConst>
729  static size_t
730  getIndexInBlock(CFGBlock::ElementRefIterator<true, IsOtherConst> E) {
731  return E.Parent->size() - (E.Pos - E.Parent->rbegin()) - 1;
732  }
733 
734  template <bool IsOtherConst>
735  static size_t
736  getIndexInBlock(CFGBlock::ElementRefIterator<false, IsOtherConst> E) {
737  return E.Pos - E.Parent->begin();
738  }
739 
740  public:
741  value_type operator*() { return {Parent, getIndexInBlock(*this)}; }
742 
743  difference_type operator-(ElementRefIterator Other) const {
744  return Pos - Other.Pos;
745  }
746 
747  ElementRefIterator operator++() {
748  ++this->Pos;
749  return *this;
750  }
751  ElementRefIterator operator++(int) {
752  ElementRefIterator Ret = *this;
753  ++*this;
754  return Ret;
755  }
756  ElementRefIterator operator+(size_t count) {
757  this->Pos += count;
758  return *this;
759  }
760  ElementRefIterator operator-(size_t count) {
761  this->Pos -= count;
762  return *this;
763  }
764  };
765 
766 public:
767  /// The set of statements in the basic block.
768  ElementList Elements;
769 
770  /// An (optional) label that prefixes the executable statements in the block.
771  /// When this variable is non-NULL, it is either an instance of LabelStmt,
772  /// SwitchCase or CXXCatchStmt.
773  Stmt *Label = nullptr;
774 
775  /// The terminator for a basic block that indicates the type of control-flow
776  /// that occurs between a block and its successors.
778 
779  /// Some blocks are used to represent the "loop edge" to the start of a loop
780  /// from within the loop body. This Stmt* will be refer to the loop statement
781  /// for such blocks (and be null otherwise).
782  const Stmt *LoopTarget = nullptr;
783 
784  /// A numerical ID assigned to a CFGBlock during construction of the CFG.
785  unsigned BlockID;
786 
787 public:
788  /// This class represents a potential adjacent block in the CFG. It encodes
789  /// whether or not the block is actually reachable, or can be proved to be
790  /// trivially unreachable. For some cases it allows one to encode scenarios
791  /// where a block was substituted because the original (now alternate) block
792  /// is unreachable.
794  enum Kind {
795  AB_Normal,
796  AB_Unreachable,
797  AB_Alternate
798  };
799 
800  CFGBlock *ReachableBlock;
801  llvm::PointerIntPair<CFGBlock *, 2> UnreachableBlock;
802 
803  public:
804  /// Construct an AdjacentBlock with a possibly unreachable block.
805  AdjacentBlock(CFGBlock *B, bool IsReachable);
806 
807  /// Construct an AdjacentBlock with a reachable block and an alternate
808  /// unreachable block.
809  AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock);
810 
811  /// Get the reachable block, if one exists.
813  return ReachableBlock;
814  }
815 
816  /// Get the potentially unreachable block.
818  return UnreachableBlock.getPointer();
819  }
820 
821  /// Provide an implicit conversion to CFGBlock* so that
822  /// AdjacentBlock can be substituted for CFGBlock*.
823  operator CFGBlock*() const {
824  return getReachableBlock();
825  }
826 
827  CFGBlock& operator *() const {
828  return *getReachableBlock();
829  }
830 
832  return getReachableBlock();
833  }
834 
835  bool isReachable() const {
836  Kind K = (Kind) UnreachableBlock.getInt();
837  return K == AB_Normal || K == AB_Alternate;
838  }
839  };
840 
841 private:
842  /// Keep track of the predecessor / successor CFG blocks.
843  using AdjacentBlocks = BumpVector<AdjacentBlock>;
844  AdjacentBlocks Preds;
845  AdjacentBlocks Succs;
846 
847  /// This bit is set when the basic block contains a function call
848  /// or implicit destructor that is attributed as 'noreturn'. In that case,
849  /// control cannot technically ever proceed past this block. All such blocks
850  /// will have a single immediate successor: the exit block. This allows them
851  /// to be easily reached from the exit block and using this bit quickly
852  /// recognized without scanning the contents of the block.
853  ///
854  /// Optimization Note: This bit could be profitably folded with Terminator's
855  /// storage if the memory usage of CFGBlock becomes an issue.
856  unsigned HasNoReturnElement : 1;
857 
858  /// The parent CFG that owns this CFGBlock.
859  CFG *Parent;
860 
861 public:
862  explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
863  : Elements(C), Terminator(nullptr), BlockID(blockid), Preds(C, 1),
864  Succs(C, 1), HasNoReturnElement(false), Parent(parent) {}
865 
866  // Statement iterators
867  using iterator = ElementList::iterator;
868  using const_iterator = ElementList::const_iterator;
871 
872  size_t getIndexInCFG() const;
873 
874  CFGElement front() const { return Elements.front(); }
875  CFGElement back() const { return Elements.back(); }
876 
877  iterator begin() { return Elements.begin(); }
878  iterator end() { return Elements.end(); }
879  const_iterator begin() const { return Elements.begin(); }
880  const_iterator end() const { return Elements.end(); }
881 
882  reverse_iterator rbegin() { return Elements.rbegin(); }
883  reverse_iterator rend() { return Elements.rend(); }
884  const_reverse_iterator rbegin() const { return Elements.rbegin(); }
885  const_reverse_iterator rend() const { return Elements.rend(); }
886 
887  using CFGElementRef = ElementRefImpl<false>;
888  using ConstCFGElementRef = ElementRefImpl<true>;
889 
890  using ref_iterator = ElementRefIterator<false, false>;
891  using ref_iterator_range = llvm::iterator_range<ref_iterator>;
892  using const_ref_iterator = ElementRefIterator<false, true>;
893  using const_ref_iterator_range = llvm::iterator_range<const_ref_iterator>;
894 
895  using reverse_ref_iterator = ElementRefIterator<true, false>;
896  using reverse_ref_iterator_range = llvm::iterator_range<reverse_ref_iterator>;
897 
898  using const_reverse_ref_iterator = ElementRefIterator<true, true>;
900  llvm::iterator_range<const_reverse_ref_iterator>;
901 
902  ref_iterator ref_begin() { return {this, begin()}; }
903  ref_iterator ref_end() { return {this, end()}; }
904  const_ref_iterator ref_begin() const { return {this, begin()}; }
905  const_ref_iterator ref_end() const { return {this, end()}; }
906 
907  reverse_ref_iterator rref_begin() { return {this, rbegin()}; }
908  reverse_ref_iterator rref_end() { return {this, rend()}; }
909  const_reverse_ref_iterator rref_begin() const { return {this, rbegin()}; }
910  const_reverse_ref_iterator rref_end() const { return {this, rend()}; }
911 
913  const_ref_iterator_range refs() const { return {ref_begin(), ref_end()}; }
916  return {rref_begin(), rref_end()};
917  }
918 
919  unsigned size() const { return Elements.size(); }
920  bool empty() const { return Elements.empty(); }
921 
922  CFGElement operator[](size_t i) const { return Elements[i]; }
923 
924  // CFG iterators
929  using pred_range = llvm::iterator_range<pred_iterator>;
930  using pred_const_range = llvm::iterator_range<const_pred_iterator>;
931 
936  using succ_range = llvm::iterator_range<succ_iterator>;
937  using succ_const_range = llvm::iterator_range<const_succ_iterator>;
938 
939  pred_iterator pred_begin() { return Preds.begin(); }
940  pred_iterator pred_end() { return Preds.end(); }
941  const_pred_iterator pred_begin() const { return Preds.begin(); }
942  const_pred_iterator pred_end() const { return Preds.end(); }
943 
944  pred_reverse_iterator pred_rbegin() { return Preds.rbegin(); }
945  pred_reverse_iterator pred_rend() { return Preds.rend(); }
946  const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); }
947  const_pred_reverse_iterator pred_rend() const { return Preds.rend(); }
948 
950  return pred_range(pred_begin(), pred_end());
951  }
952 
954  return pred_const_range(pred_begin(), pred_end());
955  }
956 
957  succ_iterator succ_begin() { return Succs.begin(); }
958  succ_iterator succ_end() { return Succs.end(); }
959  const_succ_iterator succ_begin() const { return Succs.begin(); }
960  const_succ_iterator succ_end() const { return Succs.end(); }
961 
962  succ_reverse_iterator succ_rbegin() { return Succs.rbegin(); }
963  succ_reverse_iterator succ_rend() { return Succs.rend(); }
964  const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); }
965  const_succ_reverse_iterator succ_rend() const { return Succs.rend(); }
966 
968  return succ_range(succ_begin(), succ_end());
969  }
970 
972  return succ_const_range(succ_begin(), succ_end());
973  }
974 
975  unsigned succ_size() const { return Succs.size(); }
976  bool succ_empty() const { return Succs.empty(); }
977 
978  unsigned pred_size() const { return Preds.size(); }
979  bool pred_empty() const { return Preds.empty(); }
980 
981 
983  public:
986 
989  };
990 
991  static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src,
992  const CFGBlock *Dst);
993 
994  template <typename IMPL, bool IsPred>
996  private:
997  IMPL I, E;
998  const FilterOptions F;
999  const CFGBlock *From;
1000 
1001  public:
1002  explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e,
1003  const CFGBlock *from,
1004  const FilterOptions &f)
1005  : I(i), E(e), F(f), From(from) {
1006  while (hasMore() && Filter(*I))
1007  ++I;
1008  }
1009 
1010  bool hasMore() const { return I != E; }
1011 
1013  do { ++I; } while (hasMore() && Filter(*I));
1014  return *this;
1015  }
1016 
1017  const CFGBlock *operator*() const { return *I; }
1018 
1019  private:
1020  bool Filter(const CFGBlock *To) {
1021  return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To);
1022  }
1023  };
1024 
1025  using filtered_pred_iterator =
1027 
1028  using filtered_succ_iterator =
1030 
1032  return filtered_pred_iterator(pred_begin(), pred_end(), this, f);
1033  }
1034 
1036  return filtered_succ_iterator(succ_begin(), succ_end(), this, f);
1037  }
1038 
1039  // Manipulation of block contents
1040 
1041  void setTerminator(CFGTerminator Term) { Terminator = Term; }
1042  void setLabel(Stmt *Statement) { Label = Statement; }
1043  void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
1044  void setHasNoReturnElement() { HasNoReturnElement = true; }
1045 
1046  /// Returns true if the block would eventually end with a sink (a noreturn
1047  /// node).
1048  bool isInevitablySinking() const;
1049 
1051 
1053  const Stmt *getTerminatorStmt() const { return Terminator.getStmt(); }
1054 
1055  /// \returns the last (\c rbegin()) condition, e.g. observe the following code
1056  /// snippet:
1057  /// if (A && B && C)
1058  /// A block would be created for \c A, \c B, and \c C. For the latter,
1059  /// \c getTerminatorStmt() would retrieve the entire condition, rather than
1060  /// C itself, while this method would only return C.
1061  const Expr *getLastCondition() const;
1062 
1063  Stmt *getTerminatorCondition(bool StripParens = true);
1064 
1065  const Stmt *getTerminatorCondition(bool StripParens = true) const {
1066  return const_cast<CFGBlock*>(this)->getTerminatorCondition(StripParens);
1067  }
1068 
1069  const Stmt *getLoopTarget() const { return LoopTarget; }
1070 
1071  Stmt *getLabel() { return Label; }
1072  const Stmt *getLabel() const { return Label; }
1073 
1074  bool hasNoReturnElement() const { return HasNoReturnElement; }
1075 
1076  unsigned getBlockID() const { return BlockID; }
1077 
1078  CFG *getParent() const { return Parent; }
1079 
1080  void dump() const;
1081 
1082  void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const;
1083  void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO,
1084  bool ShowColors) const;
1085 
1086  void printTerminator(raw_ostream &OS, const LangOptions &LO) const;
1087  void printTerminatorJson(raw_ostream &Out, const LangOptions &LO,
1088  bool AddQuotes) const;
1089 
1090  void printAsOperand(raw_ostream &OS, bool /*PrintType*/) {
1091  OS << "BB#" << getBlockID();
1092  }
1093 
1094  /// Adds a (potentially unreachable) successor block to the current block.
1095  void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C);
1096 
1098  Elements.push_back(CFGStmt(statement), C);
1099  }
1100 
1102  BumpVectorContext &C) {
1103  Elements.push_back(CFGConstructor(CE, CC), C);
1104  }
1105 
1107  const ConstructionContext *CC,
1108  BumpVectorContext &C) {
1109  Elements.push_back(CFGCXXRecordTypedCall(E, CC), C);
1110  }
1111 
1113  BumpVectorContext &C) {
1114  Elements.push_back(CFGInitializer(initializer), C);
1115  }
1116 
1118  BumpVectorContext &C) {
1119  Elements.push_back(CFGNewAllocator(NE), C);
1120  }
1121 
1122  void appendScopeBegin(const VarDecl *VD, const Stmt *S,
1123  BumpVectorContext &C) {
1124  Elements.push_back(CFGScopeBegin(VD, S), C);
1125  }
1126 
1127  void prependScopeBegin(const VarDecl *VD, const Stmt *S,
1128  BumpVectorContext &C) {
1129  Elements.insert(Elements.rbegin(), 1, CFGScopeBegin(VD, S), C);
1130  }
1131 
1132  void appendScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C) {
1133  Elements.push_back(CFGScopeEnd(VD, S), C);
1134  }
1135 
1136  void prependScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C) {
1137  Elements.insert(Elements.rbegin(), 1, CFGScopeEnd(VD, S), C);
1138  }
1139 
1141  Elements.push_back(CFGBaseDtor(BS), C);
1142  }
1143 
1145  Elements.push_back(CFGMemberDtor(FD), C);
1146  }
1147 
1149  Elements.push_back(CFGTemporaryDtor(E), C);
1150  }
1151 
1153  Elements.push_back(CFGAutomaticObjDtor(VD, S), C);
1154  }
1155 
1157  Elements.push_back(CFGLifetimeEnds(VD, S), C);
1158  }
1159 
1160  void appendLoopExit(const Stmt *LoopStmt, BumpVectorContext &C) {
1161  Elements.push_back(CFGLoopExit(LoopStmt), C);
1162  }
1163 
1165  Elements.push_back(CFGDeleteDtor(RD, DE), C);
1166  }
1167 
1168  // Destructors must be inserted in reversed order. So insertion is in two
1169  // steps. First we prepare space for some number of elements, then we insert
1170  // the elements beginning at the last position in prepared space.
1172  BumpVectorContext &C) {
1173  return iterator(Elements.insert(I.base(), Cnt,
1174  CFGAutomaticObjDtor(nullptr, nullptr), C));
1175  }
1177  *I = CFGAutomaticObjDtor(VD, S);
1178  return ++I;
1179  }
1180 
1181  // Scope leaving must be performed in reversed order. So insertion is in two
1182  // steps. First we prepare space for some number of elements, then we insert
1183  // the elements beginning at the last position in prepared space.
1185  BumpVectorContext &C) {
1186  return iterator(
1187  Elements.insert(I.base(), Cnt, CFGLifetimeEnds(nullptr, nullptr), C));
1188  }
1190  *I = CFGLifetimeEnds(VD, S);
1191  return ++I;
1192  }
1193 
1194  // Scope leaving must be performed in reversed order. So insertion is in two
1195  // steps. First we prepare space for some number of elements, then we insert
1196  // the elements beginning at the last position in prepared space.
1198  return iterator(
1199  Elements.insert(I.base(), Cnt, CFGScopeEnd(nullptr, nullptr), C));
1200  }
1202  *I = CFGScopeEnd(VD, S);
1203  return ++I;
1204  }
1205 };
1206 
1207 /// CFGCallback defines methods that should be called when a logical
1208 /// operator error is found when building the CFG.
1210 public:
1211  CFGCallback() = default;
1212  virtual ~CFGCallback() = default;
1213 
1214  virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {}
1216  bool isAlwaysTrue) {}
1217  virtual void compareBitwiseOr(const BinaryOperator *B) {}
1218 };
1219 
1220 /// Represents a source-level, intra-procedural CFG that represents the
1221 /// control-flow of a Stmt. The Stmt can represent an entire function body,
1222 /// or a single expression. A CFG will always contain one empty block that
1223 /// represents the Exit point of the CFG. A CFG will also contain a designated
1224 /// Entry block. The CFG solely represents control-flow; it consists of
1225 /// CFGBlocks which are simply containers of Stmt*'s in the AST the CFG
1226 /// was constructed from.
1227 class CFG {
1228 public:
1229  //===--------------------------------------------------------------------===//
1230  // CFG Construction & Manipulation.
1231  //===--------------------------------------------------------------------===//
1232 
1234  std::bitset<Stmt::lastStmtConstant> alwaysAddMask;
1235 
1236  public:
1237  using ForcedBlkExprs = llvm::DenseMap<const Stmt *, const CFGBlock *>;
1238 
1240  CFGCallback *Observer = nullptr;
1242  bool AddEHEdges = false;
1243  bool AddInitializers = false;
1244  bool AddImplicitDtors = false;
1245  bool AddLifetime = false;
1246  bool AddLoopExit = false;
1247  bool AddTemporaryDtors = false;
1248  bool AddScopes = false;
1250  bool AddCXXNewAllocator = false;
1257 
1258  BuildOptions() = default;
1259 
1260  bool alwaysAdd(const Stmt *stmt) const {
1261  return alwaysAddMask[stmt->getStmtClass()];
1262  }
1263 
1264  BuildOptions &setAlwaysAdd(Stmt::StmtClass stmtClass, bool val = true) {
1265  alwaysAddMask[stmtClass] = val;
1266  return *this;
1267  }
1268 
1270  alwaysAddMask.set();
1271  return *this;
1272  }
1273  };
1274 
1275  /// Builds a CFG from an AST.
1276  static std::unique_ptr<CFG> buildCFG(const Decl *D, Stmt *AST, ASTContext *C,
1277  const BuildOptions &BO);
1278 
1279  /// Create a new block in the CFG. The CFG owns the block; the caller should
1280  /// not directly free it.
1281  CFGBlock *createBlock();
1282 
1283  /// Set the entry block of the CFG. This is typically used only during CFG
1284  /// construction. Most CFG clients expect that the entry block has no
1285  /// predecessors and contains no statements.
1286  void setEntry(CFGBlock *B) { Entry = B; }
1287 
1288  /// Set the block used for indirect goto jumps. This is typically used only
1289  /// during CFG construction.
1290  void setIndirectGotoBlock(CFGBlock *B) { IndirectGotoBlock = B; }
1291 
1292  //===--------------------------------------------------------------------===//
1293  // Block Iterators
1294  //===--------------------------------------------------------------------===//
1295 
1299  using reverse_iterator = std::reverse_iterator<iterator>;
1300  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
1301 
1302  CFGBlock & front() { return *Blocks.front(); }
1303  CFGBlock & back() { return *Blocks.back(); }
1304 
1305  iterator begin() { return Blocks.begin(); }
1306  iterator end() { return Blocks.end(); }
1307  const_iterator begin() const { return Blocks.begin(); }
1308  const_iterator end() const { return Blocks.end(); }
1309 
1310  iterator nodes_begin() { return iterator(Blocks.begin()); }
1311  iterator nodes_end() { return iterator(Blocks.end()); }
1312 
1313  llvm::iterator_range<iterator> nodes() { return {begin(), end()}; }
1314  llvm::iterator_range<const_iterator> const_nodes() const {
1315  return {begin(), end()};
1316  }
1317 
1318  const_iterator nodes_begin() const { return const_iterator(Blocks.begin()); }
1319  const_iterator nodes_end() const { return const_iterator(Blocks.end()); }
1320 
1321  reverse_iterator rbegin() { return Blocks.rbegin(); }
1322  reverse_iterator rend() { return Blocks.rend(); }
1323  const_reverse_iterator rbegin() const { return Blocks.rbegin(); }
1324  const_reverse_iterator rend() const { return Blocks.rend(); }
1325 
1326  llvm::iterator_range<reverse_iterator> reverse_nodes() {
1327  return {rbegin(), rend()};
1328  }
1329  llvm::iterator_range<const_reverse_iterator> const_reverse_nodes() const {
1330  return {rbegin(), rend()};
1331  }
1332 
1333  CFGBlock & getEntry() { return *Entry; }
1334  const CFGBlock & getEntry() const { return *Entry; }
1335  CFGBlock & getExit() { return *Exit; }
1336  const CFGBlock & getExit() const { return *Exit; }
1337 
1338  CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; }
1339  const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; }
1340 
1341  using try_block_iterator = std::vector<const CFGBlock *>::const_iterator;
1342  using try_block_range = llvm::iterator_range<try_block_iterator>;
1343 
1345  return TryDispatchBlocks.begin();
1346  }
1347 
1349  return TryDispatchBlocks.end();
1350  }
1351 
1354  }
1355 
1356  void addTryDispatchBlock(const CFGBlock *block) {
1357  TryDispatchBlocks.push_back(block);
1358  }
1359 
1360  /// Records a synthetic DeclStmt and the DeclStmt it was constructed from.
1361  ///
1362  /// The CFG uses synthetic DeclStmts when a single AST DeclStmt contains
1363  /// multiple decls.
1364  void addSyntheticDeclStmt(const DeclStmt *Synthetic,
1365  const DeclStmt *Source) {
1366  assert(Synthetic->isSingleDecl() && "Can handle single declarations only");
1367  assert(Synthetic != Source && "Don't include original DeclStmts in map");
1368  assert(!SyntheticDeclStmts.count(Synthetic) && "Already in map");
1369  SyntheticDeclStmts[Synthetic] = Source;
1370  }
1371 
1372  using synthetic_stmt_iterator =
1373  llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator;
1374  using synthetic_stmt_range = llvm::iterator_range<synthetic_stmt_iterator>;
1375 
1376  /// Iterates over synthetic DeclStmts in the CFG.
1377  ///
1378  /// Each element is a (synthetic statement, source statement) pair.
1379  ///
1380  /// \sa addSyntheticDeclStmt
1382  return SyntheticDeclStmts.begin();
1383  }
1384 
1385  /// \sa synthetic_stmt_begin
1387  return SyntheticDeclStmts.end();
1388  }
1389 
1390  /// \sa synthetic_stmt_begin
1393  }
1394 
1395  //===--------------------------------------------------------------------===//
1396  // Member templates useful for various batch operations over CFGs.
1397  //===--------------------------------------------------------------------===//
1398 
1399  template <typename Callback> void VisitBlockStmts(Callback &O) const {
1400  for (const_iterator I = begin(), E = end(); I != E; ++I)
1401  for (CFGBlock::const_iterator BI = (*I)->begin(), BE = (*I)->end();
1402  BI != BE; ++BI) {
1403  if (Optional<CFGStmt> stmt = BI->getAs<CFGStmt>())
1404  O(const_cast<Stmt *>(stmt->getStmt()));
1405  }
1406  }
1407 
1408  //===--------------------------------------------------------------------===//
1409  // CFG Introspection.
1410  //===--------------------------------------------------------------------===//
1411 
1412  /// Returns the total number of BlockIDs allocated (which start at 0).
1413  unsigned getNumBlockIDs() const { return NumBlockIDs; }
1414 
1415  /// Return the total number of CFGBlocks within the CFG This is simply a
1416  /// renaming of the getNumBlockIDs(). This is necessary because the dominator
1417  /// implementation needs such an interface.
1418  unsigned size() const { return NumBlockIDs; }
1419 
1420  /// Returns true if the CFG has no branches. Usually it boils down to the CFG
1421  /// having exactly three blocks (entry, the actual code, exit), but sometimes
1422  /// more blocks appear due to having control flow that can be fully
1423  /// resolved in compile time.
1424  bool isLinear() const;
1425 
1426  //===--------------------------------------------------------------------===//
1427  // CFG Debugging: Pretty-Printing and Visualization.
1428  //===--------------------------------------------------------------------===//
1429 
1430  void viewCFG(const LangOptions &LO) const;
1431  void print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const;
1432  void dump(const LangOptions &LO, bool ShowColors) const;
1433 
1434  //===--------------------------------------------------------------------===//
1435  // Internal: constructors and data.
1436  //===--------------------------------------------------------------------===//
1437 
1438  CFG() : Blocks(BlkBVC, 10) {}
1439 
1440  llvm::BumpPtrAllocator& getAllocator() {
1441  return BlkBVC.getAllocator();
1442  }
1443 
1445  return BlkBVC;
1446  }
1447 
1448 private:
1449  CFGBlock *Entry = nullptr;
1450  CFGBlock *Exit = nullptr;
1451 
1452  // Special block to contain collective dispatch for indirect gotos
1453  CFGBlock* IndirectGotoBlock = nullptr;
1454 
1455  unsigned NumBlockIDs = 0;
1456 
1457  BumpVectorContext BlkBVC;
1458 
1459  CFGBlockListTy Blocks;
1460 
1461  /// C++ 'try' statements are modeled with an indirect dispatch block.
1462  /// This is the collection of such blocks present in the CFG.
1463  std::vector<const CFGBlock *> TryDispatchBlocks;
1464 
1465  /// Collects DeclStmts synthesized for this CFG and maps each one back to its
1466  /// source DeclStmt.
1467  llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts;
1468 };
1469 
1470 Expr *extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE);
1471 
1472 } // namespace clang
1473 
1474 //===----------------------------------------------------------------------===//
1475 // GraphTraits specializations for CFG basic block graphs (source-level CFGs)
1476 //===----------------------------------------------------------------------===//
1477 
1478 namespace llvm {
1479 
1480 /// Implement simplify_type for CFGTerminator, so that we can dyn_cast from
1481 /// CFGTerminator to a specific Stmt class.
1482 template <> struct simplify_type< ::clang::CFGTerminator> {
1484 
1486  return Val.getStmt();
1487  }
1488 };
1489 
1490 // Traits for: CFGBlock
1491 
1492 template <> struct GraphTraits< ::clang::CFGBlock *> {
1495 
1496  static NodeRef getEntryNode(::clang::CFGBlock *BB) { return BB; }
1498  static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
1499 };
1500 
1501 template <> struct GraphTraits< const ::clang::CFGBlock *> {
1502  using NodeRef = const ::clang::CFGBlock *;
1504 
1505  static NodeRef getEntryNode(const clang::CFGBlock *BB) { return BB; }
1507  static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
1508 };
1509 
1510 template <> struct GraphTraits<Inverse< ::clang::CFGBlock *>> {
1513 
1514  static NodeRef getEntryNode(Inverse<::clang::CFGBlock *> G) {
1515  return G.Graph;
1516  }
1517 
1519  static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
1520 };
1521 
1522 template <> struct GraphTraits<Inverse<const ::clang::CFGBlock *>> {
1523  using NodeRef = const ::clang::CFGBlock *;
1525 
1526  static NodeRef getEntryNode(Inverse<const ::clang::CFGBlock *> G) {
1527  return G.Graph;
1528  }
1529 
1531  static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
1532 };
1533 
1534 // Traits for: CFG
1535 
1536 template <> struct GraphTraits< ::clang::CFG* >
1537  : public GraphTraits< ::clang::CFGBlock *> {
1539 
1540  static NodeRef getEntryNode(::clang::CFG *F) { return &F->getEntry(); }
1541  static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();}
1542  static nodes_iterator nodes_end(::clang::CFG* F) { return F->nodes_end(); }
1543  static unsigned size(::clang::CFG* F) { return F->size(); }
1544 };
1545 
1546 template <> struct GraphTraits<const ::clang::CFG* >
1547  : public GraphTraits<const ::clang::CFGBlock *> {
1549 
1550  static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getEntry(); }
1551 
1552  static nodes_iterator nodes_begin( const ::clang::CFG* F) {
1553  return F->nodes_begin();
1554  }
1555 
1556  static nodes_iterator nodes_end( const ::clang::CFG* F) {
1557  return F->nodes_end();
1558  }
1559 
1560  static unsigned size(const ::clang::CFG* F) {
1561  return F->size();
1562  }
1563 };
1564 
1565 template <> struct GraphTraits<Inverse< ::clang::CFG *>>
1566  : public GraphTraits<Inverse< ::clang::CFGBlock *>> {
1568 
1569  static NodeRef getEntryNode(::clang::CFG *F) { return &F->getExit(); }
1570  static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();}
1571  static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); }
1572 };
1573 
1574 template <> struct GraphTraits<Inverse<const ::clang::CFG *>>
1575  : public GraphTraits<Inverse<const ::clang::CFGBlock *>> {
1577 
1578  static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getExit(); }
1579 
1580  static nodes_iterator nodes_begin(const ::clang::CFG* F) {
1581  return F->nodes_begin();
1582  }
1583 
1584  static nodes_iterator nodes_end(const ::clang::CFG* F) {
1585  return F->nodes_end();
1586  }
1587 };
1588 
1589 } // namespace llvm
1590 
1591 #endif // LLVM_CLANG_ANALYSIS_CFG_H
clang::CFGBlock::beginScopeEndInsert
iterator beginScopeEndInsert(iterator I, size_t Cnt, BumpVectorContext &C)
Definition: CFG.h:1197
clang::operator!=
bool operator!=(CanQual< T > x, CanQual< U > y)
Definition: CanonicalType.h:207
clang::CFGTerminator::isStmtBranch
bool isStmtBranch() const
Definition: CFG.h:541
clang::CFGBlock::pred_rend
const_pred_reverse_iterator pred_rend() const
Definition: CFG.h:947
clang::CFGBlock::getTerminator
CFGTerminator getTerminator() const
Definition: CFG.h:1050
clang::CFGBlock::rref_begin
reverse_ref_iterator rref_begin()
Definition: CFG.h:907
clang::CFGBlock::const_ref_iterator_range
llvm::iterator_range< const_ref_iterator > const_ref_iterator_range
Definition: CFG.h:893
clang::CFG::synthetic_stmt_range
llvm::iterator_range< synthetic_stmt_iterator > synthetic_stmt_range
Definition: CFG.h:1374
clang::CFGBlock::getLabel
const Stmt * getLabel() const
Definition: CFG.h:1072
clang::CFGTerminator::isValid
bool isValid() const
Definition: CFG.h:536
clang::CFGImplicitDtor::getDestructorDecl
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
Definition: CFG.cpp:5282
clang::CFG::rend
reverse_iterator rend()
Definition: CFG.h:1322
clang::CFGScopeEnd
Represents end of a scope implicitly generated by the compiler after the last Stmt in a CompoundStmt'...
Definition: CFG.h:343
clang::CFGTerminator::Kind
Kind
Definition: CFG.h:507
clang::CFGBlock::prependScopeBegin
void prependScopeBegin(const VarDecl *VD, const Stmt *S, BumpVectorContext &C)
Definition: CFG.h:1127
clang::CFGBlock::FilterEdge
static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src, const CFGBlock *Dst)
Definition: CFG.cpp:5379
clang::CFG::nodes_begin
iterator nodes_begin()
Definition: CFG.h:1310
llvm
YAML serialization mapping.
Definition: Dominators.h:30
clang::CFG::getExit
const CFGBlock & getExit() const
Definition: CFG.h:1336
clang::CFG::VisitBlockStmts
void VisitBlockStmts(Callback &O) const
Definition: CFG.h:1399
clang::CFGConstructor::CFGConstructor
CFGConstructor(const CXXConstructExpr *CE, const ConstructionContext *C)
Definition: CFG.h:158
llvm::GraphTraits< Inverse< const ::clang::CFGBlock * > >::child_end
static ChildIteratorType child_end(NodeRef N)
Definition: CFG.h:1531
clang::CFG::synthetic_stmt_iterator
llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator
Definition: CFG.h:1373
clang::CFGBlock::succ_iterator
AdjacentBlocks::iterator succ_iterator
Definition: CFG.h:932
clang::CFGBlock::Label
Stmt * Label
An (optional) label that prefixes the executable statements in the block.
Definition: CFG.h:773
clang::CFGMemberDtor::getFieldDecl
const FieldDecl * getFieldDecl() const
Definition: CFG.h:468
clang::CFGBlock::operator[]
CFGElement operator[](size_t i) const
Definition: CFG.h:922
llvm::GraphTraits< ::clang::CFG * >::nodes_begin
static nodes_iterator nodes_begin(::clang::CFG *F)
Definition: CFG.h:1541
clang::CFGBlock::getLoopTarget
const Stmt * getLoopTarget() const
Definition: CFG.h:1069
clang::CFGBlock::begin
iterator begin()
Definition: CFG.h:877
clang::CFG::BuildOptions::BuildOptions
BuildOptions()=default
llvm::GraphTraits< const ::clang::CFG * >::size
static unsigned size(const ::clang::CFG *F)
Definition: CFG.h:1560
clang::CFGLifetimeEnds::getTriggerStmt
const Stmt * getTriggerStmt() const
Definition: CFG.h:301
clang::CFGBlock::succ_rbegin
succ_reverse_iterator succ_rbegin()
Definition: CFG.h:962
clang::CFGLifetimeEnds::CFGLifetimeEnds
CFGLifetimeEnds(const VarDecl *var, const Stmt *stmt)
Definition: CFG.h:294
clang::CFG::BuildOptions::AddCXXDefaultInitExprInAggregates
bool AddCXXDefaultInitExprInAggregates
Definition: CFG.h:1252
clang::CFGBlock::const_pred_reverse_iterator
AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator
Definition: CFG.h:928
clang::CFGBlock::empty
bool empty() const
Definition: CFG.h:920
Ret
static bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
Definition: Interp.cpp:34
clang::CFGScopeEnd::getTriggerStmt
const Stmt * getTriggerStmt() const
Definition: CFG.h:352
clang::ast_matchers::stmt
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
Definition: ASTMatchersInternal.cpp:811
clang::CFGLoopExit::CFGLoopExit
CFGLoopExit(const Stmt *stmt)
Definition: CFG.h:275
clang::CFGBlock::filtered_succ_iterator
FilteredCFGBlockIterator< const_succ_iterator, false > filtered_succ_iterator
Definition: CFG.h:1029
clang::CFG::nodes_end
iterator nodes_end()
Definition: CFG.h:1311
IMPL
#define IMPL(Index)
Definition: ASTMatchFinder.cpp:780
llvm::GraphTraits< const ::clang::CFGBlock * >::child_end
static ChildIteratorType child_end(NodeRef N)
Definition: CFG.h:1507
clang::CFGBlock::succ_size
unsigned succ_size() const
Definition: CFG.h:975
clang::CFGBlock::iterator
ElementList::iterator iterator
Definition: CFG.h:867
clang::CFG::addSyntheticDeclStmt
void addSyntheticDeclStmt(const DeclStmt *Synthetic, const DeclStmt *Source)
Records a synthetic DeclStmt and the DeclStmt it was constructed from.
Definition: CFG.h:1364
llvm::GraphTraits< const ::clang::CFG * >::getEntryNode
static NodeRef getEntryNode(const ::clang::CFG *F)
Definition: CFG.h:1550
clang::CFG::getNumBlockIDs
unsigned getNumBlockIDs() const
Returns the total number of BlockIDs allocated (which start at 0).
Definition: CFG.h:1413
clang::CFGBlock::succ_begin
succ_iterator succ_begin()
Definition: CFG.h:957
clang::CFGConstructor::getConstructionContext
const ConstructionContext * getConstructionContext() const
Definition: CFG.h:165
clang::CFGBlock::AdjacentBlock::operator->
CFGBlock * operator->() const
Definition: CFG.h:831
clang::CFGBlock::reverse_ref_iterator
ElementRefIterator< true, false > reverse_ref_iterator
Definition: CFG.h:895
clang::CFG::BuildOptions::AddEHEdges
bool AddEHEdges
Definition: CFG.h:1242
clang::CFGElement::Kind
Kind
Definition: CFG.h:57
clang::CFGBlock::front
CFGElement front() const
Definition: CFG.h:874
clang::CFGBlock::appendScopeEnd
void appendScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C)
Definition: CFG.h:1132
clang::CFG::try_block_range
llvm::iterator_range< try_block_iterator > try_block_range
Definition: CFG.h:1342
clang::Stmt::StmtClass
StmtClass
Definition: Stmt.h:73
clang::CFGBlock::succ_rbegin
const_succ_reverse_iterator succ_rbegin() const
Definition: CFG.h:964
clang::CFG::addTryDispatchBlock
void addTryDispatchBlock(const CFGBlock *block)
Definition: CFG.h:1356
clang::CFGTemporaryDtor::getBindTemporaryExpr
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
Definition: CFG.h:489
clang::CFGElement::NewAllocator
@ NewAllocator
Definition: CFG.h:62
clang::CFGBlock::getBlockID
unsigned getBlockID() const
Definition: CFG.h:1076
clang::CFG::BuildOptions::setAllAlwaysAdd
BuildOptions & setAllAlwaysAdd()
Definition: CFG.h:1269
llvm::GraphTraits< Inverse< ::clang::CFGBlock * > >::child_begin
static ChildIteratorType child_begin(NodeRef N)
Definition: CFG.h:1518
clang::CFG::rbegin
reverse_iterator rbegin()
Definition: CFG.h:1321
clang::CFGTemporaryDtor
Represents C++ object destructor implicitly generated at the end of full expression for temporary obj...
Definition: CFG.h:484
clang::CFGTerminator::isTemporaryDtorsBranch
bool isTemporaryDtorsBranch() const
Definition: CFG.h:544
clang::CFGAutomaticObjDtor::getTriggerStmt
const Stmt * getTriggerStmt() const
Definition: CFG.h:401
clang::CFGBlock::appendNewAllocator
void appendNewAllocator(CXXNewExpr *NE, BumpVectorContext &C)
Definition: CFG.h:1117
clang::ConstructionContext
ConstructionContext's subclasses describe different ways of constructing an object in C++.
Definition: ConstructionContext.h:243
clang::CFGLoopExit::getLoopStmt
const Stmt * getLoopStmt() const
Definition: CFG.h:277
clang::CFGBlock::FilteredCFGBlockIterator::operator*
const CFGBlock * operator*() const
Definition: CFG.h:1017
clang::CFGScopeBegin::CFGScopeBegin
CFGScopeBegin()
Definition: CFG.h:319
clang::CFGBlock::pred_empty
bool pred_empty() const
Definition: CFG.h:979
clang::CFGBlock::appendLifetimeEnds
void appendLifetimeEnds(VarDecl *VD, Stmt *S, BumpVectorContext &C)
Definition: CFG.h:1156
clang::QualType::getCanonicalType
QualType getCanonicalType() const
Definition: Type.h:6674
clang::FieldDecl
Represents a member of a struct/union/class.
Definition: Decl.h:2930
clang::CFGElement::LifetimeEnds
@ LifetimeEnds
Definition: CFG.h:63
clang::CFG::getIndirectGotoBlock
const CFGBlock * getIndirectGotoBlock() const
Definition: CFG.h:1339
llvm::GraphTraits< Inverse< const ::clang::CFG * > >::nodes_end
static nodes_iterator nodes_end(const ::clang::CFG *F)
Definition: CFG.h:1584
clang::CFG::getEntry
const CFGBlock & getEntry() const
Definition: CFG.h:1334
clang::CFGImplicitDtor::isNoReturn
bool isNoReturn(ASTContext &astContext) const
clang::CXXNewExpr
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition: ExprCXX.h:2146
clang::CFGBlock::prependScopeEnd
void prependScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C)
Definition: CFG.h:1136
clang::CFGBlock::ref_begin
ref_iterator ref_begin()
Definition: CFG.h:902
clang::CFGTerminator::CFGTerminator
CFGTerminator()
Definition: CFG.h:533
clang::CFGBlock::insertAutomaticObjDtor
iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S)
Definition: CFG.h:1176
clang::CFG::nodes_end
const_iterator nodes_end() const
Definition: CFG.h:1319
clang::CFGBlock::printTerminator
void printTerminator(raw_ostream &OS, const LangOptions &LO) const
printTerminator - A simple pretty printer of the terminator of a CFGBlock.
Definition: CFG.cpp:6140
clang::CFG::end
iterator end()
Definition: CFG.h:1306
llvm::Optional
Definition: LLVM.h:40
clang::CFG::isLinear
bool isLinear() const
Returns true if the CFG has no branches.
Definition: CFG.cpp:5236
clang::CFGScopeEnd::CFGScopeEnd
CFGScopeEnd()
Definition: CFG.h:345
clang::CFGElement::CFGElement
CFGElement(Kind kind, const void *Ptr1, const void *Ptr2=nullptr)
Definition: CFG.h:86
clang::CFGCXXRecordTypedCall::isCXXRecordTypedCall
static bool isCXXRecordTypedCall(const Expr *E)
Returns true when call expression CE needs to be represented by CFGCXXRecordTypedCall,...
Definition: CFG.h:189
clang::CFG::dump
void dump(const LangOptions &LO, bool ShowColors) const
dump - A simple pretty printer of a CFG that outputs to stderr.
Definition: CFG.cpp:6090
clang::CFGBlock::FilterOptions::IgnoreNullPredecessors
unsigned IgnoreNullPredecessors
Definition: CFG.h:984
clang::CFG::BuildOptions::MarkElidedCXXConstructors
bool MarkElidedCXXConstructors
Definition: CFG.h:1254
clang::CFGElement::LoopExit
@ LoopExit
Definition: CFG.h:64
clang::CFG::CFG
CFG()
Definition: CFG.h:1438
clang::CFGBlock::const_ref_iterator
ElementRefIterator< false, true > const_ref_iterator
Definition: CFG.h:892
clang::CFGElement::DTOR_BEGIN
@ DTOR_BEGIN
Definition: CFG.h:77
clang::CFG::size
unsigned size() const
Return the total number of CFGBlocks within the CFG This is simply a renaming of the getNumBlockIDs()...
Definition: CFG.h:1418
clang::CFGBlock::AdjacentBlock::operator*
CFGBlock & operator*() const
Definition: CFG.h:827
clang::CFGTerminator::StmtBranch
@ StmtBranch
A branch that corresponds to a statement in the code, such as an if-statement.
Definition: CFG.h:510
clang::CFGTerminator::getStmt
const Stmt * getStmt() const
Definition: CFG.h:538
clang::CFGBlock::const_succ_iterator
AdjacentBlocks::const_iterator const_succ_iterator
Definition: CFG.h:933
clang::CFGTemporaryDtor::CFGTemporaryDtor
CFGTemporaryDtor(const CXXBindTemporaryExpr *expr)
Definition: CFG.h:486
clang::CFGBlock::filtered_pred_iterator
FilteredCFGBlockIterator< const_pred_iterator, true > filtered_pred_iterator
Definition: CFG.h:1026
clang::CFGBlock::pred_begin
const_pred_iterator pred_begin() const
Definition: CFG.h:941
clang::CFG
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition: CFG.h:1227
clang::CFG::BuildOptions::OmitImplicitValueInitializers
bool OmitImplicitValueInitializers
Definition: CFG.h:1256
clang::CFGBlock::printTerminatorJson
void printTerminatorJson(raw_ostream &Out, const LangOptions &LO, bool AddQuotes) const
printTerminatorJson - Pretty-prints the terminator in JSON format.
Definition: CFG.cpp:6147
clang::BumpVector< AdjacentBlock >::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: BumpVector.h:84
clang::CFG::BuildOptions::AddRichCXXConstructors
bool AddRichCXXConstructors
Definition: CFG.h:1253
clang::Expr::isGLValue
bool isGLValue() const
Definition: Expr.h:273
clang::BumpVector::end
iterator end()
Definition: BumpVector.h:94
clang::CFGBlock::preds
pred_const_range preds() const
Definition: CFG.h:953
clang::CFGBlock::FilteredCFGBlockIterator::FilteredCFGBlockIterator
FilteredCFGBlockIterator(const IMPL &i, const IMPL &e, const CFGBlock *from, const FilterOptions &f)
Definition: CFG.h:1002
clang::CFG::BuildOptions::PruneTriviallyFalseEdges
bool PruneTriviallyFalseEdges
Definition: CFG.h:1241
clang::CFGBlock::rend
const_reverse_iterator rend() const
Definition: CFG.h:885
llvm::GraphTraits< const ::clang::CFG * >::nodes_begin
static nodes_iterator nodes_begin(const ::clang::CFG *F)
Definition: CFG.h:1552
clang::CFGBlock::setLoopTarget
void setLoopTarget(const Stmt *loopTarget)
Definition: CFG.h:1043
clang::CFGBlock::print
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:6132
clang::CFGAutomaticObjDtor::getVarDecl
const VarDecl * getVarDecl() const
Definition: CFG.h:396
clang::LoopExit
Represents a point when we exit a loop.
Definition: ProgramPoint.h:712
clang::CodeGen::AlignmentSource::Decl
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
clang::CFGTerminator::getStmt
Stmt * getStmt()
Definition: CFG.h:537
clang::CFGBlock::appendLoopExit
void appendLoopExit(const Stmt *LoopStmt, BumpVectorContext &C)
Definition: CFG.h:1160
clang::CFGBlock
Represents a single basic block in a source-level CFG.
Definition: CFG.h:578
clang::CFGBlock::getTerminatorStmt
const Stmt * getTerminatorStmt() const
Definition: CFG.h:1053
clang::CFG::BuildOptions
Definition: CFG.h:1233
llvm::GraphTraits< ::clang::CFGBlock * >::child_end
static ChildIteratorType child_end(NodeRef N)
Definition: CFG.h:1498
clang::CFGBlock::appendAutomaticObjDtor
void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C)
Definition: CFG.h:1152
clang::CFG::createBlock
CFGBlock * createBlock()
Create a new block in the CFG.
Definition: CFG.cpp:5213
llvm::GraphTraits< Inverse< ::clang::CFGBlock * > >::getEntryNode
static NodeRef getEntryNode(Inverse<::clang::CFGBlock * > G)
Definition: CFG.h:1514
clang::CFGBlock::succs
succ_range succs()
Definition: CFG.h:967
clang::CFG::const_reverse_nodes
llvm::iterator_range< const_reverse_iterator > const_reverse_nodes() const
Definition: CFG.h:1329
clang::ast_matchers::expr
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
Definition: ASTMatchersInternal.cpp:891
clang::CFGBlock::setTerminator
void setTerminator(CFGTerminator Term)
Definition: CFG.h:1041
clang::CFG::end
const_iterator end() const
Definition: CFG.h:1308
clang::CFGBlock::succ_range
llvm::iterator_range< succ_iterator > succ_range
Definition: CFG.h:936
llvm::GraphTraits< const ::clang::CFG * >::nodes_end
static nodes_iterator nodes_end(const ::clang::CFG *F)
Definition: CFG.h:1556
clang::CFGTerminator::TemporaryDtorsBranch
@ TemporaryDtorsBranch
A branch in control flow of destructors of temporaries.
Definition: CFG.h:514
clang::CFG::reverse_nodes
llvm::iterator_range< reverse_iterator > reverse_nodes()
Definition: CFG.h:1326
clang::CFG::nodes
llvm::iterator_range< iterator > nodes()
Definition: CFG.h:1313
clang::CFG::try_blocks_end
try_block_iterator try_blocks_end() const
Definition: CFG.h:1348
clang::CFGBlock::appendConstructor
void appendConstructor(CXXConstructExpr *CE, const ConstructionContext *CC, BumpVectorContext &C)
Definition: CFG.h:1101
clang::CFGBlock::end
const_iterator end() const
Definition: CFG.h:880
clang::CFG::back
CFGBlock & back()
Definition: CFG.h:1303
clang::CFGElement::ScopeBegin
@ ScopeBegin
Definition: CFG.h:60
clang::CXXBindTemporaryExpr
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1419
clang::CFGConstructor
Represents C++ constructor call.
Definition: CFG.h:156
clang::CFG::BuildOptions::alwaysAdd
bool alwaysAdd(const Stmt *stmt) const
Definition: CFG.h:1260
clang::CFGCallback::~CFGCallback
virtual ~CFGCallback()=default
clang::BinaryOperator
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3813
clang::CFGElement::ScopeEnd
@ ScopeEnd
Definition: CFG.h:61
clang::CFGBlock::pred_iterator
AdjacentBlocks::iterator pred_iterator
Definition: CFG.h:925
clang::CFG::buildCFG
static std::unique_ptr< CFG > buildCFG(const Decl *D, Stmt *AST, ASTContext *C, const BuildOptions &BO)
Builds a CFG from an AST.
Definition: CFG.cpp:5230
llvm::GraphTraits< ::clang::CFG * >::nodes_end
static nodes_iterator nodes_end(::clang::CFG *F)
Definition: CFG.h:1542
clang::CFGNewAllocator::getAllocatorExpr
const CXXNewExpr * getAllocatorExpr() const
Definition: CFG.h:253
clang::CFGBlock::CFGElementRef
ElementRefImpl< false > CFGElementRef
Definition: CFG.h:887
clang::CFGScopeBegin::getTriggerStmt
const Stmt * getTriggerStmt() const
Definition: CFG.h:324
clang::BumpVector::rbegin
reverse_iterator rbegin()
Definition: BumpVector.h:98
clang::transformer::statement
RangeSelector statement(std::string ID)
Selects a node, including trailing semicolon (always).
Definition: RangeSelector.cpp:154
clang::CFGBlock::appendBaseDtor
void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C)
Definition: CFG.h:1140
clang::BumpVector::back
reference back()
Definition: BumpVector.h:124
clang::CFGMemberDtor
Represents C++ object destructor implicitly generated for member object in destructor.
Definition: CFG.h:463
clang::BumpVector::rend
reverse_iterator rend()
Definition: BumpVector.h:100
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
clang::CFG::getBumpVectorContext
BumpVectorContext & getBumpVectorContext()
Definition: CFG.h:1444
clang::CFGCXXRecordTypedCall::CFGCXXRecordTypedCall
CFGCXXRecordTypedCall(const Expr *E, const ConstructionContext *C)
Definition: CFG.h:198
llvm::GraphTraits< const ::clang::CFGBlock * >::getEntryNode
static NodeRef getEntryNode(const clang::CFGBlock *BB)
Definition: CFG.h:1505
clang::CFGBlock::succ_begin
const_succ_iterator succ_begin() const
Definition: CFG.h:959
clang::CFGBlock::size
unsigned size() const
Definition: CFG.h:919
clang::CFGBlock::succ_end
const_succ_iterator succ_end() const
Definition: CFG.h:960
clang::CFG::BuildOptions::AddLifetime
bool AddLifetime
Definition: CFG.h:1245
clang::CFG::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: CFG.h:1299
clang::CFGDeleteDtor::getCXXRecordDecl
const CXXRecordDecl * getCXXRecordDecl() const
Definition: CFG.h:421
clang::CFGElement::CFGElement
CFGElement()=default
clang::CFGInitializer::getInitializer
CXXCtorInitializer * getInitializer() const
Definition: CFG.h:232
clang::CFG::getAllocator
llvm::BumpPtrAllocator & getAllocator()
Definition: CFG.h:1440
clang::CFGBlock::FilterOptions
Definition: CFG.h:982
clang::CFGAutomaticObjDtor
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
Definition: CFG.h:391
clang::CFGBlock::getLastCondition
const Expr * getLastCondition() const
Definition: CFG.cpp:6222
clang::CFGBlock::succ_empty
bool succ_empty() const
Definition: CFG.h:976
clang::CFGTerminator::VirtualBaseBranch
@ VirtualBaseBranch
A shortcut around virtual base initializers.
Definition: CFG.h:518
llvm::GraphTraits< Inverse< const ::clang::CFG * > >::getEntryNode
static NodeRef getEntryNode(const ::clang::CFG *F)
Definition: CFG.h:1578
llvm::GraphTraits< Inverse< const ::clang::CFGBlock * > >::getEntryNode
static NodeRef getEntryNode(Inverse< const ::clang::CFGBlock * > G)
Definition: CFG.h:1526
clang::CFGElement::CXXRecordTypedCall
@ CXXRecordTypedCall
Definition: CFG.h:68
clang::CFGElement::Initializer
@ Initializer
Definition: CFG.h:59
clang::CFGBlock::rend
reverse_iterator rend()
Definition: CFG.h:883
clang::CXXDestructorDecl
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2703
clang::CFG::BuildOptions::AddVirtualBaseBranches
bool AddVirtualBaseBranches
Definition: CFG.h:1255
clang::CFGBlock::const_iterator
ElementList::const_iterator const_iterator
Definition: CFG.h:868
clang::CFGTerminator::isVirtualBaseBranch
bool isVirtualBaseBranch() const
Definition: CFG.h:547
clang::CFG::synthetic_stmt_begin
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
Definition: CFG.h:1381
clang::CFGTerminator::NumKindsMinusOne
@ NumKindsMinusOne
Number of different kinds, for assertions.
Definition: CFG.h:523
clang::CFGBlock::getParent
CFG * getParent() const
Definition: CFG.h:1078
llvm::GraphTraits< ::clang::CFG * >::getEntryNode
static NodeRef getEntryNode(::clang::CFG *F)
Definition: CFG.h:1540
BumpVector.h
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:906
clang::CFGBlock::begin
const_iterator begin() const
Definition: CFG.h:879
clang::CFGLifetimeEnds
Represents the point where the lifetime of an automatic object ends.
Definition: CFG.h:292
clang::CFGBlock::refs
const_ref_iterator_range refs() const
Definition: CFG.h:913
clang::CFGCXXRecordTypedCall
Represents a function call that returns a C++ object by value.
Definition: CFG.h:185
clang::dataflow::var
static constexpr Variable var(Literal L)
Returns the variable of L.
Definition: WatchedLiteralsSolver.cpp:71
clang::extractElementInitializerFromNestedAILE
Expr * extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE)
Definition: CFG.cpp:1336
clang::Type::getAsCXXRecordDecl
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1760
clang::CFGElement::STMT_END
@ STMT_END
Definition: CFG.h:70
clang::CFG::iterator
CFGBlockListTy::iterator iterator
Definition: CFG.h:1297
clang::CFGBlock::reverse_ref_iterator_range
llvm::iterator_range< reverse_ref_iterator > reverse_ref_iterator_range
Definition: CFG.h:896
ExprObjC.h
ExprCXX.h
clang::CFGCallback
CFGCallback defines methods that should be called when a logical operator error is found when buildin...
Definition: CFG.h:1209
clang::CFGImplicitDtor::CFGImplicitDtor
CFGImplicitDtor()=default
clang::CFGBlock::getTerminatorCondition
Stmt * getTerminatorCondition(bool StripParens=true)
Definition: CFG.cpp:6250
clang::CFGBlock::rbegin
reverse_iterator rbegin()
Definition: CFG.h:882
clang::CFG::getIndirectGotoBlock
CFGBlock * getIndirectGotoBlock()
Definition: CFG.h:1338
clang::CFGStmt::CFGStmt
CFGStmt()=default
clang::CFG::getExit
CFGBlock & getExit()
Definition: CFG.h:1335
clang::CFGImplicitDtor::CFGImplicitDtor
CFGImplicitDtor(Kind kind, const void *data1, const void *data2=nullptr)
Definition: CFG.h:370
clang::CFGTerminator
Represents CFGBlock terminator statement.
Definition: CFG.h:505
clang::BumpVector< CFGElement >::const_reference
const CFGElement & const_reference
Definition: BumpVector.h:87
clang::CFGBlock::succ_rend
const_succ_reverse_iterator succ_rend() const
Definition: CFG.h:965
x
IRgen optimization opportunities The common pattern of short x
Definition: README.txt:7
clang::CFGBlock::AdjacentBlock::AdjacentBlock
AdjacentBlock(CFGBlock *B, bool IsReachable)
Construct an AdjacentBlock with a possibly unreachable block.
Definition: CFG.cpp:5358
clang::CFG::BuildOptions::AddScopes
bool AddScopes
Definition: CFG.h:1248
clang::BumpVector::begin
iterator begin()
Definition: BumpVector.h:92
clang::CFGBlock::FilteredCFGBlockIterator::operator++
FilteredCFGBlockIterator & operator++()
Definition: CFG.h:1012
clang::CFGElement::AutomaticObjectDtor
@ AutomaticObjectDtor
Definition: CFG.h:72
clang::CFGBlock::pred_rend
pred_reverse_iterator pred_rend()
Definition: CFG.h:945
clang::BumpVector::front
reference front()
Definition: BumpVector.h:117
clang::CFGBlock::filtered_pred_start_end
filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const
Definition: CFG.h:1031
clang::CFGImplicitDtor
Represents C++ object destructor implicitly generated by compiler on various occasions.
Definition: CFG.h:366
clang::CFG::setIndirectGotoBlock
void setIndirectGotoBlock(CFGBlock *B)
Set the block used for indirect goto jumps.
Definition: CFG.h:1290
clang::CFGTerminator::CFGTerminator
CFGTerminator(Stmt *S, Kind K=StmtBranch)
Definition: CFG.h:534
clang::CFGBaseDtor::getBaseSpecifier
const CXXBaseSpecifier * getBaseSpecifier() const
Definition: CFG.h:447
clang::CFGBlock::setLabel
void setLabel(Stmt *Statement)
Definition: CFG.h:1042
llvm::GraphTraits< Inverse< const ::clang::CFG * > >::nodes_begin
static nodes_iterator nodes_begin(const ::clang::CFG *F)
Definition: CFG.h:1580
operator*
clang::CharUnits operator*(clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU)
Definition: CharUnits.h:219
llvm::GraphTraits< ::clang::CFGBlock * >::getEntryNode
static NodeRef getEntryNode(::clang::CFGBlock *BB)
Definition: CFG.h:1496
clang::CFGBlock::pred_end
const_pred_iterator pred_end() const
Definition: CFG.h:942
clang::CFGElement::Statement
@ Statement
Definition: CFG.h:66
clang::CFGBlock::succs
succ_const_range succs() const
Definition: CFG.h:971
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
clang::BumpVector< AdjacentBlock >::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: BumpVector.h:83
clang::CFGMemberDtor::CFGMemberDtor
CFGMemberDtor(const FieldDecl *field)
Definition: CFG.h:465
clang::CFG::const_iterator
CFGBlockListTy::const_iterator const_iterator
Definition: CFG.h:1298
clang::CFGBlock::back
CFGElement back() const
Definition: CFG.h:875
clang::DeclStmt::isSingleDecl
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
Definition: Stmt.h:1316
clang::CFGBlock::FilteredCFGBlockIterator
Definition: CFG.h:995
clang::CFGStmt
Definition: CFG.h:132
clang::CFG::begin
const_iterator begin() const
Definition: CFG.h:1307
clang::CFGElement::castAs
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.
Definition: CFG.h:98
clang::CFGInitializer::CFGInitializer
CFGInitializer(const CXXCtorInitializer *initializer)
Definition: CFG.h:229
false
#define false
Definition: stdbool.h:22
clang::CFGBlock::ref_iterator
ElementRefIterator< false, false > ref_iterator
Definition: CFG.h:890
clang::CFG::BuildOptions::AddLoopExit
bool AddLoopExit
Definition: CFG.h:1246
clang::CFGElement::getAs
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
Definition: CFG.h:109
clang::CFGBlock::appendStmt
void appendStmt(Stmt *statement, BumpVectorContext &C)
Definition: CFG.h:1097
clang::CFG::const_nodes
llvm::iterator_range< const_iterator > const_nodes() const
Definition: CFG.h:1314
llvm::GraphTraits< const ::clang::CFGBlock * >::ChildIteratorType
::clang::CFGBlock::const_succ_iterator ChildIteratorType
Definition: CFG.h:1503
clang::CFGBlock::succ_end
succ_iterator succ_end()
Definition: CFG.h:958
clang::CFGBlock::FilterOptions::FilterOptions
FilterOptions()
Definition: CFG.h:987
clang::CFGInitializer
Represents C++ base or member initializer from constructor's initialization list.
Definition: CFG.h:227
llvm::GraphTraits< ::clang::CFGBlock * >::ChildIteratorType
::clang::CFGBlock::succ_iterator ChildIteratorType
Definition: CFG.h:1494
clang::CFGBlock::ref_iterator_range
llvm::iterator_range< ref_iterator > ref_iterator_range
Definition: CFG.h:891
clang::CFGNewAllocator::CFGNewAllocator
CFGNewAllocator(const CXXNewExpr *S)
Definition: CFG.h:249
llvm::GraphTraits< Inverse< ::clang::CFGBlock * > >::child_end
static ChildIteratorType child_end(NodeRef N)
Definition: CFG.h:1519
clang::CFGLoopExit
Represents the point where a loop ends.
Definition: CFG.h:273
clang::CFGBlock::getTerminatorCondition
const Stmt * getTerminatorCondition(bool StripParens=true) const
Definition: CFG.h:1065
clang::CXXDeleteExpr
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition: ExprCXX.h:2422
clang::CFGBlock::getLabel
Stmt * getLabel()
Definition: CFG.h:1071
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::CFGBlock::pred_begin
pred_iterator pred_begin()
Definition: CFG.h:939
clang::CFGElement::dumpToStream
void dumpToStream(llvm::raw_ostream &OS) const
Definition: CFG.cpp:5749
clang::CFG::CFGBlockListTy
BumpVector< CFGBlock * > CFGBlockListTy
Definition: CFG.h:1296
llvm::simplify_type< ::clang::CFGTerminator >::getSimplifiedValue
static SimpleType getSimplifiedValue(::clang::CFGTerminator Val)
Definition: CFG.h:1485
clang::CFGBlock::isInevitablySinking
bool isInevitablySinking() const
Returns true if the block would eventually end with a sink (a noreturn node).
Definition: CFG.cpp:6184
clang::CFG::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: CFG.h:1300
clang::CFG::nodes_begin
const_iterator nodes_begin() const
Definition: CFG.h:1318
clang::CFGBlock::insertScopeEnd
iterator insertScopeEnd(iterator I, VarDecl *VD, Stmt *S)
Definition: CFG.h:1201
clang::CFGBlock::succ_const_range
llvm::iterator_range< const_succ_iterator > succ_const_range
Definition: CFG.h:937
LLVM.h
clang::CFG::BuildOptions::AddStaticInitBranches
bool AddStaticInitBranches
Definition: CFG.h:1249
clang::CFGBlock::pred_const_range
llvm::iterator_range< const_pred_iterator > pred_const_range
Definition: CFG.h:930
clang::CFGBlock::succ_rend
succ_reverse_iterator succ_rend()
Definition: CFG.h:963
clang::CFGStmt::getStmt
const Stmt * getStmt() const
Definition: CFG.h:138
llvm::GraphTraits< ::clang::CFG * >::size
static unsigned size(::clang::CFG *F)
Definition: CFG.h:1543
clang::BumpVectorContext::getAllocator
llvm::BumpPtrAllocator & getAllocator()
Definition: BumpVector.h:55
clang::CFG::getEntry
CFGBlock & getEntry()
Definition: CFG.h:1333
clang::CFGBlock::appendCXXRecordTypedCall
void appendCXXRecordTypedCall(Expr *E, const ConstructionContext *CC, BumpVectorContext &C)
Definition: CFG.h:1106
clang::CFGBlock::Terminator
CFGTerminator Terminator
The terminator for a basic block that indicates the type of control-flow that occurs between a block ...
Definition: CFG.h:777
clang::CFGBlock::pred_size
unsigned pred_size() const
Definition: CFG.h:978
clang::CFG::setEntry
void setEntry(CFGBlock *B)
Set the entry block of the CFG.
Definition: CFG.h:1286
clang::CFGBlock::AdjacentBlock::isReachable
bool isReachable() const
Definition: CFG.h:835
clang::CFGBlock::appendInitializer
void appendInitializer(CXXCtorInitializer *initializer, BumpVectorContext &C)
Definition: CFG.h:1112
clang::CFGBaseDtor::CFGBaseDtor
CFGBaseDtor(const CXXBaseSpecifier *base)
Definition: CFG.h:444
clang::CFGDeleteDtor::CFGDeleteDtor
CFGDeleteDtor(const CXXRecordDecl *RD, const CXXDeleteExpr *DE)
Definition: CFG.h:418
clang::CFGCallback::compareAlwaysTrue
virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue)
Definition: CFG.h:1214
clang::CFGBlock::appendScopeBegin
void appendScopeBegin(const VarDecl *VD, const Stmt *S, BumpVectorContext &C)
Definition: CFG.h:1122
clang::CFGBlock::AdjacentBlock
This class represents a potential adjacent block in the CFG.
Definition: CFG.h:793
clang::CFGBlock::appendMemberDtor
void appendMemberDtor(FieldDecl *FD, BumpVectorContext &C)
Definition: CFG.h:1144
clang::CFG::synthetic_stmt_end
synthetic_stmt_iterator synthetic_stmt_end() const
Definition: CFG.h:1386
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:81
clang::CFGElement::BaseDtor
@ BaseDtor
Definition: CFG.h:74
clang::CFGElement
Represents a top-level expression in a basic block.
Definition: CFG.h:55
clang::CFGBlock::pred_rbegin
pred_reverse_iterator pred_rbegin()
Definition: CFG.h:944
clang::DeclStmt
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1303
llvm::GraphTraits< Inverse< ::clang::CFG * > >::nodes_begin
static nodes_iterator nodes_begin(::clang::CFG *F)
Definition: CFG.h:1570
clang::CFGBlock::pred_rbegin
const_pred_reverse_iterator pred_rbegin() const
Definition: CFG.h:946
clang::CFGBlock::dump
void dump() const
Definition: CFG.cpp:6126
clang::CFGScopeEnd::getVarDecl
const VarDecl * getVarDecl() const
Definition: CFG.h:348
clang::CFGBlock::ref_end
ref_iterator ref_end()
Definition: CFG.h:903
clang::CFG::BuildOptions::AddCXXNewAllocator
bool AddCXXNewAllocator
Definition: CFG.h:1250
clang::CFG::BuildOptions::AddImplicitDtors
bool AddImplicitDtors
Definition: CFG.h:1244
clang::CFGBlock::LoopTarget
const Stmt * LoopTarget
Some blocks are used to represent the "loop edge" to the start of a loop from within the loop body.
Definition: CFG.h:782
clang::CFGBlock::getIndexInCFG
size_t getIndexInCFG() const
Definition: CFG.cpp:6116
clang::CFGBlock::ConstCFGElementRef
ElementRefImpl< true > ConstCFGElementRef
Definition: CFG.h:888
clang::interp::NE
bool NE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:490
clang::CFGBlock::succ_reverse_iterator
AdjacentBlocks::reverse_iterator succ_reverse_iterator
Definition: CFG.h:934
llvm::GraphTraits< Inverse< ::clang::CFGBlock * > >::ChildIteratorType
::clang::CFGBlock::const_pred_iterator ChildIteratorType
Definition: CFG.h:1512
clang::CFGCallback::compareBitwiseOr
virtual void compareBitwiseOr(const BinaryOperator *B)
Definition: CFG.h:1217
clang::CFGBlock::insertLifetimeEnds
iterator insertLifetimeEnds(iterator I, VarDecl *VD, Stmt *S)
Definition: CFG.h:1189
llvm::GraphTraits< ::clang::CFGBlock * >::child_begin
static ChildIteratorType child_begin(NodeRef N)
Definition: CFG.h:1497
clang
Definition: CalledOnceCheck.h:17
clang::CFGBlock::beginAutomaticObjDtorsInsert
iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt, BumpVectorContext &C)
Definition: CFG.h:1171
clang::CFGBlock::FilterOptions::IgnoreDefaultsWithCoveredEnums
unsigned IgnoreDefaultsWithCoveredEnums
Definition: CFG.h:985
clang::CFGScopeBegin::CFGScopeBegin
CFGScopeBegin(const VarDecl *VD, const Stmt *S)
Definition: CFG.h:320
clang::CFGDeleteDtor
Represents C++ object destructor generated from a call to delete.
Definition: CFG.h:416
clang::CFGElement::Data1
llvm::PointerIntPair< void *, 2 > Data1
Definition: CFG.h:83
clang::CFGElement::DeleteDtor
@ DeleteDtor
Definition: CFG.h:73
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:71
clang::CFGBlock::hasNoReturnElement
bool hasNoReturnElement() const
Definition: CFG.h:1074
clang::CFG::try_blocks_begin
try_block_iterator try_blocks_begin() const
Definition: CFG.h:1344
clang::CFG::try_blocks
try_block_range try_blocks() const
Definition: CFG.h:1352
clang::CFGBaseDtor
Represents C++ object destructor implicitly generated for base object in destructor.
Definition: CFG.h:442
clang::CFGBlock::appendDeleteDtor
void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C)
Definition: CFG.h:1164
clang::CFGBlock::getTerminatorStmt
Stmt * getTerminatorStmt()
Definition: CFG.h:1052
clang::CFGBlock::FilteredCFGBlockIterator::hasMore
bool hasMore() const
Definition: CFG.h:1010
ConstructionContext.h
clang::operator<
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
Definition: DeclarationName.h:549
clang::CFGBlock::printAsOperand
void printAsOperand(raw_ostream &OS, bool)
Definition: CFG.h:1090
clang::Expr::getType
QualType getType() const
Definition: Expr.h:141
clang::CFGDeleteDtor::getDeleteExpr
const CXXDeleteExpr * getDeleteExpr() const
Definition: CFG.h:426
clang::CFGStmt::CFGStmt
CFGStmt(const Stmt *S, Kind K=Statement)
Definition: CFG.h:134
clang::CXXBaseSpecifier
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
clang::CFGBlock::const_reverse_ref_iterator_range
llvm::iterator_range< const_reverse_ref_iterator > const_reverse_ref_iterator_range
Definition: CFG.h:900
clang::CFGBlock::rref_end
reverse_ref_iterator rref_end()
Definition: CFG.h:908
clang::CFGBlock::rrefs
reverse_ref_iterator_range rrefs()
Definition: CFG.h:914
clang::CFGBlock::preds
pred_range preds()
Definition: CFG.h:949
unsigned
clang::CFGNewAllocator
Represents C++ allocator call.
Definition: CFG.h:247
clang::CFGScopeEnd::CFGScopeEnd
CFGScopeEnd(const VarDecl *VD, const Stmt *S)
Definition: CFG.h:346
clang::CFG::front
CFGBlock & front()
Definition: CFG.h:1302
clang::CFG::synthetic_stmts
synthetic_stmt_range synthetic_stmts() const
Definition: CFG.h:1391
clang::CFGBlock::refs
ref_iterator_range refs()
Definition: CFG.h:912
clang::CFGElement::getKind
Kind getKind() const
Definition: CFG.h:118
clang::CFGBlock::Elements
ElementList Elements
The set of statements in the basic block.
Definition: CFG.h:768
clang::CFG::begin
iterator begin()
Definition: CFG.h:1305
clang::CFGBlock::const_reverse_ref_iterator
ElementRefIterator< true, true > const_reverse_ref_iterator
Definition: CFG.h:898
clang::CFG::BuildOptions::forcedBlkExprs
ForcedBlkExprs ** forcedBlkExprs
Definition: CFG.h:1239
clang::CFGBlock::BlockID
unsigned BlockID
A numerical ID assigned to a CFGBlock during construction of the CFG.
Definition: CFG.h:785
clang::CFGCXXRecordTypedCall::getConstructionContext
const ConstructionContext * getConstructionContext() const
Definition: CFG.h:211
clang::CFGElement::TemporaryDtor
@ TemporaryDtor
Definition: CFG.h:76
clang::CFG::BuildOptions::AddCXXDefaultInitExprInCtors
bool AddCXXDefaultInitExprInCtors
Definition: CFG.h:1251
clang::CFGElement::STMT_BEGIN
@ STMT_BEGIN
Definition: CFG.h:69
clang::CFG::viewCFG
void viewCFG(const LangOptions &LO) const
Definition: CFG.cpp:6321
clang::CFGBlock::rrefs
const_reverse_ref_iterator_range rrefs() const
Definition: CFG.h:915
clang::CFG::BuildOptions::Observer
CFGCallback * Observer
Definition: CFG.h:1240
Parent
NodeId Parent
Definition: ASTDiff.cpp:190
clang::CFGCallback::CFGCallback
CFGCallback()=default
clang::CFGBlock::const_succ_reverse_iterator
AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator
Definition: CFG.h:935
clang::CFGScopeBegin
Represents beginning of a scope implicitly generated by the compiler on encountering a CompoundStmt.
Definition: CFG.h:317
clang::CFG::rbegin
const_reverse_iterator rbegin() const
Definition: CFG.h:1323
clang::CFGBlock::rbegin
const_reverse_iterator rbegin() const
Definition: CFG.h:884
llvm::GraphTraits< Inverse< const ::clang::CFGBlock * > >::child_begin
static ChildIteratorType child_begin(NodeRef N)
Definition: CFG.h:1530
clang::BumpVectorContext
Definition: BumpVector.h:32
clang::CFGBlock::setHasNoReturnElement
void setHasNoReturnElement()
Definition: CFG.h:1044
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::CFGBlock::ref_begin
const_ref_iterator ref_begin() const
Definition: CFG.h:904
clang::CFGBlock::end
iterator end()
Definition: CFG.h:878
clang::CFGCallback::compareBitwiseEquality
virtual void compareBitwiseEquality(const BinaryOperator *B, bool isAlwaysTrue)
Definition: CFG.h:1215
clang::CFGLifetimeEnds::getVarDecl
const VarDecl * getVarDecl() const
Definition: CFG.h:297
clang::CFGBlock::AdjacentBlock::getReachableBlock
CFGBlock * getReachableBlock() const
Get the reachable block, if one exists.
Definition: CFG.h:812
clang::CFG::BuildOptions::AddTemporaryDtors
bool AddTemporaryDtors
Definition: CFG.h:1247
clang::BumpVector< CFGElement >::iterator
CFGElement * iterator
Definition: BumpVector.h:80
clang::CFGBlock::beginLifetimeEndsInsert
iterator beginLifetimeEndsInsert(iterator I, size_t Cnt, BumpVectorContext &C)
Definition: CFG.h:1184
clang::CXXCtorInitializer
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2207
clang::CFGBlock::pred_range
llvm::iterator_range< pred_iterator > pred_range
Definition: CFG.h:929
llvm::GraphTraits< const ::clang::CFGBlock * >::child_begin
static ChildIteratorType child_begin(NodeRef N)
Definition: CFG.h:1506
llvm::GraphTraits< Inverse< ::clang::CFG * > >::getEntryNode
static NodeRef getEntryNode(::clang::CFG *F)
Definition: CFG.h:1569
clang::CFG::BuildOptions::ForcedBlkExprs
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
Definition: CFG.h:1237
clang::CFGElement::Constructor
@ Constructor
Definition: CFG.h:67
clang::CFGBlock::addSuccessor
void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C)
Adds a (potentially unreachable) successor block to the current block.
Definition: CFG.cpp:5368
clang::CFGBlock::pred_reverse_iterator
AdjacentBlocks::reverse_iterator pred_reverse_iterator
Definition: CFG.h:927
clang::diag::kind
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:62
clang::CFG::print
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:6095
clang::CFG::rend
const_reverse_iterator rend() const
Definition: CFG.h:1324
clang::CFG::try_block_iterator
std::vector< const CFGBlock * >::const_iterator try_block_iterator
Definition: CFG.h:1341
clang::CFG::BuildOptions::setAlwaysAdd
BuildOptions & setAlwaysAdd(Stmt::StmtClass stmtClass, bool val=true)
Definition: CFG.h:1264
clang::CFGBlock::appendTemporaryDtor
void appendTemporaryDtor(CXXBindTemporaryExpr *E, BumpVectorContext &C)
Definition: CFG.h:1148
clang::CXXConstructExpr
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1467
clang::CFGBlock::AdjacentBlock::getPossiblyUnreachableBlock
CFGBlock * getPossiblyUnreachableBlock() const
Get the potentially unreachable block.
Definition: CFG.h:817
clang::BumpVector< CFGElement >
clang::operator==
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
Definition: CallGraph.h:207
llvm::GraphTraits< Inverse< const ::clang::CFGBlock * > >::ChildIteratorType
::clang::CFGBlock::const_pred_iterator ChildIteratorType
Definition: CFG.h:1524
clang::CFGElement::dump
void dump() const
Definition: CFG.h:127
clang::CFGBlock::ref_end
const_ref_iterator ref_end() const
Definition: CFG.h:905
clang::CFGBlock::rref_begin
const_reverse_ref_iterator rref_begin() const
Definition: CFG.h:909
clang::BumpVector< CFGElement >::const_iterator
const CFGElement * const_iterator
Definition: BumpVector.h:81
clang::CFG::BuildOptions::AddInitializers
bool AddInitializers
Definition: CFG.h:1243
clang::CFGBlock::CFGBlock
CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
Definition: CFG.h:862
clang::CFGBlock::rref_end
const_reverse_ref_iterator rref_end() const
Definition: CFG.h:910
clang::CFGScopeBegin::getVarDecl
const VarDecl * getVarDecl() const
Definition: CFG.h:329
clang::CFGTerminator::getKind
Kind getKind() const
Definition: CFG.h:539
clang::CFGBlock::pred_end
pred_iterator pred_end()
Definition: CFG.h:940
clang::CFGElement::MemberDtor
@ MemberDtor
Definition: CFG.h:75
clang::CFGAutomaticObjDtor::CFGAutomaticObjDtor
CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt)
Definition: CFG.h:393
clang::CFGBlock::filtered_succ_start_end
filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const
Definition: CFG.h:1035
clang::CFGBlock::const_pred_iterator
AdjacentBlocks::const_iterator const_pred_iterator
Definition: CFG.h:926
clang::CFGElement::DTOR_END
@ DTOR_END
Definition: CFG.h:78
llvm::GraphTraits< Inverse< ::clang::CFG * > >::nodes_end
static nodes_iterator nodes_end(::clang::CFG *F)
Definition: CFG.h:1571
clang::CFGElement::Data2
llvm::PointerIntPair< void *, 2 > Data2
Definition: CFG.h:84