Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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/PointerIntPair.h"
25
#include "llvm/ADT/iterator_range.h"
26
#include "llvm/Support/Allocator.h"
27
#include "llvm/Support/raw_ostream.h"
28
#include <bitset>
29
#include <cassert>
30
#include <cstddef>
31
#include <iterator>
32
#include <memory>
33
#include <optional>
34
#include <vector>
35
 
36
namespace clang {
37
 
38
class ASTContext;
39
class BinaryOperator;
40
class CFG;
41
class CXXBaseSpecifier;
42
class CXXBindTemporaryExpr;
43
class CXXCtorInitializer;
44
class CXXDeleteExpr;
45
class CXXDestructorDecl;
46
class CXXNewExpr;
47
class CXXRecordDecl;
48
class Decl;
49
class FieldDecl;
50
class LangOptions;
51
class VarDecl;
52
 
53
/// Represents a top-level expression in a basic block.
54
class CFGElement {
55
public:
56
  enum Kind {
57
    // main kind
58
    Initializer,
59
    ScopeBegin,
60
    ScopeEnd,
61
    NewAllocator,
62
    LifetimeEnds,
63
    LoopExit,
64
    // stmt kind
65
    Statement,
66
    Constructor,
67
    CXXRecordTypedCall,
68
    STMT_BEGIN = Statement,
69
    STMT_END = CXXRecordTypedCall,
70
    // dtor kind
71
    AutomaticObjectDtor,
72
    DeleteDtor,
73
    BaseDtor,
74
    MemberDtor,
75
    TemporaryDtor,
76
    DTOR_BEGIN = AutomaticObjectDtor,
77
    DTOR_END = TemporaryDtor
78
  };
79
 
80
protected:
81
  // The int bits are used to mark the kind.
82
  llvm::PointerIntPair<void *, 2> Data1;
83
  llvm::PointerIntPair<void *, 2> Data2;
84
 
85
  CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr)
86
      : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
87
        Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
88
    assert(getKind() == kind);
89
  }
90
 
91
  CFGElement() = default;
92
 
93
public:
94
  /// Convert to the specified CFGElement type, asserting that this
95
  /// CFGElement is of the desired type.
96
  template<typename T>
97
  T castAs() const {
98
    assert(T::isKind(*this));
99
    T t;
100
    CFGElement& e = t;
101
    e = *this;
102
    return t;
103
  }
104
 
105
  /// Convert to the specified CFGElement type, returning std::nullopt if this
106
  /// CFGElement is not of the desired type.
107
  template <typename T> std::optional<T> getAs() const {
108
    if (!T::isKind(*this))
109
      return std::nullopt;
110
    T t;
111
    CFGElement& e = t;
112
    e = *this;
113
    return t;
114
  }
115
 
116
  Kind getKind() const {
117
    unsigned x = Data2.getInt();
118
    x <<= 2;
119
    x |= Data1.getInt();
120
    return (Kind) x;
121
  }
122
 
123
  void dumpToStream(llvm::raw_ostream &OS) const;
124
 
125
  void dump() const {
126
    dumpToStream(llvm::errs());
127
  }
128
};
129
 
130
class CFGStmt : public CFGElement {
131
public:
132
  explicit CFGStmt(const Stmt *S, Kind K = Statement) : CFGElement(K, S) {
133
    assert(isKind(*this));
134
  }
135
 
136
  const Stmt *getStmt() const {
137
    return static_cast<const Stmt *>(Data1.getPointer());
138
  }
139
 
140
private:
141
  friend class CFGElement;
142
 
143
  static bool isKind(const CFGElement &E) {
144
    return E.getKind() >= STMT_BEGIN && E.getKind() <= STMT_END;
145
  }
146
 
147
protected:
148
  CFGStmt() = default;
149
};
150
 
151
/// Represents C++ constructor call. Maintains information necessary to figure
152
/// out what memory is being initialized by the constructor expression. For now
153
/// this is only used by the analyzer's CFG.
154
class CFGConstructor : public CFGStmt {
155
public:
156
  explicit CFGConstructor(const CXXConstructExpr *CE,
157
                          const ConstructionContext *C)
158
      : CFGStmt(CE, Constructor) {
159
    assert(C);
160
    Data2.setPointer(const_cast<ConstructionContext *>(C));
161
  }
162
 
163
  const ConstructionContext *getConstructionContext() const {
164
    return static_cast<ConstructionContext *>(Data2.getPointer());
165
  }
166
 
167
private:
168
  friend class CFGElement;
169
 
170
  CFGConstructor() = default;
171
 
172
  static bool isKind(const CFGElement &E) {
173
    return E.getKind() == Constructor;
174
  }
175
};
176
 
