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