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