177
/// Represents a function call that returns a C++ object by value. This, like
178
/// constructor, requires a construction context in order to understand the
179
/// storage of the returned object . In C such tracking is not necessary because
180
/// no additional effort is required for destroying the object or modeling copy
181
/// elision. Like CFGConstructor, this element is for now only used by the
182
/// analyzer's CFG.
183
class CFGCXXRecordTypedCall : public CFGStmt {
184
public:
185
  /// Returns true when call expression \p CE needs to be represented
186
  /// by CFGCXXRecordTypedCall, as opposed to a regular CFGStmt.
187
  static bool isCXXRecordTypedCall(const Expr *E) {
188
    assert(isa<CallExpr>(E) || isa<ObjCMessageExpr>(E));
189
    // There is no such thing as reference-type expression. If the function
190
    // returns a reference, it'll return the respective lvalue or xvalue
191
    // instead, and we're only interested in objects.
192
    return !E->isGLValue() &&
193
           E->getType().getCanonicalType()->getAsCXXRecordDecl();
194
  }
195
 
196
  explicit CFGCXXRecordTypedCall(const Expr *E, const ConstructionContext *C)
197
      : CFGStmt(E, CXXRecordTypedCall) {
198
    assert(isCXXRecordTypedCall(E));
199
    assert(C && (isa<TemporaryObjectConstructionContext>(C) ||
200
                 // These are possible in C++17 due to mandatory copy elision.
201
                 isa<ReturnedValueConstructionContext>(C) ||
202
                 isa<VariableConstructionContext>(C) ||
203
                 isa<ConstructorInitializerConstructionContext>(C) ||
204
                 isa<ArgumentConstructionContext>(C) ||
205
                 isa<LambdaCaptureConstructionContext>(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(const 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 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(const 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 assertions. 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
        std::conditional_t<IsConst, const CFGBlock *, CFGBlock *>;
628
 
629
    using CFGElementPtr =
630
        std::conditional_t<IsConst, const CFGElement *, CFGElement *>;
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
        std::conditional_t<IsConst, const CFGBlock *, CFGBlock *>;
679
 
680
    using UnderlayingIteratorTy = std::conditional_t<
681
        IsConst,
682
        std::conditional_t<IsReverse, ElementList::const_reverse_iterator,
683
                           ElementList::const_iterator>,
684
        std::conditional_t<IsReverse, ElementList::reverse_iterator,
685
                           ElementList::iterator>>;
686
 
687
    using IteratorTraits = typename std::iterator_traits<UnderlayingIteratorTy>;
688
    using ElementRef = typename CFGBlock::ElementRefImpl<IsConst>;
689
 
690
  public:
691
    using difference_type = typename IteratorTraits::difference_type;
692
    using value_type = ElementRef;
693
    using pointer = ElementRef *;
694
    using iterator_category = typename IteratorTraits::iterator_category;
695
 
696
  private:
697
    CFGBlockRef Parent;
698
    UnderlayingIteratorTy Pos;
699
 
700
  public:
701
    ElementRefIterator(CFGBlockRef Parent, UnderlayingIteratorTy Pos)
702
        : Parent(Parent), Pos(Pos) {}
703
 
704
    template <bool IsOtherConst>
705
    ElementRefIterator(ElementRefIterator<false, IsOtherConst> E)
706
        : ElementRefIterator(E.Parent, E.Pos.base()) {}
707
 
708
    template <bool IsOtherConst>
709
    ElementRefIterator(ElementRefIterator<true, IsOtherConst> E)
710
        : ElementRefIterator(E.Parent, std::make_reverse_iterator(E.Pos)) {}
711
 
712
    bool operator<(ElementRefIterator Other) const {
713
      assert(Parent == Other.Parent);
714
      return Pos < Other.Pos;
715
    }
716
 
717
    bool operator==(ElementRefIterator Other) const {
718
      return Parent == Other.Parent && Pos == Other.Pos;
719
    }
720
 
721
    bool operator!=(ElementRefIterator Other) const {
722
      return !(*this == Other);
723
    }
724
 
725
  private:
726
    template <bool IsOtherConst>
727
    static size_t
728
    getIndexInBlock(CFGBlock::ElementRefIterator<true, IsOtherConst> E) {
729
      return E.Parent->size() - (E.Pos - E.Parent->rbegin()) - 1;
730
    }
731
 
732
    template <bool IsOtherConst>
733
    static size_t
734
    getIndexInBlock(CFGBlock::ElementRefIterator<false, IsOtherConst> E) {
735
      return E.Pos - E.Parent->begin();
736
    }
737
 
738
  public:
739
    value_type operator*() { return {Parent, getIndexInBlock(*this)}; }
740
 
741
    difference_type operator-(ElementRefIterator Other) const {
742
      return Pos - Other.Pos;
743
    }
744
 
745
    ElementRefIterator operator++() {
746
      ++this->Pos;
747
      return *this;
748
    }
749
    ElementRefIterator operator++(int) {
750
      ElementRefIterator Ret = *this;
751
      ++*this;
752
      return Ret;
753
    }
754
    ElementRefIterator operator+(size_t count) {
755
      this->Pos += count;
756
      return *this;
757
    }
758
    ElementRefIterator operator-(size_t count) {
759
      this->Pos -= count;
760
      return *this;
761
    }
762
  };
763
 
764
public:
765
  /// The set of statements in the basic block.
766
  ElementList Elements;
767
 
768
  /// An (optional) label that prefixes the executable statements in the block.
769
  /// When this variable is non-NULL, it is either an instance of LabelStmt,
770
  /// SwitchCase or CXXCatchStmt.
771
  Stmt *Label = nullptr;
772
 
773
  /// The terminator for a basic block that indicates the type of control-flow
774
  /// that occurs between a block and its successors.
775
  CFGTerminator Terminator;
776
 
777
  /// Some blocks are used to represent the "loop edge" to the start of a loop
778
  /// from within the loop body. This Stmt* will be refer to the loop statement
779
  /// for such blocks (and be null otherwise).
780
  const Stmt *LoopTarget = nullptr;
781
 
782
  /// A numerical ID assigned to a CFGBlock during construction of the CFG.
783
  unsigned BlockID;
784
 
785
public:
786
  /// This class represents a potential adjacent block in the CFG.  It encodes
787
  /// whether or not the block is actually reachable, or can be proved to be
788
  /// trivially unreachable.  For some cases it allows one to encode scenarios
789
  /// where a block was substituted because the original (now alternate) block
790
  /// is unreachable.
791
  class AdjacentBlock {
792
    enum Kind {
793
      AB_Normal,
794
      AB_Unreachable,
795
      AB_Alternate
796
    };
797
 
798
    CFGBlock *ReachableBlock;
799
    llvm::PointerIntPair<CFGBlock *, 2> UnreachableBlock;
800
 
801
  public:
802
    /// Construct an AdjacentBlock with a possibly unreachable block.
803
    AdjacentBlock(CFGBlock *B, bool IsReachable);
804
 
805
    /// Construct an AdjacentBlock with a reachable block and an alternate
806
    /// unreachable block.
807
    AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock);
808
 
809
    /// Get the reachable block, if one exists.
810
    CFGBlock *getReachableBlock() const {
811
      return ReachableBlock;
812
    }
813
 
814
    /// Get the potentially unreachable block.
815
    CFGBlock *getPossiblyUnreachableBlock() const {
816
      return UnreachableBlock.getPointer();
817
    }
818
 
819
    /// Provide an implicit conversion to CFGBlock* so that
820
    /// AdjacentBlock can be substituted for CFGBlock*.
821
    operator CFGBlock*() const {
822
      return getReachableBlock();
823
    }
824
 
825
    CFGBlock& operator *() const {
826
      return *getReachableBlock();
827
    }
828
 
829
    CFGBlock* operator ->() const {
830
      return getReachableBlock();
831
    }
832
 
833
    bool isReachable() const {
834
      Kind K = (Kind) UnreachableBlock.getInt();
835
      return K == AB_Normal || K == AB_Alternate;
836
    }
837
  };
838
 
839
private:
840
  /// Keep track of the predecessor / successor CFG blocks.
841
  using AdjacentBlocks = BumpVector<AdjacentBlock>;
842
  AdjacentBlocks Preds;
843
  AdjacentBlocks Succs;
844
 
845
  /// This bit is set when the basic block contains a function call
846
  /// or implicit destructor that is attributed as 'noreturn'. In that case,
847
  /// control cannot technically ever proceed past this block. All such blocks
848
  /// will have a single immediate successor: the exit block. This allows them
849
  /// to be easily reached from the exit block and using this bit quickly
850
  /// recognized without scanning the contents of the block.
851
  ///
852
  /// Optimization Note: This bit could be profitably folded with Terminator's
853
  /// storage if the memory usage of CFGBlock becomes an issue.
854
  unsigned HasNoReturnElement : 1;
855
 
856
  /// The parent CFG that owns this CFGBlock.
857
  CFG *Parent;
858
 
859
public:
860
  explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
861
      : Elements(C), Terminator(nullptr), BlockID(blockid), Preds(C, 1),
862
        Succs(C, 1), HasNoReturnElement(false), Parent(parent) {}
863
 
864
  // Statement iterators
865
  using iterator = ElementList::iterator;
866
  using const_iterator = ElementList::const_iterator;
867
  using reverse_iterator = ElementList::reverse_iterator;
868
  using const_reverse_iterator = ElementList::const_reverse_iterator;
869
 
870
  size_t getIndexInCFG() const;
871
 
872
  CFGElement                 front()       const { return Elements.front();   }
873
  CFGElement                 back()        const { return Elements.back();    }
874
 
875
  iterator                   begin()             { return Elements.begin();   }
876
  iterator                   end()               { return Elements.end();     }
877
  const_iterator             begin()       const { return Elements.begin();   }
878
  const_iterator             end()         const { return Elements.end();     }
879
 
880
  reverse_iterator           rbegin()            { return Elements.rbegin();  }
881
  reverse_iterator           rend()              { return Elements.rend();    }
882
  const_reverse_iterator     rbegin()      const { return Elements.rbegin();  }
883
  const_reverse_iterator     rend()        const { return Elements.rend();    }
884
 
885
  using CFGElementRef = ElementRefImpl<false>;
886
  using ConstCFGElementRef = ElementRefImpl<true>;
887
 
888
  using ref_iterator = ElementRefIterator<false, false>;
889
  using ref_iterator_range = llvm::iterator_range<ref_iterator>;
890
  using const_ref_iterator = ElementRefIterator<false, true>;
891
  using const_ref_iterator_range = llvm::iterator_range<const_ref_iterator>;
892
 
893
  using reverse_ref_iterator = ElementRefIterator<true, false>;
894
  using reverse_ref_iterator_range = llvm::iterator_range<reverse_ref_iterator>;
895
 
896
  using const_reverse_ref_iterator = ElementRefIterator<true, true>;
897
  using const_reverse_ref_iterator_range =
898
      llvm::iterator_range<const_reverse_ref_iterator>;
899
 
900
  ref_iterator ref_begin() { return {this, begin()}; }
901
  ref_iterator ref_end() { return {this, end()}; }
902
  const_ref_iterator ref_begin() const { return {this, begin()}; }
903
  const_ref_iterator ref_end() const { return {this, end()}; }
904
 
905
  reverse_ref_iterator rref_begin() { return {this, rbegin()}; }
906
  reverse_ref_iterator rref_end() { return {this, rend()}; }
907
  const_reverse_ref_iterator rref_begin() const { return {this, rbegin()}; }
908
  const_reverse_ref_iterator rref_end() const { return {this, rend()}; }
909
 
910
  ref_iterator_range refs() { return {ref_begin(), ref_end()}; }
911
  const_ref_iterator_range refs() const { return {ref_begin(), ref_end()}; }
912
  reverse_ref_iterator_range rrefs() { return {rref_begin(), rref_end()}; }
913
  const_reverse_ref_iterator_range rrefs() const {
914
    return {rref_begin(), rref_end()};
915
  }
916
 
917
  unsigned                   size()        const { return Elements.size();    }
918
  bool                       empty()       const { return Elements.empty();   }
919
 
920
  CFGElement operator[](size_t i) const  { return Elements[i]; }
921
 
922
  // CFG iterators
923
  using pred_iterator = AdjacentBlocks::iterator;
924
  using const_pred_iterator = AdjacentBlocks::const_iterator;
925
  using pred_reverse_iterator = AdjacentBlocks::reverse_iterator;
926
  using const_pred_reverse_iterator = AdjacentBlocks::const_reverse_iterator;
927
  using pred_range = llvm::iterator_range<pred_iterator>;
928
  using pred_const_range = llvm::iterator_range<const_pred_iterator>;
929
 
930
  using succ_iterator = AdjacentBlocks::iterator;
931
  using const_succ_iterator = AdjacentBlocks::const_iterator;
932
  using succ_reverse_iterator = AdjacentBlocks::reverse_iterator;
933
  using const_succ_reverse_iterator = AdjacentBlocks::const_reverse_iterator;
934
  using succ_range = llvm::iterator_range<succ_iterator>;
935
  using succ_const_range = llvm::iterator_range<const_succ_iterator>;
936
 
937
  pred_iterator                pred_begin()        { return Preds.begin();   }
938
  pred_iterator                pred_end()          { return Preds.end();     }
939
  const_pred_iterator          pred_begin()  const { return Preds.begin();   }
940
  const_pred_iterator          pred_end()    const { return Preds.end();     }
941
 
942
  pred_reverse_iterator        pred_rbegin()       { return Preds.rbegin();  }
943
  pred_reverse_iterator        pred_rend()         { return Preds.rend();    }
944
  const_pred_reverse_iterator  pred_rbegin() const { return Preds.rbegin();  }
945
  const_pred_reverse_iterator  pred_rend()   const { return Preds.rend();    }
946
 
947
  pred_range preds() {
948
    return pred_range(pred_begin(), pred_end());
949
  }
950
 
951
  pred_const_range preds() const {
952
    return pred_const_range(pred_begin(), pred_end());
953
  }
954
 
955
  succ_iterator                succ_begin()        { return Succs.begin();   }
956
  succ_iterator                succ_end()          { return Succs.end();     }
957
  const_succ_iterator          succ_begin()  const { return Succs.begin();   }
958
  const_succ_iterator          succ_end()    const { return Succs.end();     }
959
 
960
  succ_reverse_iterator        succ_rbegin()       { return Succs.rbegin();  }
961
  succ_reverse_iterator        succ_rend()         { return Succs.rend();    }
962
  const_succ_reverse_iterator  succ_rbegin() const { return Succs.rbegin();  }
963
  const_succ_reverse_iterator  succ_rend()   const { return Succs.rend();    }
964
 
965
  succ_range succs() {
966
    return succ_range(succ_begin(), succ_end());
967
  }
968
 
969
  succ_const_range succs() const {
970
    return succ_const_range(succ_begin(), succ_end());
971
  }
972
 
973
  unsigned                     succ_size()   const { return Succs.size();    }
974
  bool                         succ_empty()  const { return Succs.empty();   }
975
 
976
  unsigned                     pred_size()   const { return Preds.size();    }
977
  bool                         pred_empty()  const { return Preds.empty();   }
978
 
979
 
980
  class FilterOptions {
981
  public:
982
    unsigned IgnoreNullPredecessors : 1;
983
    unsigned IgnoreDefaultsWithCoveredEnums : 1;
984
 
985
    FilterOptions()
986
        : IgnoreNullPredecessors(1), IgnoreDefaultsWithCoveredEnums(0) {}
987
  };
988
 
989
  static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src,
990
       const CFGBlock *Dst);
991
 
992
  template <typename IMPL, bool IsPred>
993
  class FilteredCFGBlockIterator {
994
  private:
995
    IMPL I, E;
996
    const FilterOptions F;
997
    const CFGBlock *From;
998
 
999
  public:
1000
    explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e,
1001
                                      const CFGBlock *from,
1002
                                      const FilterOptions &f)
1003
        : I(i), E(e), F(f), From(from) {
1004
      while (hasMore() && Filter(*I))
1005
        ++I;
1006
    }
1007
 
1008
    bool hasMore() const { return I != E; }
1009
 
1010
    FilteredCFGBlockIterator &operator++() {
1011
      do { ++I; } while (hasMore() && Filter(*I));
1012
      return *this;
1013
    }
1014
 
1015
    const CFGBlock *operator*() const { return *I; }
1016
 
1017
  private:
1018
    bool Filter(const CFGBlock *To) {
1019
      return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To);
1020
    }
1021
  };
1022
 
1023
  using filtered_pred_iterator =
1024
      FilteredCFGBlockIterator<const_pred_iterator, true>;
1025
 
1026
  using filtered_succ_iterator =
1027
      FilteredCFGBlockIterator<const_succ_iterator, false>;
1028
 
1029
  filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const {
1030
    return filtered_pred_iterator(pred_begin(), pred_end(), this, f);
1031
  }
1032
 
1033
  filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const {
1034
    return filtered_succ_iterator(succ_begin(), succ_end(), this, f);
1035
  }
1036
 
1037
  // Manipulation of block contents
1038
 
1039
  void setTerminator(CFGTerminator Term) { Terminator = Term; }
1040
  void setLabel(Stmt *Statement) { Label = Statement; }
1041
  void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
1042
  void setHasNoReturnElement() { HasNoReturnElement = true; }
1043
 
1044
  /// Returns true if the block would eventually end with a sink (a noreturn
1045
  /// node).
1046
  bool isInevitablySinking() const;
1047
 
1048
  CFGTerminator getTerminator() const { return Terminator; }
1049
 
1050
  Stmt *getTerminatorStmt() { return Terminator.getStmt(); }
1051
  const Stmt *getTerminatorStmt() const { return Terminator.getStmt(); }
1052
 
1053
  /// \returns the last (\c rbegin()) condition, e.g. observe the following code
1054
  /// snippet:
1055
  ///   if (A && B && C)
1056
  /// A block would be created for \c A, \c B, and \c C. For the latter,
1057
  /// \c getTerminatorStmt() would retrieve the entire condition, rather than
1058
  /// C itself, while this method would only return C.
1059
  const Expr *getLastCondition() const;
1060
 
1061
  Stmt *getTerminatorCondition(bool StripParens = true);
1062
 
1063
  const Stmt *getTerminatorCondition(bool StripParens = true) const {
1064
    return const_cast<CFGBlock*>(this)->getTerminatorCondition(StripParens);
1065
  }
1066
 
1067
  const Stmt *getLoopTarget() const { return LoopTarget; }
1068
 
1069
  Stmt *getLabel() { return Label; }
1070
  const Stmt *getLabel() const { return Label; }
1071
 
1072
  bool hasNoReturnElement() const { return HasNoReturnElement; }
1073
 
1074
  unsigned getBlockID() const { return BlockID; }
1075
 
1076
  CFG *getParent() const { return Parent; }
1077
 
1078
  void dump() const;
1079
 
1080
  void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const;
1081
  void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO,
1082
             bool ShowColors) const;
1083
 
1084
  void printTerminator(raw_ostream &OS, const LangOptions &LO) const;
1085
  void printTerminatorJson(raw_ostream &Out, const LangOptions &LO,
1086
                           bool AddQuotes) const;
1087
 
1088
  void printAsOperand(raw_ostream &OS, bool /*PrintType*/) {
1089
    OS << "BB#" << getBlockID();
1090
  }
1091
 
1092
  /// Adds a (potentially unreachable) successor block to the current block.
1093
  void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C);
