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