clang 17.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/PointerIntPair.h"
25#include "llvm/ADT/iterator_range.h"
26#include "llvm/Support/Allocator.h"
27#include "llvm/Support/raw_ostream.h"
28#include <bitset>
29#include <cassert>
30#include <cstddef>
31#include <iterator>
32#include <memory>
33#include <optional>
34#include <vector>
35
36namespace clang {
37
38class ASTContext;
39class BinaryOperator;
40class CFG;
41class CXXBaseSpecifier;
42class CXXBindTemporaryExpr;
43class CXXCtorInitializer;
44class CXXDeleteExpr;
45class CXXDestructorDecl;
46class CXXNewExpr;
47class CXXRecordDecl;
48class Decl;
49class FieldDecl;
50class LangOptions;
51class VarDecl;
52
53/// Represents a top-level expression in a basic block.
55public:
56 enum Kind {
57 // main kind
64 // stmt kind
70 // dtor kind
78 };
79
80protected:
81 // The int bits are used to mark the kind.
82 llvm::PointerIntPair<void *, 2> Data1;
83 llvm::PointerIntPair<void *, 2> Data2;
84
85 CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr)
86 : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
87 Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
88 assert(getKind() == kind);
89 }
90
91 CFGElement() = default;
92
93public:
94 /// Convert to the specified CFGElement type, asserting that this
95 /// CFGElement is of the desired type.
96 template<typename T>
97 T castAs() const {
98 assert(T::isKind(*this));
99 T t;
100 CFGElement& e = t;
101 e = *this;
102 return t;
103 }
104
105 /// Convert to the specified CFGElement type, returning std::nullopt if this
106 /// CFGElement is not of the desired type.
107 template <typename T> std::optional<T> getAs() const {
108 if (!T::isKind(*this))
109 return std::nullopt;
110 T t;
111 CFGElement& e = t;
112 e = *this;
113 return t;
114 }
115
116 Kind getKind() const {
117 unsigned x = Data2.getInt();
118 x <<= 2;
119 x |= Data1.getInt();
120 return (Kind) x;
121 }
122
123 void dumpToStream(llvm::raw_ostream &OS) const;
124
125 void dump() const {
126 dumpToStream(llvm::errs());
127 }
128};
129
130class CFGStmt : public CFGElement {
131public:
132 explicit CFGStmt(const Stmt *S, Kind K = Statement) : CFGElement(K, S) {
133 assert(isKind(*this));
134 }
135
136 const Stmt *getStmt() const {
137 return static_cast<const Stmt *>(Data1.getPointer());
138 }
139
140private:
141 friend class CFGElement;
142
143 static bool isKind(const CFGElement &E) {
144 return E.getKind() >= STMT_BEGIN && E.getKind() <= STMT_END;
145 }
146
147protected:
148 CFGStmt() = default;
149};
150
151/// Represents C++ constructor call. Maintains information necessary to figure
152/// out what memory is being initialized by the constructor expression. For now
153/// this is only used by the analyzer's CFG.
154class CFGConstructor : public CFGStmt {
155public:
157 const ConstructionContext *C)
158 : CFGStmt(CE, Constructor) {
159 assert(C);
160 Data2.setPointer(const_cast<ConstructionContext *>(C));
161 }
162
164 return static_cast<ConstructionContext *>(Data2.getPointer());
165 }
166
167private:
168 friend class CFGElement;
169
170 CFGConstructor() = default;
171
172 static bool isKind(const CFGElement &E) {
173 return E.getKind() == Constructor;
174 }
175};
176
177/// Represents a function call that returns a C++ object by value. This, like
178/// constructor, requires a construction context in order to understand the
179/// storage of the returned object . In C such tracking is not necessary because
180/// no additional effort is required for destroying the object or modeling copy
181/// elision. Like CFGConstructor, this element is for now only used by the
182/// analyzer's CFG.
184public:
185 /// Returns true when call expression \p CE needs to be represented
186 /// by CFGCXXRecordTypedCall, as opposed to a regular CFGStmt.
187 static bool isCXXRecordTypedCall(const Expr *E) {
188 assert(isa<CallExpr>(E) || isa<ObjCMessageExpr>(E));
189 // There is no such thing as reference-type expression. If the function
190 // returns a reference, it'll return the respective lvalue or xvalue
191 // instead, and we're only interested in objects.
192 return !E->isGLValue() &&
194 }
195
198 assert(isCXXRecordTypedCall(E));
199 assert(C && (isa<TemporaryObjectConstructionContext>(C) ||
200 // These are possible in C++17 due to mandatory copy elision.
201 isa<ReturnedValueConstructionContext>(C) ||
202 isa<VariableConstructionContext>(C) ||
203 isa<ConstructorInitializerConstructionContext>(C) ||
204 isa<ArgumentConstructionContext>(C) ||
205 isa<LambdaCaptureConstructionContext>(C)));
206 Data2.setPointer(const_cast<ConstructionContext *>(C));
207 }
208
210 return static_cast<ConstructionContext *>(Data2.getPointer());
211 }
212
213private:
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.
226public:
227 explicit CFGInitializer(const CXXCtorInitializer *initializer)
228 : CFGElement(Initializer, initializer) {}
229
231 return static_cast<CXXCtorInitializer*>(Data1.getPointer());
232 }
233
234private:
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.
246public:
247 explicit CFGNewAllocator(const CXXNewExpr *S)
248 : CFGElement(NewAllocator, S) {}
249
250 // Get the new expression.
252 return static_cast<CXXNewExpr *>(Data1.getPointer());
253 }
254
255private:
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 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.
271class CFGLoopExit : public CFGElement {
272public:
273 explicit CFGLoopExit(const Stmt *stmt) : CFGElement(LoopExit, stmt) {}
274
275 const Stmt *getLoopStmt() const {
276 return static_cast<Stmt *>(Data1.getPointer());
277 }
278
279private:
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
291public:
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
303private:
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
315class CFGScopeBegin : public CFGElement {
316public:
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
331private:
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
341class CFGScopeEnd : public CFGElement {
342public:
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
354private:
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.
365protected:
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
373public:
374 const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const;
375 bool isNoReturn(ASTContext &astContext) const;
376
377private:
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.
390public:
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
403private:
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.
415public:
417 : CFGImplicitDtor(DeleteDtor, RD, DE) {}
418
420 return static_cast<CXXRecordDecl*>(Data1.getPointer());
421 }
422
423 // Get Delete expression which triggered the destructor call.
425 return static_cast<CXXDeleteExpr *>(Data2.getPointer());
426 }
427
428private:
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.
441public:
443 : CFGImplicitDtor(BaseDtor, base) {}
444
446 return static_cast<const CXXBaseSpecifier*>(Data1.getPointer());
447 }
448
449private:
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.
462public:
464 : CFGImplicitDtor(MemberDtor, field, nullptr) {}
465
466 const FieldDecl *getFieldDecl() const {
467 return static_cast<const FieldDecl*>(Data1.getPointer());
468 }
469
470private:
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.
483public:
485 : CFGImplicitDtor(TemporaryDtor, expr, nullptr) {}
486
488 return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer());
489 }
490
491private:
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///
504public:
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 assertions. 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
524private:
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
530public:
531 CFGTerminator() { assert(!isValid()); }
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 }
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.
576class 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,
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, std::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
764public:
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
785public:
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
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
839private:
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
859public:
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
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
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
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
1025
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
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
1095 void appendStmt(Stmt *statement, BumpVectorContext &C) {
1096 Elements.push_back(CFGStmt(statement), C);
1097 }
1098
1101 Elements.push_back(CFGConstructor(CE, CC), C);
1102 }
1103
1105 const ConstructionContext *CC,
1107 Elements.push_back(CFGCXXRecordTypedCall(E, CC), C);
1108 }
1109
1112 Elements.push_back(CFGInitializer(initializer), C);
1113 }
1114
1117 Elements.push_back(CFGNewAllocator(NE), C);
1118 }
1119
1120 void appendScopeBegin(const VarDecl *VD, const Stmt *S,
1122 Elements.push_back(CFGScopeBegin(VD, S), C);
1123 }
1124
1125 void prependScopeBegin(const VarDecl *VD, const Stmt *S,
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.
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.
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.
1208public:
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.
1225class CFG {
1226public:
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
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;
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.
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 using try_block_range = llvm::iterator_range<try_block_iterator>;
1341
1343 return TryDispatchBlocks.begin();
1344 }
1345
1347 return TryDispatchBlocks.end();
1348 }
1349
1352 }
1353
1354 void addTryDispatchBlock(const CFGBlock *block) {
1355 TryDispatchBlocks.push_back(block);
1356 }
1357
1358 /// Records a synthetic DeclStmt and the DeclStmt it was constructed from.
1359 ///
1360 /// The CFG uses synthetic DeclStmts when a single AST DeclStmt contains
1361 /// multiple decls.
1362 void addSyntheticDeclStmt(const DeclStmt *Synthetic,
1363 const DeclStmt *Source) {
1364 assert(Synthetic->isSingleDecl() && "Can handle single declarations only");
1365 assert(Synthetic != Source && "Don't include original DeclStmts in map");
1366 assert(!SyntheticDeclStmts.count(Synthetic) && "Already in map");
1367 SyntheticDeclStmts[Synthetic] = Source;
1368 }
1369
1371 llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator;
1372 using synthetic_stmt_range = llvm::iterator_range<synthetic_stmt_iterator>;
1373
1374 /// Iterates over synthetic DeclStmts in the CFG.
1375 ///
1376 /// Each element is a (synthetic statement, source statement) pair.
1377 ///
1378 /// \sa addSyntheticDeclStmt
1380 return SyntheticDeclStmts.begin();
1381 }
1382
1383 /// \sa synthetic_stmt_begin
1385 return SyntheticDeclStmts.end();
1386 }
1387
1388 /// \sa synthetic_stmt_begin
1391 }
1392
1393 //===--------------------------------------------------------------------===//
1394 // Member templates useful for various batch operations over CFGs.
1395 //===--------------------------------------------------------------------===//
1396
1397 template <typename Callback> void VisitBlockStmts(Callback &O) const {
1398 for (const_iterator I = begin(), E = end(); I != E; ++I)
1399 for (CFGBlock::const_iterator BI = (*I)->begin(), BE = (*I)->end();
1400 BI != BE; ++BI) {
1401 if (std::optional<CFGStmt> stmt = BI->getAs<CFGStmt>())
1402 O(const_cast<Stmt *>(stmt->getStmt()));
1403 }
1404 }
1405
1406 //===--------------------------------------------------------------------===//
1407 // CFG Introspection.
1408 //===--------------------------------------------------------------------===//
1409
1410 /// Returns the total number of BlockIDs allocated (which start at 0).
1411 unsigned getNumBlockIDs() const { return NumBlockIDs; }
1412
1413 /// Return the total number of CFGBlocks within the CFG This is simply a
1414 /// renaming of the getNumBlockIDs(). This is necessary because the dominator
1415 /// implementation needs such an interface.
1416 unsigned size() const { return NumBlockIDs; }
1417
1418 /// Returns true if the CFG has no branches. Usually it boils down to the CFG
1419 /// having exactly three blocks (entry, the actual code, exit), but sometimes
1420 /// more blocks appear due to having control flow that can be fully
1421 /// resolved in compile time.
1422 bool isLinear() const;
1423
1424 //===--------------------------------------------------------------------===//
1425 // CFG Debugging: Pretty-Printing and Visualization.
1426 //===--------------------------------------------------------------------===//
1427
1428 void viewCFG(const LangOptions &LO) const;
1429 void print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const;
1430 void dump(const LangOptions &LO, bool ShowColors) const;
1431
1432 //===--------------------------------------------------------------------===//
1433 // Internal: constructors and data.
1434 //===--------------------------------------------------------------------===//
1435
1436 CFG() : Blocks(BlkBVC, 10) {}
1437
1438 llvm::BumpPtrAllocator& getAllocator() {
1439 return BlkBVC.getAllocator();
1440 }
1441
1443 return BlkBVC;
1444 }
1445
1446private:
1447 CFGBlock *Entry = nullptr;
1448 CFGBlock *Exit = nullptr;
1449
1450 // Special block to contain collective dispatch for indirect gotos
1451 CFGBlock* IndirectGotoBlock = nullptr;
1452
1453 unsigned NumBlockIDs = 0;
1454
1455 BumpVectorContext BlkBVC;
1456
1457 CFGBlockListTy Blocks;
1458
1459 /// C++ 'try' statements are modeled with an indirect dispatch block.
1460 /// This is the collection of such blocks present in the CFG.
1461 std::vector<const CFGBlock *> TryDispatchBlocks;
1462
1463 /// Collects DeclStmts synthesized for this CFG and maps each one back to its
1464 /// source DeclStmt.
1465 llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts;
1466};
1467
1468Expr *extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE);
1469
1470} // namespace clang
1471
1472//===----------------------------------------------------------------------===//
1473// GraphTraits specializations for CFG basic block graphs (source-level CFGs)
1474//===----------------------------------------------------------------------===//
1475
1476namespace llvm {
1477
1478/// Implement simplify_type for CFGTerminator, so that we can dyn_cast from
1479/// CFGTerminator to a specific Stmt class.
1480template <> struct simplify_type< ::clang::CFGTerminator> {
1482
1484 return Val.getStmt();
1485 }
1486};
1487
1488// Traits for: CFGBlock
1489
1490template <> struct GraphTraits< ::clang::CFGBlock *> {
1493
1494 static NodeRef getEntryNode(::clang::CFGBlock *BB) { return BB; }
1496 static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
1497};
1498
1499template <> struct GraphTraits< const ::clang::CFGBlock *> {
1500 using NodeRef = const ::clang::CFGBlock *;
1502
1503 static NodeRef getEntryNode(const clang::CFGBlock *BB) { return BB; }
1505 static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
1506};
1507
1508template <> struct GraphTraits<Inverse< ::clang::CFGBlock *>> {
1511
1512 static NodeRef getEntryNode(Inverse<::clang::CFGBlock *> G) {
1513 return G.Graph;
1514 }
1515
1517 static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
1518};
1519
1520template <> struct GraphTraits<Inverse<const ::clang::CFGBlock *>> {
1521 using NodeRef = const ::clang::CFGBlock *;
1523
1524 static NodeRef getEntryNode(Inverse<const ::clang::CFGBlock *> G) {
1525 return G.Graph;
1526 }
1527
1529 static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
1530};
1531
1532// Traits for: CFG
1533
1534template <> struct GraphTraits< ::clang::CFG* >
1535 : public GraphTraits< ::clang::CFGBlock *> {
1537
1538 static NodeRef getEntryNode(::clang::CFG *F) { return &F->getEntry(); }
1541 static unsigned size(::clang::CFG* F) { return F->size(); }
1542};
1543
1544template <> struct GraphTraits<const ::clang::CFG* >
1545 : public GraphTraits<const ::clang::CFGBlock *> {
1547
1548 static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getEntry(); }
1549
1550 static nodes_iterator nodes_begin( const ::clang::CFG* F) {
1551 return F->nodes_begin();
1552 }
1553
1554 static nodes_iterator nodes_end( const ::clang::CFG* F) {
1555 return F->nodes_end();
1556 }
1557
1558 static unsigned size(const ::clang::CFG* F) {
1559 return F->size();
1560 }
1561};
1562
1563template <> struct GraphTraits<Inverse< ::clang::CFG *>>
1564 : public GraphTraits<Inverse< ::clang::CFGBlock *>> {
1566
1567 static NodeRef getEntryNode(::clang::CFG *F) { return &F->getExit(); }
1569 static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); }
1570};
1571
1572template <> struct GraphTraits<Inverse<const ::clang::CFG *>>
1573 : public GraphTraits<Inverse<const ::clang::CFGBlock *>> {
1575
1576 static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getExit(); }
1577
1578 static nodes_iterator nodes_begin(const ::clang::CFG* F) {
1579 return F->nodes_begin();
1580 }
1581
1582 static nodes_iterator nodes_end(const ::clang::CFG* F) {
1583 return F->nodes_end();
1584 }
1585};
1586
1587} // namespace llvm
1588
1589#endif // LLVM_CLANG_ANALYSIS_CFG_H
NodeId Parent
Definition: ASTDiff.cpp:191
#define IMPL(Index)
clang::CharUnits operator*(clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU)
Definition: CharUnits.h:225
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
bool ShowColors
Definition: Logger.cpp:29
llvm::raw_ostream & OS
Definition: Logger.cpp:24
const char * Data
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3814
llvm::BumpPtrAllocator & getAllocator()
Definition: BumpVector.h:55
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: BumpVector.h:83
reference back()
Definition: BumpVector.h:124
reference front()
Definition: BumpVector.h:117
iterator end()
Definition: BumpVector.h:94
const CFGElement & const_reference
Definition: BumpVector.h:87
reverse_iterator rbegin()
Definition: BumpVector.h:98
std::reverse_iterator< iterator > reverse_iterator
Definition: BumpVector.h:84
reverse_iterator rend()
Definition: BumpVector.h:100
const CFGElement * const_iterator
Definition: BumpVector.h:81
iterator begin()
Definition: BumpVector.h:92
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
Definition: CFG.h:389
const VarDecl * getVarDecl() const
Definition: CFG.h:394
const Stmt * getTriggerStmt() const
Definition: CFG.h:399
CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt)
Definition: CFG.h:391
Represents C++ object destructor implicitly generated for base object in destructor.
Definition: CFG.h:440
CFGBaseDtor(const CXXBaseSpecifier *base)
Definition: CFG.h:442
const CXXBaseSpecifier * getBaseSpecifier() const
Definition: CFG.h:445
This class represents a potential adjacent block in the CFG.
Definition: CFG.h:791
CFGBlock & operator*() const
Definition: CFG.h:825
CFGBlock * operator->() const
Definition: CFG.h:829
CFGBlock * getReachableBlock() const
Get the reachable block, if one exists.
Definition: CFG.h:810
bool isReachable() const
Definition: CFG.h:833
CFGBlock * getPossiblyUnreachableBlock() const
Get the potentially unreachable block.
Definition: CFG.h:815
unsigned IgnoreNullPredecessors
Definition: CFG.h:982
unsigned IgnoreDefaultsWithCoveredEnums
Definition: CFG.h:983
FilteredCFGBlockIterator & operator++()
Definition: CFG.h:1010
const CFGBlock * operator*() const
Definition: CFG.h:1015
FilteredCFGBlockIterator(const IMPL &i, const IMPL &e, const CFGBlock *from, const FilterOptions &f)
Definition: CFG.h:1000
Represents a single basic block in a source-level CFG.
Definition: CFG.h:576
void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C)
Definition: CFG.h:1150
void prependScopeBegin(const VarDecl *VD, const Stmt *S, BumpVectorContext &C)
Definition: CFG.h:1125
FilteredCFGBlockIterator< const_succ_iterator, false > filtered_succ_iterator
Definition: CFG.h:1027
void printTerminator(raw_ostream &OS, const LangOptions &LO) const
printTerminator - A simple pretty printer of the terminator of a CFGBlock.
Definition: CFG.cpp:6141
ElementList::iterator iterator
Definition: CFG.h:865
void setLoopTarget(const Stmt *loopTarget)
Definition: CFG.h:1041
bool isInevitablySinking() const
Returns true if the block would eventually end with a sink (a noreturn node).
Definition: CFG.cpp:6185
filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const
Definition: CFG.h:1029
pred_iterator pred_end()
Definition: CFG.h:938
size_t getIndexInCFG() const
Definition: CFG.cpp:6117
succ_iterator succ_end()
Definition: CFG.h:956
void appendScopeBegin(const VarDecl *VD, const Stmt *S, BumpVectorContext &C)
Definition: CFG.h:1120
AdjacentBlocks::reverse_iterator pred_reverse_iterator
Definition: CFG.h:925
const_reverse_iterator rend() const
Definition: CFG.h:883
CFGElement operator[](size_t i) const
Definition: CFG.h:920
llvm::iterator_range< pred_iterator > pred_range
Definition: CFG.h:927
FilteredCFGBlockIterator< const_pred_iterator, true > filtered_pred_iterator
Definition: CFG.h:1024
const_reverse_ref_iterator_range rrefs() const
Definition: CFG.h:913
llvm::iterator_range< const_succ_iterator > succ_const_range
Definition: CFG.h:935
static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src, const CFGBlock *Dst)
Definition: CFG.cpp:5379
ElementRefIterator< false, false > ref_iterator
Definition: CFG.h:888
ref_iterator ref_begin()
Definition: CFG.h:900
reverse_iterator rbegin()
Definition: CFG.h:880
void setTerminator(CFGTerminator Term)
Definition: CFG.h:1039
void printAsOperand(raw_ostream &OS, bool)
Definition: CFG.h:1088
void appendMemberDtor(FieldDecl *FD, BumpVectorContext &C)
Definition: CFG.h:1142
llvm::iterator_range< const_reverse_ref_iterator > const_reverse_ref_iterator_range
Definition: CFG.h:898
filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const
Definition: CFG.h:1033
llvm::iterator_range< reverse_ref_iterator > reverse_ref_iterator_range
Definition: CFG.h:894
void appendLifetimeEnds(VarDecl *VD, Stmt *S, BumpVectorContext &C)
Definition: CFG.h:1154
iterator insertLifetimeEnds(iterator I, VarDecl *VD, Stmt *S)
Definition: CFG.h:1187
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:6133
ElementList::const_iterator const_iterator
Definition: CFG.h:866
const Stmt * getLabel() const
Definition: CFG.h:1070
reverse_iterator rend()
Definition: CFG.h:881
AdjacentBlocks::iterator pred_iterator
Definition: CFG.h:923
pred_reverse_iterator pred_rend()
Definition: CFG.h:943
bool hasNoReturnElement() const
Definition: CFG.h:1072
CFGElement back() const
Definition: CFG.h:873
iterator beginLifetimeEndsInsert(iterator I, size_t Cnt, BumpVectorContext &C)
Definition: CFG.h:1182
succ_reverse_iterator succ_rend()
Definition: CFG.h:961
ElementRefIterator< true, false > reverse_ref_iterator
Definition: CFG.h:893
CFGElement front() const
Definition: CFG.h:872
const_reverse_ref_iterator rref_end() const
Definition: CFG.h:908
unsigned size() const
Definition: CFG.h:917
const_succ_iterator succ_begin() const
Definition: CFG.h:957
void prependScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C)
Definition: CFG.h:1134
void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C)
Definition: CFG.h:1162
void appendScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C)
Definition: CFG.h:1130
const_pred_iterator pred_end() const
Definition: CFG.h:940
const_iterator begin() const
Definition: CFG.h:877
void appendInitializer(CXXCtorInitializer *initializer, BumpVectorContext &C)
Definition: CFG.h:1110
unsigned BlockID
A numerical ID assigned to a CFGBlock during construction of the CFG.
Definition: CFG.h:783
iterator begin()
Definition: CFG.h:875
iterator beginScopeEndInsert(iterator I, size_t Cnt, BumpVectorContext &C)
Definition: CFG.h:1195
const_pred_reverse_iterator pred_rbegin() const
Definition: CFG.h:944
succ_reverse_iterator succ_rbegin()
Definition: CFG.h:960
void printTerminatorJson(raw_ostream &Out, const LangOptions &LO, bool AddQuotes) const
printTerminatorJson - Pretty-prints the terminator in JSON format.
Definition: CFG.cpp:6148
llvm::iterator_range< ref_iterator > ref_iterator_range
Definition: CFG.h:889
succ_range succs()
Definition: CFG.h:965
void dump() const
Definition: CFG.cpp:6127
bool empty() const
Definition: CFG.h:918
AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator
Definition: CFG.h:933
ref_iterator_range refs()
Definition: CFG.h:910
ElementRefIterator< false, true > const_ref_iterator
Definition: CFG.h:890
ElementRefImpl< true > ConstCFGElementRef
Definition: CFG.h:886
void appendNewAllocator(CXXNewExpr *NE, BumpVectorContext &C)
Definition: CFG.h:1115
CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
Definition: CFG.h:860
Stmt * Label
An (optional) label that prefixes the executable statements in the block.
Definition: CFG.h:771
const_ref_iterator ref_begin() const
Definition: CFG.h:902
Stmt * getLabel()
Definition: CFG.h:1069
CFGTerminator getTerminator() const
Definition: CFG.h:1048
succ_iterator succ_begin()
Definition: CFG.h:955
iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt, BumpVectorContext &C)
Definition: CFG.h:1169
Stmt * getTerminatorStmt()
Definition: CFG.h:1050
const_succ_reverse_iterator succ_rend() const
Definition: CFG.h:963
void appendTemporaryDtor(CXXBindTemporaryExpr *E, BumpVectorContext &C)
Definition: CFG.h:1146
const Stmt * getLoopTarget() const
Definition: CFG.h:1067
AdjacentBlocks::const_iterator const_pred_iterator
Definition: CFG.h:924
succ_const_range succs() const
Definition: CFG.h:969
unsigned pred_size() const
Definition: CFG.h:976
void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C)
Definition: CFG.h:1138
AdjacentBlocks::iterator succ_iterator
Definition: CFG.h:930
void appendCXXRecordTypedCall(Expr *E, const ConstructionContext *CC, BumpVectorContext &C)
Definition: CFG.h:1104
pred_const_range preds() const
Definition: CFG.h:951
ElementList Elements
The set of statements in the basic block.
Definition: CFG.h:766
const_reverse_iterator rbegin() const
Definition: CFG.h:882
ElementRefImpl< false > CFGElementRef
Definition: CFG.h:885
ref_iterator ref_end()
Definition: CFG.h:901
pred_reverse_iterator pred_rbegin()
Definition: CFG.h:942
ElementRefIterator< true, true > const_reverse_ref_iterator
Definition: CFG.h:896
pred_iterator pred_begin()
Definition: CFG.h:937
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
reverse_ref_iterator rref_begin()
Definition: CFG.h:905
iterator end()
Definition: CFG.h:876
CFG * getParent() const
Definition: CFG.h:1076
pred_range preds()
Definition: CFG.h:947
reverse_ref_iterator rref_end()
Definition: CFG.h:906
const Stmt * getTerminatorStmt() const
Definition: CFG.h:1051
const_ref_iterator_range refs() const
Definition: CFG.h:911
const_iterator end() const
Definition: CFG.h:878
const_ref_iterator ref_end() const
Definition: CFG.h:903
void setLabel(Stmt *Statement)
Definition: CFG.h:1040
unsigned getBlockID() const
Definition: CFG.h:1074
const_succ_reverse_iterator succ_rbegin() const
Definition: CFG.h:962
void appendStmt(Stmt *statement, BumpVectorContext &C)
Definition: CFG.h:1095
llvm::iterator_range< const_ref_iterator > const_ref_iterator_range
Definition: CFG.h:891
void setHasNoReturnElement()
Definition: CFG.h:1042
const_pred_iterator pred_begin() const
Definition: CFG.h:939
const Stmt * getTerminatorCondition(bool StripParens=true) const
Definition: CFG.h:1063
const_succ_iterator succ_end() const
Definition: CFG.h:958
const Expr * getLastCondition() const
Definition: CFG.cpp:6223
const_pred_reverse_iterator pred_rend() const
Definition: CFG.h:945
iterator insertScopeEnd(iterator I, VarDecl *VD, Stmt *S)
Definition: CFG.h:1199
void appendConstructor(CXXConstructExpr *CE, const ConstructionContext *CC, BumpVectorContext &C)
Definition: CFG.h:1099
AdjacentBlocks::reverse_iterator succ_reverse_iterator
Definition: CFG.h:932
Stmt * getTerminatorCondition(bool StripParens=true)
Definition: CFG.cpp:6251
AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator
Definition: CFG.h:926
void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C)
Adds a (potentially unreachable) successor block to the current block.
Definition: CFG.cpp:5368
void appendLoopExit(const Stmt *LoopStmt, BumpVectorContext &C)
Definition: CFG.h:1158
AdjacentBlocks::const_iterator const_succ_iterator
Definition: CFG.h:931
reverse_ref_iterator_range rrefs()
Definition: CFG.h:912
bool pred_empty() const
Definition: CFG.h:977
CFGTerminator Terminator
The terminator for a basic block that indicates the type of control-flow that occurs between a block ...
Definition: CFG.h:775
llvm::iterator_range< succ_iterator > succ_range
Definition: CFG.h:934
unsigned succ_size() const
Definition: CFG.h:973
bool succ_empty() const
Definition: CFG.h:974
const_reverse_ref_iterator rref_begin() const
Definition: CFG.h:907
llvm::iterator_range< const_pred_iterator > pred_const_range
Definition: CFG.h:928
iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S)
Definition: CFG.h:1174
Represents a function call that returns a C++ object by value.
Definition: CFG.h:183
const ConstructionContext * getConstructionContext() const
Definition: CFG.h:209
CFGCXXRecordTypedCall(const Expr *E, const ConstructionContext *C)
Definition: CFG.h:196
static bool isCXXRecordTypedCall(const Expr *E)
Returns true when call expression CE needs to be represented by CFGCXXRecordTypedCall,...
Definition: CFG.h:187
CFGCallback defines methods that should be called when a logical operator error is found when buildin...
Definition: CFG.h:1207
CFGCallback()=default
virtual void compareBitwiseEquality(const BinaryOperator *B, bool isAlwaysTrue)
Definition: CFG.h:1213
virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue)
Definition: CFG.h:1212
virtual void compareBitwiseOr(const BinaryOperator *B)
Definition: CFG.h:1215
virtual ~CFGCallback()=default
Represents C++ constructor call.
Definition: CFG.h:154
const ConstructionContext * getConstructionContext() const
Definition: CFG.h:163
CFGConstructor(const CXXConstructExpr *CE, const ConstructionContext *C)
Definition: CFG.h:156
Represents C++ object destructor generated from a call to delete.
Definition: CFG.h:414
CFGDeleteDtor(const CXXRecordDecl *RD, const CXXDeleteExpr *DE)
Definition: CFG.h:416
const CXXDeleteExpr * getDeleteExpr() const
Definition: CFG.h:424
const CXXRecordDecl * getCXXRecordDecl() const
Definition: CFG.h:419
Represents a top-level expression in a basic block.
Definition: CFG.h:54
void dumpToStream(llvm::raw_ostream &OS) const
Definition: CFG.cpp:5749
@ LifetimeEnds
Definition: CFG.h:62
@ CXXRecordTypedCall
Definition: CFG.h:67
@ AutomaticObjectDtor
Definition: CFG.h:71
@ TemporaryDtor
Definition: CFG.h:75
@ NewAllocator
Definition: CFG.h:61
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.
Definition: CFG.h:97
Kind getKind() const
Definition: CFG.h:116
void dump() const
Definition: CFG.h:125
llvm::PointerIntPair< void *, 2 > Data1
Definition: CFG.h:82
llvm::PointerIntPair< void *, 2 > Data2
Definition: CFG.h:83
std::optional< T > getAs() const
Convert to the specified CFGElement type, returning std::nullopt if this CFGElement is not of the des...
Definition: CFG.h:107
CFGElement(Kind kind, const void *Ptr1, const void *Ptr2=nullptr)
Definition: CFG.h:85
CFGElement()=default
Represents C++ object destructor implicitly generated by compiler on various occasions.
Definition: CFG.h:364
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
Definition: CFG.cpp:5282
CFGImplicitDtor(Kind kind, const void *data1, const void *data2=nullptr)
Definition: CFG.h:368
bool isNoReturn(ASTContext &astContext) const
Represents C++ base or member initializer from constructor's initialization list.
Definition: CFG.h:225
CXXCtorInitializer * getInitializer() const
Definition: CFG.h:230
CFGInitializer(const CXXCtorInitializer *initializer)
Definition: CFG.h:227
Represents the point where the lifetime of an automatic object ends.
Definition: CFG.h:290
CFGLifetimeEnds(const VarDecl *var, const Stmt *stmt)
Definition: CFG.h:292
const Stmt * getTriggerStmt() const
Definition: CFG.h:299
const VarDecl * getVarDecl() const
Definition: CFG.h:295
Represents the point where a loop ends.
Definition: CFG.h:271
const Stmt * getLoopStmt() const
Definition: CFG.h:275
CFGLoopExit(const Stmt *stmt)
Definition: CFG.h:273
Represents C++ object destructor implicitly generated for member object in destructor.
Definition: CFG.h:461
const FieldDecl * getFieldDecl() const
Definition: CFG.h:466
CFGMemberDtor(const FieldDecl *field)
Definition: CFG.h:463
Represents C++ allocator call.
Definition: CFG.h:245
const CXXNewExpr * getAllocatorExpr() const
Definition: CFG.h:251
CFGNewAllocator(const CXXNewExpr *S)
Definition: CFG.h:247
Represents beginning of a scope implicitly generated by the compiler on encountering a CompoundStmt.
Definition: CFG.h:315
const VarDecl * getVarDecl() const
Definition: CFG.h:327
const Stmt * getTriggerStmt() const
Definition: CFG.h:322
CFGScopeBegin(const VarDecl *VD, const Stmt *S)
Definition: CFG.h:318
Represents end of a scope implicitly generated by the compiler after the last Stmt in a CompoundStmt'...
Definition: CFG.h:341
CFGScopeEnd(const VarDecl *VD, const Stmt *S)
Definition: CFG.h:344
const Stmt * getTriggerStmt() const
Definition: CFG.h:350
const VarDecl * getVarDecl() const
Definition: CFG.h:346
CFGStmt(const Stmt *S, Kind K=Statement)
Definition: CFG.h:132
CFGStmt()=default
const Stmt * getStmt() const
Definition: CFG.h:136
Represents C++ object destructor implicitly generated at the end of full expression for temporary obj...
Definition: CFG.h:482
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
Definition: CFG.h:487
CFGTemporaryDtor(const CXXBindTemporaryExpr *expr)
Definition: CFG.h:484
Represents CFGBlock terminator statement.
Definition: CFG.h:503
Stmt * getStmt()
Definition: CFG.h:535
bool isVirtualBaseBranch() const
Definition: CFG.h:545
bool isTemporaryDtorsBranch() const
Definition: CFG.h:542
bool isValid() const
Definition: CFG.h:534
bool isStmtBranch() const
Definition: CFG.h:539
Kind getKind() const
Definition: CFG.h:537
CFGTerminator(Stmt *S, Kind K=StmtBranch)
Definition: CFG.h:532
const Stmt * getStmt() const
Definition: CFG.h:536
@ TemporaryDtorsBranch
A branch in control flow of destructors of temporaries.
Definition: CFG.h:512
@ VirtualBaseBranch
A shortcut around virtual base initializers.
Definition: CFG.h:516
@ StmtBranch
A branch that corresponds to a statement in the code, such as an if-statement.
Definition: CFG.h:508
@ NumKindsMinusOne
Number of different kinds, for assertions.
Definition: CFG.h:521
bool PruneTriviallyFalseEdges
Definition: CFG.h:1239
bool AddStaticInitBranches
Definition: CFG.h:1247
bool OmitImplicitValueInitializers
Definition: CFG.h:1254
ForcedBlkExprs ** forcedBlkExprs
Definition: CFG.h:1237
bool AddCXXDefaultInitExprInAggregates
Definition: CFG.h:1250
bool AddCXXDefaultInitExprInCtors
Definition: CFG.h:1249
BuildOptions & setAllAlwaysAdd()
Definition: CFG.h:1267
BuildOptions & setAlwaysAdd(Stmt::StmtClass stmtClass, bool val=true)
Definition: CFG.h:1262
CFGCallback * Observer
Definition: CFG.h:1238
bool alwaysAdd(const Stmt *stmt) const
Definition: CFG.h:1258
bool AddRichCXXConstructors
Definition: CFG.h:1251
bool AddVirtualBaseBranches
Definition: CFG.h:1253
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
Definition: CFG.h:1235
bool MarkElidedCXXConstructors
Definition: CFG.h:1252
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition: CFG.h:1225
unsigned size() const
Return the total number of CFGBlocks within the CFG This is simply a renaming of the getNumBlockIDs()...
Definition: CFG.h:1416
llvm::iterator_range< synthetic_stmt_iterator > synthetic_stmt_range
Definition: CFG.h:1372
CFGBlockListTy::const_iterator const_iterator
Definition: CFG.h:1296
const_iterator nodes_end() const
Definition: CFG.h:1317
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:6096
llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator
Definition: CFG.h:1371
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: CFG.h:1298
try_block_range try_blocks() const
Definition: CFG.h:1350
iterator end()
Definition: CFG.h:1304
bool isLinear() const
Returns true if the CFG has no branches.
Definition: CFG.cpp:5236
synthetic_stmt_range synthetic_stmts() const
Definition: CFG.h:1389
void VisitBlockStmts(Callback &O) const
Definition: CFG.h:1397
static std::unique_ptr< CFG > buildCFG(const Decl *D, Stmt *AST, ASTContext *C, const BuildOptions &BO)
Builds a CFG from an AST.
Definition: CFG.cpp:5230
llvm::BumpPtrAllocator & getAllocator()
Definition: CFG.h:1438
std::reverse_iterator< iterator > reverse_iterator
Definition: CFG.h:1297
CFGBlockListTy::iterator iterator
Definition: CFG.h:1295
const_reverse_iterator rbegin() const
Definition: CFG.h:1321
const_iterator end() const
Definition: CFG.h:1306
CFGBlock * createBlock()
Create a new block in the CFG.
Definition: CFG.cpp:5213
void addSyntheticDeclStmt(const DeclStmt *Synthetic, const DeclStmt *Source)
Records a synthetic DeclStmt and the DeclStmt it was constructed from.
Definition: CFG.h:1362
const CFGBlock * getIndirectGotoBlock() const
Definition: CFG.h:1337
llvm::iterator_range< try_block_iterator > try_block_range
Definition: CFG.h:1340
const_iterator begin() const
Definition: CFG.h:1305
CFGBlock & getExit()
Definition: CFG.h:1333
iterator begin()
Definition: CFG.h:1303
void setIndirectGotoBlock(CFGBlock *B)
Set the block used for indirect goto jumps.
Definition: CFG.h:1288
void addTryDispatchBlock(const CFGBlock *block)
Definition: CFG.h:1354
try_block_iterator try_blocks_end() const
Definition: CFG.h:1346
synthetic_stmt_iterator synthetic_stmt_end() const
Definition: CFG.h:1384
void setEntry(CFGBlock *B)
Set the entry block of the CFG.
Definition: CFG.h:1284
CFGBlock & getEntry()
Definition: CFG.h:1331
llvm::iterator_range< const_iterator > const_nodes() const
Definition: CFG.h:1312
const CFGBlock & getEntry() const
Definition: CFG.h:1332
CFGBlock * getIndirectGotoBlock()
Definition: CFG.h:1336
llvm::iterator_range< reverse_iterator > reverse_nodes()
Definition: CFG.h:1324
std::vector< const CFGBlock * >::const_iterator try_block_iterator
Definition: CFG.h:1339
CFGBlock & front()
Definition: CFG.h:1300
const CFGBlock & getExit() const
Definition: CFG.h:1334
llvm::iterator_range< const_reverse_iterator > const_reverse_nodes() const
Definition: CFG.h:1327
const_reverse_iterator rend() const
Definition: CFG.h:1322
void dump(const LangOptions &LO, bool ShowColors) const
dump - A simple pretty printer of a CFG that outputs to stderr.
Definition: CFG.cpp:6091
iterator nodes_begin()
Definition: CFG.h:1308
unsigned getNumBlockIDs() const
Returns the total number of BlockIDs allocated (which start at 0).
Definition: CFG.h:1411
const_iterator nodes_begin() const
Definition: CFG.h:1316
void viewCFG(const LangOptions &LO) const
Definition: CFG.cpp:6322
try_block_iterator try_blocks_begin() const
Definition: CFG.h:1342
CFG()
Definition: CFG.h:1436
BumpVector< CFGBlock * > CFGBlockListTy
Definition: CFG.h:1294
iterator nodes_end()
Definition: CFG.h:1309
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
Definition: CFG.h:1379
reverse_iterator rbegin()
Definition: CFG.h:1319
reverse_iterator rend()
Definition: CFG.h:1320
CFGBlock & back()
Definition: CFG.h:1301
llvm::iterator_range< iterator > nodes()
Definition: CFG.h:1311
BumpVectorContext & getBumpVectorContext()
Definition: CFG.h:1442
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1470
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1518
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2242
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition: ExprCXX.h:2473
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2738
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition: ExprCXX.h:2199
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
ConstructionContext's subclasses describe different ways of constructing an object in C++.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1311
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
Definition: Stmt.h:1324
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
This represents one expression.
Definition: Expr.h:110
bool isGLValue() const
Definition: Expr.h:274
QualType getType() const
Definition: Expr.h:142
Represents a member of a struct/union/class.
Definition: Decl.h:2941
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:82
Represents a point when we exit a loop.
Definition: ProgramPoint.h:711
QualType getCanonicalType() const
Definition: Type.h:6701
Stmt - This represents one statement.
Definition: Stmt.h:72
StmtClass
Definition: Stmt.h:74
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1783
Represents a variable declaration or definition.
Definition: Decl.h:913
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
Definition: CallGraph.h:207
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ C
Languages that the frontend can parse and compile.
Expr * extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE)
Definition: CFG.cpp:1337
YAML serialization mapping.
Definition: Dominators.h:30
#define false
Definition: stdbool.h:22
static ChildIteratorType child_end(NodeRef N)
Definition: CFG.h:1517
static NodeRef getEntryNode(Inverse<::clang::CFGBlock * > G)
Definition: CFG.h:1512
::clang::CFGBlock::const_pred_iterator ChildIteratorType
Definition: CFG.h:1510
static ChildIteratorType child_begin(NodeRef N)
Definition: CFG.h:1516
static nodes_iterator nodes_end(::clang::CFG *F)
Definition: CFG.h:1569
static NodeRef getEntryNode(::clang::CFG *F)
Definition: CFG.h:1567
static nodes_iterator nodes_begin(::clang::CFG *F)
Definition: CFG.h:1568
static NodeRef getEntryNode(Inverse< const ::clang::CFGBlock * > G)
Definition: CFG.h:1524
static ChildIteratorType child_begin(NodeRef N)
Definition: CFG.h:1528
::clang::CFGBlock::const_pred_iterator ChildIteratorType
Definition: CFG.h:1522
static ChildIteratorType child_end(NodeRef N)
Definition: CFG.h:1529
static NodeRef getEntryNode(const ::clang::CFG *F)
Definition: CFG.h:1576
static nodes_iterator nodes_begin(const ::clang::CFG *F)
Definition: CFG.h:1578
static nodes_iterator nodes_end(const ::clang::CFG *F)
Definition: CFG.h:1582
static ChildIteratorType child_begin(NodeRef N)
Definition: CFG.h:1495
static ChildIteratorType child_end(NodeRef N)
Definition: CFG.h:1496
static NodeRef getEntryNode(::clang::CFGBlock *BB)
Definition: CFG.h:1494
::clang::CFGBlock::succ_iterator ChildIteratorType
Definition: CFG.h:1492
static nodes_iterator nodes_end(::clang::CFG *F)
Definition: CFG.h:1540
static NodeRef getEntryNode(::clang::CFG *F)
Definition: CFG.h:1538
static unsigned size(::clang::CFG *F)
Definition: CFG.h:1541
static nodes_iterator nodes_begin(::clang::CFG *F)
Definition: CFG.h:1539
::clang::CFGBlock::const_succ_iterator ChildIteratorType
Definition: CFG.h:1501
static NodeRef getEntryNode(const clang::CFGBlock *BB)
Definition: CFG.h:1503
static ChildIteratorType child_begin(NodeRef N)
Definition: CFG.h:1504
static ChildIteratorType child_end(NodeRef N)
Definition: CFG.h:1505
static nodes_iterator nodes_begin(const ::clang::CFG *F)
Definition: CFG.h:1550
static unsigned size(const ::clang::CFG *F)
Definition: CFG.h:1558
static nodes_iterator nodes_end(const ::clang::CFG *F)
Definition: CFG.h:1554
static NodeRef getEntryNode(const ::clang::CFG *F)
Definition: CFG.h:1548
static SimpleType getSimplifiedValue(::clang::CFGTerminator Val)
Definition: CFG.h:1483