1094
 
1095
  void appendStmt(Stmt *statement, BumpVectorContext &C) {
1096
    Elements.push_back(CFGStmt(statement), C);
1097
  }
1098
 
1099
  void appendConstructor(CXXConstructExpr *CE, const ConstructionContext *CC,
1100
                         BumpVectorContext &C) {
1101
    Elements.push_back(CFGConstructor(CE, CC), C);
1102
  }
1103
 
1104
  void appendCXXRecordTypedCall(Expr *E,
1105
                                const ConstructionContext *CC,
1106
                                BumpVectorContext &C) {
1107
    Elements.push_back(CFGCXXRecordTypedCall(E, CC), C);
1108
  }
1109
 
1110
  void appendInitializer(CXXCtorInitializer *initializer,
1111
                        BumpVectorContext &C) {
1112
    Elements.push_back(CFGInitializer(initializer), C);
1113
  }
1114
 
1115
  void appendNewAllocator(CXXNewExpr *NE,
1116
                          BumpVectorContext &C) {
1117
    Elements.push_back(CFGNewAllocator(NE), C);
1118
  }
1119
 
1120
  void appendScopeBegin(const VarDecl *VD, const Stmt *S,
1121
                        BumpVectorContext &C) {
1122
    Elements.push_back(CFGScopeBegin(VD, S), C);
1123
  }
