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