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