1124
 
1125
  void prependScopeBegin(const VarDecl *VD, const Stmt *S,
1126
                         BumpVectorContext &C) {
1127
    Elements.insert(Elements.rbegin(), 1, CFGScopeBegin(VD, S), C);
1128
  }
1129
 
1130
  void appendScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C) {
1131
    Elements.push_back(CFGScopeEnd(VD, S), C);
1132
  }
1133
 
1134
  void prependScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C) {
1135
    Elements.insert(Elements.rbegin(), 1, CFGScopeEnd(VD, S), C);
1136
  }
1137
 
1138
  void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C) {
1139
    Elements.push_back(CFGBaseDtor(BS), C);
1140
  }
1141
 
1142
  void appendMemberDtor(FieldDecl *FD, BumpVectorContext &C) {
1143
    Elements.push_back(CFGMemberDtor(FD), C);
1144
  }
1145
 
1146
  void appendTemporaryDtor(CXXBindTemporaryExpr *E, BumpVectorContext &C) {
1147
    Elements.push_back(CFGTemporaryDtor(E), C);
1148
  }
1149
 
1150
  void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C) {
1151
    Elements.push_back(CFGAutomaticObjDtor(VD, S), C);
1152
  }
1153
 
1154
  void appendLifetimeEnds(VarDecl *VD, Stmt *S, BumpVectorContext &C) {
1155
    Elements.push_back(CFGLifetimeEnds(VD, S), C);
1156
  }
