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