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