1157
 
1158
  void appendLoopExit(const Stmt *LoopStmt, BumpVectorContext &C) {
1159
    Elements.push_back(CFGLoopExit(LoopStmt), C);
1160
  }
1161
 
1162
  void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) {
1163
    Elements.push_back(CFGDeleteDtor(RD, DE), C);
1164
  }
1165
 
1166
  // Destructors must be inserted in reversed order. So insertion is in two
1167
  // steps. First we prepare space for some number of elements, then we insert
1168
  // the elements beginning at the last position in prepared space.
1169
  iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt,
1170
      BumpVectorContext &C) {
1171
    return iterator(Elements.insert(I.base(), Cnt,
1172
                                    CFGAutomaticObjDtor(nullptr, nullptr), C));
1173
  }
1174
  iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) {
1175
    *I = CFGAutomaticObjDtor(VD, S);
1176
    return ++I;
1177
  }
1178
 
1179
  // Scope leaving must be performed in reversed order. So insertion is in two
1180
  // steps. First we prepare space for some number of elements, then we insert
1181
  // the elements beginning at the last position in prepared space.
1182
  iterator beginLifetimeEndsInsert(iterator I, size_t Cnt,
1183
                                   BumpVectorContext &C) {
1184
    return iterator(
1185
        Elements.insert(I.base(), Cnt, CFGLifetimeEnds(nullptr, nullptr), C));
1186
  }
1187
  iterator insertLifetimeEnds(iterator I, VarDecl *VD, Stmt *S) {
1188
    *I = CFGLifetimeEnds(VD, S);
1189
    return ++I;
1190
  }
1191
 
1192
  // Scope leaving must be performed in reversed order. So insertion is in two
1193
  // steps. First we prepare space for some number of elements, then we insert
1194
  // the elements beginning at the last position in prepared space.
1195
  iterator beginScopeEndInsert(iterator I, size_t Cnt, BumpVectorContext &C) {
1196
    return iterator(
1197
        Elements.insert(I.base(), Cnt, CFGScopeEnd(nullptr, nullptr), C));
1198
  }
1199
  iterator insertScopeEnd(iterator I, VarDecl *VD, Stmt *S) {
1200
    *I = CFGScopeEnd(VD, S);
1201
    return ++I;
1202
  }
1203
};
1204
 
1205
/// CFGCallback defines methods that should be called when a logical
1206
/// operator error is found when building the CFG.
1207
class CFGCallback {
1208
public:
1209
  CFGCallback() = default;
1210
  virtual ~CFGCallback() = default;
1211
 
1212
  virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {}
1213
  virtual void compareBitwiseEquality(const BinaryOperator *B,
1214
                                      bool isAlwaysTrue) {}
1215
  virtual void compareBitwiseOr(const BinaryOperator *B) {}
1216
};
1217
 
1218
/// Represents a source-level, intra-procedural CFG that represents the
1219
///  control-flow of a Stmt.  The Stmt can represent an entire function body,
1220
///  or a single expression.  A CFG will always contain one empty block that
1221
///  represents the Exit point of the CFG.  A CFG will also contain a designated
1222
///  Entry block.  The CFG solely represents control-flow; it consists of
1223
///  CFGBlocks which are simply containers of Stmt*'s in the AST the CFG
1224
///  was constructed from.
1225
class CFG {
1226
public:
1227
  //===--------------------------------------------------------------------===//
1228
  // CFG Construction & Manipulation.
1229
  //===--------------------------------------------------------------------===//
1230
 
1231
  class BuildOptions {
1232
    std::bitset<Stmt::lastStmtConstant> alwaysAddMask;
1233
 
1234
  public:
1235
    using ForcedBlkExprs = llvm::DenseMap<const Stmt *, const CFGBlock *>;
1236
 
1237
    ForcedBlkExprs **forcedBlkExprs = nullptr;
1238
    CFGCallback *Observer = nullptr;
1239
    bool PruneTriviallyFalseEdges = true;
1240
    bool AddEHEdges = false;
1241
    bool AddInitializers = false;
1242
    bool AddImplicitDtors = false;
1243
    bool AddLifetime = false;
1244
    bool AddLoopExit = false;
1245
    bool AddTemporaryDtors = false;
1246
    bool AddScopes = false;
1247
    bool AddStaticInitBranches = false;
1248
    bool AddCXXNewAllocator = false;
1249
    bool AddCXXDefaultInitExprInCtors = false;
1250
    bool AddCXXDefaultInitExprInAggregates = false;
1251
    bool AddRichCXXConstructors = false;
1252
    bool MarkElidedCXXConstructors = false;
1253
    bool AddVirtualBaseBranches = false;
1254
    bool OmitImplicitValueInitializers = false;
1255
 
1256
    BuildOptions() = default;
1257
 
1258
    bool alwaysAdd(const Stmt *stmt) const {
1259
      return alwaysAddMask[stmt->getStmtClass()];
1260
    }
1261
 
1262
    BuildOptions &setAlwaysAdd(Stmt::StmtClass stmtClass, bool val = true) {
1263
      alwaysAddMask[stmtClass] = val;
1264
      return *this;
1265
    }
1266
 
1267
    BuildOptions &setAllAlwaysAdd() {
1268
      alwaysAddMask.set();
1269
      return *this;
1270
    }
1271
  };
1272
 
1273
  /// Builds a CFG from an AST.
1274
  static std::unique_ptr<CFG> buildCFG(const Decl *D, Stmt *AST, ASTContext *C,
1275
                                       const BuildOptions &BO);
1276
 
1277
  /// Create a new block in the CFG. The CFG owns the block; the caller should
1278
  /// not directly free it.
1279
  CFGBlock *createBlock();
1280
 
1281
  /// Set the entry block of the CFG. This is typically used only during CFG
1282
  /// construction. Most CFG clients expect that the entry block has no
1283
  /// predecessors and contains no statements.
1284
  void setEntry(CFGBlock *B) { Entry = B; }
1285
 
1286
  /// Set the block used for indirect goto jumps. This is typically used only
1287
  /// during CFG construction.
1288
  void setIndirectGotoBlock(CFGBlock *B) { IndirectGotoBlock = B; }
1289
 
1290
  //===--------------------------------------------------------------------===//
1291
  // Block Iterators
1292
  //===--------------------------------------------------------------------===//
1293
 
1294
  using CFGBlockListTy = BumpVector<CFGBlock *>;
1295
  using iterator = CFGBlockListTy::iterator;
1296
  using const_iterator = CFGBlockListTy::const_iterator;
1297
  using reverse_iterator = std::reverse_iterator<iterator>;
1298
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
1299
 
1300
  CFGBlock &                front()                { return *Blocks.front(); }
1301
  CFGBlock &                back()                 { return *Blocks.back(); }
1302
 
1303
  iterator                  begin()                { return Blocks.begin(); }
1304
  iterator                  end()                  { return Blocks.end(); }
1305
  const_iterator            begin()       const    { return Blocks.begin(); }
1306
  const_iterator            end()         const    { return Blocks.end(); }
1307
 
1308
  iterator nodes_begin() { return iterator(Blocks.begin()); }
1309
  iterator nodes_end() { return iterator(Blocks.end()); }
1310
 
1311
  llvm::iterator_range<iterator> nodes() { return {begin(), end()}; }
1312
  llvm::iterator_range<const_iterator> const_nodes() const {
1313
    return {begin(), end()};
1314
  }
1315
 
1316
  const_iterator nodes_begin() const { return const_iterator(Blocks.begin()); }
1317
  const_iterator nodes_end() const { return const_iterator(Blocks.end()); }
1318
 
1319
  reverse_iterator          rbegin()               { return Blocks.rbegin(); }
1320
  reverse_iterator          rend()                 { return Blocks.rend(); }
1321
  const_reverse_iterator    rbegin()      const    { return Blocks.rbegin(); }
1322
  const_reverse_iterator    rend()        const    { return Blocks.rend(); }
1323
 
1324
  llvm::iterator_range<reverse_iterator> reverse_nodes() {
1325
    return {rbegin(), rend()};
1326
  }
1327
  llvm::iterator_range<const_reverse_iterator> const_reverse_nodes() const {
1328
    return {rbegin(), rend()};
1329
  }
1330
 
1331
  CFGBlock &                getEntry()             { return *Entry; }
1332
  const CFGBlock &          getEntry()    const    { return *Entry; }
1333
  CFGBlock &                getExit()              { return *Exit; }
1334
  const CFGBlock &          getExit()     const    { return *Exit; }
1335
 
1336
  CFGBlock *       getIndirectGotoBlock() { return IndirectGotoBlock; }
1337
  const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; }
1338
 
1339
  using try_block_iterator = std::vector<const CFGBlock *>::const_iterator;
1340
  using try_block_range = llvm::iterator_range<try_block_iterator>;
1341
 
1342
  try_block_iterator try_blocks_begin() const {
1343
    return TryDispatchBlocks.begin();
1344
  }
1345
 
1346
  try_block_iterator try_blocks_end() const {
1347
    return TryDispatchBlocks.end();
1348
  }
1349
 
1350
  try_block_range try_blocks() const {
1351
    return try_block_range(try_blocks_begin(), try_blocks_end());
1352
  }
1353
 
1354
  void addTryDispatchBlock(const CFGBlock *block) {
1355
    TryDispatchBlocks.push_back(block);
1356
  }
1357
 
1358
  /// Records a synthetic DeclStmt and the DeclStmt it was constructed from.
1359
  ///
1360
  /// The CFG uses synthetic DeclStmts when a single AST DeclStmt contains
1361
  /// multiple decls.
1362
  void addSyntheticDeclStmt(const DeclStmt *Synthetic,
1363
                            const DeclStmt *Source) {
1364
    assert(Synthetic->isSingleDecl() && "Can handle single declarations only");
1365
    assert(Synthetic != Source && "Don't include original DeclStmts in map");
1366
    assert(!SyntheticDeclStmts.count(Synthetic) && "Already in map");
1367
    SyntheticDeclStmts[Synthetic] = Source;
1368
  }
1369
 
1370
  using synthetic_stmt_iterator =
1371
      llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator;
1372
  using synthetic_stmt_range = llvm::iterator_range<synthetic_stmt_iterator>;
1373
 
1374
  /// Iterates over synthetic DeclStmts in the CFG.
1375
  ///
1376
  /// Each element is a (synthetic statement, source statement) pair.
1377
  ///
1378
  /// \sa addSyntheticDeclStmt
1379
  synthetic_stmt_iterator synthetic_stmt_begin() const {
1380
    return SyntheticDeclStmts.begin();
1381
  }
1382
 
1383
  /// \sa synthetic_stmt_begin
1384
  synthetic_stmt_iterator synthetic_stmt_end() const {
1385
    return SyntheticDeclStmts.end();
1386
  }
1387
 
1388
  /// \sa synthetic_stmt_begin
1389
  synthetic_stmt_range synthetic_stmts() const {
1390
    return synthetic_stmt_range(synthetic_stmt_begin(), synthetic_stmt_end());
1391
  }
1392
 
1393
  //===--------------------------------------------------------------------===//
1394
  // Member templates useful for various batch operations over CFGs.
1395
  //===--------------------------------------------------------------------===//
1396
 
1397
  template <typename Callback> void VisitBlockStmts(Callback &O) const {
1398
    for (const_iterator I = begin(), E = end(); I != E; ++I)
1399
      for (CFGBlock::const_iterator BI = (*I)->begin(), BE = (*I)->end();
1400
           BI != BE; ++BI) {
1401
        if (std::optional<CFGStmt> stmt = BI->getAs<CFGStmt>())
1402
          O(const_cast<Stmt *>(stmt->getStmt()));
1403
      }
1404
  }
1405
 
1406
  //===--------------------------------------------------------------------===//
1407
  // CFG Introspection.
1408
  //===--------------------------------------------------------------------===//
1409
 
1410
  /// Returns the total number of BlockIDs allocated (which start at 0).
1411
  unsigned getNumBlockIDs() const { return NumBlockIDs; }
1412
 
1413
  /// Return the total number of CFGBlocks within the CFG This is simply a
1414
  /// renaming of the getNumBlockIDs(). This is necessary because the dominator
1415
  /// implementation needs such an interface.
1416
  unsigned size() const { return NumBlockIDs; }
1417
 
1418
  /// Returns true if the CFG has no branches. Usually it boils down to the CFG
1419
  /// having exactly three blocks (entry, the actual code, exit), but sometimes
1420
  /// more blocks appear due to having control flow that can be fully
1421
  /// resolved in compile time.
1422
  bool isLinear() const;
1423
 
1424
  //===--------------------------------------------------------------------===//
1425
  // CFG Debugging: Pretty-Printing and Visualization.
1426
  //===--------------------------------------------------------------------===//
1427
 
1428
  void viewCFG(const LangOptions &LO) const;
1429
  void print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const;
1430
  void dump(const LangOptions &LO, bool ShowColors) const;
1431
 
1432
  //===--------------------------------------------------------------------===//
1433
  // Internal: constructors and data.
1434
  //===--------------------------------------------------------------------===//
1435
 
1436
  CFG() : Blocks(BlkBVC, 10) {}
1437
 
1438
  llvm::BumpPtrAllocator& getAllocator() {
1439
    return BlkBVC.getAllocator();
1440
  }
1441
 
1442
  BumpVectorContext &getBumpVectorContext() {
1443
    return BlkBVC;
1444
  }
1445
 
1446
private:
1447
  CFGBlock *Entry = nullptr;
1448
  CFGBlock *Exit = nullptr;
1449
 
1450
  // Special block to contain collective dispatch for indirect gotos
1451
  CFGBlock* IndirectGotoBlock = nullptr;
1452
 
1453
  unsigned  NumBlockIDs = 0;
1454
 
1455
  BumpVectorContext BlkBVC;
1456
 
1457
  CFGBlockListTy Blocks;
1458
 
1459
  /// C++ 'try' statements are modeled with an indirect dispatch block.
1460
  /// This is the collection of such blocks present in the CFG.
1461
  std::vector<const CFGBlock *> TryDispatchBlocks;
1462
 
1463
  /// Collects DeclStmts synthesized for this CFG and maps each one back to its
1464
  /// source DeclStmt.
1465
  llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts;
1466
};
1467
 
1468
Expr *extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE);
1469
 
1470
} // namespace clang
1471
 
1472
//===----------------------------------------------------------------------===//
1473
// GraphTraits specializations for CFG basic block graphs (source-level CFGs)
1474
//===----------------------------------------------------------------------===//
1475
 
1476
namespace llvm {
1477
 
1478
/// Implement simplify_type for CFGTerminator, so that we can dyn_cast from
1479
/// CFGTerminator to a specific Stmt class.
1480
template <> struct simplify_type< ::clang::CFGTerminator> {
1481
  using SimpleType = ::clang::Stmt *;
1482
 
1483
  static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) {
1484
    return Val.getStmt();
1485
  }
1486
};
1487
 
1488
// Traits for: CFGBlock
1489
 
1490
template <> struct GraphTraits< ::clang::CFGBlock *> {
1491
  using NodeRef = ::clang::CFGBlock *;
1492
  using ChildIteratorType = ::clang::CFGBlock::succ_iterator;
1493
 
1494
  static NodeRef getEntryNode(::clang::CFGBlock *BB) { return BB; }
1495
  static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
1496
  static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
1497
};
1498
 
1499
template <> struct GraphTraits< const ::clang::CFGBlock *> {
1500
  using NodeRef = const ::clang::CFGBlock *;
1501
  using ChildIteratorType = ::clang::CFGBlock::const_succ_iterator;
1502
 
1503
  static NodeRef getEntryNode(const clang::CFGBlock *BB) { return BB; }
1504
  static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
1505
  static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
1506
};
1507
 
1508
template <> struct GraphTraits<Inverse< ::clang::CFGBlock *>> {
1509
  using NodeRef = ::clang::CFGBlock *;
1510
  using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator;
1511
 
1512
  static NodeRef getEntryNode(Inverse<::clang::CFGBlock *> G) {
1513
    return G.Graph;
1514
  }
1515
 
1516
  static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
1517
  static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
1518
};
1519
 
1520
template <> struct GraphTraits<Inverse<const ::clang::CFGBlock *>> {
1521
  using NodeRef = const ::clang::CFGBlock *;
1522
  using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator;
1523
 
1524
  static NodeRef getEntryNode(Inverse<const ::clang::CFGBlock *> G) {
1525
    return G.Graph;
1526
  }
1527
 
1528
  static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
1529
  static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
1530
};
1531
 
1532
// Traits for: CFG
1533
 
1534
template <> struct GraphTraits< ::clang::CFG* >
1535
    : public GraphTraits< ::clang::CFGBlock *>  {
1536
  using nodes_iterator = ::clang::CFG::iterator;
1537
 
1538
  static NodeRef getEntryNode(::clang::CFG *F) { return &F->getEntry(); }
1539
  static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();}
1540
  static nodes_iterator   nodes_end(::clang::CFG* F) { return F->nodes_end(); }
1541
  static unsigned              size(::clang::CFG* F) { return F->size(); }
1542
};
1543
 
1544
template <> struct GraphTraits<const ::clang::CFG* >
1545
    : public GraphTraits<const ::clang::CFGBlock *>  {
1546
  using nodes_iterator = ::clang::CFG::const_iterator;
1547
 
1548
  static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getEntry(); }
1549
 
1550
  static nodes_iterator nodes_begin( const ::clang::CFG* F) {
1551
    return F->nodes_begin();
1552
  }
1553
 
1554
  static nodes_iterator nodes_end( const ::clang::CFG* F) {
1555
    return F->nodes_end();
1556
  }
1557
 
1558
  static unsigned size(const ::clang::CFG* F) {
1559
    return F->size();
1560
  }
1561
};
1562
 
1563
template <> struct GraphTraits<Inverse< ::clang::CFG *>>
1564
  : public GraphTraits<Inverse< ::clang::CFGBlock *>> {
1565
  using nodes_iterator = ::clang::CFG::iterator;
1566
 
1567
  static NodeRef getEntryNode(::clang::CFG *F) { return &F->getExit(); }
1568
  static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();}
1569
  static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); }
1570
};
1571
 
1572
template <> struct GraphTraits<Inverse<const ::clang::CFG *>>
1573
  : public GraphTraits<Inverse<const ::clang::CFGBlock *>> {
1574
  using nodes_iterator = ::clang::CFG::const_iterator;
1575
 
1576
  static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getExit(); }
1577
 
1578
  static nodes_iterator nodes_begin(const ::clang::CFG* F) {
1579
    return F->nodes_begin();
1580
  }
1581
 
1582
  static nodes_iterator nodes_end(const ::clang::CFG* F) {
1583
    return F->nodes_end();
1584
  }
1585
};
1586
 
1587
} // namespace llvm
1588
 
1589
#endif // LLVM_CLANG_ANALYSIS_CFG_H