xref: /minix3/external/bsd/llvm/dist/clang/lib/Analysis/CFG.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc   //===--- CFG.cpp - Classes for representing and building CFGs----*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc //  This file defines the CFG and CFGBuilder classes for representing and
11f4a2713aSLionel Sambuc //  building Control-Flow Graphs (CFGs) from ASTs.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc 
15f4a2713aSLionel Sambuc #include "clang/Analysis/CFG.h"
16f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
17f4a2713aSLionel Sambuc #include "clang/AST/Attr.h"
18f4a2713aSLionel Sambuc #include "clang/AST/CharUnits.h"
19f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h"
20f4a2713aSLionel Sambuc #include "clang/AST/PrettyPrinter.h"
21f4a2713aSLionel Sambuc #include "clang/AST/StmtVisitor.h"
22f4a2713aSLionel Sambuc #include "clang/Basic/Builtins.h"
23f4a2713aSLionel Sambuc #include "llvm/ADT/DenseMap.h"
24*0a6a1f1dSLionel Sambuc #include <memory>
25f4a2713aSLionel Sambuc #include "llvm/ADT/SmallPtrSet.h"
26f4a2713aSLionel Sambuc #include "llvm/Support/Allocator.h"
27f4a2713aSLionel Sambuc #include "llvm/Support/Format.h"
28f4a2713aSLionel Sambuc #include "llvm/Support/GraphWriter.h"
29f4a2713aSLionel Sambuc #include "llvm/Support/SaveAndRestore.h"
30f4a2713aSLionel Sambuc 
31f4a2713aSLionel Sambuc using namespace clang;
32f4a2713aSLionel Sambuc 
33f4a2713aSLionel Sambuc namespace {
34f4a2713aSLionel Sambuc 
GetEndLoc(Decl * D)35f4a2713aSLionel Sambuc static SourceLocation GetEndLoc(Decl *D) {
36f4a2713aSLionel Sambuc   if (VarDecl *VD = dyn_cast<VarDecl>(D))
37f4a2713aSLionel Sambuc     if (Expr *Ex = VD->getInit())
38f4a2713aSLionel Sambuc       return Ex->getSourceRange().getEnd();
39f4a2713aSLionel Sambuc   return D->getLocation();
40f4a2713aSLionel Sambuc }
41f4a2713aSLionel Sambuc 
42f4a2713aSLionel Sambuc class CFGBuilder;
43f4a2713aSLionel Sambuc 
44f4a2713aSLionel Sambuc /// The CFG builder uses a recursive algorithm to build the CFG.  When
45f4a2713aSLionel Sambuc ///  we process an expression, sometimes we know that we must add the
46f4a2713aSLionel Sambuc ///  subexpressions as block-level expressions.  For example:
47f4a2713aSLionel Sambuc ///
48f4a2713aSLionel Sambuc ///    exp1 || exp2
49f4a2713aSLionel Sambuc ///
50f4a2713aSLionel Sambuc ///  When processing the '||' expression, we know that exp1 and exp2
51f4a2713aSLionel Sambuc ///  need to be added as block-level expressions, even though they
52f4a2713aSLionel Sambuc ///  might not normally need to be.  AddStmtChoice records this
53f4a2713aSLionel Sambuc ///  contextual information.  If AddStmtChoice is 'NotAlwaysAdd', then
54f4a2713aSLionel Sambuc ///  the builder has an option not to add a subexpression as a
55f4a2713aSLionel Sambuc ///  block-level expression.
56f4a2713aSLionel Sambuc ///
57f4a2713aSLionel Sambuc class AddStmtChoice {
58f4a2713aSLionel Sambuc public:
59f4a2713aSLionel Sambuc   enum Kind { NotAlwaysAdd = 0, AlwaysAdd = 1 };
60f4a2713aSLionel Sambuc 
AddStmtChoice(Kind a_kind=NotAlwaysAdd)61f4a2713aSLionel Sambuc   AddStmtChoice(Kind a_kind = NotAlwaysAdd) : kind(a_kind) {}
62f4a2713aSLionel Sambuc 
63f4a2713aSLionel Sambuc   bool alwaysAdd(CFGBuilder &builder,
64f4a2713aSLionel Sambuc                  const Stmt *stmt) const;
65f4a2713aSLionel Sambuc 
66f4a2713aSLionel Sambuc   /// Return a copy of this object, except with the 'always-add' bit
67f4a2713aSLionel Sambuc   ///  set as specified.
withAlwaysAdd(bool alwaysAdd) const68f4a2713aSLionel Sambuc   AddStmtChoice withAlwaysAdd(bool alwaysAdd) const {
69f4a2713aSLionel Sambuc     return AddStmtChoice(alwaysAdd ? AlwaysAdd : NotAlwaysAdd);
70f4a2713aSLionel Sambuc   }
71f4a2713aSLionel Sambuc 
72f4a2713aSLionel Sambuc private:
73f4a2713aSLionel Sambuc   Kind kind;
74f4a2713aSLionel Sambuc };
75f4a2713aSLionel Sambuc 
76f4a2713aSLionel Sambuc /// LocalScope - Node in tree of local scopes created for C++ implicit
77f4a2713aSLionel Sambuc /// destructor calls generation. It contains list of automatic variables
78f4a2713aSLionel Sambuc /// declared in the scope and link to position in previous scope this scope
79f4a2713aSLionel Sambuc /// began in.
80f4a2713aSLionel Sambuc ///
81f4a2713aSLionel Sambuc /// The process of creating local scopes is as follows:
82f4a2713aSLionel Sambuc /// - Init CFGBuilder::ScopePos with invalid position (equivalent for null),
83f4a2713aSLionel Sambuc /// - Before processing statements in scope (e.g. CompoundStmt) create
84f4a2713aSLionel Sambuc ///   LocalScope object using CFGBuilder::ScopePos as link to previous scope
85f4a2713aSLionel Sambuc ///   and set CFGBuilder::ScopePos to the end of new scope,
86f4a2713aSLionel Sambuc /// - On every occurrence of VarDecl increase CFGBuilder::ScopePos if it points
87f4a2713aSLionel Sambuc ///   at this VarDecl,
88f4a2713aSLionel Sambuc /// - For every normal (without jump) end of scope add to CFGBlock destructors
89f4a2713aSLionel Sambuc ///   for objects in the current scope,
90f4a2713aSLionel Sambuc /// - For every jump add to CFGBlock destructors for objects
91f4a2713aSLionel Sambuc ///   between CFGBuilder::ScopePos and local scope position saved for jump
92f4a2713aSLionel Sambuc ///   target. Thanks to C++ restrictions on goto jumps we can be sure that
93f4a2713aSLionel Sambuc ///   jump target position will be on the path to root from CFGBuilder::ScopePos
94f4a2713aSLionel Sambuc ///   (adding any variable that doesn't need constructor to be called to
95f4a2713aSLionel Sambuc ///   LocalScope can break this assumption),
96f4a2713aSLionel Sambuc ///
97f4a2713aSLionel Sambuc class LocalScope {
98f4a2713aSLionel Sambuc public:
99f4a2713aSLionel Sambuc   typedef BumpVector<VarDecl*> AutomaticVarsTy;
100f4a2713aSLionel Sambuc 
101f4a2713aSLionel Sambuc   /// const_iterator - Iterates local scope backwards and jumps to previous
102f4a2713aSLionel Sambuc   /// scope on reaching the beginning of currently iterated scope.
103f4a2713aSLionel Sambuc   class const_iterator {
104f4a2713aSLionel Sambuc     const LocalScope* Scope;
105f4a2713aSLionel Sambuc 
106f4a2713aSLionel Sambuc     /// VarIter is guaranteed to be greater then 0 for every valid iterator.
107f4a2713aSLionel Sambuc     /// Invalid iterator (with null Scope) has VarIter equal to 0.
108f4a2713aSLionel Sambuc     unsigned VarIter;
109f4a2713aSLionel Sambuc 
110f4a2713aSLionel Sambuc   public:
111f4a2713aSLionel Sambuc     /// Create invalid iterator. Dereferencing invalid iterator is not allowed.
112f4a2713aSLionel Sambuc     /// Incrementing invalid iterator is allowed and will result in invalid
113f4a2713aSLionel Sambuc     /// iterator.
const_iterator()114f4a2713aSLionel Sambuc     const_iterator()
115*0a6a1f1dSLionel Sambuc         : Scope(nullptr), VarIter(0) {}
116f4a2713aSLionel Sambuc 
117f4a2713aSLionel Sambuc     /// Create valid iterator. In case when S.Prev is an invalid iterator and
118f4a2713aSLionel Sambuc     /// I is equal to 0, this will create invalid iterator.
const_iterator(const LocalScope & S,unsigned I)119f4a2713aSLionel Sambuc     const_iterator(const LocalScope& S, unsigned I)
120f4a2713aSLionel Sambuc         : Scope(&S), VarIter(I) {
121f4a2713aSLionel Sambuc       // Iterator to "end" of scope is not allowed. Handle it by going up
122f4a2713aSLionel Sambuc       // in scopes tree possibly up to invalid iterator in the root.
123f4a2713aSLionel Sambuc       if (VarIter == 0 && Scope)
124f4a2713aSLionel Sambuc         *this = Scope->Prev;
125f4a2713aSLionel Sambuc     }
126f4a2713aSLionel Sambuc 
operator ->() const127f4a2713aSLionel Sambuc     VarDecl *const* operator->() const {
128f4a2713aSLionel Sambuc       assert (Scope && "Dereferencing invalid iterator is not allowed");
129f4a2713aSLionel Sambuc       assert (VarIter != 0 && "Iterator has invalid value of VarIter member");
130f4a2713aSLionel Sambuc       return &Scope->Vars[VarIter - 1];
131f4a2713aSLionel Sambuc     }
operator *() const132f4a2713aSLionel Sambuc     VarDecl *operator*() const {
133f4a2713aSLionel Sambuc       return *this->operator->();
134f4a2713aSLionel Sambuc     }
135f4a2713aSLionel Sambuc 
operator ++()136f4a2713aSLionel Sambuc     const_iterator &operator++() {
137f4a2713aSLionel Sambuc       if (!Scope)
138f4a2713aSLionel Sambuc         return *this;
139f4a2713aSLionel Sambuc 
140f4a2713aSLionel Sambuc       assert (VarIter != 0 && "Iterator has invalid value of VarIter member");
141f4a2713aSLionel Sambuc       --VarIter;
142f4a2713aSLionel Sambuc       if (VarIter == 0)
143f4a2713aSLionel Sambuc         *this = Scope->Prev;
144f4a2713aSLionel Sambuc       return *this;
145f4a2713aSLionel Sambuc     }
operator ++(int)146f4a2713aSLionel Sambuc     const_iterator operator++(int) {
147f4a2713aSLionel Sambuc       const_iterator P = *this;
148f4a2713aSLionel Sambuc       ++*this;
149f4a2713aSLionel Sambuc       return P;
150f4a2713aSLionel Sambuc     }
151f4a2713aSLionel Sambuc 
operator ==(const const_iterator & rhs) const152f4a2713aSLionel Sambuc     bool operator==(const const_iterator &rhs) const {
153f4a2713aSLionel Sambuc       return Scope == rhs.Scope && VarIter == rhs.VarIter;
154f4a2713aSLionel Sambuc     }
operator !=(const const_iterator & rhs) const155f4a2713aSLionel Sambuc     bool operator!=(const const_iterator &rhs) const {
156f4a2713aSLionel Sambuc       return !(*this == rhs);
157f4a2713aSLionel Sambuc     }
158f4a2713aSLionel Sambuc 
operator bool() const159f4a2713aSLionel Sambuc     LLVM_EXPLICIT operator bool() const {
160f4a2713aSLionel Sambuc       return *this != const_iterator();
161f4a2713aSLionel Sambuc     }
162f4a2713aSLionel Sambuc 
163f4a2713aSLionel Sambuc     int distance(const_iterator L);
164f4a2713aSLionel Sambuc   };
165f4a2713aSLionel Sambuc 
166f4a2713aSLionel Sambuc   friend class const_iterator;
167f4a2713aSLionel Sambuc 
168f4a2713aSLionel Sambuc private:
169f4a2713aSLionel Sambuc   BumpVectorContext ctx;
170f4a2713aSLionel Sambuc 
171f4a2713aSLionel Sambuc   /// Automatic variables in order of declaration.
172f4a2713aSLionel Sambuc   AutomaticVarsTy Vars;
173f4a2713aSLionel Sambuc   /// Iterator to variable in previous scope that was declared just before
174f4a2713aSLionel Sambuc   /// begin of this scope.
175f4a2713aSLionel Sambuc   const_iterator Prev;
176f4a2713aSLionel Sambuc 
177f4a2713aSLionel Sambuc public:
178f4a2713aSLionel Sambuc   /// Constructs empty scope linked to previous scope in specified place.
LocalScope(BumpVectorContext & ctx,const_iterator P)179f4a2713aSLionel Sambuc   LocalScope(BumpVectorContext &ctx, const_iterator P)
180f4a2713aSLionel Sambuc       : ctx(ctx), Vars(ctx, 4), Prev(P) {}
181f4a2713aSLionel Sambuc 
182f4a2713aSLionel Sambuc   /// Begin of scope in direction of CFG building (backwards).
begin() const183f4a2713aSLionel Sambuc   const_iterator begin() const { return const_iterator(*this, Vars.size()); }
184f4a2713aSLionel Sambuc 
addVar(VarDecl * VD)185f4a2713aSLionel Sambuc   void addVar(VarDecl *VD) {
186f4a2713aSLionel Sambuc     Vars.push_back(VD, ctx);
187f4a2713aSLionel Sambuc   }
188f4a2713aSLionel Sambuc };
189f4a2713aSLionel Sambuc 
190f4a2713aSLionel Sambuc /// distance - Calculates distance from this to L. L must be reachable from this
191f4a2713aSLionel Sambuc /// (with use of ++ operator). Cost of calculating the distance is linear w.r.t.
192f4a2713aSLionel Sambuc /// number of scopes between this and L.
distance(LocalScope::const_iterator L)193f4a2713aSLionel Sambuc int LocalScope::const_iterator::distance(LocalScope::const_iterator L) {
194f4a2713aSLionel Sambuc   int D = 0;
195f4a2713aSLionel Sambuc   const_iterator F = *this;
196f4a2713aSLionel Sambuc   while (F.Scope != L.Scope) {
197f4a2713aSLionel Sambuc     assert (F != const_iterator()
198f4a2713aSLionel Sambuc         && "L iterator is not reachable from F iterator.");
199f4a2713aSLionel Sambuc     D += F.VarIter;
200f4a2713aSLionel Sambuc     F = F.Scope->Prev;
201f4a2713aSLionel Sambuc   }
202f4a2713aSLionel Sambuc   D += F.VarIter - L.VarIter;
203f4a2713aSLionel Sambuc   return D;
204f4a2713aSLionel Sambuc }
205f4a2713aSLionel Sambuc 
206f4a2713aSLionel Sambuc /// BlockScopePosPair - Structure for specifying position in CFG during its
207f4a2713aSLionel Sambuc /// build process. It consists of CFGBlock that specifies position in CFG graph
208f4a2713aSLionel Sambuc /// and  LocalScope::const_iterator that specifies position in LocalScope graph.
209f4a2713aSLionel Sambuc struct BlockScopePosPair {
BlockScopePosPair__anon557f5a500111::BlockScopePosPair210*0a6a1f1dSLionel Sambuc   BlockScopePosPair() : block(nullptr) {}
BlockScopePosPair__anon557f5a500111::BlockScopePosPair211f4a2713aSLionel Sambuc   BlockScopePosPair(CFGBlock *b, LocalScope::const_iterator scopePos)
212f4a2713aSLionel Sambuc       : block(b), scopePosition(scopePos) {}
213f4a2713aSLionel Sambuc 
214f4a2713aSLionel Sambuc   CFGBlock *block;
215f4a2713aSLionel Sambuc   LocalScope::const_iterator scopePosition;
216f4a2713aSLionel Sambuc };
217f4a2713aSLionel Sambuc 
218f4a2713aSLionel Sambuc /// TryResult - a class representing a variant over the values
219f4a2713aSLionel Sambuc ///  'true', 'false', or 'unknown'.  This is returned by tryEvaluateBool,
220f4a2713aSLionel Sambuc ///  and is used by the CFGBuilder to decide if a branch condition
221f4a2713aSLionel Sambuc ///  can be decided up front during CFG construction.
222f4a2713aSLionel Sambuc class TryResult {
223f4a2713aSLionel Sambuc   int X;
224f4a2713aSLionel Sambuc public:
TryResult(bool b)225f4a2713aSLionel Sambuc   TryResult(bool b) : X(b ? 1 : 0) {}
TryResult()226f4a2713aSLionel Sambuc   TryResult() : X(-1) {}
227f4a2713aSLionel Sambuc 
isTrue() const228f4a2713aSLionel Sambuc   bool isTrue() const { return X == 1; }
isFalse() const229f4a2713aSLionel Sambuc   bool isFalse() const { return X == 0; }
isKnown() const230f4a2713aSLionel Sambuc   bool isKnown() const { return X >= 0; }
negate()231f4a2713aSLionel Sambuc   void negate() {
232f4a2713aSLionel Sambuc     assert(isKnown());
233f4a2713aSLionel Sambuc     X ^= 0x1;
234f4a2713aSLionel Sambuc   }
235f4a2713aSLionel Sambuc };
236f4a2713aSLionel Sambuc 
bothKnownTrue(TryResult R1,TryResult R2)237*0a6a1f1dSLionel Sambuc TryResult bothKnownTrue(TryResult R1, TryResult R2) {
238*0a6a1f1dSLionel Sambuc   if (!R1.isKnown() || !R2.isKnown())
239*0a6a1f1dSLionel Sambuc     return TryResult();
240*0a6a1f1dSLionel Sambuc   return TryResult(R1.isTrue() && R2.isTrue());
241*0a6a1f1dSLionel Sambuc }
242*0a6a1f1dSLionel Sambuc 
243f4a2713aSLionel Sambuc class reverse_children {
244f4a2713aSLionel Sambuc   llvm::SmallVector<Stmt *, 12> childrenBuf;
245f4a2713aSLionel Sambuc   ArrayRef<Stmt*> children;
246f4a2713aSLionel Sambuc public:
247f4a2713aSLionel Sambuc   reverse_children(Stmt *S);
248f4a2713aSLionel Sambuc 
249f4a2713aSLionel Sambuc   typedef ArrayRef<Stmt*>::reverse_iterator iterator;
begin() const250f4a2713aSLionel Sambuc   iterator begin() const { return children.rbegin(); }
end() const251f4a2713aSLionel Sambuc   iterator end() const { return children.rend(); }
252f4a2713aSLionel Sambuc };
253f4a2713aSLionel Sambuc 
254f4a2713aSLionel Sambuc 
reverse_children(Stmt * S)255f4a2713aSLionel Sambuc reverse_children::reverse_children(Stmt *S) {
256f4a2713aSLionel Sambuc   if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
257f4a2713aSLionel Sambuc     children = CE->getRawSubExprs();
258f4a2713aSLionel Sambuc     return;
259f4a2713aSLionel Sambuc   }
260f4a2713aSLionel Sambuc   switch (S->getStmtClass()) {
261f4a2713aSLionel Sambuc     // Note: Fill in this switch with more cases we want to optimize.
262f4a2713aSLionel Sambuc     case Stmt::InitListExprClass: {
263f4a2713aSLionel Sambuc       InitListExpr *IE = cast<InitListExpr>(S);
264f4a2713aSLionel Sambuc       children = llvm::makeArrayRef(reinterpret_cast<Stmt**>(IE->getInits()),
265f4a2713aSLionel Sambuc                                     IE->getNumInits());
266f4a2713aSLionel Sambuc       return;
267f4a2713aSLionel Sambuc     }
268f4a2713aSLionel Sambuc     default:
269f4a2713aSLionel Sambuc       break;
270f4a2713aSLionel Sambuc   }
271f4a2713aSLionel Sambuc 
272f4a2713aSLionel Sambuc   // Default case for all other statements.
273f4a2713aSLionel Sambuc   for (Stmt::child_range I = S->children(); I; ++I) {
274f4a2713aSLionel Sambuc     childrenBuf.push_back(*I);
275f4a2713aSLionel Sambuc   }
276f4a2713aSLionel Sambuc 
277f4a2713aSLionel Sambuc   // This needs to be done *after* childrenBuf has been populated.
278f4a2713aSLionel Sambuc   children = childrenBuf;
279f4a2713aSLionel Sambuc }
280f4a2713aSLionel Sambuc 
281f4a2713aSLionel Sambuc /// CFGBuilder - This class implements CFG construction from an AST.
282f4a2713aSLionel Sambuc ///   The builder is stateful: an instance of the builder should be used to only
283f4a2713aSLionel Sambuc ///   construct a single CFG.
284f4a2713aSLionel Sambuc ///
285f4a2713aSLionel Sambuc ///   Example usage:
286f4a2713aSLionel Sambuc ///
287f4a2713aSLionel Sambuc ///     CFGBuilder builder;
288f4a2713aSLionel Sambuc ///     CFG* cfg = builder.BuildAST(stmt1);
289f4a2713aSLionel Sambuc ///
290f4a2713aSLionel Sambuc ///  CFG construction is done via a recursive walk of an AST.  We actually parse
291f4a2713aSLionel Sambuc ///  the AST in reverse order so that the successor of a basic block is
292f4a2713aSLionel Sambuc ///  constructed prior to its predecessor.  This allows us to nicely capture
293f4a2713aSLionel Sambuc ///  implicit fall-throughs without extra basic blocks.
294f4a2713aSLionel Sambuc ///
295f4a2713aSLionel Sambuc class CFGBuilder {
296f4a2713aSLionel Sambuc   typedef BlockScopePosPair JumpTarget;
297f4a2713aSLionel Sambuc   typedef BlockScopePosPair JumpSource;
298f4a2713aSLionel Sambuc 
299f4a2713aSLionel Sambuc   ASTContext *Context;
300*0a6a1f1dSLionel Sambuc   std::unique_ptr<CFG> cfg;
301f4a2713aSLionel Sambuc 
302f4a2713aSLionel Sambuc   CFGBlock *Block;
303f4a2713aSLionel Sambuc   CFGBlock *Succ;
304f4a2713aSLionel Sambuc   JumpTarget ContinueJumpTarget;
305f4a2713aSLionel Sambuc   JumpTarget BreakJumpTarget;
306f4a2713aSLionel Sambuc   CFGBlock *SwitchTerminatedBlock;
307f4a2713aSLionel Sambuc   CFGBlock *DefaultCaseBlock;
308f4a2713aSLionel Sambuc   CFGBlock *TryTerminatedBlock;
309f4a2713aSLionel Sambuc 
310f4a2713aSLionel Sambuc   // Current position in local scope.
311f4a2713aSLionel Sambuc   LocalScope::const_iterator ScopePos;
312f4a2713aSLionel Sambuc 
313f4a2713aSLionel Sambuc   // LabelMap records the mapping from Label expressions to their jump targets.
314f4a2713aSLionel Sambuc   typedef llvm::DenseMap<LabelDecl*, JumpTarget> LabelMapTy;
315f4a2713aSLionel Sambuc   LabelMapTy LabelMap;
316f4a2713aSLionel Sambuc 
317f4a2713aSLionel Sambuc   // A list of blocks that end with a "goto" that must be backpatched to their
318f4a2713aSLionel Sambuc   // resolved targets upon completion of CFG construction.
319f4a2713aSLionel Sambuc   typedef std::vector<JumpSource> BackpatchBlocksTy;
320f4a2713aSLionel Sambuc   BackpatchBlocksTy BackpatchBlocks;
321f4a2713aSLionel Sambuc 
322f4a2713aSLionel Sambuc   // A list of labels whose address has been taken (for indirect gotos).
323f4a2713aSLionel Sambuc   typedef llvm::SmallPtrSet<LabelDecl*, 5> LabelSetTy;
324f4a2713aSLionel Sambuc   LabelSetTy AddressTakenLabels;
325f4a2713aSLionel Sambuc 
326f4a2713aSLionel Sambuc   bool badCFG;
327f4a2713aSLionel Sambuc   const CFG::BuildOptions &BuildOpts;
328f4a2713aSLionel Sambuc 
329f4a2713aSLionel Sambuc   // State to track for building switch statements.
330f4a2713aSLionel Sambuc   bool switchExclusivelyCovered;
331f4a2713aSLionel Sambuc   Expr::EvalResult *switchCond;
332f4a2713aSLionel Sambuc 
333f4a2713aSLionel Sambuc   CFG::BuildOptions::ForcedBlkExprs::value_type *cachedEntry;
334f4a2713aSLionel Sambuc   const Stmt *lastLookup;
335f4a2713aSLionel Sambuc 
336f4a2713aSLionel Sambuc   // Caches boolean evaluations of expressions to avoid multiple re-evaluations
337f4a2713aSLionel Sambuc   // during construction of branches for chained logical operators.
338f4a2713aSLionel Sambuc   typedef llvm::DenseMap<Expr *, TryResult> CachedBoolEvalsTy;
339f4a2713aSLionel Sambuc   CachedBoolEvalsTy CachedBoolEvals;
340f4a2713aSLionel Sambuc 
341f4a2713aSLionel Sambuc public:
CFGBuilder(ASTContext * astContext,const CFG::BuildOptions & buildOpts)342f4a2713aSLionel Sambuc   explicit CFGBuilder(ASTContext *astContext,
343f4a2713aSLionel Sambuc                       const CFG::BuildOptions &buildOpts)
344f4a2713aSLionel Sambuc     : Context(astContext), cfg(new CFG()), // crew a new CFG
345*0a6a1f1dSLionel Sambuc       Block(nullptr), Succ(nullptr),
346*0a6a1f1dSLionel Sambuc       SwitchTerminatedBlock(nullptr), DefaultCaseBlock(nullptr),
347*0a6a1f1dSLionel Sambuc       TryTerminatedBlock(nullptr), badCFG(false), BuildOpts(buildOpts),
348*0a6a1f1dSLionel Sambuc       switchExclusivelyCovered(false), switchCond(nullptr),
349*0a6a1f1dSLionel Sambuc       cachedEntry(nullptr), lastLookup(nullptr) {}
350f4a2713aSLionel Sambuc 
351f4a2713aSLionel Sambuc   // buildCFG - Used by external clients to construct the CFG.
352*0a6a1f1dSLionel Sambuc   std::unique_ptr<CFG> buildCFG(const Decl *D, Stmt *Statement);
353f4a2713aSLionel Sambuc 
354f4a2713aSLionel Sambuc   bool alwaysAdd(const Stmt *stmt);
355f4a2713aSLionel Sambuc 
356f4a2713aSLionel Sambuc private:
357f4a2713aSLionel Sambuc   // Visitors to walk an AST and construct the CFG.
358f4a2713aSLionel Sambuc   CFGBlock *VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc);
359f4a2713aSLionel Sambuc   CFGBlock *VisitBinaryOperator(BinaryOperator *B, AddStmtChoice asc);
360f4a2713aSLionel Sambuc   CFGBlock *VisitBreakStmt(BreakStmt *B);
361f4a2713aSLionel Sambuc   CFGBlock *VisitCallExpr(CallExpr *C, AddStmtChoice asc);
362f4a2713aSLionel Sambuc   CFGBlock *VisitCaseStmt(CaseStmt *C);
363f4a2713aSLionel Sambuc   CFGBlock *VisitChooseExpr(ChooseExpr *C, AddStmtChoice asc);
364f4a2713aSLionel Sambuc   CFGBlock *VisitCompoundStmt(CompoundStmt *C);
365f4a2713aSLionel Sambuc   CFGBlock *VisitConditionalOperator(AbstractConditionalOperator *C,
366f4a2713aSLionel Sambuc                                      AddStmtChoice asc);
367f4a2713aSLionel Sambuc   CFGBlock *VisitContinueStmt(ContinueStmt *C);
368f4a2713aSLionel Sambuc   CFGBlock *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E,
369f4a2713aSLionel Sambuc                                       AddStmtChoice asc);
370f4a2713aSLionel Sambuc   CFGBlock *VisitCXXCatchStmt(CXXCatchStmt *S);
371f4a2713aSLionel Sambuc   CFGBlock *VisitCXXConstructExpr(CXXConstructExpr *C, AddStmtChoice asc);
372*0a6a1f1dSLionel Sambuc   CFGBlock *VisitCXXNewExpr(CXXNewExpr *DE, AddStmtChoice asc);
373f4a2713aSLionel Sambuc   CFGBlock *VisitCXXDeleteExpr(CXXDeleteExpr *DE, AddStmtChoice asc);
374f4a2713aSLionel Sambuc   CFGBlock *VisitCXXForRangeStmt(CXXForRangeStmt *S);
375f4a2713aSLionel Sambuc   CFGBlock *VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E,
376f4a2713aSLionel Sambuc                                        AddStmtChoice asc);
377f4a2713aSLionel Sambuc   CFGBlock *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C,
378f4a2713aSLionel Sambuc                                         AddStmtChoice asc);
379f4a2713aSLionel Sambuc   CFGBlock *VisitCXXThrowExpr(CXXThrowExpr *T);
380f4a2713aSLionel Sambuc   CFGBlock *VisitCXXTryStmt(CXXTryStmt *S);
381f4a2713aSLionel Sambuc   CFGBlock *VisitDeclStmt(DeclStmt *DS);
382f4a2713aSLionel Sambuc   CFGBlock *VisitDeclSubExpr(DeclStmt *DS);
383f4a2713aSLionel Sambuc   CFGBlock *VisitDefaultStmt(DefaultStmt *D);
384f4a2713aSLionel Sambuc   CFGBlock *VisitDoStmt(DoStmt *D);
385f4a2713aSLionel Sambuc   CFGBlock *VisitExprWithCleanups(ExprWithCleanups *E, AddStmtChoice asc);
386f4a2713aSLionel Sambuc   CFGBlock *VisitForStmt(ForStmt *F);
387f4a2713aSLionel Sambuc   CFGBlock *VisitGotoStmt(GotoStmt *G);
388f4a2713aSLionel Sambuc   CFGBlock *VisitIfStmt(IfStmt *I);
389f4a2713aSLionel Sambuc   CFGBlock *VisitImplicitCastExpr(ImplicitCastExpr *E, AddStmtChoice asc);
390f4a2713aSLionel Sambuc   CFGBlock *VisitIndirectGotoStmt(IndirectGotoStmt *I);
391f4a2713aSLionel Sambuc   CFGBlock *VisitLabelStmt(LabelStmt *L);
392f4a2713aSLionel Sambuc   CFGBlock *VisitLambdaExpr(LambdaExpr *E, AddStmtChoice asc);
393f4a2713aSLionel Sambuc   CFGBlock *VisitLogicalOperator(BinaryOperator *B);
394f4a2713aSLionel Sambuc   std::pair<CFGBlock *, CFGBlock *> VisitLogicalOperator(BinaryOperator *B,
395f4a2713aSLionel Sambuc                                                          Stmt *Term,
396f4a2713aSLionel Sambuc                                                          CFGBlock *TrueBlock,
397f4a2713aSLionel Sambuc                                                          CFGBlock *FalseBlock);
398f4a2713aSLionel Sambuc   CFGBlock *VisitMemberExpr(MemberExpr *M, AddStmtChoice asc);
399f4a2713aSLionel Sambuc   CFGBlock *VisitObjCAtCatchStmt(ObjCAtCatchStmt *S);
400f4a2713aSLionel Sambuc   CFGBlock *VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S);
401f4a2713aSLionel Sambuc   CFGBlock *VisitObjCAtThrowStmt(ObjCAtThrowStmt *S);
402f4a2713aSLionel Sambuc   CFGBlock *VisitObjCAtTryStmt(ObjCAtTryStmt *S);
403f4a2713aSLionel Sambuc   CFGBlock *VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S);
404f4a2713aSLionel Sambuc   CFGBlock *VisitObjCForCollectionStmt(ObjCForCollectionStmt *S);
405f4a2713aSLionel Sambuc   CFGBlock *VisitPseudoObjectExpr(PseudoObjectExpr *E);
406f4a2713aSLionel Sambuc   CFGBlock *VisitReturnStmt(ReturnStmt *R);
407f4a2713aSLionel Sambuc   CFGBlock *VisitStmtExpr(StmtExpr *S, AddStmtChoice asc);
408f4a2713aSLionel Sambuc   CFGBlock *VisitSwitchStmt(SwitchStmt *S);
409f4a2713aSLionel Sambuc   CFGBlock *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E,
410f4a2713aSLionel Sambuc                                           AddStmtChoice asc);
411f4a2713aSLionel Sambuc   CFGBlock *VisitUnaryOperator(UnaryOperator *U, AddStmtChoice asc);
412f4a2713aSLionel Sambuc   CFGBlock *VisitWhileStmt(WhileStmt *W);
413f4a2713aSLionel Sambuc 
414f4a2713aSLionel Sambuc   CFGBlock *Visit(Stmt *S, AddStmtChoice asc = AddStmtChoice::NotAlwaysAdd);
415f4a2713aSLionel Sambuc   CFGBlock *VisitStmt(Stmt *S, AddStmtChoice asc);
416f4a2713aSLionel Sambuc   CFGBlock *VisitChildren(Stmt *S);
417f4a2713aSLionel Sambuc   CFGBlock *VisitNoRecurse(Expr *E, AddStmtChoice asc);
418f4a2713aSLionel Sambuc 
419*0a6a1f1dSLionel Sambuc   /// When creating the CFG for temporary destructors, we want to mirror the
420*0a6a1f1dSLionel Sambuc   /// branch structure of the corresponding constructor calls.
421*0a6a1f1dSLionel Sambuc   /// Thus, while visiting a statement for temporary destructors, we keep a
422*0a6a1f1dSLionel Sambuc   /// context to keep track of the following information:
423*0a6a1f1dSLionel Sambuc   /// - whether a subexpression is executed unconditionally
424*0a6a1f1dSLionel Sambuc   /// - if a subexpression is executed conditionally, the first
425*0a6a1f1dSLionel Sambuc   ///   CXXBindTemporaryExpr we encounter in that subexpression (which
426*0a6a1f1dSLionel Sambuc   ///   corresponds to the last temporary destructor we have to call for this
427*0a6a1f1dSLionel Sambuc   ///   subexpression) and the CFG block at that point (which will become the
428*0a6a1f1dSLionel Sambuc   ///   successor block when inserting the decision point).
429*0a6a1f1dSLionel Sambuc   ///
430*0a6a1f1dSLionel Sambuc   /// That way, we can build the branch structure for temporary destructors as
431*0a6a1f1dSLionel Sambuc   /// follows:
432*0a6a1f1dSLionel Sambuc   /// 1. If a subexpression is executed unconditionally, we add the temporary
433*0a6a1f1dSLionel Sambuc   ///    destructor calls to the current block.
434*0a6a1f1dSLionel Sambuc   /// 2. If a subexpression is executed conditionally, when we encounter a
435*0a6a1f1dSLionel Sambuc   ///    CXXBindTemporaryExpr:
436*0a6a1f1dSLionel Sambuc   ///    a) If it is the first temporary destructor call in the subexpression,
437*0a6a1f1dSLionel Sambuc   ///       we remember the CXXBindTemporaryExpr and the current block in the
438*0a6a1f1dSLionel Sambuc   ///       TempDtorContext; we start a new block, and insert the temporary
439*0a6a1f1dSLionel Sambuc   ///       destructor call.
440*0a6a1f1dSLionel Sambuc   ///    b) Otherwise, add the temporary destructor call to the current block.
441*0a6a1f1dSLionel Sambuc   ///  3. When we finished visiting a conditionally executed subexpression,
442*0a6a1f1dSLionel Sambuc   ///     and we found at least one temporary constructor during the visitation
443*0a6a1f1dSLionel Sambuc   ///     (2.a has executed), we insert a decision block that uses the
444*0a6a1f1dSLionel Sambuc   ///     CXXBindTemporaryExpr as terminator, and branches to the current block
445*0a6a1f1dSLionel Sambuc   ///     if the CXXBindTemporaryExpr was marked executed, and otherwise
446*0a6a1f1dSLionel Sambuc   ///     branches to the stored successor.
447*0a6a1f1dSLionel Sambuc   struct TempDtorContext {
TempDtorContext__anon557f5a500111::CFGBuilder::TempDtorContext448*0a6a1f1dSLionel Sambuc     TempDtorContext()
449*0a6a1f1dSLionel Sambuc         : IsConditional(false), KnownExecuted(true), Succ(nullptr),
450*0a6a1f1dSLionel Sambuc           TerminatorExpr(nullptr) {}
451*0a6a1f1dSLionel Sambuc 
TempDtorContext__anon557f5a500111::CFGBuilder::TempDtorContext452*0a6a1f1dSLionel Sambuc     TempDtorContext(TryResult KnownExecuted)
453*0a6a1f1dSLionel Sambuc         : IsConditional(true), KnownExecuted(KnownExecuted), Succ(nullptr),
454*0a6a1f1dSLionel Sambuc           TerminatorExpr(nullptr) {}
455*0a6a1f1dSLionel Sambuc 
456*0a6a1f1dSLionel Sambuc     /// Returns whether we need to start a new branch for a temporary destructor
457*0a6a1f1dSLionel Sambuc     /// call. This is the case when the the temporary destructor is
458*0a6a1f1dSLionel Sambuc     /// conditionally executed, and it is the first one we encounter while
459*0a6a1f1dSLionel Sambuc     /// visiting a subexpression - other temporary destructors at the same level
460*0a6a1f1dSLionel Sambuc     /// will be added to the same block and are executed under the same
461*0a6a1f1dSLionel Sambuc     /// condition.
needsTempDtorBranch__anon557f5a500111::CFGBuilder::TempDtorContext462*0a6a1f1dSLionel Sambuc     bool needsTempDtorBranch() const {
463*0a6a1f1dSLionel Sambuc       return IsConditional && !TerminatorExpr;
464*0a6a1f1dSLionel Sambuc     }
465*0a6a1f1dSLionel Sambuc 
466*0a6a1f1dSLionel Sambuc     /// Remember the successor S of a temporary destructor decision branch for
467*0a6a1f1dSLionel Sambuc     /// the corresponding CXXBindTemporaryExpr E.
setDecisionPoint__anon557f5a500111::CFGBuilder::TempDtorContext468*0a6a1f1dSLionel Sambuc     void setDecisionPoint(CFGBlock *S, CXXBindTemporaryExpr *E) {
469*0a6a1f1dSLionel Sambuc       Succ = S;
470*0a6a1f1dSLionel Sambuc       TerminatorExpr = E;
471*0a6a1f1dSLionel Sambuc     }
472*0a6a1f1dSLionel Sambuc 
473*0a6a1f1dSLionel Sambuc     const bool IsConditional;
474*0a6a1f1dSLionel Sambuc     const TryResult KnownExecuted;
475*0a6a1f1dSLionel Sambuc     CFGBlock *Succ;
476*0a6a1f1dSLionel Sambuc     CXXBindTemporaryExpr *TerminatorExpr;
477*0a6a1f1dSLionel Sambuc   };
478*0a6a1f1dSLionel Sambuc 
479f4a2713aSLionel Sambuc   // Visitors to walk an AST and generate destructors of temporaries in
480f4a2713aSLionel Sambuc   // full expression.
481*0a6a1f1dSLionel Sambuc   CFGBlock *VisitForTemporaryDtors(Stmt *E, bool BindToTemporary,
482*0a6a1f1dSLionel Sambuc                                    TempDtorContext &Context);
483*0a6a1f1dSLionel Sambuc   CFGBlock *VisitChildrenForTemporaryDtors(Stmt *E, TempDtorContext &Context);
484*0a6a1f1dSLionel Sambuc   CFGBlock *VisitBinaryOperatorForTemporaryDtors(BinaryOperator *E,
485*0a6a1f1dSLionel Sambuc                                                  TempDtorContext &Context);
486*0a6a1f1dSLionel Sambuc   CFGBlock *VisitCXXBindTemporaryExprForTemporaryDtors(
487*0a6a1f1dSLionel Sambuc       CXXBindTemporaryExpr *E, bool BindToTemporary, TempDtorContext &Context);
488*0a6a1f1dSLionel Sambuc   CFGBlock *VisitConditionalOperatorForTemporaryDtors(
489*0a6a1f1dSLionel Sambuc       AbstractConditionalOperator *E, bool BindToTemporary,
490*0a6a1f1dSLionel Sambuc       TempDtorContext &Context);
491*0a6a1f1dSLionel Sambuc   void InsertTempDtorDecisionBlock(const TempDtorContext &Context,
492*0a6a1f1dSLionel Sambuc                                    CFGBlock *FalseSucc = nullptr);
493f4a2713aSLionel Sambuc 
494f4a2713aSLionel Sambuc   // NYS == Not Yet Supported
NYS()495f4a2713aSLionel Sambuc   CFGBlock *NYS() {
496f4a2713aSLionel Sambuc     badCFG = true;
497f4a2713aSLionel Sambuc     return Block;
498f4a2713aSLionel Sambuc   }
499f4a2713aSLionel Sambuc 
autoCreateBlock()500f4a2713aSLionel Sambuc   void autoCreateBlock() { if (!Block) Block = createBlock(); }
501f4a2713aSLionel Sambuc   CFGBlock *createBlock(bool add_successor = true);
502f4a2713aSLionel Sambuc   CFGBlock *createNoReturnBlock();
503f4a2713aSLionel Sambuc 
addStmt(Stmt * S)504f4a2713aSLionel Sambuc   CFGBlock *addStmt(Stmt *S) {
505f4a2713aSLionel Sambuc     return Visit(S, AddStmtChoice::AlwaysAdd);
506f4a2713aSLionel Sambuc   }
507f4a2713aSLionel Sambuc   CFGBlock *addInitializer(CXXCtorInitializer *I);
508f4a2713aSLionel Sambuc   void addAutomaticObjDtors(LocalScope::const_iterator B,
509f4a2713aSLionel Sambuc                             LocalScope::const_iterator E, Stmt *S);
510f4a2713aSLionel Sambuc   void addImplicitDtorsForDestructor(const CXXDestructorDecl *DD);
511f4a2713aSLionel Sambuc 
512f4a2713aSLionel Sambuc   // Local scopes creation.
513f4a2713aSLionel Sambuc   LocalScope* createOrReuseLocalScope(LocalScope* Scope);
514f4a2713aSLionel Sambuc 
515f4a2713aSLionel Sambuc   void addLocalScopeForStmt(Stmt *S);
516*0a6a1f1dSLionel Sambuc   LocalScope* addLocalScopeForDeclStmt(DeclStmt *DS,
517*0a6a1f1dSLionel Sambuc                                        LocalScope* Scope = nullptr);
518*0a6a1f1dSLionel Sambuc   LocalScope* addLocalScopeForVarDecl(VarDecl *VD, LocalScope* Scope = nullptr);
519f4a2713aSLionel Sambuc 
520f4a2713aSLionel Sambuc   void addLocalScopeAndDtors(Stmt *S);
521f4a2713aSLionel Sambuc 
522f4a2713aSLionel Sambuc   // Interface to CFGBlock - adding CFGElements.
appendStmt(CFGBlock * B,const Stmt * S)523f4a2713aSLionel Sambuc   void appendStmt(CFGBlock *B, const Stmt *S) {
524f4a2713aSLionel Sambuc     if (alwaysAdd(S) && cachedEntry)
525f4a2713aSLionel Sambuc       cachedEntry->second = B;
526f4a2713aSLionel Sambuc 
527f4a2713aSLionel Sambuc     // All block-level expressions should have already been IgnoreParens()ed.
528f4a2713aSLionel Sambuc     assert(!isa<Expr>(S) || cast<Expr>(S)->IgnoreParens() == S);
529f4a2713aSLionel Sambuc     B->appendStmt(const_cast<Stmt*>(S), cfg->getBumpVectorContext());
530f4a2713aSLionel Sambuc   }
appendInitializer(CFGBlock * B,CXXCtorInitializer * I)531f4a2713aSLionel Sambuc   void appendInitializer(CFGBlock *B, CXXCtorInitializer *I) {
532f4a2713aSLionel Sambuc     B->appendInitializer(I, cfg->getBumpVectorContext());
533f4a2713aSLionel Sambuc   }
appendNewAllocator(CFGBlock * B,CXXNewExpr * NE)534*0a6a1f1dSLionel Sambuc   void appendNewAllocator(CFGBlock *B, CXXNewExpr *NE) {
535*0a6a1f1dSLionel Sambuc     B->appendNewAllocator(NE, cfg->getBumpVectorContext());
536*0a6a1f1dSLionel Sambuc   }
appendBaseDtor(CFGBlock * B,const CXXBaseSpecifier * BS)537f4a2713aSLionel Sambuc   void appendBaseDtor(CFGBlock *B, const CXXBaseSpecifier *BS) {
538f4a2713aSLionel Sambuc     B->appendBaseDtor(BS, cfg->getBumpVectorContext());
539f4a2713aSLionel Sambuc   }
appendMemberDtor(CFGBlock * B,FieldDecl * FD)540f4a2713aSLionel Sambuc   void appendMemberDtor(CFGBlock *B, FieldDecl *FD) {
541f4a2713aSLionel Sambuc     B->appendMemberDtor(FD, cfg->getBumpVectorContext());
542f4a2713aSLionel Sambuc   }
appendTemporaryDtor(CFGBlock * B,CXXBindTemporaryExpr * E)543f4a2713aSLionel Sambuc   void appendTemporaryDtor(CFGBlock *B, CXXBindTemporaryExpr *E) {
544f4a2713aSLionel Sambuc     B->appendTemporaryDtor(E, cfg->getBumpVectorContext());
545f4a2713aSLionel Sambuc   }
appendAutomaticObjDtor(CFGBlock * B,VarDecl * VD,Stmt * S)546f4a2713aSLionel Sambuc   void appendAutomaticObjDtor(CFGBlock *B, VarDecl *VD, Stmt *S) {
547f4a2713aSLionel Sambuc     B->appendAutomaticObjDtor(VD, S, cfg->getBumpVectorContext());
548f4a2713aSLionel Sambuc   }
549f4a2713aSLionel Sambuc 
appendDeleteDtor(CFGBlock * B,CXXRecordDecl * RD,CXXDeleteExpr * DE)550f4a2713aSLionel Sambuc   void appendDeleteDtor(CFGBlock *B, CXXRecordDecl *RD, CXXDeleteExpr *DE) {
551f4a2713aSLionel Sambuc     B->appendDeleteDtor(RD, DE, cfg->getBumpVectorContext());
552f4a2713aSLionel Sambuc   }
553f4a2713aSLionel Sambuc 
554f4a2713aSLionel Sambuc   void prependAutomaticObjDtorsWithTerminator(CFGBlock *Blk,
555f4a2713aSLionel Sambuc       LocalScope::const_iterator B, LocalScope::const_iterator E);
556f4a2713aSLionel Sambuc 
addSuccessor(CFGBlock * B,CFGBlock * S,bool IsReachable=true)557*0a6a1f1dSLionel Sambuc   void addSuccessor(CFGBlock *B, CFGBlock *S, bool IsReachable = true) {
558*0a6a1f1dSLionel Sambuc     B->addSuccessor(CFGBlock::AdjacentBlock(S, IsReachable),
559*0a6a1f1dSLionel Sambuc                     cfg->getBumpVectorContext());
560*0a6a1f1dSLionel Sambuc   }
561*0a6a1f1dSLionel Sambuc 
562*0a6a1f1dSLionel Sambuc   /// Add a reachable successor to a block, with the alternate variant that is
563*0a6a1f1dSLionel Sambuc   /// unreachable.
addSuccessor(CFGBlock * B,CFGBlock * ReachableBlock,CFGBlock * AltBlock)564*0a6a1f1dSLionel Sambuc   void addSuccessor(CFGBlock *B, CFGBlock *ReachableBlock, CFGBlock *AltBlock) {
565*0a6a1f1dSLionel Sambuc     B->addSuccessor(CFGBlock::AdjacentBlock(ReachableBlock, AltBlock),
566*0a6a1f1dSLionel Sambuc                     cfg->getBumpVectorContext());
567*0a6a1f1dSLionel Sambuc   }
568*0a6a1f1dSLionel Sambuc 
569*0a6a1f1dSLionel Sambuc   /// \brief Find a relational comparison with an expression evaluating to a
570*0a6a1f1dSLionel Sambuc   /// boolean and a constant other than 0 and 1.
571*0a6a1f1dSLionel Sambuc   /// e.g. if ((x < y) == 10)
checkIncorrectRelationalOperator(const BinaryOperator * B)572*0a6a1f1dSLionel Sambuc   TryResult checkIncorrectRelationalOperator(const BinaryOperator *B) {
573*0a6a1f1dSLionel Sambuc     const Expr *LHSExpr = B->getLHS()->IgnoreParens();
574*0a6a1f1dSLionel Sambuc     const Expr *RHSExpr = B->getRHS()->IgnoreParens();
575*0a6a1f1dSLionel Sambuc 
576*0a6a1f1dSLionel Sambuc     const IntegerLiteral *IntLiteral = dyn_cast<IntegerLiteral>(LHSExpr);
577*0a6a1f1dSLionel Sambuc     const Expr *BoolExpr = RHSExpr;
578*0a6a1f1dSLionel Sambuc     bool IntFirst = true;
579*0a6a1f1dSLionel Sambuc     if (!IntLiteral) {
580*0a6a1f1dSLionel Sambuc       IntLiteral = dyn_cast<IntegerLiteral>(RHSExpr);
581*0a6a1f1dSLionel Sambuc       BoolExpr = LHSExpr;
582*0a6a1f1dSLionel Sambuc       IntFirst = false;
583*0a6a1f1dSLionel Sambuc     }
584*0a6a1f1dSLionel Sambuc 
585*0a6a1f1dSLionel Sambuc     if (!IntLiteral || !BoolExpr->isKnownToHaveBooleanValue())
586*0a6a1f1dSLionel Sambuc       return TryResult();
587*0a6a1f1dSLionel Sambuc 
588*0a6a1f1dSLionel Sambuc     llvm::APInt IntValue = IntLiteral->getValue();
589*0a6a1f1dSLionel Sambuc     if ((IntValue == 1) || (IntValue == 0))
590*0a6a1f1dSLionel Sambuc       return TryResult();
591*0a6a1f1dSLionel Sambuc 
592*0a6a1f1dSLionel Sambuc     bool IntLarger = IntLiteral->getType()->isUnsignedIntegerType() ||
593*0a6a1f1dSLionel Sambuc                      !IntValue.isNegative();
594*0a6a1f1dSLionel Sambuc 
595*0a6a1f1dSLionel Sambuc     BinaryOperatorKind Bok = B->getOpcode();
596*0a6a1f1dSLionel Sambuc     if (Bok == BO_GT || Bok == BO_GE) {
597*0a6a1f1dSLionel Sambuc       // Always true for 10 > bool and bool > -1
598*0a6a1f1dSLionel Sambuc       // Always false for -1 > bool and bool > 10
599*0a6a1f1dSLionel Sambuc       return TryResult(IntFirst == IntLarger);
600*0a6a1f1dSLionel Sambuc     } else {
601*0a6a1f1dSLionel Sambuc       // Always true for -1 < bool and bool < 10
602*0a6a1f1dSLionel Sambuc       // Always false for 10 < bool and bool < -1
603*0a6a1f1dSLionel Sambuc       return TryResult(IntFirst != IntLarger);
604*0a6a1f1dSLionel Sambuc     }
605*0a6a1f1dSLionel Sambuc   }
606*0a6a1f1dSLionel Sambuc 
607*0a6a1f1dSLionel Sambuc   /// Find an incorrect equality comparison. Either with an expression
608*0a6a1f1dSLionel Sambuc   /// evaluating to a boolean and a constant other than 0 and 1.
609*0a6a1f1dSLionel Sambuc   /// e.g. if (!x == 10) or a bitwise and/or operation that always evaluates to
610*0a6a1f1dSLionel Sambuc   /// true/false e.q. (x & 8) == 4.
checkIncorrectEqualityOperator(const BinaryOperator * B)611*0a6a1f1dSLionel Sambuc   TryResult checkIncorrectEqualityOperator(const BinaryOperator *B) {
612*0a6a1f1dSLionel Sambuc     const Expr *LHSExpr = B->getLHS()->IgnoreParens();
613*0a6a1f1dSLionel Sambuc     const Expr *RHSExpr = B->getRHS()->IgnoreParens();
614*0a6a1f1dSLionel Sambuc 
615*0a6a1f1dSLionel Sambuc     const IntegerLiteral *IntLiteral = dyn_cast<IntegerLiteral>(LHSExpr);
616*0a6a1f1dSLionel Sambuc     const Expr *BoolExpr = RHSExpr;
617*0a6a1f1dSLionel Sambuc 
618*0a6a1f1dSLionel Sambuc     if (!IntLiteral) {
619*0a6a1f1dSLionel Sambuc       IntLiteral = dyn_cast<IntegerLiteral>(RHSExpr);
620*0a6a1f1dSLionel Sambuc       BoolExpr = LHSExpr;
621*0a6a1f1dSLionel Sambuc     }
622*0a6a1f1dSLionel Sambuc 
623*0a6a1f1dSLionel Sambuc     if (!IntLiteral)
624*0a6a1f1dSLionel Sambuc       return TryResult();
625*0a6a1f1dSLionel Sambuc 
626*0a6a1f1dSLionel Sambuc     const BinaryOperator *BitOp = dyn_cast<BinaryOperator>(BoolExpr);
627*0a6a1f1dSLionel Sambuc     if (BitOp && (BitOp->getOpcode() == BO_And ||
628*0a6a1f1dSLionel Sambuc                   BitOp->getOpcode() == BO_Or)) {
629*0a6a1f1dSLionel Sambuc       const Expr *LHSExpr2 = BitOp->getLHS()->IgnoreParens();
630*0a6a1f1dSLionel Sambuc       const Expr *RHSExpr2 = BitOp->getRHS()->IgnoreParens();
631*0a6a1f1dSLionel Sambuc 
632*0a6a1f1dSLionel Sambuc       const IntegerLiteral *IntLiteral2 = dyn_cast<IntegerLiteral>(LHSExpr2);
633*0a6a1f1dSLionel Sambuc 
634*0a6a1f1dSLionel Sambuc       if (!IntLiteral2)
635*0a6a1f1dSLionel Sambuc         IntLiteral2 = dyn_cast<IntegerLiteral>(RHSExpr2);
636*0a6a1f1dSLionel Sambuc 
637*0a6a1f1dSLionel Sambuc       if (!IntLiteral2)
638*0a6a1f1dSLionel Sambuc         return TryResult();
639*0a6a1f1dSLionel Sambuc 
640*0a6a1f1dSLionel Sambuc       llvm::APInt L1 = IntLiteral->getValue();
641*0a6a1f1dSLionel Sambuc       llvm::APInt L2 = IntLiteral2->getValue();
642*0a6a1f1dSLionel Sambuc       if ((BitOp->getOpcode() == BO_And && (L2 & L1) != L1) ||
643*0a6a1f1dSLionel Sambuc           (BitOp->getOpcode() == BO_Or  && (L2 | L1) != L1)) {
644*0a6a1f1dSLionel Sambuc         if (BuildOpts.Observer)
645*0a6a1f1dSLionel Sambuc           BuildOpts.Observer->compareBitwiseEquality(B,
646*0a6a1f1dSLionel Sambuc                                                      B->getOpcode() != BO_EQ);
647*0a6a1f1dSLionel Sambuc         TryResult(B->getOpcode() != BO_EQ);
648*0a6a1f1dSLionel Sambuc       }
649*0a6a1f1dSLionel Sambuc     } else if (BoolExpr->isKnownToHaveBooleanValue()) {
650*0a6a1f1dSLionel Sambuc       llvm::APInt IntValue = IntLiteral->getValue();
651*0a6a1f1dSLionel Sambuc       if ((IntValue == 1) || (IntValue == 0)) {
652*0a6a1f1dSLionel Sambuc         return TryResult();
653*0a6a1f1dSLionel Sambuc       }
654*0a6a1f1dSLionel Sambuc       return TryResult(B->getOpcode() != BO_EQ);
655*0a6a1f1dSLionel Sambuc     }
656*0a6a1f1dSLionel Sambuc 
657*0a6a1f1dSLionel Sambuc     return TryResult();
658*0a6a1f1dSLionel Sambuc   }
659*0a6a1f1dSLionel Sambuc 
analyzeLogicOperatorCondition(BinaryOperatorKind Relation,const llvm::APSInt & Value1,const llvm::APSInt & Value2)660*0a6a1f1dSLionel Sambuc   TryResult analyzeLogicOperatorCondition(BinaryOperatorKind Relation,
661*0a6a1f1dSLionel Sambuc                                           const llvm::APSInt &Value1,
662*0a6a1f1dSLionel Sambuc                                           const llvm::APSInt &Value2) {
663*0a6a1f1dSLionel Sambuc     assert(Value1.isSigned() == Value2.isSigned());
664*0a6a1f1dSLionel Sambuc     switch (Relation) {
665*0a6a1f1dSLionel Sambuc       default:
666*0a6a1f1dSLionel Sambuc         return TryResult();
667*0a6a1f1dSLionel Sambuc       case BO_EQ:
668*0a6a1f1dSLionel Sambuc         return TryResult(Value1 == Value2);
669*0a6a1f1dSLionel Sambuc       case BO_NE:
670*0a6a1f1dSLionel Sambuc         return TryResult(Value1 != Value2);
671*0a6a1f1dSLionel Sambuc       case BO_LT:
672*0a6a1f1dSLionel Sambuc         return TryResult(Value1 <  Value2);
673*0a6a1f1dSLionel Sambuc       case BO_LE:
674*0a6a1f1dSLionel Sambuc         return TryResult(Value1 <= Value2);
675*0a6a1f1dSLionel Sambuc       case BO_GT:
676*0a6a1f1dSLionel Sambuc         return TryResult(Value1 >  Value2);
677*0a6a1f1dSLionel Sambuc       case BO_GE:
678*0a6a1f1dSLionel Sambuc         return TryResult(Value1 >= Value2);
679*0a6a1f1dSLionel Sambuc     }
680*0a6a1f1dSLionel Sambuc   }
681*0a6a1f1dSLionel Sambuc 
682*0a6a1f1dSLionel Sambuc   /// \brief Find a pair of comparison expressions with or without parentheses
683*0a6a1f1dSLionel Sambuc   /// with a shared variable and constants and a logical operator between them
684*0a6a1f1dSLionel Sambuc   /// that always evaluates to either true or false.
685*0a6a1f1dSLionel Sambuc   /// e.g. if (x != 3 || x != 4)
checkIncorrectLogicOperator(const BinaryOperator * B)686*0a6a1f1dSLionel Sambuc   TryResult checkIncorrectLogicOperator(const BinaryOperator *B) {
687*0a6a1f1dSLionel Sambuc     assert(B->isLogicalOp());
688*0a6a1f1dSLionel Sambuc     const BinaryOperator *LHS =
689*0a6a1f1dSLionel Sambuc         dyn_cast<BinaryOperator>(B->getLHS()->IgnoreParens());
690*0a6a1f1dSLionel Sambuc     const BinaryOperator *RHS =
691*0a6a1f1dSLionel Sambuc         dyn_cast<BinaryOperator>(B->getRHS()->IgnoreParens());
692*0a6a1f1dSLionel Sambuc     if (!LHS || !RHS)
693*0a6a1f1dSLionel Sambuc       return TryResult();
694*0a6a1f1dSLionel Sambuc 
695*0a6a1f1dSLionel Sambuc     if (!LHS->isComparisonOp() || !RHS->isComparisonOp())
696*0a6a1f1dSLionel Sambuc       return TryResult();
697*0a6a1f1dSLionel Sambuc 
698*0a6a1f1dSLionel Sambuc     BinaryOperatorKind BO1 = LHS->getOpcode();
699*0a6a1f1dSLionel Sambuc     const DeclRefExpr *Decl1 =
700*0a6a1f1dSLionel Sambuc         dyn_cast<DeclRefExpr>(LHS->getLHS()->IgnoreParenImpCasts());
701*0a6a1f1dSLionel Sambuc     const IntegerLiteral *Literal1 =
702*0a6a1f1dSLionel Sambuc         dyn_cast<IntegerLiteral>(LHS->getRHS()->IgnoreParens());
703*0a6a1f1dSLionel Sambuc     if (!Decl1 && !Literal1) {
704*0a6a1f1dSLionel Sambuc       if (BO1 == BO_GT)
705*0a6a1f1dSLionel Sambuc         BO1 = BO_LT;
706*0a6a1f1dSLionel Sambuc       else if (BO1 == BO_GE)
707*0a6a1f1dSLionel Sambuc         BO1 = BO_LE;
708*0a6a1f1dSLionel Sambuc       else if (BO1 == BO_LT)
709*0a6a1f1dSLionel Sambuc         BO1 = BO_GT;
710*0a6a1f1dSLionel Sambuc       else if (BO1 == BO_LE)
711*0a6a1f1dSLionel Sambuc         BO1 = BO_GE;
712*0a6a1f1dSLionel Sambuc       Decl1 = dyn_cast<DeclRefExpr>(LHS->getRHS()->IgnoreParenImpCasts());
713*0a6a1f1dSLionel Sambuc       Literal1 = dyn_cast<IntegerLiteral>(LHS->getLHS()->IgnoreParens());
714*0a6a1f1dSLionel Sambuc     }
715*0a6a1f1dSLionel Sambuc 
716*0a6a1f1dSLionel Sambuc     if (!Decl1 || !Literal1)
717*0a6a1f1dSLionel Sambuc       return TryResult();
718*0a6a1f1dSLionel Sambuc 
719*0a6a1f1dSLionel Sambuc     BinaryOperatorKind BO2 = RHS->getOpcode();
720*0a6a1f1dSLionel Sambuc     const DeclRefExpr *Decl2 =
721*0a6a1f1dSLionel Sambuc         dyn_cast<DeclRefExpr>(RHS->getLHS()->IgnoreParenImpCasts());
722*0a6a1f1dSLionel Sambuc     const IntegerLiteral *Literal2 =
723*0a6a1f1dSLionel Sambuc         dyn_cast<IntegerLiteral>(RHS->getRHS()->IgnoreParens());
724*0a6a1f1dSLionel Sambuc     if (!Decl2 && !Literal2) {
725*0a6a1f1dSLionel Sambuc       if (BO2 == BO_GT)
726*0a6a1f1dSLionel Sambuc         BO2 = BO_LT;
727*0a6a1f1dSLionel Sambuc       else if (BO2 == BO_GE)
728*0a6a1f1dSLionel Sambuc         BO2 = BO_LE;
729*0a6a1f1dSLionel Sambuc       else if (BO2 == BO_LT)
730*0a6a1f1dSLionel Sambuc         BO2 = BO_GT;
731*0a6a1f1dSLionel Sambuc       else if (BO2 == BO_LE)
732*0a6a1f1dSLionel Sambuc         BO2 = BO_GE;
733*0a6a1f1dSLionel Sambuc       Decl2 = dyn_cast<DeclRefExpr>(RHS->getRHS()->IgnoreParenImpCasts());
734*0a6a1f1dSLionel Sambuc       Literal2 = dyn_cast<IntegerLiteral>(RHS->getLHS()->IgnoreParens());
735*0a6a1f1dSLionel Sambuc     }
736*0a6a1f1dSLionel Sambuc 
737*0a6a1f1dSLionel Sambuc     if (!Decl2 || !Literal2)
738*0a6a1f1dSLionel Sambuc       return TryResult();
739*0a6a1f1dSLionel Sambuc 
740*0a6a1f1dSLionel Sambuc     // Check that it is the same variable on both sides.
741*0a6a1f1dSLionel Sambuc     if (Decl1->getDecl() != Decl2->getDecl())
742*0a6a1f1dSLionel Sambuc       return TryResult();
743*0a6a1f1dSLionel Sambuc 
744*0a6a1f1dSLionel Sambuc     llvm::APSInt L1, L2;
745*0a6a1f1dSLionel Sambuc 
746*0a6a1f1dSLionel Sambuc     if (!Literal1->EvaluateAsInt(L1, *Context) ||
747*0a6a1f1dSLionel Sambuc         !Literal2->EvaluateAsInt(L2, *Context))
748*0a6a1f1dSLionel Sambuc       return TryResult();
749*0a6a1f1dSLionel Sambuc 
750*0a6a1f1dSLionel Sambuc     // Can't compare signed with unsigned or with different bit width.
751*0a6a1f1dSLionel Sambuc     if (L1.isSigned() != L2.isSigned() || L1.getBitWidth() != L2.getBitWidth())
752*0a6a1f1dSLionel Sambuc       return TryResult();
753*0a6a1f1dSLionel Sambuc 
754*0a6a1f1dSLionel Sambuc     // Values that will be used to determine if result of logical
755*0a6a1f1dSLionel Sambuc     // operator is always true/false
756*0a6a1f1dSLionel Sambuc     const llvm::APSInt Values[] = {
757*0a6a1f1dSLionel Sambuc       // Value less than both Value1 and Value2
758*0a6a1f1dSLionel Sambuc       llvm::APSInt::getMinValue(L1.getBitWidth(), L1.isUnsigned()),
759*0a6a1f1dSLionel Sambuc       // L1
760*0a6a1f1dSLionel Sambuc       L1,
761*0a6a1f1dSLionel Sambuc       // Value between Value1 and Value2
762*0a6a1f1dSLionel Sambuc       ((L1 < L2) ? L1 : L2) + llvm::APSInt(llvm::APInt(L1.getBitWidth(), 1),
763*0a6a1f1dSLionel Sambuc                               L1.isUnsigned()),
764*0a6a1f1dSLionel Sambuc       // L2
765*0a6a1f1dSLionel Sambuc       L2,
766*0a6a1f1dSLionel Sambuc       // Value greater than both Value1 and Value2
767*0a6a1f1dSLionel Sambuc       llvm::APSInt::getMaxValue(L1.getBitWidth(), L1.isUnsigned()),
768*0a6a1f1dSLionel Sambuc     };
769*0a6a1f1dSLionel Sambuc 
770*0a6a1f1dSLionel Sambuc     // Check whether expression is always true/false by evaluating the following
771*0a6a1f1dSLionel Sambuc     // * variable x is less than the smallest literal.
772*0a6a1f1dSLionel Sambuc     // * variable x is equal to the smallest literal.
773*0a6a1f1dSLionel Sambuc     // * Variable x is between smallest and largest literal.
774*0a6a1f1dSLionel Sambuc     // * Variable x is equal to the largest literal.
775*0a6a1f1dSLionel Sambuc     // * Variable x is greater than largest literal.
776*0a6a1f1dSLionel Sambuc     bool AlwaysTrue = true, AlwaysFalse = true;
777*0a6a1f1dSLionel Sambuc     for (unsigned int ValueIndex = 0;
778*0a6a1f1dSLionel Sambuc          ValueIndex < sizeof(Values) / sizeof(Values[0]);
779*0a6a1f1dSLionel Sambuc          ++ValueIndex) {
780*0a6a1f1dSLionel Sambuc       llvm::APSInt Value = Values[ValueIndex];
781*0a6a1f1dSLionel Sambuc       TryResult Res1, Res2;
782*0a6a1f1dSLionel Sambuc       Res1 = analyzeLogicOperatorCondition(BO1, Value, L1);
783*0a6a1f1dSLionel Sambuc       Res2 = analyzeLogicOperatorCondition(BO2, Value, L2);
784*0a6a1f1dSLionel Sambuc 
785*0a6a1f1dSLionel Sambuc       if (!Res1.isKnown() || !Res2.isKnown())
786*0a6a1f1dSLionel Sambuc         return TryResult();
787*0a6a1f1dSLionel Sambuc 
788*0a6a1f1dSLionel Sambuc       if (B->getOpcode() == BO_LAnd) {
789*0a6a1f1dSLionel Sambuc         AlwaysTrue &= (Res1.isTrue() && Res2.isTrue());
790*0a6a1f1dSLionel Sambuc         AlwaysFalse &= !(Res1.isTrue() && Res2.isTrue());
791*0a6a1f1dSLionel Sambuc       } else {
792*0a6a1f1dSLionel Sambuc         AlwaysTrue &= (Res1.isTrue() || Res2.isTrue());
793*0a6a1f1dSLionel Sambuc         AlwaysFalse &= !(Res1.isTrue() || Res2.isTrue());
794*0a6a1f1dSLionel Sambuc       }
795*0a6a1f1dSLionel Sambuc     }
796*0a6a1f1dSLionel Sambuc 
797*0a6a1f1dSLionel Sambuc     if (AlwaysTrue || AlwaysFalse) {
798*0a6a1f1dSLionel Sambuc       if (BuildOpts.Observer)
799*0a6a1f1dSLionel Sambuc         BuildOpts.Observer->compareAlwaysTrue(B, AlwaysTrue);
800*0a6a1f1dSLionel Sambuc       return TryResult(AlwaysTrue);
801*0a6a1f1dSLionel Sambuc     }
802*0a6a1f1dSLionel Sambuc     return TryResult();
803f4a2713aSLionel Sambuc   }
804f4a2713aSLionel Sambuc 
805f4a2713aSLionel Sambuc   /// Try and evaluate an expression to an integer constant.
tryEvaluate(Expr * S,Expr::EvalResult & outResult)806f4a2713aSLionel Sambuc   bool tryEvaluate(Expr *S, Expr::EvalResult &outResult) {
807f4a2713aSLionel Sambuc     if (!BuildOpts.PruneTriviallyFalseEdges)
808f4a2713aSLionel Sambuc       return false;
809f4a2713aSLionel Sambuc     return !S->isTypeDependent() &&
810f4a2713aSLionel Sambuc            !S->isValueDependent() &&
811f4a2713aSLionel Sambuc            S->EvaluateAsRValue(outResult, *Context);
812f4a2713aSLionel Sambuc   }
813f4a2713aSLionel Sambuc 
814f4a2713aSLionel Sambuc   /// tryEvaluateBool - Try and evaluate the Stmt and return 0 or 1
815f4a2713aSLionel Sambuc   /// if we can evaluate to a known value, otherwise return -1.
tryEvaluateBool(Expr * S)816f4a2713aSLionel Sambuc   TryResult tryEvaluateBool(Expr *S) {
817f4a2713aSLionel Sambuc     if (!BuildOpts.PruneTriviallyFalseEdges ||
818f4a2713aSLionel Sambuc         S->isTypeDependent() || S->isValueDependent())
819f4a2713aSLionel Sambuc       return TryResult();
820f4a2713aSLionel Sambuc 
821f4a2713aSLionel Sambuc     if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(S)) {
822f4a2713aSLionel Sambuc       if (Bop->isLogicalOp()) {
823f4a2713aSLionel Sambuc         // Check the cache first.
824f4a2713aSLionel Sambuc         CachedBoolEvalsTy::iterator I = CachedBoolEvals.find(S);
825f4a2713aSLionel Sambuc         if (I != CachedBoolEvals.end())
826f4a2713aSLionel Sambuc           return I->second; // already in map;
827f4a2713aSLionel Sambuc 
828f4a2713aSLionel Sambuc         // Retrieve result at first, or the map might be updated.
829f4a2713aSLionel Sambuc         TryResult Result = evaluateAsBooleanConditionNoCache(S);
830f4a2713aSLionel Sambuc         CachedBoolEvals[S] = Result; // update or insert
831f4a2713aSLionel Sambuc         return Result;
832f4a2713aSLionel Sambuc       }
833f4a2713aSLionel Sambuc       else {
834f4a2713aSLionel Sambuc         switch (Bop->getOpcode()) {
835f4a2713aSLionel Sambuc           default: break;
836f4a2713aSLionel Sambuc           // For 'x & 0' and 'x * 0', we can determine that
837f4a2713aSLionel Sambuc           // the value is always false.
838f4a2713aSLionel Sambuc           case BO_Mul:
839f4a2713aSLionel Sambuc           case BO_And: {
840f4a2713aSLionel Sambuc             // If either operand is zero, we know the value
841f4a2713aSLionel Sambuc             // must be false.
842f4a2713aSLionel Sambuc             llvm::APSInt IntVal;
843f4a2713aSLionel Sambuc             if (Bop->getLHS()->EvaluateAsInt(IntVal, *Context)) {
844f4a2713aSLionel Sambuc               if (IntVal.getBoolValue() == false) {
845f4a2713aSLionel Sambuc                 return TryResult(false);
846f4a2713aSLionel Sambuc               }
847f4a2713aSLionel Sambuc             }
848f4a2713aSLionel Sambuc             if (Bop->getRHS()->EvaluateAsInt(IntVal, *Context)) {
849f4a2713aSLionel Sambuc               if (IntVal.getBoolValue() == false) {
850f4a2713aSLionel Sambuc                 return TryResult(false);
851f4a2713aSLionel Sambuc               }
852f4a2713aSLionel Sambuc             }
853f4a2713aSLionel Sambuc           }
854f4a2713aSLionel Sambuc           break;
855f4a2713aSLionel Sambuc         }
856f4a2713aSLionel Sambuc       }
857f4a2713aSLionel Sambuc     }
858f4a2713aSLionel Sambuc 
859f4a2713aSLionel Sambuc     return evaluateAsBooleanConditionNoCache(S);
860f4a2713aSLionel Sambuc   }
861f4a2713aSLionel Sambuc 
862f4a2713aSLionel Sambuc   /// \brief Evaluate as boolean \param E without using the cache.
evaluateAsBooleanConditionNoCache(Expr * E)863f4a2713aSLionel Sambuc   TryResult evaluateAsBooleanConditionNoCache(Expr *E) {
864f4a2713aSLionel Sambuc     if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(E)) {
865f4a2713aSLionel Sambuc       if (Bop->isLogicalOp()) {
866f4a2713aSLionel Sambuc         TryResult LHS = tryEvaluateBool(Bop->getLHS());
867f4a2713aSLionel Sambuc         if (LHS.isKnown()) {
868f4a2713aSLionel Sambuc           // We were able to evaluate the LHS, see if we can get away with not
869f4a2713aSLionel Sambuc           // evaluating the RHS: 0 && X -> 0, 1 || X -> 1
870f4a2713aSLionel Sambuc           if (LHS.isTrue() == (Bop->getOpcode() == BO_LOr))
871f4a2713aSLionel Sambuc             return LHS.isTrue();
872f4a2713aSLionel Sambuc 
873f4a2713aSLionel Sambuc           TryResult RHS = tryEvaluateBool(Bop->getRHS());
874f4a2713aSLionel Sambuc           if (RHS.isKnown()) {
875f4a2713aSLionel Sambuc             if (Bop->getOpcode() == BO_LOr)
876f4a2713aSLionel Sambuc               return LHS.isTrue() || RHS.isTrue();
877f4a2713aSLionel Sambuc             else
878f4a2713aSLionel Sambuc               return LHS.isTrue() && RHS.isTrue();
879f4a2713aSLionel Sambuc           }
880f4a2713aSLionel Sambuc         } else {
881f4a2713aSLionel Sambuc           TryResult RHS = tryEvaluateBool(Bop->getRHS());
882f4a2713aSLionel Sambuc           if (RHS.isKnown()) {
883f4a2713aSLionel Sambuc             // We can't evaluate the LHS; however, sometimes the result
884f4a2713aSLionel Sambuc             // is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
885f4a2713aSLionel Sambuc             if (RHS.isTrue() == (Bop->getOpcode() == BO_LOr))
886f4a2713aSLionel Sambuc               return RHS.isTrue();
887*0a6a1f1dSLionel Sambuc           } else {
888*0a6a1f1dSLionel Sambuc             TryResult BopRes = checkIncorrectLogicOperator(Bop);
889*0a6a1f1dSLionel Sambuc             if (BopRes.isKnown())
890*0a6a1f1dSLionel Sambuc               return BopRes.isTrue();
891f4a2713aSLionel Sambuc           }
892f4a2713aSLionel Sambuc         }
893f4a2713aSLionel Sambuc 
894f4a2713aSLionel Sambuc         return TryResult();
895*0a6a1f1dSLionel Sambuc       } else if (Bop->isEqualityOp()) {
896*0a6a1f1dSLionel Sambuc           TryResult BopRes = checkIncorrectEqualityOperator(Bop);
897*0a6a1f1dSLionel Sambuc           if (BopRes.isKnown())
898*0a6a1f1dSLionel Sambuc             return BopRes.isTrue();
899*0a6a1f1dSLionel Sambuc       } else if (Bop->isRelationalOp()) {
900*0a6a1f1dSLionel Sambuc         TryResult BopRes = checkIncorrectRelationalOperator(Bop);
901*0a6a1f1dSLionel Sambuc         if (BopRes.isKnown())
902*0a6a1f1dSLionel Sambuc           return BopRes.isTrue();
903f4a2713aSLionel Sambuc       }
904f4a2713aSLionel Sambuc     }
905f4a2713aSLionel Sambuc 
906f4a2713aSLionel Sambuc     bool Result;
907f4a2713aSLionel Sambuc     if (E->EvaluateAsBooleanCondition(Result, *Context))
908f4a2713aSLionel Sambuc       return Result;
909f4a2713aSLionel Sambuc 
910f4a2713aSLionel Sambuc     return TryResult();
911f4a2713aSLionel Sambuc   }
912f4a2713aSLionel Sambuc 
913f4a2713aSLionel Sambuc };
914f4a2713aSLionel Sambuc 
alwaysAdd(CFGBuilder & builder,const Stmt * stmt) const915f4a2713aSLionel Sambuc inline bool AddStmtChoice::alwaysAdd(CFGBuilder &builder,
916f4a2713aSLionel Sambuc                                      const Stmt *stmt) const {
917f4a2713aSLionel Sambuc   return builder.alwaysAdd(stmt) || kind == AlwaysAdd;
918f4a2713aSLionel Sambuc }
919f4a2713aSLionel Sambuc 
alwaysAdd(const Stmt * stmt)920f4a2713aSLionel Sambuc bool CFGBuilder::alwaysAdd(const Stmt *stmt) {
921f4a2713aSLionel Sambuc   bool shouldAdd = BuildOpts.alwaysAdd(stmt);
922f4a2713aSLionel Sambuc 
923f4a2713aSLionel Sambuc   if (!BuildOpts.forcedBlkExprs)
924f4a2713aSLionel Sambuc     return shouldAdd;
925f4a2713aSLionel Sambuc 
926f4a2713aSLionel Sambuc   if (lastLookup == stmt) {
927f4a2713aSLionel Sambuc     if (cachedEntry) {
928f4a2713aSLionel Sambuc       assert(cachedEntry->first == stmt);
929f4a2713aSLionel Sambuc       return true;
930f4a2713aSLionel Sambuc     }
931f4a2713aSLionel Sambuc     return shouldAdd;
932f4a2713aSLionel Sambuc   }
933f4a2713aSLionel Sambuc 
934f4a2713aSLionel Sambuc   lastLookup = stmt;
935f4a2713aSLionel Sambuc 
936f4a2713aSLionel Sambuc   // Perform the lookup!
937f4a2713aSLionel Sambuc   CFG::BuildOptions::ForcedBlkExprs *fb = *BuildOpts.forcedBlkExprs;
938f4a2713aSLionel Sambuc 
939f4a2713aSLionel Sambuc   if (!fb) {
940f4a2713aSLionel Sambuc     // No need to update 'cachedEntry', since it will always be null.
941*0a6a1f1dSLionel Sambuc     assert(!cachedEntry);
942f4a2713aSLionel Sambuc     return shouldAdd;
943f4a2713aSLionel Sambuc   }
944f4a2713aSLionel Sambuc 
945f4a2713aSLionel Sambuc   CFG::BuildOptions::ForcedBlkExprs::iterator itr = fb->find(stmt);
946f4a2713aSLionel Sambuc   if (itr == fb->end()) {
947*0a6a1f1dSLionel Sambuc     cachedEntry = nullptr;
948f4a2713aSLionel Sambuc     return shouldAdd;
949f4a2713aSLionel Sambuc   }
950f4a2713aSLionel Sambuc 
951f4a2713aSLionel Sambuc   cachedEntry = &*itr;
952f4a2713aSLionel Sambuc   return true;
953f4a2713aSLionel Sambuc }
954f4a2713aSLionel Sambuc 
955f4a2713aSLionel Sambuc // FIXME: Add support for dependent-sized array types in C++?
956f4a2713aSLionel Sambuc // Does it even make sense to build a CFG for an uninstantiated template?
FindVA(const Type * t)957f4a2713aSLionel Sambuc static const VariableArrayType *FindVA(const Type *t) {
958f4a2713aSLionel Sambuc   while (const ArrayType *vt = dyn_cast<ArrayType>(t)) {
959f4a2713aSLionel Sambuc     if (const VariableArrayType *vat = dyn_cast<VariableArrayType>(vt))
960f4a2713aSLionel Sambuc       if (vat->getSizeExpr())
961f4a2713aSLionel Sambuc         return vat;
962f4a2713aSLionel Sambuc 
963f4a2713aSLionel Sambuc     t = vt->getElementType().getTypePtr();
964f4a2713aSLionel Sambuc   }
965f4a2713aSLionel Sambuc 
966*0a6a1f1dSLionel Sambuc   return nullptr;
967f4a2713aSLionel Sambuc }
968f4a2713aSLionel Sambuc 
969f4a2713aSLionel Sambuc /// BuildCFG - Constructs a CFG from an AST (a Stmt*).  The AST can represent an
970f4a2713aSLionel Sambuc ///  arbitrary statement.  Examples include a single expression or a function
971f4a2713aSLionel Sambuc ///  body (compound statement).  The ownership of the returned CFG is
972f4a2713aSLionel Sambuc ///  transferred to the caller.  If CFG construction fails, this method returns
973f4a2713aSLionel Sambuc ///  NULL.
buildCFG(const Decl * D,Stmt * Statement)974*0a6a1f1dSLionel Sambuc std::unique_ptr<CFG> CFGBuilder::buildCFG(const Decl *D, Stmt *Statement) {
975f4a2713aSLionel Sambuc   assert(cfg.get());
976f4a2713aSLionel Sambuc   if (!Statement)
977*0a6a1f1dSLionel Sambuc     return nullptr;
978f4a2713aSLionel Sambuc 
979f4a2713aSLionel Sambuc   // Create an empty block that will serve as the exit block for the CFG.  Since
980f4a2713aSLionel Sambuc   // this is the first block added to the CFG, it will be implicitly registered
981f4a2713aSLionel Sambuc   // as the exit block.
982f4a2713aSLionel Sambuc   Succ = createBlock();
983f4a2713aSLionel Sambuc   assert(Succ == &cfg->getExit());
984*0a6a1f1dSLionel Sambuc   Block = nullptr;  // the EXIT block is empty.  Create all other blocks lazily.
985f4a2713aSLionel Sambuc 
986f4a2713aSLionel Sambuc   if (BuildOpts.AddImplicitDtors)
987f4a2713aSLionel Sambuc     if (const CXXDestructorDecl *DD = dyn_cast_or_null<CXXDestructorDecl>(D))
988f4a2713aSLionel Sambuc       addImplicitDtorsForDestructor(DD);
989f4a2713aSLionel Sambuc 
990f4a2713aSLionel Sambuc   // Visit the statements and create the CFG.
991f4a2713aSLionel Sambuc   CFGBlock *B = addStmt(Statement);
992f4a2713aSLionel Sambuc 
993f4a2713aSLionel Sambuc   if (badCFG)
994*0a6a1f1dSLionel Sambuc     return nullptr;
995f4a2713aSLionel Sambuc 
996f4a2713aSLionel Sambuc   // For C++ constructor add initializers to CFG.
997f4a2713aSLionel Sambuc   if (const CXXConstructorDecl *CD = dyn_cast_or_null<CXXConstructorDecl>(D)) {
998f4a2713aSLionel Sambuc     for (CXXConstructorDecl::init_const_reverse_iterator I = CD->init_rbegin(),
999f4a2713aSLionel Sambuc         E = CD->init_rend(); I != E; ++I) {
1000f4a2713aSLionel Sambuc       B = addInitializer(*I);
1001f4a2713aSLionel Sambuc       if (badCFG)
1002*0a6a1f1dSLionel Sambuc         return nullptr;
1003f4a2713aSLionel Sambuc     }
1004f4a2713aSLionel Sambuc   }
1005f4a2713aSLionel Sambuc 
1006f4a2713aSLionel Sambuc   if (B)
1007f4a2713aSLionel Sambuc     Succ = B;
1008f4a2713aSLionel Sambuc 
1009f4a2713aSLionel Sambuc   // Backpatch the gotos whose label -> block mappings we didn't know when we
1010f4a2713aSLionel Sambuc   // encountered them.
1011f4a2713aSLionel Sambuc   for (BackpatchBlocksTy::iterator I = BackpatchBlocks.begin(),
1012f4a2713aSLionel Sambuc                                    E = BackpatchBlocks.end(); I != E; ++I ) {
1013f4a2713aSLionel Sambuc 
1014f4a2713aSLionel Sambuc     CFGBlock *B = I->block;
1015f4a2713aSLionel Sambuc     const GotoStmt *G = cast<GotoStmt>(B->getTerminator());
1016f4a2713aSLionel Sambuc     LabelMapTy::iterator LI = LabelMap.find(G->getLabel());
1017f4a2713aSLionel Sambuc 
1018f4a2713aSLionel Sambuc     // If there is no target for the goto, then we are looking at an
1019f4a2713aSLionel Sambuc     // incomplete AST.  Handle this by not registering a successor.
1020f4a2713aSLionel Sambuc     if (LI == LabelMap.end()) continue;
1021f4a2713aSLionel Sambuc 
1022f4a2713aSLionel Sambuc     JumpTarget JT = LI->second;
1023f4a2713aSLionel Sambuc     prependAutomaticObjDtorsWithTerminator(B, I->scopePosition,
1024f4a2713aSLionel Sambuc                                            JT.scopePosition);
1025f4a2713aSLionel Sambuc     addSuccessor(B, JT.block);
1026f4a2713aSLionel Sambuc   }
1027f4a2713aSLionel Sambuc 
1028f4a2713aSLionel Sambuc   // Add successors to the Indirect Goto Dispatch block (if we have one).
1029f4a2713aSLionel Sambuc   if (CFGBlock *B = cfg->getIndirectGotoBlock())
1030f4a2713aSLionel Sambuc     for (LabelSetTy::iterator I = AddressTakenLabels.begin(),
1031f4a2713aSLionel Sambuc                               E = AddressTakenLabels.end(); I != E; ++I ) {
1032f4a2713aSLionel Sambuc 
1033f4a2713aSLionel Sambuc       // Lookup the target block.
1034f4a2713aSLionel Sambuc       LabelMapTy::iterator LI = LabelMap.find(*I);
1035f4a2713aSLionel Sambuc 
1036f4a2713aSLionel Sambuc       // If there is no target block that contains label, then we are looking
1037f4a2713aSLionel Sambuc       // at an incomplete AST.  Handle this by not registering a successor.
1038f4a2713aSLionel Sambuc       if (LI == LabelMap.end()) continue;
1039f4a2713aSLionel Sambuc 
1040f4a2713aSLionel Sambuc       addSuccessor(B, LI->second.block);
1041f4a2713aSLionel Sambuc     }
1042f4a2713aSLionel Sambuc 
1043f4a2713aSLionel Sambuc   // Create an empty entry block that has no predecessors.
1044f4a2713aSLionel Sambuc   cfg->setEntry(createBlock());
1045f4a2713aSLionel Sambuc 
1046*0a6a1f1dSLionel Sambuc   return std::move(cfg);
1047f4a2713aSLionel Sambuc }
1048f4a2713aSLionel Sambuc 
1049f4a2713aSLionel Sambuc /// createBlock - Used to lazily create blocks that are connected
1050f4a2713aSLionel Sambuc ///  to the current (global) succcessor.
createBlock(bool add_successor)1051f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::createBlock(bool add_successor) {
1052f4a2713aSLionel Sambuc   CFGBlock *B = cfg->createBlock();
1053f4a2713aSLionel Sambuc   if (add_successor && Succ)
1054f4a2713aSLionel Sambuc     addSuccessor(B, Succ);
1055f4a2713aSLionel Sambuc   return B;
1056f4a2713aSLionel Sambuc }
1057f4a2713aSLionel Sambuc 
1058f4a2713aSLionel Sambuc /// createNoReturnBlock - Used to create a block is a 'noreturn' point in the
1059f4a2713aSLionel Sambuc /// CFG. It is *not* connected to the current (global) successor, and instead
1060f4a2713aSLionel Sambuc /// directly tied to the exit block in order to be reachable.
createNoReturnBlock()1061f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::createNoReturnBlock() {
1062f4a2713aSLionel Sambuc   CFGBlock *B = createBlock(false);
1063f4a2713aSLionel Sambuc   B->setHasNoReturnElement();
1064*0a6a1f1dSLionel Sambuc   addSuccessor(B, &cfg->getExit(), Succ);
1065f4a2713aSLionel Sambuc   return B;
1066f4a2713aSLionel Sambuc }
1067f4a2713aSLionel Sambuc 
1068f4a2713aSLionel Sambuc /// addInitializer - Add C++ base or member initializer element to CFG.
addInitializer(CXXCtorInitializer * I)1069f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::addInitializer(CXXCtorInitializer *I) {
1070f4a2713aSLionel Sambuc   if (!BuildOpts.AddInitializers)
1071f4a2713aSLionel Sambuc     return Block;
1072f4a2713aSLionel Sambuc 
1073f4a2713aSLionel Sambuc   bool HasTemporaries = false;
1074f4a2713aSLionel Sambuc 
1075f4a2713aSLionel Sambuc   // Destructors of temporaries in initialization expression should be called
1076f4a2713aSLionel Sambuc   // after initialization finishes.
1077f4a2713aSLionel Sambuc   Expr *Init = I->getInit();
1078f4a2713aSLionel Sambuc   if (Init) {
1079f4a2713aSLionel Sambuc     HasTemporaries = isa<ExprWithCleanups>(Init);
1080f4a2713aSLionel Sambuc 
1081f4a2713aSLionel Sambuc     if (BuildOpts.AddTemporaryDtors && HasTemporaries) {
1082f4a2713aSLionel Sambuc       // Generate destructors for temporaries in initialization expression.
1083*0a6a1f1dSLionel Sambuc       TempDtorContext Context;
1084f4a2713aSLionel Sambuc       VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
1085*0a6a1f1dSLionel Sambuc                              /*BindToTemporary=*/false, Context);
1086f4a2713aSLionel Sambuc     }
1087f4a2713aSLionel Sambuc   }
1088f4a2713aSLionel Sambuc 
1089f4a2713aSLionel Sambuc   autoCreateBlock();
1090f4a2713aSLionel Sambuc   appendInitializer(Block, I);
1091f4a2713aSLionel Sambuc 
1092f4a2713aSLionel Sambuc   if (Init) {
1093f4a2713aSLionel Sambuc     if (HasTemporaries) {
1094f4a2713aSLionel Sambuc       // For expression with temporaries go directly to subexpression to omit
1095f4a2713aSLionel Sambuc       // generating destructors for the second time.
1096f4a2713aSLionel Sambuc       return Visit(cast<ExprWithCleanups>(Init)->getSubExpr());
1097f4a2713aSLionel Sambuc     }
1098f4a2713aSLionel Sambuc     return Visit(Init);
1099f4a2713aSLionel Sambuc   }
1100f4a2713aSLionel Sambuc 
1101f4a2713aSLionel Sambuc   return Block;
1102f4a2713aSLionel Sambuc }
1103f4a2713aSLionel Sambuc 
1104f4a2713aSLionel Sambuc /// \brief Retrieve the type of the temporary object whose lifetime was
1105f4a2713aSLionel Sambuc /// extended by a local reference with the given initializer.
getReferenceInitTemporaryType(ASTContext & Context,const Expr * Init)1106f4a2713aSLionel Sambuc static QualType getReferenceInitTemporaryType(ASTContext &Context,
1107f4a2713aSLionel Sambuc                                               const Expr *Init) {
1108f4a2713aSLionel Sambuc   while (true) {
1109f4a2713aSLionel Sambuc     // Skip parentheses.
1110f4a2713aSLionel Sambuc     Init = Init->IgnoreParens();
1111f4a2713aSLionel Sambuc 
1112f4a2713aSLionel Sambuc     // Skip through cleanups.
1113f4a2713aSLionel Sambuc     if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Init)) {
1114f4a2713aSLionel Sambuc       Init = EWC->getSubExpr();
1115f4a2713aSLionel Sambuc       continue;
1116f4a2713aSLionel Sambuc     }
1117f4a2713aSLionel Sambuc 
1118f4a2713aSLionel Sambuc     // Skip through the temporary-materialization expression.
1119f4a2713aSLionel Sambuc     if (const MaterializeTemporaryExpr *MTE
1120f4a2713aSLionel Sambuc           = dyn_cast<MaterializeTemporaryExpr>(Init)) {
1121f4a2713aSLionel Sambuc       Init = MTE->GetTemporaryExpr();
1122f4a2713aSLionel Sambuc       continue;
1123f4a2713aSLionel Sambuc     }
1124f4a2713aSLionel Sambuc 
1125f4a2713aSLionel Sambuc     // Skip derived-to-base and no-op casts.
1126f4a2713aSLionel Sambuc     if (const CastExpr *CE = dyn_cast<CastExpr>(Init)) {
1127f4a2713aSLionel Sambuc       if ((CE->getCastKind() == CK_DerivedToBase ||
1128f4a2713aSLionel Sambuc            CE->getCastKind() == CK_UncheckedDerivedToBase ||
1129f4a2713aSLionel Sambuc            CE->getCastKind() == CK_NoOp) &&
1130f4a2713aSLionel Sambuc           Init->getType()->isRecordType()) {
1131f4a2713aSLionel Sambuc         Init = CE->getSubExpr();
1132f4a2713aSLionel Sambuc         continue;
1133f4a2713aSLionel Sambuc       }
1134f4a2713aSLionel Sambuc     }
1135f4a2713aSLionel Sambuc 
1136f4a2713aSLionel Sambuc     // Skip member accesses into rvalues.
1137f4a2713aSLionel Sambuc     if (const MemberExpr *ME = dyn_cast<MemberExpr>(Init)) {
1138f4a2713aSLionel Sambuc       if (!ME->isArrow() && ME->getBase()->isRValue()) {
1139f4a2713aSLionel Sambuc         Init = ME->getBase();
1140f4a2713aSLionel Sambuc         continue;
1141f4a2713aSLionel Sambuc       }
1142f4a2713aSLionel Sambuc     }
1143f4a2713aSLionel Sambuc 
1144f4a2713aSLionel Sambuc     break;
1145f4a2713aSLionel Sambuc   }
1146f4a2713aSLionel Sambuc 
1147f4a2713aSLionel Sambuc   return Init->getType();
1148f4a2713aSLionel Sambuc }
1149f4a2713aSLionel Sambuc 
1150f4a2713aSLionel Sambuc /// addAutomaticObjDtors - Add to current block automatic objects destructors
1151f4a2713aSLionel Sambuc /// for objects in range of local scope positions. Use S as trigger statement
1152f4a2713aSLionel Sambuc /// for destructors.
addAutomaticObjDtors(LocalScope::const_iterator B,LocalScope::const_iterator E,Stmt * S)1153f4a2713aSLionel Sambuc void CFGBuilder::addAutomaticObjDtors(LocalScope::const_iterator B,
1154f4a2713aSLionel Sambuc                                       LocalScope::const_iterator E, Stmt *S) {
1155f4a2713aSLionel Sambuc   if (!BuildOpts.AddImplicitDtors)
1156f4a2713aSLionel Sambuc     return;
1157f4a2713aSLionel Sambuc 
1158f4a2713aSLionel Sambuc   if (B == E)
1159f4a2713aSLionel Sambuc     return;
1160f4a2713aSLionel Sambuc 
1161f4a2713aSLionel Sambuc   // We need to append the destructors in reverse order, but any one of them
1162f4a2713aSLionel Sambuc   // may be a no-return destructor which changes the CFG. As a result, buffer
1163f4a2713aSLionel Sambuc   // this sequence up and replay them in reverse order when appending onto the
1164f4a2713aSLionel Sambuc   // CFGBlock(s).
1165f4a2713aSLionel Sambuc   SmallVector<VarDecl*, 10> Decls;
1166f4a2713aSLionel Sambuc   Decls.reserve(B.distance(E));
1167f4a2713aSLionel Sambuc   for (LocalScope::const_iterator I = B; I != E; ++I)
1168f4a2713aSLionel Sambuc     Decls.push_back(*I);
1169f4a2713aSLionel Sambuc 
1170f4a2713aSLionel Sambuc   for (SmallVectorImpl<VarDecl*>::reverse_iterator I = Decls.rbegin(),
1171f4a2713aSLionel Sambuc                                                    E = Decls.rend();
1172f4a2713aSLionel Sambuc        I != E; ++I) {
1173f4a2713aSLionel Sambuc     // If this destructor is marked as a no-return destructor, we need to
1174f4a2713aSLionel Sambuc     // create a new block for the destructor which does not have as a successor
1175f4a2713aSLionel Sambuc     // anything built thus far: control won't flow out of this block.
1176f4a2713aSLionel Sambuc     QualType Ty = (*I)->getType();
1177f4a2713aSLionel Sambuc     if (Ty->isReferenceType()) {
1178f4a2713aSLionel Sambuc       Ty = getReferenceInitTemporaryType(*Context, (*I)->getInit());
1179f4a2713aSLionel Sambuc     }
1180f4a2713aSLionel Sambuc     Ty = Context->getBaseElementType(Ty);
1181f4a2713aSLionel Sambuc 
1182f4a2713aSLionel Sambuc     const CXXDestructorDecl *Dtor = Ty->getAsCXXRecordDecl()->getDestructor();
1183f4a2713aSLionel Sambuc     if (Dtor->isNoReturn())
1184f4a2713aSLionel Sambuc       Block = createNoReturnBlock();
1185f4a2713aSLionel Sambuc     else
1186f4a2713aSLionel Sambuc       autoCreateBlock();
1187f4a2713aSLionel Sambuc 
1188f4a2713aSLionel Sambuc     appendAutomaticObjDtor(Block, *I, S);
1189f4a2713aSLionel Sambuc   }
1190f4a2713aSLionel Sambuc }
1191f4a2713aSLionel Sambuc 
1192f4a2713aSLionel Sambuc /// addImplicitDtorsForDestructor - Add implicit destructors generated for
1193f4a2713aSLionel Sambuc /// base and member objects in destructor.
addImplicitDtorsForDestructor(const CXXDestructorDecl * DD)1194f4a2713aSLionel Sambuc void CFGBuilder::addImplicitDtorsForDestructor(const CXXDestructorDecl *DD) {
1195f4a2713aSLionel Sambuc   assert (BuildOpts.AddImplicitDtors
1196f4a2713aSLionel Sambuc       && "Can be called only when dtors should be added");
1197f4a2713aSLionel Sambuc   const CXXRecordDecl *RD = DD->getParent();
1198f4a2713aSLionel Sambuc 
1199f4a2713aSLionel Sambuc   // At the end destroy virtual base objects.
1200*0a6a1f1dSLionel Sambuc   for (const auto &VI : RD->vbases()) {
1201*0a6a1f1dSLionel Sambuc     const CXXRecordDecl *CD = VI.getType()->getAsCXXRecordDecl();
1202f4a2713aSLionel Sambuc     if (!CD->hasTrivialDestructor()) {
1203f4a2713aSLionel Sambuc       autoCreateBlock();
1204*0a6a1f1dSLionel Sambuc       appendBaseDtor(Block, &VI);
1205f4a2713aSLionel Sambuc     }
1206f4a2713aSLionel Sambuc   }
1207f4a2713aSLionel Sambuc 
1208f4a2713aSLionel Sambuc   // Before virtual bases destroy direct base objects.
1209*0a6a1f1dSLionel Sambuc   for (const auto &BI : RD->bases()) {
1210*0a6a1f1dSLionel Sambuc     if (!BI.isVirtual()) {
1211*0a6a1f1dSLionel Sambuc       const CXXRecordDecl *CD = BI.getType()->getAsCXXRecordDecl();
1212f4a2713aSLionel Sambuc       if (!CD->hasTrivialDestructor()) {
1213f4a2713aSLionel Sambuc         autoCreateBlock();
1214*0a6a1f1dSLionel Sambuc         appendBaseDtor(Block, &BI);
1215f4a2713aSLionel Sambuc       }
1216f4a2713aSLionel Sambuc     }
1217f4a2713aSLionel Sambuc   }
1218f4a2713aSLionel Sambuc 
1219f4a2713aSLionel Sambuc   // First destroy member objects.
1220*0a6a1f1dSLionel Sambuc   for (auto *FI : RD->fields()) {
1221f4a2713aSLionel Sambuc     // Check for constant size array. Set type to array element type.
1222f4a2713aSLionel Sambuc     QualType QT = FI->getType();
1223f4a2713aSLionel Sambuc     if (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) {
1224f4a2713aSLionel Sambuc       if (AT->getSize() == 0)
1225f4a2713aSLionel Sambuc         continue;
1226f4a2713aSLionel Sambuc       QT = AT->getElementType();
1227f4a2713aSLionel Sambuc     }
1228f4a2713aSLionel Sambuc 
1229f4a2713aSLionel Sambuc     if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl())
1230f4a2713aSLionel Sambuc       if (!CD->hasTrivialDestructor()) {
1231f4a2713aSLionel Sambuc         autoCreateBlock();
1232*0a6a1f1dSLionel Sambuc         appendMemberDtor(Block, FI);
1233f4a2713aSLionel Sambuc       }
1234f4a2713aSLionel Sambuc   }
1235f4a2713aSLionel Sambuc }
1236f4a2713aSLionel Sambuc 
1237f4a2713aSLionel Sambuc /// createOrReuseLocalScope - If Scope is NULL create new LocalScope. Either
1238f4a2713aSLionel Sambuc /// way return valid LocalScope object.
createOrReuseLocalScope(LocalScope * Scope)1239f4a2713aSLionel Sambuc LocalScope* CFGBuilder::createOrReuseLocalScope(LocalScope* Scope) {
1240f4a2713aSLionel Sambuc   if (!Scope) {
1241f4a2713aSLionel Sambuc     llvm::BumpPtrAllocator &alloc = cfg->getAllocator();
1242f4a2713aSLionel Sambuc     Scope = alloc.Allocate<LocalScope>();
1243f4a2713aSLionel Sambuc     BumpVectorContext ctx(alloc);
1244f4a2713aSLionel Sambuc     new (Scope) LocalScope(ctx, ScopePos);
1245f4a2713aSLionel Sambuc   }
1246f4a2713aSLionel Sambuc   return Scope;
1247f4a2713aSLionel Sambuc }
1248f4a2713aSLionel Sambuc 
1249f4a2713aSLionel Sambuc /// addLocalScopeForStmt - Add LocalScope to local scopes tree for statement
1250f4a2713aSLionel Sambuc /// that should create implicit scope (e.g. if/else substatements).
addLocalScopeForStmt(Stmt * S)1251f4a2713aSLionel Sambuc void CFGBuilder::addLocalScopeForStmt(Stmt *S) {
1252f4a2713aSLionel Sambuc   if (!BuildOpts.AddImplicitDtors)
1253f4a2713aSLionel Sambuc     return;
1254f4a2713aSLionel Sambuc 
1255*0a6a1f1dSLionel Sambuc   LocalScope *Scope = nullptr;
1256f4a2713aSLionel Sambuc 
1257f4a2713aSLionel Sambuc   // For compound statement we will be creating explicit scope.
1258f4a2713aSLionel Sambuc   if (CompoundStmt *CS = dyn_cast<CompoundStmt>(S)) {
1259*0a6a1f1dSLionel Sambuc     for (auto *BI : CS->body()) {
1260*0a6a1f1dSLionel Sambuc       Stmt *SI = BI->stripLabelLikeStatements();
1261f4a2713aSLionel Sambuc       if (DeclStmt *DS = dyn_cast<DeclStmt>(SI))
1262f4a2713aSLionel Sambuc         Scope = addLocalScopeForDeclStmt(DS, Scope);
1263f4a2713aSLionel Sambuc     }
1264f4a2713aSLionel Sambuc     return;
1265f4a2713aSLionel Sambuc   }
1266f4a2713aSLionel Sambuc 
1267f4a2713aSLionel Sambuc   // For any other statement scope will be implicit and as such will be
1268f4a2713aSLionel Sambuc   // interesting only for DeclStmt.
1269f4a2713aSLionel Sambuc   if (DeclStmt *DS = dyn_cast<DeclStmt>(S->stripLabelLikeStatements()))
1270f4a2713aSLionel Sambuc     addLocalScopeForDeclStmt(DS);
1271f4a2713aSLionel Sambuc }
1272f4a2713aSLionel Sambuc 
1273f4a2713aSLionel Sambuc /// addLocalScopeForDeclStmt - Add LocalScope for declaration statement. Will
1274f4a2713aSLionel Sambuc /// reuse Scope if not NULL.
addLocalScopeForDeclStmt(DeclStmt * DS,LocalScope * Scope)1275f4a2713aSLionel Sambuc LocalScope* CFGBuilder::addLocalScopeForDeclStmt(DeclStmt *DS,
1276f4a2713aSLionel Sambuc                                                  LocalScope* Scope) {
1277f4a2713aSLionel Sambuc   if (!BuildOpts.AddImplicitDtors)
1278f4a2713aSLionel Sambuc     return Scope;
1279f4a2713aSLionel Sambuc 
1280*0a6a1f1dSLionel Sambuc   for (auto *DI : DS->decls())
1281*0a6a1f1dSLionel Sambuc     if (VarDecl *VD = dyn_cast<VarDecl>(DI))
1282f4a2713aSLionel Sambuc       Scope = addLocalScopeForVarDecl(VD, Scope);
1283f4a2713aSLionel Sambuc   return Scope;
1284f4a2713aSLionel Sambuc }
1285f4a2713aSLionel Sambuc 
1286f4a2713aSLionel Sambuc /// addLocalScopeForVarDecl - Add LocalScope for variable declaration. It will
1287f4a2713aSLionel Sambuc /// create add scope for automatic objects and temporary objects bound to
1288f4a2713aSLionel Sambuc /// const reference. Will reuse Scope if not NULL.
addLocalScopeForVarDecl(VarDecl * VD,LocalScope * Scope)1289f4a2713aSLionel Sambuc LocalScope* CFGBuilder::addLocalScopeForVarDecl(VarDecl *VD,
1290f4a2713aSLionel Sambuc                                                 LocalScope* Scope) {
1291f4a2713aSLionel Sambuc   if (!BuildOpts.AddImplicitDtors)
1292f4a2713aSLionel Sambuc     return Scope;
1293f4a2713aSLionel Sambuc 
1294f4a2713aSLionel Sambuc   // Check if variable is local.
1295f4a2713aSLionel Sambuc   switch (VD->getStorageClass()) {
1296f4a2713aSLionel Sambuc   case SC_None:
1297f4a2713aSLionel Sambuc   case SC_Auto:
1298f4a2713aSLionel Sambuc   case SC_Register:
1299f4a2713aSLionel Sambuc     break;
1300f4a2713aSLionel Sambuc   default: return Scope;
1301f4a2713aSLionel Sambuc   }
1302f4a2713aSLionel Sambuc 
1303f4a2713aSLionel Sambuc   // Check for const references bound to temporary. Set type to pointee.
1304f4a2713aSLionel Sambuc   QualType QT = VD->getType();
1305f4a2713aSLionel Sambuc   if (QT.getTypePtr()->isReferenceType()) {
1306f4a2713aSLionel Sambuc     // Attempt to determine whether this declaration lifetime-extends a
1307f4a2713aSLionel Sambuc     // temporary.
1308f4a2713aSLionel Sambuc     //
1309f4a2713aSLionel Sambuc     // FIXME: This is incorrect. Non-reference declarations can lifetime-extend
1310f4a2713aSLionel Sambuc     // temporaries, and a single declaration can extend multiple temporaries.
1311f4a2713aSLionel Sambuc     // We should look at the storage duration on each nested
1312f4a2713aSLionel Sambuc     // MaterializeTemporaryExpr instead.
1313f4a2713aSLionel Sambuc     const Expr *Init = VD->getInit();
1314f4a2713aSLionel Sambuc     if (!Init)
1315f4a2713aSLionel Sambuc       return Scope;
1316f4a2713aSLionel Sambuc     if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Init))
1317f4a2713aSLionel Sambuc       Init = EWC->getSubExpr();
1318f4a2713aSLionel Sambuc     if (!isa<MaterializeTemporaryExpr>(Init))
1319f4a2713aSLionel Sambuc       return Scope;
1320f4a2713aSLionel Sambuc 
1321f4a2713aSLionel Sambuc     // Lifetime-extending a temporary.
1322f4a2713aSLionel Sambuc     QT = getReferenceInitTemporaryType(*Context, Init);
1323f4a2713aSLionel Sambuc   }
1324f4a2713aSLionel Sambuc 
1325f4a2713aSLionel Sambuc   // Check for constant size array. Set type to array element type.
1326f4a2713aSLionel Sambuc   while (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) {
1327f4a2713aSLionel Sambuc     if (AT->getSize() == 0)
1328f4a2713aSLionel Sambuc       return Scope;
1329f4a2713aSLionel Sambuc     QT = AT->getElementType();
1330f4a2713aSLionel Sambuc   }
1331f4a2713aSLionel Sambuc 
1332f4a2713aSLionel Sambuc   // Check if type is a C++ class with non-trivial destructor.
1333f4a2713aSLionel Sambuc   if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl())
1334f4a2713aSLionel Sambuc     if (!CD->hasTrivialDestructor()) {
1335f4a2713aSLionel Sambuc       // Add the variable to scope
1336f4a2713aSLionel Sambuc       Scope = createOrReuseLocalScope(Scope);
1337f4a2713aSLionel Sambuc       Scope->addVar(VD);
1338f4a2713aSLionel Sambuc       ScopePos = Scope->begin();
1339f4a2713aSLionel Sambuc     }
1340f4a2713aSLionel Sambuc   return Scope;
1341f4a2713aSLionel Sambuc }
1342f4a2713aSLionel Sambuc 
1343f4a2713aSLionel Sambuc /// addLocalScopeAndDtors - For given statement add local scope for it and
1344f4a2713aSLionel Sambuc /// add destructors that will cleanup the scope. Will reuse Scope if not NULL.
addLocalScopeAndDtors(Stmt * S)1345f4a2713aSLionel Sambuc void CFGBuilder::addLocalScopeAndDtors(Stmt *S) {
1346f4a2713aSLionel Sambuc   if (!BuildOpts.AddImplicitDtors)
1347f4a2713aSLionel Sambuc     return;
1348f4a2713aSLionel Sambuc 
1349f4a2713aSLionel Sambuc   LocalScope::const_iterator scopeBeginPos = ScopePos;
1350f4a2713aSLionel Sambuc   addLocalScopeForStmt(S);
1351f4a2713aSLionel Sambuc   addAutomaticObjDtors(ScopePos, scopeBeginPos, S);
1352f4a2713aSLionel Sambuc }
1353f4a2713aSLionel Sambuc 
1354f4a2713aSLionel Sambuc /// prependAutomaticObjDtorsWithTerminator - Prepend destructor CFGElements for
1355f4a2713aSLionel Sambuc /// variables with automatic storage duration to CFGBlock's elements vector.
1356f4a2713aSLionel Sambuc /// Elements will be prepended to physical beginning of the vector which
1357f4a2713aSLionel Sambuc /// happens to be logical end. Use blocks terminator as statement that specifies
1358f4a2713aSLionel Sambuc /// destructors call site.
1359f4a2713aSLionel Sambuc /// FIXME: This mechanism for adding automatic destructors doesn't handle
1360f4a2713aSLionel Sambuc /// no-return destructors properly.
prependAutomaticObjDtorsWithTerminator(CFGBlock * Blk,LocalScope::const_iterator B,LocalScope::const_iterator E)1361f4a2713aSLionel Sambuc void CFGBuilder::prependAutomaticObjDtorsWithTerminator(CFGBlock *Blk,
1362f4a2713aSLionel Sambuc     LocalScope::const_iterator B, LocalScope::const_iterator E) {
1363f4a2713aSLionel Sambuc   BumpVectorContext &C = cfg->getBumpVectorContext();
1364f4a2713aSLionel Sambuc   CFGBlock::iterator InsertPos
1365f4a2713aSLionel Sambuc     = Blk->beginAutomaticObjDtorsInsert(Blk->end(), B.distance(E), C);
1366f4a2713aSLionel Sambuc   for (LocalScope::const_iterator I = B; I != E; ++I)
1367f4a2713aSLionel Sambuc     InsertPos = Blk->insertAutomaticObjDtor(InsertPos, *I,
1368f4a2713aSLionel Sambuc                                             Blk->getTerminator());
1369f4a2713aSLionel Sambuc }
1370f4a2713aSLionel Sambuc 
1371f4a2713aSLionel Sambuc /// Visit - Walk the subtree of a statement and add extra
1372f4a2713aSLionel Sambuc ///   blocks for ternary operators, &&, and ||.  We also process "," and
1373f4a2713aSLionel Sambuc ///   DeclStmts (which may contain nested control-flow).
Visit(Stmt * S,AddStmtChoice asc)1374f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc) {
1375f4a2713aSLionel Sambuc   if (!S) {
1376f4a2713aSLionel Sambuc     badCFG = true;
1377*0a6a1f1dSLionel Sambuc     return nullptr;
1378f4a2713aSLionel Sambuc   }
1379f4a2713aSLionel Sambuc 
1380f4a2713aSLionel Sambuc   if (Expr *E = dyn_cast<Expr>(S))
1381f4a2713aSLionel Sambuc     S = E->IgnoreParens();
1382f4a2713aSLionel Sambuc 
1383f4a2713aSLionel Sambuc   switch (S->getStmtClass()) {
1384f4a2713aSLionel Sambuc     default:
1385f4a2713aSLionel Sambuc       return VisitStmt(S, asc);
1386f4a2713aSLionel Sambuc 
1387f4a2713aSLionel Sambuc     case Stmt::AddrLabelExprClass:
1388f4a2713aSLionel Sambuc       return VisitAddrLabelExpr(cast<AddrLabelExpr>(S), asc);
1389f4a2713aSLionel Sambuc 
1390f4a2713aSLionel Sambuc     case Stmt::BinaryConditionalOperatorClass:
1391f4a2713aSLionel Sambuc       return VisitConditionalOperator(cast<BinaryConditionalOperator>(S), asc);
1392f4a2713aSLionel Sambuc 
1393f4a2713aSLionel Sambuc     case Stmt::BinaryOperatorClass:
1394f4a2713aSLionel Sambuc       return VisitBinaryOperator(cast<BinaryOperator>(S), asc);
1395f4a2713aSLionel Sambuc 
1396f4a2713aSLionel Sambuc     case Stmt::BlockExprClass:
1397f4a2713aSLionel Sambuc       return VisitNoRecurse(cast<Expr>(S), asc);
1398f4a2713aSLionel Sambuc 
1399f4a2713aSLionel Sambuc     case Stmt::BreakStmtClass:
1400f4a2713aSLionel Sambuc       return VisitBreakStmt(cast<BreakStmt>(S));
1401f4a2713aSLionel Sambuc 
1402f4a2713aSLionel Sambuc     case Stmt::CallExprClass:
1403f4a2713aSLionel Sambuc     case Stmt::CXXOperatorCallExprClass:
1404f4a2713aSLionel Sambuc     case Stmt::CXXMemberCallExprClass:
1405f4a2713aSLionel Sambuc     case Stmt::UserDefinedLiteralClass:
1406f4a2713aSLionel Sambuc       return VisitCallExpr(cast<CallExpr>(S), asc);
1407f4a2713aSLionel Sambuc 
1408f4a2713aSLionel Sambuc     case Stmt::CaseStmtClass:
1409f4a2713aSLionel Sambuc       return VisitCaseStmt(cast<CaseStmt>(S));
1410f4a2713aSLionel Sambuc 
1411f4a2713aSLionel Sambuc     case Stmt::ChooseExprClass:
1412f4a2713aSLionel Sambuc       return VisitChooseExpr(cast<ChooseExpr>(S), asc);
1413f4a2713aSLionel Sambuc 
1414f4a2713aSLionel Sambuc     case Stmt::CompoundStmtClass:
1415f4a2713aSLionel Sambuc       return VisitCompoundStmt(cast<CompoundStmt>(S));
1416f4a2713aSLionel Sambuc 
1417f4a2713aSLionel Sambuc     case Stmt::ConditionalOperatorClass:
1418f4a2713aSLionel Sambuc       return VisitConditionalOperator(cast<ConditionalOperator>(S), asc);
1419f4a2713aSLionel Sambuc 
1420f4a2713aSLionel Sambuc     case Stmt::ContinueStmtClass:
1421f4a2713aSLionel Sambuc       return VisitContinueStmt(cast<ContinueStmt>(S));
1422f4a2713aSLionel Sambuc 
1423f4a2713aSLionel Sambuc     case Stmt::CXXCatchStmtClass:
1424f4a2713aSLionel Sambuc       return VisitCXXCatchStmt(cast<CXXCatchStmt>(S));
1425f4a2713aSLionel Sambuc 
1426f4a2713aSLionel Sambuc     case Stmt::ExprWithCleanupsClass:
1427f4a2713aSLionel Sambuc       return VisitExprWithCleanups(cast<ExprWithCleanups>(S), asc);
1428f4a2713aSLionel Sambuc 
1429f4a2713aSLionel Sambuc     case Stmt::CXXDefaultArgExprClass:
1430f4a2713aSLionel Sambuc     case Stmt::CXXDefaultInitExprClass:
1431f4a2713aSLionel Sambuc       // FIXME: The expression inside a CXXDefaultArgExpr is owned by the
1432f4a2713aSLionel Sambuc       // called function's declaration, not by the caller. If we simply add
1433f4a2713aSLionel Sambuc       // this expression to the CFG, we could end up with the same Expr
1434f4a2713aSLionel Sambuc       // appearing multiple times.
1435f4a2713aSLionel Sambuc       // PR13385 / <rdar://problem/12156507>
1436f4a2713aSLionel Sambuc       //
1437f4a2713aSLionel Sambuc       // It's likewise possible for multiple CXXDefaultInitExprs for the same
1438f4a2713aSLionel Sambuc       // expression to be used in the same function (through aggregate
1439f4a2713aSLionel Sambuc       // initialization).
1440f4a2713aSLionel Sambuc       return VisitStmt(S, asc);
1441f4a2713aSLionel Sambuc 
1442f4a2713aSLionel Sambuc     case Stmt::CXXBindTemporaryExprClass:
1443f4a2713aSLionel Sambuc       return VisitCXXBindTemporaryExpr(cast<CXXBindTemporaryExpr>(S), asc);
1444f4a2713aSLionel Sambuc 
1445f4a2713aSLionel Sambuc     case Stmt::CXXConstructExprClass:
1446f4a2713aSLionel Sambuc       return VisitCXXConstructExpr(cast<CXXConstructExpr>(S), asc);
1447f4a2713aSLionel Sambuc 
1448*0a6a1f1dSLionel Sambuc     case Stmt::CXXNewExprClass:
1449*0a6a1f1dSLionel Sambuc       return VisitCXXNewExpr(cast<CXXNewExpr>(S), asc);
1450*0a6a1f1dSLionel Sambuc 
1451f4a2713aSLionel Sambuc     case Stmt::CXXDeleteExprClass:
1452f4a2713aSLionel Sambuc       return VisitCXXDeleteExpr(cast<CXXDeleteExpr>(S), asc);
1453f4a2713aSLionel Sambuc 
1454f4a2713aSLionel Sambuc     case Stmt::CXXFunctionalCastExprClass:
1455f4a2713aSLionel Sambuc       return VisitCXXFunctionalCastExpr(cast<CXXFunctionalCastExpr>(S), asc);
1456f4a2713aSLionel Sambuc 
1457f4a2713aSLionel Sambuc     case Stmt::CXXTemporaryObjectExprClass:
1458f4a2713aSLionel Sambuc       return VisitCXXTemporaryObjectExpr(cast<CXXTemporaryObjectExpr>(S), asc);
1459f4a2713aSLionel Sambuc 
1460f4a2713aSLionel Sambuc     case Stmt::CXXThrowExprClass:
1461f4a2713aSLionel Sambuc       return VisitCXXThrowExpr(cast<CXXThrowExpr>(S));
1462f4a2713aSLionel Sambuc 
1463f4a2713aSLionel Sambuc     case Stmt::CXXTryStmtClass:
1464f4a2713aSLionel Sambuc       return VisitCXXTryStmt(cast<CXXTryStmt>(S));
1465f4a2713aSLionel Sambuc 
1466f4a2713aSLionel Sambuc     case Stmt::CXXForRangeStmtClass:
1467f4a2713aSLionel Sambuc       return VisitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
1468f4a2713aSLionel Sambuc 
1469f4a2713aSLionel Sambuc     case Stmt::DeclStmtClass:
1470f4a2713aSLionel Sambuc       return VisitDeclStmt(cast<DeclStmt>(S));
1471f4a2713aSLionel Sambuc 
1472f4a2713aSLionel Sambuc     case Stmt::DefaultStmtClass:
1473f4a2713aSLionel Sambuc       return VisitDefaultStmt(cast<DefaultStmt>(S));
1474f4a2713aSLionel Sambuc 
1475f4a2713aSLionel Sambuc     case Stmt::DoStmtClass:
1476f4a2713aSLionel Sambuc       return VisitDoStmt(cast<DoStmt>(S));
1477f4a2713aSLionel Sambuc 
1478f4a2713aSLionel Sambuc     case Stmt::ForStmtClass:
1479f4a2713aSLionel Sambuc       return VisitForStmt(cast<ForStmt>(S));
1480f4a2713aSLionel Sambuc 
1481f4a2713aSLionel Sambuc     case Stmt::GotoStmtClass:
1482f4a2713aSLionel Sambuc       return VisitGotoStmt(cast<GotoStmt>(S));
1483f4a2713aSLionel Sambuc 
1484f4a2713aSLionel Sambuc     case Stmt::IfStmtClass:
1485f4a2713aSLionel Sambuc       return VisitIfStmt(cast<IfStmt>(S));
1486f4a2713aSLionel Sambuc 
1487f4a2713aSLionel Sambuc     case Stmt::ImplicitCastExprClass:
1488f4a2713aSLionel Sambuc       return VisitImplicitCastExpr(cast<ImplicitCastExpr>(S), asc);
1489f4a2713aSLionel Sambuc 
1490f4a2713aSLionel Sambuc     case Stmt::IndirectGotoStmtClass:
1491f4a2713aSLionel Sambuc       return VisitIndirectGotoStmt(cast<IndirectGotoStmt>(S));
1492f4a2713aSLionel Sambuc 
1493f4a2713aSLionel Sambuc     case Stmt::LabelStmtClass:
1494f4a2713aSLionel Sambuc       return VisitLabelStmt(cast<LabelStmt>(S));
1495f4a2713aSLionel Sambuc 
1496f4a2713aSLionel Sambuc     case Stmt::LambdaExprClass:
1497f4a2713aSLionel Sambuc       return VisitLambdaExpr(cast<LambdaExpr>(S), asc);
1498f4a2713aSLionel Sambuc 
1499f4a2713aSLionel Sambuc     case Stmt::MemberExprClass:
1500f4a2713aSLionel Sambuc       return VisitMemberExpr(cast<MemberExpr>(S), asc);
1501f4a2713aSLionel Sambuc 
1502f4a2713aSLionel Sambuc     case Stmt::NullStmtClass:
1503f4a2713aSLionel Sambuc       return Block;
1504f4a2713aSLionel Sambuc 
1505f4a2713aSLionel Sambuc     case Stmt::ObjCAtCatchStmtClass:
1506f4a2713aSLionel Sambuc       return VisitObjCAtCatchStmt(cast<ObjCAtCatchStmt>(S));
1507f4a2713aSLionel Sambuc 
1508f4a2713aSLionel Sambuc     case Stmt::ObjCAutoreleasePoolStmtClass:
1509f4a2713aSLionel Sambuc     return VisitObjCAutoreleasePoolStmt(cast<ObjCAutoreleasePoolStmt>(S));
1510f4a2713aSLionel Sambuc 
1511f4a2713aSLionel Sambuc     case Stmt::ObjCAtSynchronizedStmtClass:
1512f4a2713aSLionel Sambuc       return VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S));
1513f4a2713aSLionel Sambuc 
1514f4a2713aSLionel Sambuc     case Stmt::ObjCAtThrowStmtClass:
1515f4a2713aSLionel Sambuc       return VisitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(S));
1516f4a2713aSLionel Sambuc 
1517f4a2713aSLionel Sambuc     case Stmt::ObjCAtTryStmtClass:
1518f4a2713aSLionel Sambuc       return VisitObjCAtTryStmt(cast<ObjCAtTryStmt>(S));
1519f4a2713aSLionel Sambuc 
1520f4a2713aSLionel Sambuc     case Stmt::ObjCForCollectionStmtClass:
1521f4a2713aSLionel Sambuc       return VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S));
1522f4a2713aSLionel Sambuc 
1523f4a2713aSLionel Sambuc     case Stmt::OpaqueValueExprClass:
1524f4a2713aSLionel Sambuc       return Block;
1525f4a2713aSLionel Sambuc 
1526f4a2713aSLionel Sambuc     case Stmt::PseudoObjectExprClass:
1527f4a2713aSLionel Sambuc       return VisitPseudoObjectExpr(cast<PseudoObjectExpr>(S));
1528f4a2713aSLionel Sambuc 
1529f4a2713aSLionel Sambuc     case Stmt::ReturnStmtClass:
1530f4a2713aSLionel Sambuc       return VisitReturnStmt(cast<ReturnStmt>(S));
1531f4a2713aSLionel Sambuc 
1532f4a2713aSLionel Sambuc     case Stmt::UnaryExprOrTypeTraitExprClass:
1533f4a2713aSLionel Sambuc       return VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
1534f4a2713aSLionel Sambuc                                            asc);
1535f4a2713aSLionel Sambuc 
1536f4a2713aSLionel Sambuc     case Stmt::StmtExprClass:
1537f4a2713aSLionel Sambuc       return VisitStmtExpr(cast<StmtExpr>(S), asc);
1538f4a2713aSLionel Sambuc 
1539f4a2713aSLionel Sambuc     case Stmt::SwitchStmtClass:
1540f4a2713aSLionel Sambuc       return VisitSwitchStmt(cast<SwitchStmt>(S));
1541f4a2713aSLionel Sambuc 
1542f4a2713aSLionel Sambuc     case Stmt::UnaryOperatorClass:
1543f4a2713aSLionel Sambuc       return VisitUnaryOperator(cast<UnaryOperator>(S), asc);
1544f4a2713aSLionel Sambuc 
1545f4a2713aSLionel Sambuc     case Stmt::WhileStmtClass:
1546f4a2713aSLionel Sambuc       return VisitWhileStmt(cast<WhileStmt>(S));
1547f4a2713aSLionel Sambuc   }
1548f4a2713aSLionel Sambuc }
1549f4a2713aSLionel Sambuc 
VisitStmt(Stmt * S,AddStmtChoice asc)1550f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitStmt(Stmt *S, AddStmtChoice asc) {
1551f4a2713aSLionel Sambuc   if (asc.alwaysAdd(*this, S)) {
1552f4a2713aSLionel Sambuc     autoCreateBlock();
1553f4a2713aSLionel Sambuc     appendStmt(Block, S);
1554f4a2713aSLionel Sambuc   }
1555f4a2713aSLionel Sambuc 
1556f4a2713aSLionel Sambuc   return VisitChildren(S);
1557f4a2713aSLionel Sambuc }
1558f4a2713aSLionel Sambuc 
1559f4a2713aSLionel Sambuc /// VisitChildren - Visit the children of a Stmt.
VisitChildren(Stmt * S)1560f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitChildren(Stmt *S) {
1561f4a2713aSLionel Sambuc   CFGBlock *B = Block;
1562f4a2713aSLionel Sambuc 
1563f4a2713aSLionel Sambuc   // Visit the children in their reverse order so that they appear in
1564f4a2713aSLionel Sambuc   // left-to-right (natural) order in the CFG.
1565f4a2713aSLionel Sambuc   reverse_children RChildren(S);
1566f4a2713aSLionel Sambuc   for (reverse_children::iterator I = RChildren.begin(), E = RChildren.end();
1567f4a2713aSLionel Sambuc        I != E; ++I) {
1568f4a2713aSLionel Sambuc     if (Stmt *Child = *I)
1569f4a2713aSLionel Sambuc       if (CFGBlock *R = Visit(Child))
1570f4a2713aSLionel Sambuc         B = R;
1571f4a2713aSLionel Sambuc   }
1572f4a2713aSLionel Sambuc   return B;
1573f4a2713aSLionel Sambuc }
1574f4a2713aSLionel Sambuc 
VisitAddrLabelExpr(AddrLabelExpr * A,AddStmtChoice asc)1575f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A,
1576f4a2713aSLionel Sambuc                                          AddStmtChoice asc) {
1577f4a2713aSLionel Sambuc   AddressTakenLabels.insert(A->getLabel());
1578f4a2713aSLionel Sambuc 
1579f4a2713aSLionel Sambuc   if (asc.alwaysAdd(*this, A)) {
1580f4a2713aSLionel Sambuc     autoCreateBlock();
1581f4a2713aSLionel Sambuc     appendStmt(Block, A);
1582f4a2713aSLionel Sambuc   }
1583f4a2713aSLionel Sambuc 
1584f4a2713aSLionel Sambuc   return Block;
1585f4a2713aSLionel Sambuc }
1586f4a2713aSLionel Sambuc 
VisitUnaryOperator(UnaryOperator * U,AddStmtChoice asc)1587f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitUnaryOperator(UnaryOperator *U,
1588f4a2713aSLionel Sambuc            AddStmtChoice asc) {
1589f4a2713aSLionel Sambuc   if (asc.alwaysAdd(*this, U)) {
1590f4a2713aSLionel Sambuc     autoCreateBlock();
1591f4a2713aSLionel Sambuc     appendStmt(Block, U);
1592f4a2713aSLionel Sambuc   }
1593f4a2713aSLionel Sambuc 
1594f4a2713aSLionel Sambuc   return Visit(U->getSubExpr(), AddStmtChoice());
1595f4a2713aSLionel Sambuc }
1596f4a2713aSLionel Sambuc 
VisitLogicalOperator(BinaryOperator * B)1597f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitLogicalOperator(BinaryOperator *B) {
1598f4a2713aSLionel Sambuc   CFGBlock *ConfluenceBlock = Block ? Block : createBlock();
1599f4a2713aSLionel Sambuc   appendStmt(ConfluenceBlock, B);
1600f4a2713aSLionel Sambuc 
1601f4a2713aSLionel Sambuc   if (badCFG)
1602*0a6a1f1dSLionel Sambuc     return nullptr;
1603f4a2713aSLionel Sambuc 
1604*0a6a1f1dSLionel Sambuc   return VisitLogicalOperator(B, nullptr, ConfluenceBlock,
1605*0a6a1f1dSLionel Sambuc                               ConfluenceBlock).first;
1606f4a2713aSLionel Sambuc }
1607f4a2713aSLionel Sambuc 
1608f4a2713aSLionel Sambuc std::pair<CFGBlock*, CFGBlock*>
VisitLogicalOperator(BinaryOperator * B,Stmt * Term,CFGBlock * TrueBlock,CFGBlock * FalseBlock)1609f4a2713aSLionel Sambuc CFGBuilder::VisitLogicalOperator(BinaryOperator *B,
1610f4a2713aSLionel Sambuc                                  Stmt *Term,
1611f4a2713aSLionel Sambuc                                  CFGBlock *TrueBlock,
1612f4a2713aSLionel Sambuc                                  CFGBlock *FalseBlock) {
1613f4a2713aSLionel Sambuc 
1614f4a2713aSLionel Sambuc   // Introspect the RHS.  If it is a nested logical operation, we recursively
1615f4a2713aSLionel Sambuc   // build the CFG using this function.  Otherwise, resort to default
1616f4a2713aSLionel Sambuc   // CFG construction behavior.
1617f4a2713aSLionel Sambuc   Expr *RHS = B->getRHS()->IgnoreParens();
1618f4a2713aSLionel Sambuc   CFGBlock *RHSBlock, *ExitBlock;
1619f4a2713aSLionel Sambuc 
1620f4a2713aSLionel Sambuc   do {
1621f4a2713aSLionel Sambuc     if (BinaryOperator *B_RHS = dyn_cast<BinaryOperator>(RHS))
1622f4a2713aSLionel Sambuc       if (B_RHS->isLogicalOp()) {
1623*0a6a1f1dSLionel Sambuc         std::tie(RHSBlock, ExitBlock) =
1624f4a2713aSLionel Sambuc           VisitLogicalOperator(B_RHS, Term, TrueBlock, FalseBlock);
1625f4a2713aSLionel Sambuc         break;
1626f4a2713aSLionel Sambuc       }
1627f4a2713aSLionel Sambuc 
1628f4a2713aSLionel Sambuc     // The RHS is not a nested logical operation.  Don't push the terminator
1629f4a2713aSLionel Sambuc     // down further, but instead visit RHS and construct the respective
1630f4a2713aSLionel Sambuc     // pieces of the CFG, and link up the RHSBlock with the terminator
1631f4a2713aSLionel Sambuc     // we have been provided.
1632f4a2713aSLionel Sambuc     ExitBlock = RHSBlock = createBlock(false);
1633f4a2713aSLionel Sambuc 
1634f4a2713aSLionel Sambuc     if (!Term) {
1635f4a2713aSLionel Sambuc       assert(TrueBlock == FalseBlock);
1636f4a2713aSLionel Sambuc       addSuccessor(RHSBlock, TrueBlock);
1637f4a2713aSLionel Sambuc     }
1638f4a2713aSLionel Sambuc     else {
1639f4a2713aSLionel Sambuc       RHSBlock->setTerminator(Term);
1640f4a2713aSLionel Sambuc       TryResult KnownVal = tryEvaluateBool(RHS);
1641*0a6a1f1dSLionel Sambuc       if (!KnownVal.isKnown())
1642*0a6a1f1dSLionel Sambuc         KnownVal = tryEvaluateBool(B);
1643*0a6a1f1dSLionel Sambuc       addSuccessor(RHSBlock, TrueBlock, !KnownVal.isFalse());
1644*0a6a1f1dSLionel Sambuc       addSuccessor(RHSBlock, FalseBlock, !KnownVal.isTrue());
1645f4a2713aSLionel Sambuc     }
1646f4a2713aSLionel Sambuc 
1647f4a2713aSLionel Sambuc     Block = RHSBlock;
1648f4a2713aSLionel Sambuc     RHSBlock = addStmt(RHS);
1649f4a2713aSLionel Sambuc   }
1650f4a2713aSLionel Sambuc   while (false);
1651f4a2713aSLionel Sambuc 
1652f4a2713aSLionel Sambuc   if (badCFG)
1653*0a6a1f1dSLionel Sambuc     return std::make_pair(nullptr, nullptr);
1654f4a2713aSLionel Sambuc 
1655f4a2713aSLionel Sambuc   // Generate the blocks for evaluating the LHS.
1656f4a2713aSLionel Sambuc   Expr *LHS = B->getLHS()->IgnoreParens();
1657f4a2713aSLionel Sambuc 
1658f4a2713aSLionel Sambuc   if (BinaryOperator *B_LHS = dyn_cast<BinaryOperator>(LHS))
1659f4a2713aSLionel Sambuc     if (B_LHS->isLogicalOp()) {
1660f4a2713aSLionel Sambuc       if (B->getOpcode() == BO_LOr)
1661f4a2713aSLionel Sambuc         FalseBlock = RHSBlock;
1662f4a2713aSLionel Sambuc       else
1663f4a2713aSLionel Sambuc         TrueBlock = RHSBlock;
1664f4a2713aSLionel Sambuc 
1665f4a2713aSLionel Sambuc       // For the LHS, treat 'B' as the terminator that we want to sink
1666f4a2713aSLionel Sambuc       // into the nested branch.  The RHS always gets the top-most
1667f4a2713aSLionel Sambuc       // terminator.
1668f4a2713aSLionel Sambuc       return VisitLogicalOperator(B_LHS, B, TrueBlock, FalseBlock);
1669f4a2713aSLionel Sambuc     }
1670f4a2713aSLionel Sambuc 
1671f4a2713aSLionel Sambuc   // Create the block evaluating the LHS.
1672f4a2713aSLionel Sambuc   // This contains the '&&' or '||' as the terminator.
1673f4a2713aSLionel Sambuc   CFGBlock *LHSBlock = createBlock(false);
1674f4a2713aSLionel Sambuc   LHSBlock->setTerminator(B);
1675f4a2713aSLionel Sambuc 
1676f4a2713aSLionel Sambuc   Block = LHSBlock;
1677f4a2713aSLionel Sambuc   CFGBlock *EntryLHSBlock = addStmt(LHS);
1678f4a2713aSLionel Sambuc 
1679f4a2713aSLionel Sambuc   if (badCFG)
1680*0a6a1f1dSLionel Sambuc     return std::make_pair(nullptr, nullptr);
1681f4a2713aSLionel Sambuc 
1682f4a2713aSLionel Sambuc   // See if this is a known constant.
1683f4a2713aSLionel Sambuc   TryResult KnownVal = tryEvaluateBool(LHS);
1684f4a2713aSLionel Sambuc 
1685f4a2713aSLionel Sambuc   // Now link the LHSBlock with RHSBlock.
1686f4a2713aSLionel Sambuc   if (B->getOpcode() == BO_LOr) {
1687*0a6a1f1dSLionel Sambuc     addSuccessor(LHSBlock, TrueBlock, !KnownVal.isFalse());
1688*0a6a1f1dSLionel Sambuc     addSuccessor(LHSBlock, RHSBlock, !KnownVal.isTrue());
1689f4a2713aSLionel Sambuc   } else {
1690f4a2713aSLionel Sambuc     assert(B->getOpcode() == BO_LAnd);
1691*0a6a1f1dSLionel Sambuc     addSuccessor(LHSBlock, RHSBlock, !KnownVal.isFalse());
1692*0a6a1f1dSLionel Sambuc     addSuccessor(LHSBlock, FalseBlock, !KnownVal.isTrue());
1693f4a2713aSLionel Sambuc   }
1694f4a2713aSLionel Sambuc 
1695f4a2713aSLionel Sambuc   return std::make_pair(EntryLHSBlock, ExitBlock);
1696f4a2713aSLionel Sambuc }
1697f4a2713aSLionel Sambuc 
1698f4a2713aSLionel Sambuc 
VisitBinaryOperator(BinaryOperator * B,AddStmtChoice asc)1699f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B,
1700f4a2713aSLionel Sambuc                                           AddStmtChoice asc) {
1701f4a2713aSLionel Sambuc    // && or ||
1702f4a2713aSLionel Sambuc   if (B->isLogicalOp())
1703f4a2713aSLionel Sambuc     return VisitLogicalOperator(B);
1704f4a2713aSLionel Sambuc 
1705f4a2713aSLionel Sambuc   if (B->getOpcode() == BO_Comma) { // ,
1706f4a2713aSLionel Sambuc     autoCreateBlock();
1707f4a2713aSLionel Sambuc     appendStmt(Block, B);
1708f4a2713aSLionel Sambuc     addStmt(B->getRHS());
1709f4a2713aSLionel Sambuc     return addStmt(B->getLHS());
1710f4a2713aSLionel Sambuc   }
1711f4a2713aSLionel Sambuc 
1712f4a2713aSLionel Sambuc   if (B->isAssignmentOp()) {
1713f4a2713aSLionel Sambuc     if (asc.alwaysAdd(*this, B)) {
1714f4a2713aSLionel Sambuc       autoCreateBlock();
1715f4a2713aSLionel Sambuc       appendStmt(Block, B);
1716f4a2713aSLionel Sambuc     }
1717f4a2713aSLionel Sambuc     Visit(B->getLHS());
1718f4a2713aSLionel Sambuc     return Visit(B->getRHS());
1719f4a2713aSLionel Sambuc   }
1720f4a2713aSLionel Sambuc 
1721f4a2713aSLionel Sambuc   if (asc.alwaysAdd(*this, B)) {
1722f4a2713aSLionel Sambuc     autoCreateBlock();
1723f4a2713aSLionel Sambuc     appendStmt(Block, B);
1724f4a2713aSLionel Sambuc   }
1725f4a2713aSLionel Sambuc 
1726f4a2713aSLionel Sambuc   CFGBlock *RBlock = Visit(B->getRHS());
1727f4a2713aSLionel Sambuc   CFGBlock *LBlock = Visit(B->getLHS());
1728f4a2713aSLionel Sambuc   // If visiting RHS causes us to finish 'Block', e.g. the RHS is a StmtExpr
1729f4a2713aSLionel Sambuc   // containing a DoStmt, and the LHS doesn't create a new block, then we should
1730f4a2713aSLionel Sambuc   // return RBlock.  Otherwise we'll incorrectly return NULL.
1731f4a2713aSLionel Sambuc   return (LBlock ? LBlock : RBlock);
1732f4a2713aSLionel Sambuc }
1733f4a2713aSLionel Sambuc 
VisitNoRecurse(Expr * E,AddStmtChoice asc)1734f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitNoRecurse(Expr *E, AddStmtChoice asc) {
1735f4a2713aSLionel Sambuc   if (asc.alwaysAdd(*this, E)) {
1736f4a2713aSLionel Sambuc     autoCreateBlock();
1737f4a2713aSLionel Sambuc     appendStmt(Block, E);
1738f4a2713aSLionel Sambuc   }
1739f4a2713aSLionel Sambuc   return Block;
1740f4a2713aSLionel Sambuc }
1741f4a2713aSLionel Sambuc 
VisitBreakStmt(BreakStmt * B)1742f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitBreakStmt(BreakStmt *B) {
1743f4a2713aSLionel Sambuc   // "break" is a control-flow statement.  Thus we stop processing the current
1744f4a2713aSLionel Sambuc   // block.
1745f4a2713aSLionel Sambuc   if (badCFG)
1746*0a6a1f1dSLionel Sambuc     return nullptr;
1747f4a2713aSLionel Sambuc 
1748f4a2713aSLionel Sambuc   // Now create a new block that ends with the break statement.
1749f4a2713aSLionel Sambuc   Block = createBlock(false);
1750f4a2713aSLionel Sambuc   Block->setTerminator(B);
1751f4a2713aSLionel Sambuc 
1752f4a2713aSLionel Sambuc   // If there is no target for the break, then we are looking at an incomplete
1753f4a2713aSLionel Sambuc   // AST.  This means that the CFG cannot be constructed.
1754f4a2713aSLionel Sambuc   if (BreakJumpTarget.block) {
1755f4a2713aSLionel Sambuc     addAutomaticObjDtors(ScopePos, BreakJumpTarget.scopePosition, B);
1756f4a2713aSLionel Sambuc     addSuccessor(Block, BreakJumpTarget.block);
1757f4a2713aSLionel Sambuc   } else
1758f4a2713aSLionel Sambuc     badCFG = true;
1759f4a2713aSLionel Sambuc 
1760f4a2713aSLionel Sambuc 
1761f4a2713aSLionel Sambuc   return Block;
1762f4a2713aSLionel Sambuc }
1763f4a2713aSLionel Sambuc 
CanThrow(Expr * E,ASTContext & Ctx)1764f4a2713aSLionel Sambuc static bool CanThrow(Expr *E, ASTContext &Ctx) {
1765f4a2713aSLionel Sambuc   QualType Ty = E->getType();
1766f4a2713aSLionel Sambuc   if (Ty->isFunctionPointerType())
1767f4a2713aSLionel Sambuc     Ty = Ty->getAs<PointerType>()->getPointeeType();
1768f4a2713aSLionel Sambuc   else if (Ty->isBlockPointerType())
1769f4a2713aSLionel Sambuc     Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
1770f4a2713aSLionel Sambuc 
1771f4a2713aSLionel Sambuc   const FunctionType *FT = Ty->getAs<FunctionType>();
1772f4a2713aSLionel Sambuc   if (FT) {
1773f4a2713aSLionel Sambuc     if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT))
1774f4a2713aSLionel Sambuc       if (!isUnresolvedExceptionSpec(Proto->getExceptionSpecType()) &&
1775f4a2713aSLionel Sambuc           Proto->isNothrow(Ctx))
1776f4a2713aSLionel Sambuc         return false;
1777f4a2713aSLionel Sambuc   }
1778f4a2713aSLionel Sambuc   return true;
1779f4a2713aSLionel Sambuc }
1780f4a2713aSLionel Sambuc 
VisitCallExpr(CallExpr * C,AddStmtChoice asc)1781f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) {
1782f4a2713aSLionel Sambuc   // Compute the callee type.
1783f4a2713aSLionel Sambuc   QualType calleeType = C->getCallee()->getType();
1784f4a2713aSLionel Sambuc   if (calleeType == Context->BoundMemberTy) {
1785f4a2713aSLionel Sambuc     QualType boundType = Expr::findBoundMemberType(C->getCallee());
1786f4a2713aSLionel Sambuc 
1787f4a2713aSLionel Sambuc     // We should only get a null bound type if processing a dependent
1788f4a2713aSLionel Sambuc     // CFG.  Recover by assuming nothing.
1789f4a2713aSLionel Sambuc     if (!boundType.isNull()) calleeType = boundType;
1790f4a2713aSLionel Sambuc   }
1791f4a2713aSLionel Sambuc 
1792f4a2713aSLionel Sambuc   // If this is a call to a no-return function, this stops the block here.
1793f4a2713aSLionel Sambuc   bool NoReturn = getFunctionExtInfo(*calleeType).getNoReturn();
1794f4a2713aSLionel Sambuc 
1795f4a2713aSLionel Sambuc   bool AddEHEdge = false;
1796f4a2713aSLionel Sambuc 
1797f4a2713aSLionel Sambuc   // Languages without exceptions are assumed to not throw.
1798f4a2713aSLionel Sambuc   if (Context->getLangOpts().Exceptions) {
1799f4a2713aSLionel Sambuc     if (BuildOpts.AddEHEdges)
1800f4a2713aSLionel Sambuc       AddEHEdge = true;
1801f4a2713aSLionel Sambuc   }
1802f4a2713aSLionel Sambuc 
1803f4a2713aSLionel Sambuc   // If this is a call to a builtin function, it might not actually evaluate
1804f4a2713aSLionel Sambuc   // its arguments. Don't add them to the CFG if this is the case.
1805f4a2713aSLionel Sambuc   bool OmitArguments = false;
1806f4a2713aSLionel Sambuc 
1807f4a2713aSLionel Sambuc   if (FunctionDecl *FD = C->getDirectCallee()) {
1808f4a2713aSLionel Sambuc     if (FD->isNoReturn())
1809f4a2713aSLionel Sambuc       NoReturn = true;
1810f4a2713aSLionel Sambuc     if (FD->hasAttr<NoThrowAttr>())
1811f4a2713aSLionel Sambuc       AddEHEdge = false;
1812f4a2713aSLionel Sambuc     if (FD->getBuiltinID() == Builtin::BI__builtin_object_size)
1813f4a2713aSLionel Sambuc       OmitArguments = true;
1814f4a2713aSLionel Sambuc   }
1815f4a2713aSLionel Sambuc 
1816f4a2713aSLionel Sambuc   if (!CanThrow(C->getCallee(), *Context))
1817f4a2713aSLionel Sambuc     AddEHEdge = false;
1818f4a2713aSLionel Sambuc 
1819f4a2713aSLionel Sambuc   if (OmitArguments) {
1820f4a2713aSLionel Sambuc     assert(!NoReturn && "noreturn calls with unevaluated args not implemented");
1821f4a2713aSLionel Sambuc     assert(!AddEHEdge && "EH calls with unevaluated args not implemented");
1822f4a2713aSLionel Sambuc     autoCreateBlock();
1823f4a2713aSLionel Sambuc     appendStmt(Block, C);
1824f4a2713aSLionel Sambuc     return Visit(C->getCallee());
1825f4a2713aSLionel Sambuc   }
1826f4a2713aSLionel Sambuc 
1827f4a2713aSLionel Sambuc   if (!NoReturn && !AddEHEdge) {
1828f4a2713aSLionel Sambuc     return VisitStmt(C, asc.withAlwaysAdd(true));
1829f4a2713aSLionel Sambuc   }
1830f4a2713aSLionel Sambuc 
1831f4a2713aSLionel Sambuc   if (Block) {
1832f4a2713aSLionel Sambuc     Succ = Block;
1833f4a2713aSLionel Sambuc     if (badCFG)
1834*0a6a1f1dSLionel Sambuc       return nullptr;
1835f4a2713aSLionel Sambuc   }
1836f4a2713aSLionel Sambuc 
1837f4a2713aSLionel Sambuc   if (NoReturn)
1838f4a2713aSLionel Sambuc     Block = createNoReturnBlock();
1839f4a2713aSLionel Sambuc   else
1840f4a2713aSLionel Sambuc     Block = createBlock();
1841f4a2713aSLionel Sambuc 
1842f4a2713aSLionel Sambuc   appendStmt(Block, C);
1843f4a2713aSLionel Sambuc 
1844f4a2713aSLionel Sambuc   if (AddEHEdge) {
1845f4a2713aSLionel Sambuc     // Add exceptional edges.
1846f4a2713aSLionel Sambuc     if (TryTerminatedBlock)
1847f4a2713aSLionel Sambuc       addSuccessor(Block, TryTerminatedBlock);
1848f4a2713aSLionel Sambuc     else
1849f4a2713aSLionel Sambuc       addSuccessor(Block, &cfg->getExit());
1850f4a2713aSLionel Sambuc   }
1851f4a2713aSLionel Sambuc 
1852f4a2713aSLionel Sambuc   return VisitChildren(C);
1853f4a2713aSLionel Sambuc }
1854f4a2713aSLionel Sambuc 
VisitChooseExpr(ChooseExpr * C,AddStmtChoice asc)1855f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C,
1856f4a2713aSLionel Sambuc                                       AddStmtChoice asc) {
1857f4a2713aSLionel Sambuc   CFGBlock *ConfluenceBlock = Block ? Block : createBlock();
1858f4a2713aSLionel Sambuc   appendStmt(ConfluenceBlock, C);
1859f4a2713aSLionel Sambuc   if (badCFG)
1860*0a6a1f1dSLionel Sambuc     return nullptr;
1861f4a2713aSLionel Sambuc 
1862f4a2713aSLionel Sambuc   AddStmtChoice alwaysAdd = asc.withAlwaysAdd(true);
1863f4a2713aSLionel Sambuc   Succ = ConfluenceBlock;
1864*0a6a1f1dSLionel Sambuc   Block = nullptr;
1865f4a2713aSLionel Sambuc   CFGBlock *LHSBlock = Visit(C->getLHS(), alwaysAdd);
1866f4a2713aSLionel Sambuc   if (badCFG)
1867*0a6a1f1dSLionel Sambuc     return nullptr;
1868f4a2713aSLionel Sambuc 
1869f4a2713aSLionel Sambuc   Succ = ConfluenceBlock;
1870*0a6a1f1dSLionel Sambuc   Block = nullptr;
1871f4a2713aSLionel Sambuc   CFGBlock *RHSBlock = Visit(C->getRHS(), alwaysAdd);
1872f4a2713aSLionel Sambuc   if (badCFG)
1873*0a6a1f1dSLionel Sambuc     return nullptr;
1874f4a2713aSLionel Sambuc 
1875f4a2713aSLionel Sambuc   Block = createBlock(false);
1876f4a2713aSLionel Sambuc   // See if this is a known constant.
1877f4a2713aSLionel Sambuc   const TryResult& KnownVal = tryEvaluateBool(C->getCond());
1878*0a6a1f1dSLionel Sambuc   addSuccessor(Block, KnownVal.isFalse() ? nullptr : LHSBlock);
1879*0a6a1f1dSLionel Sambuc   addSuccessor(Block, KnownVal.isTrue() ? nullptr : RHSBlock);
1880f4a2713aSLionel Sambuc   Block->setTerminator(C);
1881f4a2713aSLionel Sambuc   return addStmt(C->getCond());
1882f4a2713aSLionel Sambuc }
1883f4a2713aSLionel Sambuc 
1884f4a2713aSLionel Sambuc 
VisitCompoundStmt(CompoundStmt * C)1885f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) {
1886f4a2713aSLionel Sambuc   addLocalScopeAndDtors(C);
1887f4a2713aSLionel Sambuc   CFGBlock *LastBlock = Block;
1888f4a2713aSLionel Sambuc 
1889f4a2713aSLionel Sambuc   for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend();
1890f4a2713aSLionel Sambuc        I != E; ++I ) {
1891f4a2713aSLionel Sambuc     // If we hit a segment of code just containing ';' (NullStmts), we can
1892f4a2713aSLionel Sambuc     // get a null block back.  In such cases, just use the LastBlock
1893f4a2713aSLionel Sambuc     if (CFGBlock *newBlock = addStmt(*I))
1894f4a2713aSLionel Sambuc       LastBlock = newBlock;
1895f4a2713aSLionel Sambuc 
1896f4a2713aSLionel Sambuc     if (badCFG)
1897*0a6a1f1dSLionel Sambuc       return nullptr;
1898f4a2713aSLionel Sambuc   }
1899f4a2713aSLionel Sambuc 
1900f4a2713aSLionel Sambuc   return LastBlock;
1901f4a2713aSLionel Sambuc }
1902f4a2713aSLionel Sambuc 
VisitConditionalOperator(AbstractConditionalOperator * C,AddStmtChoice asc)1903f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitConditionalOperator(AbstractConditionalOperator *C,
1904f4a2713aSLionel Sambuc                                                AddStmtChoice asc) {
1905f4a2713aSLionel Sambuc   const BinaryConditionalOperator *BCO = dyn_cast<BinaryConditionalOperator>(C);
1906*0a6a1f1dSLionel Sambuc   const OpaqueValueExpr *opaqueValue = (BCO ? BCO->getOpaqueValue() : nullptr);
1907f4a2713aSLionel Sambuc 
1908f4a2713aSLionel Sambuc   // Create the confluence block that will "merge" the results of the ternary
1909f4a2713aSLionel Sambuc   // expression.
1910f4a2713aSLionel Sambuc   CFGBlock *ConfluenceBlock = Block ? Block : createBlock();
1911f4a2713aSLionel Sambuc   appendStmt(ConfluenceBlock, C);
1912f4a2713aSLionel Sambuc   if (badCFG)
1913*0a6a1f1dSLionel Sambuc     return nullptr;
1914f4a2713aSLionel Sambuc 
1915f4a2713aSLionel Sambuc   AddStmtChoice alwaysAdd = asc.withAlwaysAdd(true);
1916f4a2713aSLionel Sambuc 
1917f4a2713aSLionel Sambuc   // Create a block for the LHS expression if there is an LHS expression.  A
1918f4a2713aSLionel Sambuc   // GCC extension allows LHS to be NULL, causing the condition to be the
1919f4a2713aSLionel Sambuc   // value that is returned instead.
1920f4a2713aSLionel Sambuc   //  e.g: x ?: y is shorthand for: x ? x : y;
1921f4a2713aSLionel Sambuc   Succ = ConfluenceBlock;
1922*0a6a1f1dSLionel Sambuc   Block = nullptr;
1923*0a6a1f1dSLionel Sambuc   CFGBlock *LHSBlock = nullptr;
1924f4a2713aSLionel Sambuc   const Expr *trueExpr = C->getTrueExpr();
1925f4a2713aSLionel Sambuc   if (trueExpr != opaqueValue) {
1926f4a2713aSLionel Sambuc     LHSBlock = Visit(C->getTrueExpr(), alwaysAdd);
1927f4a2713aSLionel Sambuc     if (badCFG)
1928*0a6a1f1dSLionel Sambuc       return nullptr;
1929*0a6a1f1dSLionel Sambuc     Block = nullptr;
1930f4a2713aSLionel Sambuc   }
1931f4a2713aSLionel Sambuc   else
1932f4a2713aSLionel Sambuc     LHSBlock = ConfluenceBlock;
1933f4a2713aSLionel Sambuc 
1934f4a2713aSLionel Sambuc   // Create the block for the RHS expression.
1935f4a2713aSLionel Sambuc   Succ = ConfluenceBlock;
1936f4a2713aSLionel Sambuc   CFGBlock *RHSBlock = Visit(C->getFalseExpr(), alwaysAdd);
1937f4a2713aSLionel Sambuc   if (badCFG)
1938*0a6a1f1dSLionel Sambuc     return nullptr;
1939f4a2713aSLionel Sambuc 
1940f4a2713aSLionel Sambuc   // If the condition is a logical '&&' or '||', build a more accurate CFG.
1941f4a2713aSLionel Sambuc   if (BinaryOperator *Cond =
1942f4a2713aSLionel Sambuc         dyn_cast<BinaryOperator>(C->getCond()->IgnoreParens()))
1943f4a2713aSLionel Sambuc     if (Cond->isLogicalOp())
1944f4a2713aSLionel Sambuc       return VisitLogicalOperator(Cond, C, LHSBlock, RHSBlock).first;
1945f4a2713aSLionel Sambuc 
1946f4a2713aSLionel Sambuc   // Create the block that will contain the condition.
1947f4a2713aSLionel Sambuc   Block = createBlock(false);
1948f4a2713aSLionel Sambuc 
1949f4a2713aSLionel Sambuc   // See if this is a known constant.
1950f4a2713aSLionel Sambuc   const TryResult& KnownVal = tryEvaluateBool(C->getCond());
1951*0a6a1f1dSLionel Sambuc   addSuccessor(Block, LHSBlock, !KnownVal.isFalse());
1952*0a6a1f1dSLionel Sambuc   addSuccessor(Block, RHSBlock, !KnownVal.isTrue());
1953f4a2713aSLionel Sambuc   Block->setTerminator(C);
1954f4a2713aSLionel Sambuc   Expr *condExpr = C->getCond();
1955f4a2713aSLionel Sambuc 
1956f4a2713aSLionel Sambuc   if (opaqueValue) {
1957f4a2713aSLionel Sambuc     // Run the condition expression if it's not trivially expressed in
1958f4a2713aSLionel Sambuc     // terms of the opaque value (or if there is no opaque value).
1959f4a2713aSLionel Sambuc     if (condExpr != opaqueValue)
1960f4a2713aSLionel Sambuc       addStmt(condExpr);
1961f4a2713aSLionel Sambuc 
1962f4a2713aSLionel Sambuc     // Before that, run the common subexpression if there was one.
1963f4a2713aSLionel Sambuc     // At least one of this or the above will be run.
1964f4a2713aSLionel Sambuc     return addStmt(BCO->getCommon());
1965f4a2713aSLionel Sambuc   }
1966f4a2713aSLionel Sambuc 
1967f4a2713aSLionel Sambuc   return addStmt(condExpr);
1968f4a2713aSLionel Sambuc }
1969f4a2713aSLionel Sambuc 
VisitDeclStmt(DeclStmt * DS)1970f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitDeclStmt(DeclStmt *DS) {
1971f4a2713aSLionel Sambuc   // Check if the Decl is for an __label__.  If so, elide it from the
1972f4a2713aSLionel Sambuc   // CFG entirely.
1973f4a2713aSLionel Sambuc   if (isa<LabelDecl>(*DS->decl_begin()))
1974f4a2713aSLionel Sambuc     return Block;
1975f4a2713aSLionel Sambuc 
1976f4a2713aSLionel Sambuc   // This case also handles static_asserts.
1977f4a2713aSLionel Sambuc   if (DS->isSingleDecl())
1978f4a2713aSLionel Sambuc     return VisitDeclSubExpr(DS);
1979f4a2713aSLionel Sambuc 
1980*0a6a1f1dSLionel Sambuc   CFGBlock *B = nullptr;
1981f4a2713aSLionel Sambuc 
1982f4a2713aSLionel Sambuc   // Build an individual DeclStmt for each decl.
1983f4a2713aSLionel Sambuc   for (DeclStmt::reverse_decl_iterator I = DS->decl_rbegin(),
1984f4a2713aSLionel Sambuc                                        E = DS->decl_rend();
1985f4a2713aSLionel Sambuc        I != E; ++I) {
1986f4a2713aSLionel Sambuc     // Get the alignment of the new DeclStmt, padding out to >=8 bytes.
1987f4a2713aSLionel Sambuc     unsigned A = llvm::AlignOf<DeclStmt>::Alignment < 8
1988f4a2713aSLionel Sambuc                ? 8 : llvm::AlignOf<DeclStmt>::Alignment;
1989f4a2713aSLionel Sambuc 
1990f4a2713aSLionel Sambuc     // Allocate the DeclStmt using the BumpPtrAllocator.  It will get
1991f4a2713aSLionel Sambuc     // automatically freed with the CFG.
1992f4a2713aSLionel Sambuc     DeclGroupRef DG(*I);
1993f4a2713aSLionel Sambuc     Decl *D = *I;
1994f4a2713aSLionel Sambuc     void *Mem = cfg->getAllocator().Allocate(sizeof(DeclStmt), A);
1995f4a2713aSLionel Sambuc     DeclStmt *DSNew = new (Mem) DeclStmt(DG, D->getLocation(), GetEndLoc(D));
1996f4a2713aSLionel Sambuc     cfg->addSyntheticDeclStmt(DSNew, DS);
1997f4a2713aSLionel Sambuc 
1998f4a2713aSLionel Sambuc     // Append the fake DeclStmt to block.
1999f4a2713aSLionel Sambuc     B = VisitDeclSubExpr(DSNew);
2000f4a2713aSLionel Sambuc   }
2001f4a2713aSLionel Sambuc 
2002f4a2713aSLionel Sambuc   return B;
2003f4a2713aSLionel Sambuc }
2004f4a2713aSLionel Sambuc 
2005f4a2713aSLionel Sambuc /// VisitDeclSubExpr - Utility method to add block-level expressions for
2006f4a2713aSLionel Sambuc /// DeclStmts and initializers in them.
VisitDeclSubExpr(DeclStmt * DS)2007f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) {
2008f4a2713aSLionel Sambuc   assert(DS->isSingleDecl() && "Can handle single declarations only.");
2009f4a2713aSLionel Sambuc   VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
2010f4a2713aSLionel Sambuc 
2011f4a2713aSLionel Sambuc   if (!VD) {
2012f4a2713aSLionel Sambuc     // Of everything that can be declared in a DeclStmt, only VarDecls impact
2013f4a2713aSLionel Sambuc     // runtime semantics.
2014f4a2713aSLionel Sambuc     return Block;
2015f4a2713aSLionel Sambuc   }
2016f4a2713aSLionel Sambuc 
2017f4a2713aSLionel Sambuc   bool HasTemporaries = false;
2018f4a2713aSLionel Sambuc 
2019f4a2713aSLionel Sambuc   // Guard static initializers under a branch.
2020*0a6a1f1dSLionel Sambuc   CFGBlock *blockAfterStaticInit = nullptr;
2021f4a2713aSLionel Sambuc 
2022f4a2713aSLionel Sambuc   if (BuildOpts.AddStaticInitBranches && VD->isStaticLocal()) {
2023f4a2713aSLionel Sambuc     // For static variables, we need to create a branch to track
2024f4a2713aSLionel Sambuc     // whether or not they are initialized.
2025f4a2713aSLionel Sambuc     if (Block) {
2026f4a2713aSLionel Sambuc       Succ = Block;
2027*0a6a1f1dSLionel Sambuc       Block = nullptr;
2028f4a2713aSLionel Sambuc       if (badCFG)
2029*0a6a1f1dSLionel Sambuc         return nullptr;
2030f4a2713aSLionel Sambuc     }
2031f4a2713aSLionel Sambuc     blockAfterStaticInit = Succ;
2032f4a2713aSLionel Sambuc   }
2033f4a2713aSLionel Sambuc 
2034f4a2713aSLionel Sambuc   // Destructors of temporaries in initialization expression should be called
2035f4a2713aSLionel Sambuc   // after initialization finishes.
2036f4a2713aSLionel Sambuc   Expr *Init = VD->getInit();
2037f4a2713aSLionel Sambuc   if (Init) {
2038f4a2713aSLionel Sambuc     HasTemporaries = isa<ExprWithCleanups>(Init);
2039f4a2713aSLionel Sambuc 
2040f4a2713aSLionel Sambuc     if (BuildOpts.AddTemporaryDtors && HasTemporaries) {
2041f4a2713aSLionel Sambuc       // Generate destructors for temporaries in initialization expression.
2042*0a6a1f1dSLionel Sambuc       TempDtorContext Context;
2043f4a2713aSLionel Sambuc       VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
2044*0a6a1f1dSLionel Sambuc                              /*BindToTemporary=*/false, Context);
2045f4a2713aSLionel Sambuc     }
2046f4a2713aSLionel Sambuc   }
2047f4a2713aSLionel Sambuc 
2048f4a2713aSLionel Sambuc   autoCreateBlock();
2049f4a2713aSLionel Sambuc   appendStmt(Block, DS);
2050f4a2713aSLionel Sambuc 
2051f4a2713aSLionel Sambuc   // Keep track of the last non-null block, as 'Block' can be nulled out
2052f4a2713aSLionel Sambuc   // if the initializer expression is something like a 'while' in a
2053f4a2713aSLionel Sambuc   // statement-expression.
2054f4a2713aSLionel Sambuc   CFGBlock *LastBlock = Block;
2055f4a2713aSLionel Sambuc 
2056f4a2713aSLionel Sambuc   if (Init) {
2057f4a2713aSLionel Sambuc     if (HasTemporaries) {
2058f4a2713aSLionel Sambuc       // For expression with temporaries go directly to subexpression to omit
2059f4a2713aSLionel Sambuc       // generating destructors for the second time.
2060f4a2713aSLionel Sambuc       ExprWithCleanups *EC = cast<ExprWithCleanups>(Init);
2061f4a2713aSLionel Sambuc       if (CFGBlock *newBlock = Visit(EC->getSubExpr()))
2062f4a2713aSLionel Sambuc         LastBlock = newBlock;
2063f4a2713aSLionel Sambuc     }
2064f4a2713aSLionel Sambuc     else {
2065f4a2713aSLionel Sambuc       if (CFGBlock *newBlock = Visit(Init))
2066f4a2713aSLionel Sambuc         LastBlock = newBlock;
2067f4a2713aSLionel Sambuc     }
2068f4a2713aSLionel Sambuc   }
2069f4a2713aSLionel Sambuc 
2070f4a2713aSLionel Sambuc   // If the type of VD is a VLA, then we must process its size expressions.
2071f4a2713aSLionel Sambuc   for (const VariableArrayType* VA = FindVA(VD->getType().getTypePtr());
2072*0a6a1f1dSLionel Sambuc        VA != nullptr; VA = FindVA(VA->getElementType().getTypePtr())) {
2073f4a2713aSLionel Sambuc     if (CFGBlock *newBlock = addStmt(VA->getSizeExpr()))
2074f4a2713aSLionel Sambuc       LastBlock = newBlock;
2075f4a2713aSLionel Sambuc   }
2076f4a2713aSLionel Sambuc 
2077f4a2713aSLionel Sambuc   // Remove variable from local scope.
2078f4a2713aSLionel Sambuc   if (ScopePos && VD == *ScopePos)
2079f4a2713aSLionel Sambuc     ++ScopePos;
2080f4a2713aSLionel Sambuc 
2081f4a2713aSLionel Sambuc   CFGBlock *B = LastBlock;
2082f4a2713aSLionel Sambuc   if (blockAfterStaticInit) {
2083f4a2713aSLionel Sambuc     Succ = B;
2084f4a2713aSLionel Sambuc     Block = createBlock(false);
2085f4a2713aSLionel Sambuc     Block->setTerminator(DS);
2086f4a2713aSLionel Sambuc     addSuccessor(Block, blockAfterStaticInit);
2087f4a2713aSLionel Sambuc     addSuccessor(Block, B);
2088f4a2713aSLionel Sambuc     B = Block;
2089f4a2713aSLionel Sambuc   }
2090f4a2713aSLionel Sambuc 
2091f4a2713aSLionel Sambuc   return B;
2092f4a2713aSLionel Sambuc }
2093f4a2713aSLionel Sambuc 
VisitIfStmt(IfStmt * I)2094f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) {
2095f4a2713aSLionel Sambuc   // We may see an if statement in the middle of a basic block, or it may be the
2096f4a2713aSLionel Sambuc   // first statement we are processing.  In either case, we create a new basic
2097f4a2713aSLionel Sambuc   // block.  First, we create the blocks for the then...else statements, and
2098f4a2713aSLionel Sambuc   // then we create the block containing the if statement.  If we were in the
2099f4a2713aSLionel Sambuc   // middle of a block, we stop processing that block.  That block is then the
2100f4a2713aSLionel Sambuc   // implicit successor for the "then" and "else" clauses.
2101f4a2713aSLionel Sambuc 
2102f4a2713aSLionel Sambuc   // Save local scope position because in case of condition variable ScopePos
2103f4a2713aSLionel Sambuc   // won't be restored when traversing AST.
2104f4a2713aSLionel Sambuc   SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
2105f4a2713aSLionel Sambuc 
2106f4a2713aSLionel Sambuc   // Create local scope for possible condition variable.
2107f4a2713aSLionel Sambuc   // Store scope position. Add implicit destructor.
2108f4a2713aSLionel Sambuc   if (VarDecl *VD = I->getConditionVariable()) {
2109f4a2713aSLionel Sambuc     LocalScope::const_iterator BeginScopePos = ScopePos;
2110f4a2713aSLionel Sambuc     addLocalScopeForVarDecl(VD);
2111f4a2713aSLionel Sambuc     addAutomaticObjDtors(ScopePos, BeginScopePos, I);
2112f4a2713aSLionel Sambuc   }
2113f4a2713aSLionel Sambuc 
2114f4a2713aSLionel Sambuc   // The block we were processing is now finished.  Make it the successor
2115f4a2713aSLionel Sambuc   // block.
2116f4a2713aSLionel Sambuc   if (Block) {
2117f4a2713aSLionel Sambuc     Succ = Block;
2118f4a2713aSLionel Sambuc     if (badCFG)
2119*0a6a1f1dSLionel Sambuc       return nullptr;
2120f4a2713aSLionel Sambuc   }
2121f4a2713aSLionel Sambuc 
2122f4a2713aSLionel Sambuc   // Process the false branch.
2123f4a2713aSLionel Sambuc   CFGBlock *ElseBlock = Succ;
2124f4a2713aSLionel Sambuc 
2125f4a2713aSLionel Sambuc   if (Stmt *Else = I->getElse()) {
2126f4a2713aSLionel Sambuc     SaveAndRestore<CFGBlock*> sv(Succ);
2127f4a2713aSLionel Sambuc 
2128f4a2713aSLionel Sambuc     // NULL out Block so that the recursive call to Visit will
2129f4a2713aSLionel Sambuc     // create a new basic block.
2130*0a6a1f1dSLionel Sambuc     Block = nullptr;
2131f4a2713aSLionel Sambuc 
2132f4a2713aSLionel Sambuc     // If branch is not a compound statement create implicit scope
2133f4a2713aSLionel Sambuc     // and add destructors.
2134f4a2713aSLionel Sambuc     if (!isa<CompoundStmt>(Else))
2135f4a2713aSLionel Sambuc       addLocalScopeAndDtors(Else);
2136f4a2713aSLionel Sambuc 
2137f4a2713aSLionel Sambuc     ElseBlock = addStmt(Else);
2138f4a2713aSLionel Sambuc 
2139f4a2713aSLionel Sambuc     if (!ElseBlock) // Can occur when the Else body has all NullStmts.
2140f4a2713aSLionel Sambuc       ElseBlock = sv.get();
2141f4a2713aSLionel Sambuc     else if (Block) {
2142f4a2713aSLionel Sambuc       if (badCFG)
2143*0a6a1f1dSLionel Sambuc         return nullptr;
2144f4a2713aSLionel Sambuc     }
2145f4a2713aSLionel Sambuc   }
2146f4a2713aSLionel Sambuc 
2147f4a2713aSLionel Sambuc   // Process the true branch.
2148f4a2713aSLionel Sambuc   CFGBlock *ThenBlock;
2149f4a2713aSLionel Sambuc   {
2150f4a2713aSLionel Sambuc     Stmt *Then = I->getThen();
2151f4a2713aSLionel Sambuc     assert(Then);
2152f4a2713aSLionel Sambuc     SaveAndRestore<CFGBlock*> sv(Succ);
2153*0a6a1f1dSLionel Sambuc     Block = nullptr;
2154f4a2713aSLionel Sambuc 
2155f4a2713aSLionel Sambuc     // If branch is not a compound statement create implicit scope
2156f4a2713aSLionel Sambuc     // and add destructors.
2157f4a2713aSLionel Sambuc     if (!isa<CompoundStmt>(Then))
2158f4a2713aSLionel Sambuc       addLocalScopeAndDtors(Then);
2159f4a2713aSLionel Sambuc 
2160f4a2713aSLionel Sambuc     ThenBlock = addStmt(Then);
2161f4a2713aSLionel Sambuc 
2162f4a2713aSLionel Sambuc     if (!ThenBlock) {
2163f4a2713aSLionel Sambuc       // We can reach here if the "then" body has all NullStmts.
2164f4a2713aSLionel Sambuc       // Create an empty block so we can distinguish between true and false
2165f4a2713aSLionel Sambuc       // branches in path-sensitive analyses.
2166f4a2713aSLionel Sambuc       ThenBlock = createBlock(false);
2167f4a2713aSLionel Sambuc       addSuccessor(ThenBlock, sv.get());
2168f4a2713aSLionel Sambuc     } else if (Block) {
2169f4a2713aSLionel Sambuc       if (badCFG)
2170*0a6a1f1dSLionel Sambuc         return nullptr;
2171f4a2713aSLionel Sambuc     }
2172f4a2713aSLionel Sambuc   }
2173f4a2713aSLionel Sambuc 
2174f4a2713aSLionel Sambuc   // Specially handle "if (expr1 || ...)" and "if (expr1 && ...)" by
2175f4a2713aSLionel Sambuc   // having these handle the actual control-flow jump.  Note that
2176f4a2713aSLionel Sambuc   // if we introduce a condition variable, e.g. "if (int x = exp1 || exp2)"
2177f4a2713aSLionel Sambuc   // we resort to the old control-flow behavior.  This special handling
2178f4a2713aSLionel Sambuc   // removes infeasible paths from the control-flow graph by having the
2179f4a2713aSLionel Sambuc   // control-flow transfer of '&&' or '||' go directly into the then/else
2180f4a2713aSLionel Sambuc   // blocks directly.
2181f4a2713aSLionel Sambuc   if (!I->getConditionVariable())
2182f4a2713aSLionel Sambuc     if (BinaryOperator *Cond =
2183f4a2713aSLionel Sambuc             dyn_cast<BinaryOperator>(I->getCond()->IgnoreParens()))
2184f4a2713aSLionel Sambuc       if (Cond->isLogicalOp())
2185f4a2713aSLionel Sambuc         return VisitLogicalOperator(Cond, I, ThenBlock, ElseBlock).first;
2186f4a2713aSLionel Sambuc 
2187f4a2713aSLionel Sambuc   // Now create a new block containing the if statement.
2188f4a2713aSLionel Sambuc   Block = createBlock(false);
2189f4a2713aSLionel Sambuc 
2190f4a2713aSLionel Sambuc   // Set the terminator of the new block to the If statement.
2191f4a2713aSLionel Sambuc   Block->setTerminator(I);
2192f4a2713aSLionel Sambuc 
2193f4a2713aSLionel Sambuc   // See if this is a known constant.
2194f4a2713aSLionel Sambuc   const TryResult &KnownVal = tryEvaluateBool(I->getCond());
2195f4a2713aSLionel Sambuc 
2196*0a6a1f1dSLionel Sambuc   // Add the successors.  If we know that specific branches are
2197*0a6a1f1dSLionel Sambuc   // unreachable, inform addSuccessor() of that knowledge.
2198*0a6a1f1dSLionel Sambuc   addSuccessor(Block, ThenBlock, /* isReachable = */ !KnownVal.isFalse());
2199*0a6a1f1dSLionel Sambuc   addSuccessor(Block, ElseBlock, /* isReachable = */ !KnownVal.isTrue());
2200f4a2713aSLionel Sambuc 
2201f4a2713aSLionel Sambuc   // Add the condition as the last statement in the new block.  This may create
2202f4a2713aSLionel Sambuc   // new blocks as the condition may contain control-flow.  Any newly created
2203f4a2713aSLionel Sambuc   // blocks will be pointed to be "Block".
2204f4a2713aSLionel Sambuc   CFGBlock *LastBlock = addStmt(I->getCond());
2205f4a2713aSLionel Sambuc 
2206*0a6a1f1dSLionel Sambuc   // Finally, if the IfStmt contains a condition variable, add it and its
2207*0a6a1f1dSLionel Sambuc   // initializer to the CFG.
2208*0a6a1f1dSLionel Sambuc   if (const DeclStmt* DS = I->getConditionVariableDeclStmt()) {
2209f4a2713aSLionel Sambuc     autoCreateBlock();
2210*0a6a1f1dSLionel Sambuc     LastBlock = addStmt(const_cast<DeclStmt *>(DS));
2211f4a2713aSLionel Sambuc   }
2212f4a2713aSLionel Sambuc 
2213f4a2713aSLionel Sambuc   return LastBlock;
2214f4a2713aSLionel Sambuc }
2215f4a2713aSLionel Sambuc 
2216f4a2713aSLionel Sambuc 
VisitReturnStmt(ReturnStmt * R)2217f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitReturnStmt(ReturnStmt *R) {
2218f4a2713aSLionel Sambuc   // If we were in the middle of a block we stop processing that block.
2219f4a2713aSLionel Sambuc   //
2220f4a2713aSLionel Sambuc   // NOTE: If a "return" appears in the middle of a block, this means that the
2221f4a2713aSLionel Sambuc   //       code afterwards is DEAD (unreachable).  We still keep a basic block
2222f4a2713aSLionel Sambuc   //       for that code; a simple "mark-and-sweep" from the entry block will be
2223f4a2713aSLionel Sambuc   //       able to report such dead blocks.
2224f4a2713aSLionel Sambuc 
2225f4a2713aSLionel Sambuc   // Create the new block.
2226f4a2713aSLionel Sambuc   Block = createBlock(false);
2227f4a2713aSLionel Sambuc 
2228f4a2713aSLionel Sambuc   addAutomaticObjDtors(ScopePos, LocalScope::const_iterator(), R);
2229f4a2713aSLionel Sambuc 
2230f4a2713aSLionel Sambuc   // If the one of the destructors does not return, we already have the Exit
2231f4a2713aSLionel Sambuc   // block as a successor.
2232f4a2713aSLionel Sambuc   if (!Block->hasNoReturnElement())
2233f4a2713aSLionel Sambuc     addSuccessor(Block, &cfg->getExit());
2234f4a2713aSLionel Sambuc 
2235f4a2713aSLionel Sambuc   // Add the return statement to the block.  This may create new blocks if R
2236f4a2713aSLionel Sambuc   // contains control-flow (short-circuit operations).
2237f4a2713aSLionel Sambuc   return VisitStmt(R, AddStmtChoice::AlwaysAdd);
2238f4a2713aSLionel Sambuc }
2239f4a2713aSLionel Sambuc 
VisitLabelStmt(LabelStmt * L)2240f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitLabelStmt(LabelStmt *L) {
2241f4a2713aSLionel Sambuc   // Get the block of the labeled statement.  Add it to our map.
2242f4a2713aSLionel Sambuc   addStmt(L->getSubStmt());
2243f4a2713aSLionel Sambuc   CFGBlock *LabelBlock = Block;
2244f4a2713aSLionel Sambuc 
2245f4a2713aSLionel Sambuc   if (!LabelBlock)              // This can happen when the body is empty, i.e.
2246f4a2713aSLionel Sambuc     LabelBlock = createBlock(); // scopes that only contains NullStmts.
2247f4a2713aSLionel Sambuc 
2248f4a2713aSLionel Sambuc   assert(LabelMap.find(L->getDecl()) == LabelMap.end() &&
2249f4a2713aSLionel Sambuc          "label already in map");
2250f4a2713aSLionel Sambuc   LabelMap[L->getDecl()] = JumpTarget(LabelBlock, ScopePos);
2251f4a2713aSLionel Sambuc 
2252f4a2713aSLionel Sambuc   // Labels partition blocks, so this is the end of the basic block we were
2253f4a2713aSLionel Sambuc   // processing (L is the block's label).  Because this is label (and we have
2254f4a2713aSLionel Sambuc   // already processed the substatement) there is no extra control-flow to worry
2255f4a2713aSLionel Sambuc   // about.
2256f4a2713aSLionel Sambuc   LabelBlock->setLabel(L);
2257f4a2713aSLionel Sambuc   if (badCFG)
2258*0a6a1f1dSLionel Sambuc     return nullptr;
2259f4a2713aSLionel Sambuc 
2260f4a2713aSLionel Sambuc   // We set Block to NULL to allow lazy creation of a new block (if necessary);
2261*0a6a1f1dSLionel Sambuc   Block = nullptr;
2262f4a2713aSLionel Sambuc 
2263f4a2713aSLionel Sambuc   // This block is now the implicit successor of other blocks.
2264f4a2713aSLionel Sambuc   Succ = LabelBlock;
2265f4a2713aSLionel Sambuc 
2266f4a2713aSLionel Sambuc   return LabelBlock;
2267f4a2713aSLionel Sambuc }
2268f4a2713aSLionel Sambuc 
VisitLambdaExpr(LambdaExpr * E,AddStmtChoice asc)2269f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitLambdaExpr(LambdaExpr *E, AddStmtChoice asc) {
2270f4a2713aSLionel Sambuc   CFGBlock *LastBlock = VisitNoRecurse(E, asc);
2271f4a2713aSLionel Sambuc   for (LambdaExpr::capture_init_iterator it = E->capture_init_begin(),
2272f4a2713aSLionel Sambuc        et = E->capture_init_end(); it != et; ++it) {
2273f4a2713aSLionel Sambuc     if (Expr *Init = *it) {
2274f4a2713aSLionel Sambuc       CFGBlock *Tmp = Visit(Init);
2275*0a6a1f1dSLionel Sambuc       if (Tmp)
2276f4a2713aSLionel Sambuc         LastBlock = Tmp;
2277f4a2713aSLionel Sambuc     }
2278f4a2713aSLionel Sambuc   }
2279f4a2713aSLionel Sambuc   return LastBlock;
2280f4a2713aSLionel Sambuc }
2281f4a2713aSLionel Sambuc 
VisitGotoStmt(GotoStmt * G)2282f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitGotoStmt(GotoStmt *G) {
2283f4a2713aSLionel Sambuc   // Goto is a control-flow statement.  Thus we stop processing the current
2284f4a2713aSLionel Sambuc   // block and create a new one.
2285f4a2713aSLionel Sambuc 
2286f4a2713aSLionel Sambuc   Block = createBlock(false);
2287f4a2713aSLionel Sambuc   Block->setTerminator(G);
2288f4a2713aSLionel Sambuc 
2289f4a2713aSLionel Sambuc   // If we already know the mapping to the label block add the successor now.
2290f4a2713aSLionel Sambuc   LabelMapTy::iterator I = LabelMap.find(G->getLabel());
2291f4a2713aSLionel Sambuc 
2292f4a2713aSLionel Sambuc   if (I == LabelMap.end())
2293f4a2713aSLionel Sambuc     // We will need to backpatch this block later.
2294f4a2713aSLionel Sambuc     BackpatchBlocks.push_back(JumpSource(Block, ScopePos));
2295f4a2713aSLionel Sambuc   else {
2296f4a2713aSLionel Sambuc     JumpTarget JT = I->second;
2297f4a2713aSLionel Sambuc     addAutomaticObjDtors(ScopePos, JT.scopePosition, G);
2298f4a2713aSLionel Sambuc     addSuccessor(Block, JT.block);
2299f4a2713aSLionel Sambuc   }
2300f4a2713aSLionel Sambuc 
2301f4a2713aSLionel Sambuc   return Block;
2302f4a2713aSLionel Sambuc }
2303f4a2713aSLionel Sambuc 
VisitForStmt(ForStmt * F)2304f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) {
2305*0a6a1f1dSLionel Sambuc   CFGBlock *LoopSuccessor = nullptr;
2306f4a2713aSLionel Sambuc 
2307f4a2713aSLionel Sambuc   // Save local scope position because in case of condition variable ScopePos
2308f4a2713aSLionel Sambuc   // won't be restored when traversing AST.
2309f4a2713aSLionel Sambuc   SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
2310f4a2713aSLionel Sambuc 
2311f4a2713aSLionel Sambuc   // Create local scope for init statement and possible condition variable.
2312f4a2713aSLionel Sambuc   // Add destructor for init statement and condition variable.
2313f4a2713aSLionel Sambuc   // Store scope position for continue statement.
2314f4a2713aSLionel Sambuc   if (Stmt *Init = F->getInit())
2315f4a2713aSLionel Sambuc     addLocalScopeForStmt(Init);
2316f4a2713aSLionel Sambuc   LocalScope::const_iterator LoopBeginScopePos = ScopePos;
2317f4a2713aSLionel Sambuc 
2318f4a2713aSLionel Sambuc   if (VarDecl *VD = F->getConditionVariable())
2319f4a2713aSLionel Sambuc     addLocalScopeForVarDecl(VD);
2320f4a2713aSLionel Sambuc   LocalScope::const_iterator ContinueScopePos = ScopePos;
2321f4a2713aSLionel Sambuc 
2322f4a2713aSLionel Sambuc   addAutomaticObjDtors(ScopePos, save_scope_pos.get(), F);
2323f4a2713aSLionel Sambuc 
2324f4a2713aSLionel Sambuc   // "for" is a control-flow statement.  Thus we stop processing the current
2325f4a2713aSLionel Sambuc   // block.
2326f4a2713aSLionel Sambuc   if (Block) {
2327f4a2713aSLionel Sambuc     if (badCFG)
2328*0a6a1f1dSLionel Sambuc       return nullptr;
2329f4a2713aSLionel Sambuc     LoopSuccessor = Block;
2330f4a2713aSLionel Sambuc   } else
2331f4a2713aSLionel Sambuc     LoopSuccessor = Succ;
2332f4a2713aSLionel Sambuc 
2333f4a2713aSLionel Sambuc   // Save the current value for the break targets.
2334f4a2713aSLionel Sambuc   // All breaks should go to the code following the loop.
2335f4a2713aSLionel Sambuc   SaveAndRestore<JumpTarget> save_break(BreakJumpTarget);
2336f4a2713aSLionel Sambuc   BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
2337f4a2713aSLionel Sambuc 
2338*0a6a1f1dSLionel Sambuc   CFGBlock *BodyBlock = nullptr, *TransitionBlock = nullptr;
2339f4a2713aSLionel Sambuc 
2340f4a2713aSLionel Sambuc   // Now create the loop body.
2341f4a2713aSLionel Sambuc   {
2342f4a2713aSLionel Sambuc     assert(F->getBody());
2343f4a2713aSLionel Sambuc 
2344f4a2713aSLionel Sambuc     // Save the current values for Block, Succ, continue and break targets.
2345f4a2713aSLionel Sambuc     SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ);
2346f4a2713aSLionel Sambuc     SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget);
2347f4a2713aSLionel Sambuc 
2348f4a2713aSLionel Sambuc     // Create an empty block to represent the transition block for looping back
2349f4a2713aSLionel Sambuc     // to the head of the loop.  If we have increment code, it will
2350f4a2713aSLionel Sambuc     // go in this block as well.
2351f4a2713aSLionel Sambuc     Block = Succ = TransitionBlock = createBlock(false);
2352f4a2713aSLionel Sambuc     TransitionBlock->setLoopTarget(F);
2353f4a2713aSLionel Sambuc 
2354f4a2713aSLionel Sambuc     if (Stmt *I = F->getInc()) {
2355f4a2713aSLionel Sambuc       // Generate increment code in its own basic block.  This is the target of
2356f4a2713aSLionel Sambuc       // continue statements.
2357f4a2713aSLionel Sambuc       Succ = addStmt(I);
2358f4a2713aSLionel Sambuc     }
2359f4a2713aSLionel Sambuc 
2360f4a2713aSLionel Sambuc     // Finish up the increment (or empty) block if it hasn't been already.
2361f4a2713aSLionel Sambuc     if (Block) {
2362f4a2713aSLionel Sambuc       assert(Block == Succ);
2363f4a2713aSLionel Sambuc       if (badCFG)
2364*0a6a1f1dSLionel Sambuc         return nullptr;
2365*0a6a1f1dSLionel Sambuc       Block = nullptr;
2366f4a2713aSLionel Sambuc     }
2367f4a2713aSLionel Sambuc 
2368f4a2713aSLionel Sambuc    // The starting block for the loop increment is the block that should
2369f4a2713aSLionel Sambuc    // represent the 'loop target' for looping back to the start of the loop.
2370f4a2713aSLionel Sambuc    ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos);
2371f4a2713aSLionel Sambuc    ContinueJumpTarget.block->setLoopTarget(F);
2372f4a2713aSLionel Sambuc 
2373f4a2713aSLionel Sambuc     // Loop body should end with destructor of Condition variable (if any).
2374f4a2713aSLionel Sambuc     addAutomaticObjDtors(ScopePos, LoopBeginScopePos, F);
2375f4a2713aSLionel Sambuc 
2376f4a2713aSLionel Sambuc     // If body is not a compound statement create implicit scope
2377f4a2713aSLionel Sambuc     // and add destructors.
2378f4a2713aSLionel Sambuc     if (!isa<CompoundStmt>(F->getBody()))
2379f4a2713aSLionel Sambuc       addLocalScopeAndDtors(F->getBody());
2380f4a2713aSLionel Sambuc 
2381f4a2713aSLionel Sambuc     // Now populate the body block, and in the process create new blocks as we
2382f4a2713aSLionel Sambuc     // walk the body of the loop.
2383f4a2713aSLionel Sambuc     BodyBlock = addStmt(F->getBody());
2384f4a2713aSLionel Sambuc 
2385f4a2713aSLionel Sambuc     if (!BodyBlock) {
2386f4a2713aSLionel Sambuc       // In the case of "for (...;...;...);" we can have a null BodyBlock.
2387f4a2713aSLionel Sambuc       // Use the continue jump target as the proxy for the body.
2388f4a2713aSLionel Sambuc       BodyBlock = ContinueJumpTarget.block;
2389f4a2713aSLionel Sambuc     }
2390f4a2713aSLionel Sambuc     else if (badCFG)
2391*0a6a1f1dSLionel Sambuc       return nullptr;
2392f4a2713aSLionel Sambuc   }
2393f4a2713aSLionel Sambuc 
2394f4a2713aSLionel Sambuc   // Because of short-circuit evaluation, the condition of the loop can span
2395f4a2713aSLionel Sambuc   // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that
2396f4a2713aSLionel Sambuc   // evaluate the condition.
2397*0a6a1f1dSLionel Sambuc   CFGBlock *EntryConditionBlock = nullptr, *ExitConditionBlock = nullptr;
2398f4a2713aSLionel Sambuc 
2399f4a2713aSLionel Sambuc   do {
2400f4a2713aSLionel Sambuc     Expr *C = F->getCond();
2401f4a2713aSLionel Sambuc 
2402f4a2713aSLionel Sambuc     // Specially handle logical operators, which have a slightly
2403f4a2713aSLionel Sambuc     // more optimal CFG representation.
2404f4a2713aSLionel Sambuc     if (BinaryOperator *Cond =
2405*0a6a1f1dSLionel Sambuc             dyn_cast_or_null<BinaryOperator>(C ? C->IgnoreParens() : nullptr))
2406f4a2713aSLionel Sambuc       if (Cond->isLogicalOp()) {
2407*0a6a1f1dSLionel Sambuc         std::tie(EntryConditionBlock, ExitConditionBlock) =
2408f4a2713aSLionel Sambuc           VisitLogicalOperator(Cond, F, BodyBlock, LoopSuccessor);
2409f4a2713aSLionel Sambuc         break;
2410f4a2713aSLionel Sambuc       }
2411f4a2713aSLionel Sambuc 
2412f4a2713aSLionel Sambuc     // The default case when not handling logical operators.
2413f4a2713aSLionel Sambuc     EntryConditionBlock = ExitConditionBlock = createBlock(false);
2414f4a2713aSLionel Sambuc     ExitConditionBlock->setTerminator(F);
2415f4a2713aSLionel Sambuc 
2416f4a2713aSLionel Sambuc     // See if this is a known constant.
2417f4a2713aSLionel Sambuc     TryResult KnownVal(true);
2418f4a2713aSLionel Sambuc 
2419f4a2713aSLionel Sambuc     if (C) {
2420f4a2713aSLionel Sambuc       // Now add the actual condition to the condition block.
2421f4a2713aSLionel Sambuc       // Because the condition itself may contain control-flow, new blocks may
2422f4a2713aSLionel Sambuc       // be created.  Thus we update "Succ" after adding the condition.
2423f4a2713aSLionel Sambuc       Block = ExitConditionBlock;
2424f4a2713aSLionel Sambuc       EntryConditionBlock = addStmt(C);
2425f4a2713aSLionel Sambuc 
2426f4a2713aSLionel Sambuc       // If this block contains a condition variable, add both the condition
2427f4a2713aSLionel Sambuc       // variable and initializer to the CFG.
2428f4a2713aSLionel Sambuc       if (VarDecl *VD = F->getConditionVariable()) {
2429f4a2713aSLionel Sambuc         if (Expr *Init = VD->getInit()) {
2430f4a2713aSLionel Sambuc           autoCreateBlock();
2431f4a2713aSLionel Sambuc           appendStmt(Block, F->getConditionVariableDeclStmt());
2432f4a2713aSLionel Sambuc           EntryConditionBlock = addStmt(Init);
2433f4a2713aSLionel Sambuc           assert(Block == EntryConditionBlock);
2434f4a2713aSLionel Sambuc         }
2435f4a2713aSLionel Sambuc       }
2436f4a2713aSLionel Sambuc 
2437f4a2713aSLionel Sambuc       if (Block && badCFG)
2438*0a6a1f1dSLionel Sambuc         return nullptr;
2439f4a2713aSLionel Sambuc 
2440f4a2713aSLionel Sambuc       KnownVal = tryEvaluateBool(C);
2441f4a2713aSLionel Sambuc     }
2442f4a2713aSLionel Sambuc 
2443f4a2713aSLionel Sambuc     // Add the loop body entry as a successor to the condition.
2444*0a6a1f1dSLionel Sambuc     addSuccessor(ExitConditionBlock, KnownVal.isFalse() ? nullptr : BodyBlock);
2445f4a2713aSLionel Sambuc     // Link up the condition block with the code that follows the loop.  (the
2446f4a2713aSLionel Sambuc     // false branch).
2447*0a6a1f1dSLionel Sambuc     addSuccessor(ExitConditionBlock,
2448*0a6a1f1dSLionel Sambuc                  KnownVal.isTrue() ? nullptr : LoopSuccessor);
2449f4a2713aSLionel Sambuc 
2450f4a2713aSLionel Sambuc   } while (false);
2451f4a2713aSLionel Sambuc 
2452f4a2713aSLionel Sambuc   // Link up the loop-back block to the entry condition block.
2453f4a2713aSLionel Sambuc   addSuccessor(TransitionBlock, EntryConditionBlock);
2454f4a2713aSLionel Sambuc 
2455f4a2713aSLionel Sambuc   // The condition block is the implicit successor for any code above the loop.
2456f4a2713aSLionel Sambuc   Succ = EntryConditionBlock;
2457f4a2713aSLionel Sambuc 
2458f4a2713aSLionel Sambuc   // If the loop contains initialization, create a new block for those
2459f4a2713aSLionel Sambuc   // statements.  This block can also contain statements that precede the loop.
2460f4a2713aSLionel Sambuc   if (Stmt *I = F->getInit()) {
2461f4a2713aSLionel Sambuc     Block = createBlock();
2462f4a2713aSLionel Sambuc     return addStmt(I);
2463f4a2713aSLionel Sambuc   }
2464f4a2713aSLionel Sambuc 
2465f4a2713aSLionel Sambuc   // There is no loop initialization.  We are thus basically a while loop.
2466f4a2713aSLionel Sambuc   // NULL out Block to force lazy block construction.
2467*0a6a1f1dSLionel Sambuc   Block = nullptr;
2468f4a2713aSLionel Sambuc   Succ = EntryConditionBlock;
2469f4a2713aSLionel Sambuc   return EntryConditionBlock;
2470f4a2713aSLionel Sambuc }
2471f4a2713aSLionel Sambuc 
VisitMemberExpr(MemberExpr * M,AddStmtChoice asc)2472f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitMemberExpr(MemberExpr *M, AddStmtChoice asc) {
2473f4a2713aSLionel Sambuc   if (asc.alwaysAdd(*this, M)) {
2474f4a2713aSLionel Sambuc     autoCreateBlock();
2475f4a2713aSLionel Sambuc     appendStmt(Block, M);
2476f4a2713aSLionel Sambuc   }
2477f4a2713aSLionel Sambuc   return Visit(M->getBase());
2478f4a2713aSLionel Sambuc }
2479f4a2713aSLionel Sambuc 
VisitObjCForCollectionStmt(ObjCForCollectionStmt * S)2480f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
2481f4a2713aSLionel Sambuc   // Objective-C fast enumeration 'for' statements:
2482f4a2713aSLionel Sambuc   //  http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC
2483f4a2713aSLionel Sambuc   //
2484f4a2713aSLionel Sambuc   //  for ( Type newVariable in collection_expression ) { statements }
2485f4a2713aSLionel Sambuc   //
2486f4a2713aSLionel Sambuc   //  becomes:
2487f4a2713aSLionel Sambuc   //
2488f4a2713aSLionel Sambuc   //   prologue:
2489f4a2713aSLionel Sambuc   //     1. collection_expression
2490f4a2713aSLionel Sambuc   //     T. jump to loop_entry
2491f4a2713aSLionel Sambuc   //   loop_entry:
2492f4a2713aSLionel Sambuc   //     1. side-effects of element expression
2493f4a2713aSLionel Sambuc   //     1. ObjCForCollectionStmt [performs binding to newVariable]
2494f4a2713aSLionel Sambuc   //     T. ObjCForCollectionStmt  TB, FB  [jumps to TB if newVariable != nil]
2495f4a2713aSLionel Sambuc   //   TB:
2496f4a2713aSLionel Sambuc   //     statements
2497f4a2713aSLionel Sambuc   //     T. jump to loop_entry
2498f4a2713aSLionel Sambuc   //   FB:
2499f4a2713aSLionel Sambuc   //     what comes after
2500f4a2713aSLionel Sambuc   //
2501f4a2713aSLionel Sambuc   //  and
2502f4a2713aSLionel Sambuc   //
2503f4a2713aSLionel Sambuc   //  Type existingItem;
2504f4a2713aSLionel Sambuc   //  for ( existingItem in expression ) { statements }
2505f4a2713aSLionel Sambuc   //
2506f4a2713aSLionel Sambuc   //  becomes:
2507f4a2713aSLionel Sambuc   //
2508f4a2713aSLionel Sambuc   //   the same with newVariable replaced with existingItem; the binding works
2509f4a2713aSLionel Sambuc   //   the same except that for one ObjCForCollectionStmt::getElement() returns
2510f4a2713aSLionel Sambuc   //   a DeclStmt and the other returns a DeclRefExpr.
2511f4a2713aSLionel Sambuc   //
2512f4a2713aSLionel Sambuc 
2513*0a6a1f1dSLionel Sambuc   CFGBlock *LoopSuccessor = nullptr;
2514f4a2713aSLionel Sambuc 
2515f4a2713aSLionel Sambuc   if (Block) {
2516f4a2713aSLionel Sambuc     if (badCFG)
2517*0a6a1f1dSLionel Sambuc       return nullptr;
2518f4a2713aSLionel Sambuc     LoopSuccessor = Block;
2519*0a6a1f1dSLionel Sambuc     Block = nullptr;
2520f4a2713aSLionel Sambuc   } else
2521f4a2713aSLionel Sambuc     LoopSuccessor = Succ;
2522f4a2713aSLionel Sambuc 
2523f4a2713aSLionel Sambuc   // Build the condition blocks.
2524f4a2713aSLionel Sambuc   CFGBlock *ExitConditionBlock = createBlock(false);
2525f4a2713aSLionel Sambuc 
2526f4a2713aSLionel Sambuc   // Set the terminator for the "exit" condition block.
2527f4a2713aSLionel Sambuc   ExitConditionBlock->setTerminator(S);
2528f4a2713aSLionel Sambuc 
2529f4a2713aSLionel Sambuc   // The last statement in the block should be the ObjCForCollectionStmt, which
2530f4a2713aSLionel Sambuc   // performs the actual binding to 'element' and determines if there are any
2531f4a2713aSLionel Sambuc   // more items in the collection.
2532f4a2713aSLionel Sambuc   appendStmt(ExitConditionBlock, S);
2533f4a2713aSLionel Sambuc   Block = ExitConditionBlock;
2534f4a2713aSLionel Sambuc 
2535f4a2713aSLionel Sambuc   // Walk the 'element' expression to see if there are any side-effects.  We
2536f4a2713aSLionel Sambuc   // generate new blocks as necessary.  We DON'T add the statement by default to
2537f4a2713aSLionel Sambuc   // the CFG unless it contains control-flow.
2538f4a2713aSLionel Sambuc   CFGBlock *EntryConditionBlock = Visit(S->getElement(),
2539f4a2713aSLionel Sambuc                                         AddStmtChoice::NotAlwaysAdd);
2540f4a2713aSLionel Sambuc   if (Block) {
2541f4a2713aSLionel Sambuc     if (badCFG)
2542*0a6a1f1dSLionel Sambuc       return nullptr;
2543*0a6a1f1dSLionel Sambuc     Block = nullptr;
2544f4a2713aSLionel Sambuc   }
2545f4a2713aSLionel Sambuc 
2546f4a2713aSLionel Sambuc   // The condition block is the implicit successor for the loop body as well as
2547f4a2713aSLionel Sambuc   // any code above the loop.
2548f4a2713aSLionel Sambuc   Succ = EntryConditionBlock;
2549f4a2713aSLionel Sambuc 
2550f4a2713aSLionel Sambuc   // Now create the true branch.
2551f4a2713aSLionel Sambuc   {
2552f4a2713aSLionel Sambuc     // Save the current values for Succ, continue and break targets.
2553f4a2713aSLionel Sambuc     SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ);
2554f4a2713aSLionel Sambuc     SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget),
2555f4a2713aSLionel Sambuc                                save_break(BreakJumpTarget);
2556f4a2713aSLionel Sambuc 
2557f4a2713aSLionel Sambuc     // Add an intermediate block between the BodyBlock and the
2558f4a2713aSLionel Sambuc     // EntryConditionBlock to represent the "loop back" transition, for looping
2559f4a2713aSLionel Sambuc     // back to the head of the loop.
2560*0a6a1f1dSLionel Sambuc     CFGBlock *LoopBackBlock = nullptr;
2561f4a2713aSLionel Sambuc     Succ = LoopBackBlock = createBlock();
2562f4a2713aSLionel Sambuc     LoopBackBlock->setLoopTarget(S);
2563f4a2713aSLionel Sambuc 
2564f4a2713aSLionel Sambuc     BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
2565f4a2713aSLionel Sambuc     ContinueJumpTarget = JumpTarget(Succ, ScopePos);
2566f4a2713aSLionel Sambuc 
2567f4a2713aSLionel Sambuc     CFGBlock *BodyBlock = addStmt(S->getBody());
2568f4a2713aSLionel Sambuc 
2569f4a2713aSLionel Sambuc     if (!BodyBlock)
2570f4a2713aSLionel Sambuc       BodyBlock = ContinueJumpTarget.block; // can happen for "for (X in Y) ;"
2571f4a2713aSLionel Sambuc     else if (Block) {
2572f4a2713aSLionel Sambuc       if (badCFG)
2573*0a6a1f1dSLionel Sambuc         return nullptr;
2574f4a2713aSLionel Sambuc     }
2575f4a2713aSLionel Sambuc 
2576f4a2713aSLionel Sambuc     // This new body block is a successor to our "exit" condition block.
2577f4a2713aSLionel Sambuc     addSuccessor(ExitConditionBlock, BodyBlock);
2578f4a2713aSLionel Sambuc   }
2579f4a2713aSLionel Sambuc 
2580f4a2713aSLionel Sambuc   // Link up the condition block with the code that follows the loop.
2581f4a2713aSLionel Sambuc   // (the false branch).
2582f4a2713aSLionel Sambuc   addSuccessor(ExitConditionBlock, LoopSuccessor);
2583f4a2713aSLionel Sambuc 
2584f4a2713aSLionel Sambuc   // Now create a prologue block to contain the collection expression.
2585f4a2713aSLionel Sambuc   Block = createBlock();
2586f4a2713aSLionel Sambuc   return addStmt(S->getCollection());
2587f4a2713aSLionel Sambuc }
2588f4a2713aSLionel Sambuc 
VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt * S)2589f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
2590f4a2713aSLionel Sambuc   // Inline the body.
2591f4a2713aSLionel Sambuc   return addStmt(S->getSubStmt());
2592f4a2713aSLionel Sambuc   // TODO: consider adding cleanups for the end of @autoreleasepool scope.
2593f4a2713aSLionel Sambuc }
2594f4a2713aSLionel Sambuc 
VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt * S)2595f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
2596f4a2713aSLionel Sambuc   // FIXME: Add locking 'primitives' to CFG for @synchronized.
2597f4a2713aSLionel Sambuc 
2598f4a2713aSLionel Sambuc   // Inline the body.
2599f4a2713aSLionel Sambuc   CFGBlock *SyncBlock = addStmt(S->getSynchBody());
2600f4a2713aSLionel Sambuc 
2601f4a2713aSLionel Sambuc   // The sync body starts its own basic block.  This makes it a little easier
2602f4a2713aSLionel Sambuc   // for diagnostic clients.
2603f4a2713aSLionel Sambuc   if (SyncBlock) {
2604f4a2713aSLionel Sambuc     if (badCFG)
2605*0a6a1f1dSLionel Sambuc       return nullptr;
2606f4a2713aSLionel Sambuc 
2607*0a6a1f1dSLionel Sambuc     Block = nullptr;
2608f4a2713aSLionel Sambuc     Succ = SyncBlock;
2609f4a2713aSLionel Sambuc   }
2610f4a2713aSLionel Sambuc 
2611f4a2713aSLionel Sambuc   // Add the @synchronized to the CFG.
2612f4a2713aSLionel Sambuc   autoCreateBlock();
2613f4a2713aSLionel Sambuc   appendStmt(Block, S);
2614f4a2713aSLionel Sambuc 
2615f4a2713aSLionel Sambuc   // Inline the sync expression.
2616f4a2713aSLionel Sambuc   return addStmt(S->getSynchExpr());
2617f4a2713aSLionel Sambuc }
2618f4a2713aSLionel Sambuc 
VisitObjCAtTryStmt(ObjCAtTryStmt * S)2619f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
2620f4a2713aSLionel Sambuc   // FIXME
2621f4a2713aSLionel Sambuc   return NYS();
2622f4a2713aSLionel Sambuc }
2623f4a2713aSLionel Sambuc 
VisitPseudoObjectExpr(PseudoObjectExpr * E)2624f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
2625f4a2713aSLionel Sambuc   autoCreateBlock();
2626f4a2713aSLionel Sambuc 
2627f4a2713aSLionel Sambuc   // Add the PseudoObject as the last thing.
2628f4a2713aSLionel Sambuc   appendStmt(Block, E);
2629f4a2713aSLionel Sambuc 
2630f4a2713aSLionel Sambuc   CFGBlock *lastBlock = Block;
2631f4a2713aSLionel Sambuc 
2632f4a2713aSLionel Sambuc   // Before that, evaluate all of the semantics in order.  In
2633f4a2713aSLionel Sambuc   // CFG-land, that means appending them in reverse order.
2634f4a2713aSLionel Sambuc   for (unsigned i = E->getNumSemanticExprs(); i != 0; ) {
2635f4a2713aSLionel Sambuc     Expr *Semantic = E->getSemanticExpr(--i);
2636f4a2713aSLionel Sambuc 
2637f4a2713aSLionel Sambuc     // If the semantic is an opaque value, we're being asked to bind
2638f4a2713aSLionel Sambuc     // it to its source expression.
2639f4a2713aSLionel Sambuc     if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
2640f4a2713aSLionel Sambuc       Semantic = OVE->getSourceExpr();
2641f4a2713aSLionel Sambuc 
2642f4a2713aSLionel Sambuc     if (CFGBlock *B = Visit(Semantic))
2643f4a2713aSLionel Sambuc       lastBlock = B;
2644f4a2713aSLionel Sambuc   }
2645f4a2713aSLionel Sambuc 
2646f4a2713aSLionel Sambuc   return lastBlock;
2647f4a2713aSLionel Sambuc }
2648f4a2713aSLionel Sambuc 
VisitWhileStmt(WhileStmt * W)2649f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitWhileStmt(WhileStmt *W) {
2650*0a6a1f1dSLionel Sambuc   CFGBlock *LoopSuccessor = nullptr;
2651f4a2713aSLionel Sambuc 
2652f4a2713aSLionel Sambuc   // Save local scope position because in case of condition variable ScopePos
2653f4a2713aSLionel Sambuc   // won't be restored when traversing AST.
2654f4a2713aSLionel Sambuc   SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
2655f4a2713aSLionel Sambuc 
2656f4a2713aSLionel Sambuc   // Create local scope for possible condition variable.
2657f4a2713aSLionel Sambuc   // Store scope position for continue statement.
2658f4a2713aSLionel Sambuc   LocalScope::const_iterator LoopBeginScopePos = ScopePos;
2659f4a2713aSLionel Sambuc   if (VarDecl *VD = W->getConditionVariable()) {
2660f4a2713aSLionel Sambuc     addLocalScopeForVarDecl(VD);
2661f4a2713aSLionel Sambuc     addAutomaticObjDtors(ScopePos, LoopBeginScopePos, W);
2662f4a2713aSLionel Sambuc   }
2663f4a2713aSLionel Sambuc 
2664f4a2713aSLionel Sambuc   // "while" is a control-flow statement.  Thus we stop processing the current
2665f4a2713aSLionel Sambuc   // block.
2666f4a2713aSLionel Sambuc   if (Block) {
2667f4a2713aSLionel Sambuc     if (badCFG)
2668*0a6a1f1dSLionel Sambuc       return nullptr;
2669f4a2713aSLionel Sambuc     LoopSuccessor = Block;
2670*0a6a1f1dSLionel Sambuc     Block = nullptr;
2671f4a2713aSLionel Sambuc   } else {
2672f4a2713aSLionel Sambuc     LoopSuccessor = Succ;
2673f4a2713aSLionel Sambuc   }
2674f4a2713aSLionel Sambuc 
2675*0a6a1f1dSLionel Sambuc   CFGBlock *BodyBlock = nullptr, *TransitionBlock = nullptr;
2676f4a2713aSLionel Sambuc 
2677f4a2713aSLionel Sambuc   // Process the loop body.
2678f4a2713aSLionel Sambuc   {
2679f4a2713aSLionel Sambuc     assert(W->getBody());
2680f4a2713aSLionel Sambuc 
2681f4a2713aSLionel Sambuc     // Save the current values for Block, Succ, continue and break targets.
2682f4a2713aSLionel Sambuc     SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ);
2683f4a2713aSLionel Sambuc     SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget),
2684f4a2713aSLionel Sambuc                                save_break(BreakJumpTarget);
2685f4a2713aSLionel Sambuc 
2686f4a2713aSLionel Sambuc     // Create an empty block to represent the transition block for looping back
2687f4a2713aSLionel Sambuc     // to the head of the loop.
2688f4a2713aSLionel Sambuc     Succ = TransitionBlock = createBlock(false);
2689f4a2713aSLionel Sambuc     TransitionBlock->setLoopTarget(W);
2690f4a2713aSLionel Sambuc     ContinueJumpTarget = JumpTarget(Succ, LoopBeginScopePos);
2691f4a2713aSLionel Sambuc 
2692f4a2713aSLionel Sambuc     // All breaks should go to the code following the loop.
2693f4a2713aSLionel Sambuc     BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
2694f4a2713aSLionel Sambuc 
2695f4a2713aSLionel Sambuc     // Loop body should end with destructor of Condition variable (if any).
2696f4a2713aSLionel Sambuc     addAutomaticObjDtors(ScopePos, LoopBeginScopePos, W);
2697f4a2713aSLionel Sambuc 
2698f4a2713aSLionel Sambuc     // If body is not a compound statement create implicit scope
2699f4a2713aSLionel Sambuc     // and add destructors.
2700f4a2713aSLionel Sambuc     if (!isa<CompoundStmt>(W->getBody()))
2701f4a2713aSLionel Sambuc       addLocalScopeAndDtors(W->getBody());
2702f4a2713aSLionel Sambuc 
2703f4a2713aSLionel Sambuc     // Create the body.  The returned block is the entry to the loop body.
2704f4a2713aSLionel Sambuc     BodyBlock = addStmt(W->getBody());
2705f4a2713aSLionel Sambuc 
2706f4a2713aSLionel Sambuc     if (!BodyBlock)
2707f4a2713aSLionel Sambuc       BodyBlock = ContinueJumpTarget.block; // can happen for "while(...) ;"
2708f4a2713aSLionel Sambuc     else if (Block && badCFG)
2709*0a6a1f1dSLionel Sambuc       return nullptr;
2710f4a2713aSLionel Sambuc   }
2711f4a2713aSLionel Sambuc 
2712f4a2713aSLionel Sambuc   // Because of short-circuit evaluation, the condition of the loop can span
2713f4a2713aSLionel Sambuc   // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that
2714f4a2713aSLionel Sambuc   // evaluate the condition.
2715*0a6a1f1dSLionel Sambuc   CFGBlock *EntryConditionBlock = nullptr, *ExitConditionBlock = nullptr;
2716f4a2713aSLionel Sambuc 
2717f4a2713aSLionel Sambuc   do {
2718f4a2713aSLionel Sambuc     Expr *C = W->getCond();
2719f4a2713aSLionel Sambuc 
2720f4a2713aSLionel Sambuc     // Specially handle logical operators, which have a slightly
2721f4a2713aSLionel Sambuc     // more optimal CFG representation.
2722f4a2713aSLionel Sambuc     if (BinaryOperator *Cond = dyn_cast<BinaryOperator>(C->IgnoreParens()))
2723f4a2713aSLionel Sambuc       if (Cond->isLogicalOp()) {
2724*0a6a1f1dSLionel Sambuc         std::tie(EntryConditionBlock, ExitConditionBlock) =
2725*0a6a1f1dSLionel Sambuc             VisitLogicalOperator(Cond, W, BodyBlock, LoopSuccessor);
2726f4a2713aSLionel Sambuc         break;
2727f4a2713aSLionel Sambuc       }
2728f4a2713aSLionel Sambuc 
2729f4a2713aSLionel Sambuc     // The default case when not handling logical operators.
2730f4a2713aSLionel Sambuc     ExitConditionBlock = createBlock(false);
2731f4a2713aSLionel Sambuc     ExitConditionBlock->setTerminator(W);
2732f4a2713aSLionel Sambuc 
2733f4a2713aSLionel Sambuc     // Now add the actual condition to the condition block.
2734f4a2713aSLionel Sambuc     // Because the condition itself may contain control-flow, new blocks may
2735f4a2713aSLionel Sambuc     // be created.  Thus we update "Succ" after adding the condition.
2736f4a2713aSLionel Sambuc     Block = ExitConditionBlock;
2737f4a2713aSLionel Sambuc     Block = EntryConditionBlock = addStmt(C);
2738f4a2713aSLionel Sambuc 
2739f4a2713aSLionel Sambuc     // If this block contains a condition variable, add both the condition
2740f4a2713aSLionel Sambuc     // variable and initializer to the CFG.
2741f4a2713aSLionel Sambuc     if (VarDecl *VD = W->getConditionVariable()) {
2742f4a2713aSLionel Sambuc       if (Expr *Init = VD->getInit()) {
2743f4a2713aSLionel Sambuc         autoCreateBlock();
2744f4a2713aSLionel Sambuc         appendStmt(Block, W->getConditionVariableDeclStmt());
2745f4a2713aSLionel Sambuc         EntryConditionBlock = addStmt(Init);
2746f4a2713aSLionel Sambuc         assert(Block == EntryConditionBlock);
2747f4a2713aSLionel Sambuc       }
2748f4a2713aSLionel Sambuc     }
2749f4a2713aSLionel Sambuc 
2750f4a2713aSLionel Sambuc     if (Block && badCFG)
2751*0a6a1f1dSLionel Sambuc       return nullptr;
2752f4a2713aSLionel Sambuc 
2753f4a2713aSLionel Sambuc     // See if this is a known constant.
2754f4a2713aSLionel Sambuc     const TryResult& KnownVal = tryEvaluateBool(C);
2755f4a2713aSLionel Sambuc 
2756f4a2713aSLionel Sambuc     // Add the loop body entry as a successor to the condition.
2757*0a6a1f1dSLionel Sambuc     addSuccessor(ExitConditionBlock, KnownVal.isFalse() ? nullptr : BodyBlock);
2758f4a2713aSLionel Sambuc     // Link up the condition block with the code that follows the loop.  (the
2759f4a2713aSLionel Sambuc     // false branch).
2760*0a6a1f1dSLionel Sambuc     addSuccessor(ExitConditionBlock,
2761*0a6a1f1dSLionel Sambuc                  KnownVal.isTrue() ? nullptr : LoopSuccessor);
2762f4a2713aSLionel Sambuc 
2763f4a2713aSLionel Sambuc   } while(false);
2764f4a2713aSLionel Sambuc 
2765f4a2713aSLionel Sambuc   // Link up the loop-back block to the entry condition block.
2766f4a2713aSLionel Sambuc   addSuccessor(TransitionBlock, EntryConditionBlock);
2767f4a2713aSLionel Sambuc 
2768f4a2713aSLionel Sambuc   // There can be no more statements in the condition block since we loop back
2769f4a2713aSLionel Sambuc   // to this block.  NULL out Block to force lazy creation of another block.
2770*0a6a1f1dSLionel Sambuc   Block = nullptr;
2771f4a2713aSLionel Sambuc 
2772f4a2713aSLionel Sambuc   // Return the condition block, which is the dominating block for the loop.
2773f4a2713aSLionel Sambuc   Succ = EntryConditionBlock;
2774f4a2713aSLionel Sambuc   return EntryConditionBlock;
2775f4a2713aSLionel Sambuc }
2776f4a2713aSLionel Sambuc 
2777f4a2713aSLionel Sambuc 
VisitObjCAtCatchStmt(ObjCAtCatchStmt * S)2778f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
2779f4a2713aSLionel Sambuc   // FIXME: For now we pretend that @catch and the code it contains does not
2780f4a2713aSLionel Sambuc   //  exit.
2781f4a2713aSLionel Sambuc   return Block;
2782f4a2713aSLionel Sambuc }
2783f4a2713aSLionel Sambuc 
VisitObjCAtThrowStmt(ObjCAtThrowStmt * S)2784f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
2785f4a2713aSLionel Sambuc   // FIXME: This isn't complete.  We basically treat @throw like a return
2786f4a2713aSLionel Sambuc   //  statement.
2787f4a2713aSLionel Sambuc 
2788f4a2713aSLionel Sambuc   // If we were in the middle of a block we stop processing that block.
2789f4a2713aSLionel Sambuc   if (badCFG)
2790*0a6a1f1dSLionel Sambuc     return nullptr;
2791f4a2713aSLionel Sambuc 
2792f4a2713aSLionel Sambuc   // Create the new block.
2793f4a2713aSLionel Sambuc   Block = createBlock(false);
2794f4a2713aSLionel Sambuc 
2795f4a2713aSLionel Sambuc   // The Exit block is the only successor.
2796f4a2713aSLionel Sambuc   addSuccessor(Block, &cfg->getExit());
2797f4a2713aSLionel Sambuc 
2798f4a2713aSLionel Sambuc   // Add the statement to the block.  This may create new blocks if S contains
2799f4a2713aSLionel Sambuc   // control-flow (short-circuit operations).
2800f4a2713aSLionel Sambuc   return VisitStmt(S, AddStmtChoice::AlwaysAdd);
2801f4a2713aSLionel Sambuc }
2802f4a2713aSLionel Sambuc 
VisitCXXThrowExpr(CXXThrowExpr * T)2803f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitCXXThrowExpr(CXXThrowExpr *T) {
2804f4a2713aSLionel Sambuc   // If we were in the middle of a block we stop processing that block.
2805f4a2713aSLionel Sambuc   if (badCFG)
2806*0a6a1f1dSLionel Sambuc     return nullptr;
2807f4a2713aSLionel Sambuc 
2808f4a2713aSLionel Sambuc   // Create the new block.
2809f4a2713aSLionel Sambuc   Block = createBlock(false);
2810f4a2713aSLionel Sambuc 
2811f4a2713aSLionel Sambuc   if (TryTerminatedBlock)
2812f4a2713aSLionel Sambuc     // The current try statement is the only successor.
2813f4a2713aSLionel Sambuc     addSuccessor(Block, TryTerminatedBlock);
2814f4a2713aSLionel Sambuc   else
2815f4a2713aSLionel Sambuc     // otherwise the Exit block is the only successor.
2816f4a2713aSLionel Sambuc     addSuccessor(Block, &cfg->getExit());
2817f4a2713aSLionel Sambuc 
2818f4a2713aSLionel Sambuc   // Add the statement to the block.  This may create new blocks if S contains
2819f4a2713aSLionel Sambuc   // control-flow (short-circuit operations).
2820f4a2713aSLionel Sambuc   return VisitStmt(T, AddStmtChoice::AlwaysAdd);
2821f4a2713aSLionel Sambuc }
2822f4a2713aSLionel Sambuc 
VisitDoStmt(DoStmt * D)2823f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitDoStmt(DoStmt *D) {
2824*0a6a1f1dSLionel Sambuc   CFGBlock *LoopSuccessor = nullptr;
2825f4a2713aSLionel Sambuc 
2826f4a2713aSLionel Sambuc   // "do...while" is a control-flow statement.  Thus we stop processing the
2827f4a2713aSLionel Sambuc   // current block.
2828f4a2713aSLionel Sambuc   if (Block) {
2829f4a2713aSLionel Sambuc     if (badCFG)
2830*0a6a1f1dSLionel Sambuc       return nullptr;
2831f4a2713aSLionel Sambuc     LoopSuccessor = Block;
2832f4a2713aSLionel Sambuc   } else
2833f4a2713aSLionel Sambuc     LoopSuccessor = Succ;
2834f4a2713aSLionel Sambuc 
2835f4a2713aSLionel Sambuc   // Because of short-circuit evaluation, the condition of the loop can span
2836f4a2713aSLionel Sambuc   // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that
2837f4a2713aSLionel Sambuc   // evaluate the condition.
2838f4a2713aSLionel Sambuc   CFGBlock *ExitConditionBlock = createBlock(false);
2839f4a2713aSLionel Sambuc   CFGBlock *EntryConditionBlock = ExitConditionBlock;
2840f4a2713aSLionel Sambuc 
2841f4a2713aSLionel Sambuc   // Set the terminator for the "exit" condition block.
2842f4a2713aSLionel Sambuc   ExitConditionBlock->setTerminator(D);
2843f4a2713aSLionel Sambuc 
2844f4a2713aSLionel Sambuc   // Now add the actual condition to the condition block.  Because the condition
2845f4a2713aSLionel Sambuc   // itself may contain control-flow, new blocks may be created.
2846f4a2713aSLionel Sambuc   if (Stmt *C = D->getCond()) {
2847f4a2713aSLionel Sambuc     Block = ExitConditionBlock;
2848f4a2713aSLionel Sambuc     EntryConditionBlock = addStmt(C);
2849f4a2713aSLionel Sambuc     if (Block) {
2850f4a2713aSLionel Sambuc       if (badCFG)
2851*0a6a1f1dSLionel Sambuc         return nullptr;
2852f4a2713aSLionel Sambuc     }
2853f4a2713aSLionel Sambuc   }
2854f4a2713aSLionel Sambuc 
2855f4a2713aSLionel Sambuc   // The condition block is the implicit successor for the loop body.
2856f4a2713aSLionel Sambuc   Succ = EntryConditionBlock;
2857f4a2713aSLionel Sambuc 
2858f4a2713aSLionel Sambuc   // See if this is a known constant.
2859f4a2713aSLionel Sambuc   const TryResult &KnownVal = tryEvaluateBool(D->getCond());
2860f4a2713aSLionel Sambuc 
2861f4a2713aSLionel Sambuc   // Process the loop body.
2862*0a6a1f1dSLionel Sambuc   CFGBlock *BodyBlock = nullptr;
2863f4a2713aSLionel Sambuc   {
2864f4a2713aSLionel Sambuc     assert(D->getBody());
2865f4a2713aSLionel Sambuc 
2866f4a2713aSLionel Sambuc     // Save the current values for Block, Succ, and continue and break targets
2867f4a2713aSLionel Sambuc     SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ);
2868f4a2713aSLionel Sambuc     SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget),
2869f4a2713aSLionel Sambuc         save_break(BreakJumpTarget);
2870f4a2713aSLionel Sambuc 
2871f4a2713aSLionel Sambuc     // All continues within this loop should go to the condition block
2872f4a2713aSLionel Sambuc     ContinueJumpTarget = JumpTarget(EntryConditionBlock, ScopePos);
2873f4a2713aSLionel Sambuc 
2874f4a2713aSLionel Sambuc     // All breaks should go to the code following the loop.
2875f4a2713aSLionel Sambuc     BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
2876f4a2713aSLionel Sambuc 
2877f4a2713aSLionel Sambuc     // NULL out Block to force lazy instantiation of blocks for the body.
2878*0a6a1f1dSLionel Sambuc     Block = nullptr;
2879f4a2713aSLionel Sambuc 
2880f4a2713aSLionel Sambuc     // If body is not a compound statement create implicit scope
2881f4a2713aSLionel Sambuc     // and add destructors.
2882f4a2713aSLionel Sambuc     if (!isa<CompoundStmt>(D->getBody()))
2883f4a2713aSLionel Sambuc       addLocalScopeAndDtors(D->getBody());
2884f4a2713aSLionel Sambuc 
2885f4a2713aSLionel Sambuc     // Create the body.  The returned block is the entry to the loop body.
2886f4a2713aSLionel Sambuc     BodyBlock = addStmt(D->getBody());
2887f4a2713aSLionel Sambuc 
2888f4a2713aSLionel Sambuc     if (!BodyBlock)
2889f4a2713aSLionel Sambuc       BodyBlock = EntryConditionBlock; // can happen for "do ; while(...)"
2890f4a2713aSLionel Sambuc     else if (Block) {
2891f4a2713aSLionel Sambuc       if (badCFG)
2892*0a6a1f1dSLionel Sambuc         return nullptr;
2893f4a2713aSLionel Sambuc     }
2894f4a2713aSLionel Sambuc 
2895f4a2713aSLionel Sambuc     if (!KnownVal.isFalse()) {
2896f4a2713aSLionel Sambuc       // Add an intermediate block between the BodyBlock and the
2897f4a2713aSLionel Sambuc       // ExitConditionBlock to represent the "loop back" transition.  Create an
2898f4a2713aSLionel Sambuc       // empty block to represent the transition block for looping back to the
2899f4a2713aSLionel Sambuc       // head of the loop.
2900f4a2713aSLionel Sambuc       // FIXME: Can we do this more efficiently without adding another block?
2901*0a6a1f1dSLionel Sambuc       Block = nullptr;
2902f4a2713aSLionel Sambuc       Succ = BodyBlock;
2903f4a2713aSLionel Sambuc       CFGBlock *LoopBackBlock = createBlock();
2904f4a2713aSLionel Sambuc       LoopBackBlock->setLoopTarget(D);
2905f4a2713aSLionel Sambuc 
2906f4a2713aSLionel Sambuc       // Add the loop body entry as a successor to the condition.
2907f4a2713aSLionel Sambuc       addSuccessor(ExitConditionBlock, LoopBackBlock);
2908f4a2713aSLionel Sambuc     }
2909f4a2713aSLionel Sambuc     else
2910*0a6a1f1dSLionel Sambuc       addSuccessor(ExitConditionBlock, nullptr);
2911f4a2713aSLionel Sambuc   }
2912f4a2713aSLionel Sambuc 
2913f4a2713aSLionel Sambuc   // Link up the condition block with the code that follows the loop.
2914f4a2713aSLionel Sambuc   // (the false branch).
2915*0a6a1f1dSLionel Sambuc   addSuccessor(ExitConditionBlock, KnownVal.isTrue() ? nullptr : LoopSuccessor);
2916f4a2713aSLionel Sambuc 
2917f4a2713aSLionel Sambuc   // There can be no more statements in the body block(s) since we loop back to
2918f4a2713aSLionel Sambuc   // the body.  NULL out Block to force lazy creation of another block.
2919*0a6a1f1dSLionel Sambuc   Block = nullptr;
2920f4a2713aSLionel Sambuc 
2921f4a2713aSLionel Sambuc   // Return the loop body, which is the dominating block for the loop.
2922f4a2713aSLionel Sambuc   Succ = BodyBlock;
2923f4a2713aSLionel Sambuc   return BodyBlock;
2924f4a2713aSLionel Sambuc }
2925f4a2713aSLionel Sambuc 
VisitContinueStmt(ContinueStmt * C)2926f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitContinueStmt(ContinueStmt *C) {
2927f4a2713aSLionel Sambuc   // "continue" is a control-flow statement.  Thus we stop processing the
2928f4a2713aSLionel Sambuc   // current block.
2929f4a2713aSLionel Sambuc   if (badCFG)
2930*0a6a1f1dSLionel Sambuc     return nullptr;
2931f4a2713aSLionel Sambuc 
2932f4a2713aSLionel Sambuc   // Now create a new block that ends with the continue statement.
2933f4a2713aSLionel Sambuc   Block = createBlock(false);
2934f4a2713aSLionel Sambuc   Block->setTerminator(C);
2935f4a2713aSLionel Sambuc 
2936f4a2713aSLionel Sambuc   // If there is no target for the continue, then we are looking at an
2937f4a2713aSLionel Sambuc   // incomplete AST.  This means the CFG cannot be constructed.
2938f4a2713aSLionel Sambuc   if (ContinueJumpTarget.block) {
2939f4a2713aSLionel Sambuc     addAutomaticObjDtors(ScopePos, ContinueJumpTarget.scopePosition, C);
2940f4a2713aSLionel Sambuc     addSuccessor(Block, ContinueJumpTarget.block);
2941f4a2713aSLionel Sambuc   } else
2942f4a2713aSLionel Sambuc     badCFG = true;
2943f4a2713aSLionel Sambuc 
2944f4a2713aSLionel Sambuc   return Block;
2945f4a2713aSLionel Sambuc }
2946f4a2713aSLionel Sambuc 
VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr * E,AddStmtChoice asc)2947f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E,
2948f4a2713aSLionel Sambuc                                                     AddStmtChoice asc) {
2949f4a2713aSLionel Sambuc 
2950f4a2713aSLionel Sambuc   if (asc.alwaysAdd(*this, E)) {
2951f4a2713aSLionel Sambuc     autoCreateBlock();
2952f4a2713aSLionel Sambuc     appendStmt(Block, E);
2953f4a2713aSLionel Sambuc   }
2954f4a2713aSLionel Sambuc 
2955f4a2713aSLionel Sambuc   // VLA types have expressions that must be evaluated.
2956f4a2713aSLionel Sambuc   CFGBlock *lastBlock = Block;
2957f4a2713aSLionel Sambuc 
2958f4a2713aSLionel Sambuc   if (E->isArgumentType()) {
2959f4a2713aSLionel Sambuc     for (const VariableArrayType *VA =FindVA(E->getArgumentType().getTypePtr());
2960*0a6a1f1dSLionel Sambuc          VA != nullptr; VA = FindVA(VA->getElementType().getTypePtr()))
2961f4a2713aSLionel Sambuc       lastBlock = addStmt(VA->getSizeExpr());
2962f4a2713aSLionel Sambuc   }
2963f4a2713aSLionel Sambuc   return lastBlock;
2964f4a2713aSLionel Sambuc }
2965f4a2713aSLionel Sambuc 
2966f4a2713aSLionel Sambuc /// VisitStmtExpr - Utility method to handle (nested) statement
2967f4a2713aSLionel Sambuc ///  expressions (a GCC extension).
VisitStmtExpr(StmtExpr * SE,AddStmtChoice asc)2968f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitStmtExpr(StmtExpr *SE, AddStmtChoice asc) {
2969f4a2713aSLionel Sambuc   if (asc.alwaysAdd(*this, SE)) {
2970f4a2713aSLionel Sambuc     autoCreateBlock();
2971f4a2713aSLionel Sambuc     appendStmt(Block, SE);
2972f4a2713aSLionel Sambuc   }
2973f4a2713aSLionel Sambuc   return VisitCompoundStmt(SE->getSubStmt());
2974f4a2713aSLionel Sambuc }
2975f4a2713aSLionel Sambuc 
VisitSwitchStmt(SwitchStmt * Terminator)2976f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) {
2977f4a2713aSLionel Sambuc   // "switch" is a control-flow statement.  Thus we stop processing the current
2978f4a2713aSLionel Sambuc   // block.
2979*0a6a1f1dSLionel Sambuc   CFGBlock *SwitchSuccessor = nullptr;
2980f4a2713aSLionel Sambuc 
2981f4a2713aSLionel Sambuc   // Save local scope position because in case of condition variable ScopePos
2982f4a2713aSLionel Sambuc   // won't be restored when traversing AST.
2983f4a2713aSLionel Sambuc   SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
2984f4a2713aSLionel Sambuc 
2985f4a2713aSLionel Sambuc   // Create local scope for possible condition variable.
2986f4a2713aSLionel Sambuc   // Store scope position. Add implicit destructor.
2987f4a2713aSLionel Sambuc   if (VarDecl *VD = Terminator->getConditionVariable()) {
2988f4a2713aSLionel Sambuc     LocalScope::const_iterator SwitchBeginScopePos = ScopePos;
2989f4a2713aSLionel Sambuc     addLocalScopeForVarDecl(VD);
2990f4a2713aSLionel Sambuc     addAutomaticObjDtors(ScopePos, SwitchBeginScopePos, Terminator);
2991f4a2713aSLionel Sambuc   }
2992f4a2713aSLionel Sambuc 
2993f4a2713aSLionel Sambuc   if (Block) {
2994f4a2713aSLionel Sambuc     if (badCFG)
2995*0a6a1f1dSLionel Sambuc       return nullptr;
2996f4a2713aSLionel Sambuc     SwitchSuccessor = Block;
2997f4a2713aSLionel Sambuc   } else SwitchSuccessor = Succ;
2998f4a2713aSLionel Sambuc 
2999f4a2713aSLionel Sambuc   // Save the current "switch" context.
3000f4a2713aSLionel Sambuc   SaveAndRestore<CFGBlock*> save_switch(SwitchTerminatedBlock),
3001f4a2713aSLionel Sambuc                             save_default(DefaultCaseBlock);
3002f4a2713aSLionel Sambuc   SaveAndRestore<JumpTarget> save_break(BreakJumpTarget);
3003f4a2713aSLionel Sambuc 
3004f4a2713aSLionel Sambuc   // Set the "default" case to be the block after the switch statement.  If the
3005f4a2713aSLionel Sambuc   // switch statement contains a "default:", this value will be overwritten with
3006f4a2713aSLionel Sambuc   // the block for that code.
3007f4a2713aSLionel Sambuc   DefaultCaseBlock = SwitchSuccessor;
3008f4a2713aSLionel Sambuc 
3009f4a2713aSLionel Sambuc   // Create a new block that will contain the switch statement.
3010f4a2713aSLionel Sambuc   SwitchTerminatedBlock = createBlock(false);
3011f4a2713aSLionel Sambuc 
3012f4a2713aSLionel Sambuc   // Now process the switch body.  The code after the switch is the implicit
3013f4a2713aSLionel Sambuc   // successor.
3014f4a2713aSLionel Sambuc   Succ = SwitchSuccessor;
3015f4a2713aSLionel Sambuc   BreakJumpTarget = JumpTarget(SwitchSuccessor, ScopePos);
3016f4a2713aSLionel Sambuc 
3017f4a2713aSLionel Sambuc   // When visiting the body, the case statements should automatically get linked
3018f4a2713aSLionel Sambuc   // up to the switch.  We also don't keep a pointer to the body, since all
3019f4a2713aSLionel Sambuc   // control-flow from the switch goes to case/default statements.
3020f4a2713aSLionel Sambuc   assert(Terminator->getBody() && "switch must contain a non-NULL body");
3021*0a6a1f1dSLionel Sambuc   Block = nullptr;
3022f4a2713aSLionel Sambuc 
3023f4a2713aSLionel Sambuc   // For pruning unreachable case statements, save the current state
3024f4a2713aSLionel Sambuc   // for tracking the condition value.
3025f4a2713aSLionel Sambuc   SaveAndRestore<bool> save_switchExclusivelyCovered(switchExclusivelyCovered,
3026f4a2713aSLionel Sambuc                                                      false);
3027f4a2713aSLionel Sambuc 
3028f4a2713aSLionel Sambuc   // Determine if the switch condition can be explicitly evaluated.
3029f4a2713aSLionel Sambuc   assert(Terminator->getCond() && "switch condition must be non-NULL");
3030f4a2713aSLionel Sambuc   Expr::EvalResult result;
3031f4a2713aSLionel Sambuc   bool b = tryEvaluate(Terminator->getCond(), result);
3032f4a2713aSLionel Sambuc   SaveAndRestore<Expr::EvalResult*> save_switchCond(switchCond,
3033*0a6a1f1dSLionel Sambuc                                                     b ? &result : nullptr);
3034f4a2713aSLionel Sambuc 
3035f4a2713aSLionel Sambuc   // If body is not a compound statement create implicit scope
3036f4a2713aSLionel Sambuc   // and add destructors.
3037f4a2713aSLionel Sambuc   if (!isa<CompoundStmt>(Terminator->getBody()))
3038f4a2713aSLionel Sambuc     addLocalScopeAndDtors(Terminator->getBody());
3039f4a2713aSLionel Sambuc 
3040f4a2713aSLionel Sambuc   addStmt(Terminator->getBody());
3041f4a2713aSLionel Sambuc   if (Block) {
3042f4a2713aSLionel Sambuc     if (badCFG)
3043*0a6a1f1dSLionel Sambuc       return nullptr;
3044f4a2713aSLionel Sambuc   }
3045f4a2713aSLionel Sambuc 
3046f4a2713aSLionel Sambuc   // If we have no "default:" case, the default transition is to the code
3047f4a2713aSLionel Sambuc   // following the switch body.  Moreover, take into account if all the
3048f4a2713aSLionel Sambuc   // cases of a switch are covered (e.g., switching on an enum value).
3049f4a2713aSLionel Sambuc   //
3050f4a2713aSLionel Sambuc   // Note: We add a successor to a switch that is considered covered yet has no
3051f4a2713aSLionel Sambuc   //       case statements if the enumeration has no enumerators.
3052f4a2713aSLionel Sambuc   bool SwitchAlwaysHasSuccessor = false;
3053f4a2713aSLionel Sambuc   SwitchAlwaysHasSuccessor |= switchExclusivelyCovered;
3054f4a2713aSLionel Sambuc   SwitchAlwaysHasSuccessor |= Terminator->isAllEnumCasesCovered() &&
3055f4a2713aSLionel Sambuc                               Terminator->getSwitchCaseList();
3056*0a6a1f1dSLionel Sambuc   addSuccessor(SwitchTerminatedBlock, DefaultCaseBlock,
3057*0a6a1f1dSLionel Sambuc                !SwitchAlwaysHasSuccessor);
3058f4a2713aSLionel Sambuc 
3059f4a2713aSLionel Sambuc   // Add the terminator and condition in the switch block.
3060f4a2713aSLionel Sambuc   SwitchTerminatedBlock->setTerminator(Terminator);
3061f4a2713aSLionel Sambuc   Block = SwitchTerminatedBlock;
3062f4a2713aSLionel Sambuc   CFGBlock *LastBlock = addStmt(Terminator->getCond());
3063f4a2713aSLionel Sambuc 
3064f4a2713aSLionel Sambuc   // Finally, if the SwitchStmt contains a condition variable, add both the
3065f4a2713aSLionel Sambuc   // SwitchStmt and the condition variable initialization to the CFG.
3066f4a2713aSLionel Sambuc   if (VarDecl *VD = Terminator->getConditionVariable()) {
3067f4a2713aSLionel Sambuc     if (Expr *Init = VD->getInit()) {
3068f4a2713aSLionel Sambuc       autoCreateBlock();
3069f4a2713aSLionel Sambuc       appendStmt(Block, Terminator->getConditionVariableDeclStmt());
3070f4a2713aSLionel Sambuc       LastBlock = addStmt(Init);
3071f4a2713aSLionel Sambuc     }
3072f4a2713aSLionel Sambuc   }
3073f4a2713aSLionel Sambuc 
3074f4a2713aSLionel Sambuc   return LastBlock;
3075f4a2713aSLionel Sambuc }
3076f4a2713aSLionel Sambuc 
shouldAddCase(bool & switchExclusivelyCovered,const Expr::EvalResult * switchCond,const CaseStmt * CS,ASTContext & Ctx)3077f4a2713aSLionel Sambuc static bool shouldAddCase(bool &switchExclusivelyCovered,
3078f4a2713aSLionel Sambuc                           const Expr::EvalResult *switchCond,
3079f4a2713aSLionel Sambuc                           const CaseStmt *CS,
3080f4a2713aSLionel Sambuc                           ASTContext &Ctx) {
3081f4a2713aSLionel Sambuc   if (!switchCond)
3082f4a2713aSLionel Sambuc     return true;
3083f4a2713aSLionel Sambuc 
3084f4a2713aSLionel Sambuc   bool addCase = false;
3085f4a2713aSLionel Sambuc 
3086f4a2713aSLionel Sambuc   if (!switchExclusivelyCovered) {
3087f4a2713aSLionel Sambuc     if (switchCond->Val.isInt()) {
3088f4a2713aSLionel Sambuc       // Evaluate the LHS of the case value.
3089f4a2713aSLionel Sambuc       const llvm::APSInt &lhsInt = CS->getLHS()->EvaluateKnownConstInt(Ctx);
3090f4a2713aSLionel Sambuc       const llvm::APSInt &condInt = switchCond->Val.getInt();
3091f4a2713aSLionel Sambuc 
3092f4a2713aSLionel Sambuc       if (condInt == lhsInt) {
3093f4a2713aSLionel Sambuc         addCase = true;
3094f4a2713aSLionel Sambuc         switchExclusivelyCovered = true;
3095f4a2713aSLionel Sambuc       }
3096f4a2713aSLionel Sambuc       else if (condInt < lhsInt) {
3097f4a2713aSLionel Sambuc         if (const Expr *RHS = CS->getRHS()) {
3098f4a2713aSLionel Sambuc           // Evaluate the RHS of the case value.
3099f4a2713aSLionel Sambuc           const llvm::APSInt &V2 = RHS->EvaluateKnownConstInt(Ctx);
3100f4a2713aSLionel Sambuc           if (V2 <= condInt) {
3101f4a2713aSLionel Sambuc             addCase = true;
3102f4a2713aSLionel Sambuc             switchExclusivelyCovered = true;
3103f4a2713aSLionel Sambuc           }
3104f4a2713aSLionel Sambuc         }
3105f4a2713aSLionel Sambuc       }
3106f4a2713aSLionel Sambuc     }
3107f4a2713aSLionel Sambuc     else
3108f4a2713aSLionel Sambuc       addCase = true;
3109f4a2713aSLionel Sambuc   }
3110f4a2713aSLionel Sambuc   return addCase;
3111f4a2713aSLionel Sambuc }
3112f4a2713aSLionel Sambuc 
VisitCaseStmt(CaseStmt * CS)3113f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitCaseStmt(CaseStmt *CS) {
3114f4a2713aSLionel Sambuc   // CaseStmts are essentially labels, so they are the first statement in a
3115f4a2713aSLionel Sambuc   // block.
3116*0a6a1f1dSLionel Sambuc   CFGBlock *TopBlock = nullptr, *LastBlock = nullptr;
3117f4a2713aSLionel Sambuc 
3118f4a2713aSLionel Sambuc   if (Stmt *Sub = CS->getSubStmt()) {
3119f4a2713aSLionel Sambuc     // For deeply nested chains of CaseStmts, instead of doing a recursion
3120f4a2713aSLionel Sambuc     // (which can blow out the stack), manually unroll and create blocks
3121f4a2713aSLionel Sambuc     // along the way.
3122f4a2713aSLionel Sambuc     while (isa<CaseStmt>(Sub)) {
3123f4a2713aSLionel Sambuc       CFGBlock *currentBlock = createBlock(false);
3124f4a2713aSLionel Sambuc       currentBlock->setLabel(CS);
3125f4a2713aSLionel Sambuc 
3126f4a2713aSLionel Sambuc       if (TopBlock)
3127f4a2713aSLionel Sambuc         addSuccessor(LastBlock, currentBlock);
3128f4a2713aSLionel Sambuc       else
3129f4a2713aSLionel Sambuc         TopBlock = currentBlock;
3130f4a2713aSLionel Sambuc 
3131f4a2713aSLionel Sambuc       addSuccessor(SwitchTerminatedBlock,
3132f4a2713aSLionel Sambuc                    shouldAddCase(switchExclusivelyCovered, switchCond,
3133f4a2713aSLionel Sambuc                                  CS, *Context)
3134*0a6a1f1dSLionel Sambuc                    ? currentBlock : nullptr);
3135f4a2713aSLionel Sambuc 
3136f4a2713aSLionel Sambuc       LastBlock = currentBlock;
3137f4a2713aSLionel Sambuc       CS = cast<CaseStmt>(Sub);
3138f4a2713aSLionel Sambuc       Sub = CS->getSubStmt();
3139f4a2713aSLionel Sambuc     }
3140f4a2713aSLionel Sambuc 
3141f4a2713aSLionel Sambuc     addStmt(Sub);
3142f4a2713aSLionel Sambuc   }
3143f4a2713aSLionel Sambuc 
3144f4a2713aSLionel Sambuc   CFGBlock *CaseBlock = Block;
3145f4a2713aSLionel Sambuc   if (!CaseBlock)
3146f4a2713aSLionel Sambuc     CaseBlock = createBlock();
3147f4a2713aSLionel Sambuc 
3148f4a2713aSLionel Sambuc   // Cases statements partition blocks, so this is the top of the basic block we
3149f4a2713aSLionel Sambuc   // were processing (the "case XXX:" is the label).
3150f4a2713aSLionel Sambuc   CaseBlock->setLabel(CS);
3151f4a2713aSLionel Sambuc 
3152f4a2713aSLionel Sambuc   if (badCFG)
3153*0a6a1f1dSLionel Sambuc     return nullptr;
3154f4a2713aSLionel Sambuc 
3155f4a2713aSLionel Sambuc   // Add this block to the list of successors for the block with the switch
3156f4a2713aSLionel Sambuc   // statement.
3157f4a2713aSLionel Sambuc   assert(SwitchTerminatedBlock);
3158*0a6a1f1dSLionel Sambuc   addSuccessor(SwitchTerminatedBlock, CaseBlock,
3159f4a2713aSLionel Sambuc                shouldAddCase(switchExclusivelyCovered, switchCond,
3160*0a6a1f1dSLionel Sambuc                              CS, *Context));
3161f4a2713aSLionel Sambuc 
3162f4a2713aSLionel Sambuc   // We set Block to NULL to allow lazy creation of a new block (if necessary)
3163*0a6a1f1dSLionel Sambuc   Block = nullptr;
3164f4a2713aSLionel Sambuc 
3165f4a2713aSLionel Sambuc   if (TopBlock) {
3166f4a2713aSLionel Sambuc     addSuccessor(LastBlock, CaseBlock);
3167f4a2713aSLionel Sambuc     Succ = TopBlock;
3168f4a2713aSLionel Sambuc   } else {
3169f4a2713aSLionel Sambuc     // This block is now the implicit successor of other blocks.
3170f4a2713aSLionel Sambuc     Succ = CaseBlock;
3171f4a2713aSLionel Sambuc   }
3172f4a2713aSLionel Sambuc 
3173f4a2713aSLionel Sambuc   return Succ;
3174f4a2713aSLionel Sambuc }
3175f4a2713aSLionel Sambuc 
VisitDefaultStmt(DefaultStmt * Terminator)3176f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitDefaultStmt(DefaultStmt *Terminator) {
3177f4a2713aSLionel Sambuc   if (Terminator->getSubStmt())
3178f4a2713aSLionel Sambuc     addStmt(Terminator->getSubStmt());
3179f4a2713aSLionel Sambuc 
3180f4a2713aSLionel Sambuc   DefaultCaseBlock = Block;
3181f4a2713aSLionel Sambuc 
3182f4a2713aSLionel Sambuc   if (!DefaultCaseBlock)
3183f4a2713aSLionel Sambuc     DefaultCaseBlock = createBlock();
3184f4a2713aSLionel Sambuc 
3185f4a2713aSLionel Sambuc   // Default statements partition blocks, so this is the top of the basic block
3186f4a2713aSLionel Sambuc   // we were processing (the "default:" is the label).
3187f4a2713aSLionel Sambuc   DefaultCaseBlock->setLabel(Terminator);
3188f4a2713aSLionel Sambuc 
3189f4a2713aSLionel Sambuc   if (badCFG)
3190*0a6a1f1dSLionel Sambuc     return nullptr;
3191f4a2713aSLionel Sambuc 
3192f4a2713aSLionel Sambuc   // Unlike case statements, we don't add the default block to the successors
3193f4a2713aSLionel Sambuc   // for the switch statement immediately.  This is done when we finish
3194f4a2713aSLionel Sambuc   // processing the switch statement.  This allows for the default case
3195f4a2713aSLionel Sambuc   // (including a fall-through to the code after the switch statement) to always
3196f4a2713aSLionel Sambuc   // be the last successor of a switch-terminated block.
3197f4a2713aSLionel Sambuc 
3198f4a2713aSLionel Sambuc   // We set Block to NULL to allow lazy creation of a new block (if necessary)
3199*0a6a1f1dSLionel Sambuc   Block = nullptr;
3200f4a2713aSLionel Sambuc 
3201f4a2713aSLionel Sambuc   // This block is now the implicit successor of other blocks.
3202f4a2713aSLionel Sambuc   Succ = DefaultCaseBlock;
3203f4a2713aSLionel Sambuc 
3204f4a2713aSLionel Sambuc   return DefaultCaseBlock;
3205f4a2713aSLionel Sambuc }
3206f4a2713aSLionel Sambuc 
VisitCXXTryStmt(CXXTryStmt * Terminator)3207f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitCXXTryStmt(CXXTryStmt *Terminator) {
3208f4a2713aSLionel Sambuc   // "try"/"catch" is a control-flow statement.  Thus we stop processing the
3209f4a2713aSLionel Sambuc   // current block.
3210*0a6a1f1dSLionel Sambuc   CFGBlock *TrySuccessor = nullptr;
3211f4a2713aSLionel Sambuc 
3212f4a2713aSLionel Sambuc   if (Block) {
3213f4a2713aSLionel Sambuc     if (badCFG)
3214*0a6a1f1dSLionel Sambuc       return nullptr;
3215f4a2713aSLionel Sambuc     TrySuccessor = Block;
3216f4a2713aSLionel Sambuc   } else TrySuccessor = Succ;
3217f4a2713aSLionel Sambuc 
3218f4a2713aSLionel Sambuc   CFGBlock *PrevTryTerminatedBlock = TryTerminatedBlock;
3219f4a2713aSLionel Sambuc 
3220f4a2713aSLionel Sambuc   // Create a new block that will contain the try statement.
3221f4a2713aSLionel Sambuc   CFGBlock *NewTryTerminatedBlock = createBlock(false);
3222f4a2713aSLionel Sambuc   // Add the terminator in the try block.
3223f4a2713aSLionel Sambuc   NewTryTerminatedBlock->setTerminator(Terminator);
3224f4a2713aSLionel Sambuc 
3225f4a2713aSLionel Sambuc   bool HasCatchAll = false;
3226f4a2713aSLionel Sambuc   for (unsigned h = 0; h <Terminator->getNumHandlers(); ++h) {
3227f4a2713aSLionel Sambuc     // The code after the try is the implicit successor.
3228f4a2713aSLionel Sambuc     Succ = TrySuccessor;
3229f4a2713aSLionel Sambuc     CXXCatchStmt *CS = Terminator->getHandler(h);
3230*0a6a1f1dSLionel Sambuc     if (CS->getExceptionDecl() == nullptr) {
3231f4a2713aSLionel Sambuc       HasCatchAll = true;
3232f4a2713aSLionel Sambuc     }
3233*0a6a1f1dSLionel Sambuc     Block = nullptr;
3234f4a2713aSLionel Sambuc     CFGBlock *CatchBlock = VisitCXXCatchStmt(CS);
3235*0a6a1f1dSLionel Sambuc     if (!CatchBlock)
3236*0a6a1f1dSLionel Sambuc       return nullptr;
3237f4a2713aSLionel Sambuc     // Add this block to the list of successors for the block with the try
3238f4a2713aSLionel Sambuc     // statement.
3239f4a2713aSLionel Sambuc     addSuccessor(NewTryTerminatedBlock, CatchBlock);
3240f4a2713aSLionel Sambuc   }
3241f4a2713aSLionel Sambuc   if (!HasCatchAll) {
3242f4a2713aSLionel Sambuc     if (PrevTryTerminatedBlock)
3243f4a2713aSLionel Sambuc       addSuccessor(NewTryTerminatedBlock, PrevTryTerminatedBlock);
3244f4a2713aSLionel Sambuc     else
3245f4a2713aSLionel Sambuc       addSuccessor(NewTryTerminatedBlock, &cfg->getExit());
3246f4a2713aSLionel Sambuc   }
3247f4a2713aSLionel Sambuc 
3248f4a2713aSLionel Sambuc   // The code after the try is the implicit successor.
3249f4a2713aSLionel Sambuc   Succ = TrySuccessor;
3250f4a2713aSLionel Sambuc 
3251f4a2713aSLionel Sambuc   // Save the current "try" context.
3252f4a2713aSLionel Sambuc   SaveAndRestore<CFGBlock*> save_try(TryTerminatedBlock, NewTryTerminatedBlock);
3253f4a2713aSLionel Sambuc   cfg->addTryDispatchBlock(TryTerminatedBlock);
3254f4a2713aSLionel Sambuc 
3255f4a2713aSLionel Sambuc   assert(Terminator->getTryBlock() && "try must contain a non-NULL body");
3256*0a6a1f1dSLionel Sambuc   Block = nullptr;
3257f4a2713aSLionel Sambuc   return addStmt(Terminator->getTryBlock());
3258f4a2713aSLionel Sambuc }
3259f4a2713aSLionel Sambuc 
VisitCXXCatchStmt(CXXCatchStmt * CS)3260f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitCXXCatchStmt(CXXCatchStmt *CS) {
3261f4a2713aSLionel Sambuc   // CXXCatchStmt are treated like labels, so they are the first statement in a
3262f4a2713aSLionel Sambuc   // block.
3263f4a2713aSLionel Sambuc 
3264f4a2713aSLionel Sambuc   // Save local scope position because in case of exception variable ScopePos
3265f4a2713aSLionel Sambuc   // won't be restored when traversing AST.
3266f4a2713aSLionel Sambuc   SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
3267f4a2713aSLionel Sambuc 
3268f4a2713aSLionel Sambuc   // Create local scope for possible exception variable.
3269f4a2713aSLionel Sambuc   // Store scope position. Add implicit destructor.
3270f4a2713aSLionel Sambuc   if (VarDecl *VD = CS->getExceptionDecl()) {
3271f4a2713aSLionel Sambuc     LocalScope::const_iterator BeginScopePos = ScopePos;
3272f4a2713aSLionel Sambuc     addLocalScopeForVarDecl(VD);
3273f4a2713aSLionel Sambuc     addAutomaticObjDtors(ScopePos, BeginScopePos, CS);
3274f4a2713aSLionel Sambuc   }
3275f4a2713aSLionel Sambuc 
3276f4a2713aSLionel Sambuc   if (CS->getHandlerBlock())
3277f4a2713aSLionel Sambuc     addStmt(CS->getHandlerBlock());
3278f4a2713aSLionel Sambuc 
3279f4a2713aSLionel Sambuc   CFGBlock *CatchBlock = Block;
3280f4a2713aSLionel Sambuc   if (!CatchBlock)
3281f4a2713aSLionel Sambuc     CatchBlock = createBlock();
3282f4a2713aSLionel Sambuc 
3283f4a2713aSLionel Sambuc   // CXXCatchStmt is more than just a label.  They have semantic meaning
3284f4a2713aSLionel Sambuc   // as well, as they implicitly "initialize" the catch variable.  Add
3285f4a2713aSLionel Sambuc   // it to the CFG as a CFGElement so that the control-flow of these
3286f4a2713aSLionel Sambuc   // semantics gets captured.
3287f4a2713aSLionel Sambuc   appendStmt(CatchBlock, CS);
3288f4a2713aSLionel Sambuc 
3289f4a2713aSLionel Sambuc   // Also add the CXXCatchStmt as a label, to mirror handling of regular
3290f4a2713aSLionel Sambuc   // labels.
3291f4a2713aSLionel Sambuc   CatchBlock->setLabel(CS);
3292f4a2713aSLionel Sambuc 
3293f4a2713aSLionel Sambuc   // Bail out if the CFG is bad.
3294f4a2713aSLionel Sambuc   if (badCFG)
3295*0a6a1f1dSLionel Sambuc     return nullptr;
3296f4a2713aSLionel Sambuc 
3297f4a2713aSLionel Sambuc   // We set Block to NULL to allow lazy creation of a new block (if necessary)
3298*0a6a1f1dSLionel Sambuc   Block = nullptr;
3299f4a2713aSLionel Sambuc 
3300f4a2713aSLionel Sambuc   return CatchBlock;
3301f4a2713aSLionel Sambuc }
3302f4a2713aSLionel Sambuc 
VisitCXXForRangeStmt(CXXForRangeStmt * S)3303f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
3304f4a2713aSLionel Sambuc   // C++0x for-range statements are specified as [stmt.ranged]:
3305f4a2713aSLionel Sambuc   //
3306f4a2713aSLionel Sambuc   // {
3307f4a2713aSLionel Sambuc   //   auto && __range = range-init;
3308f4a2713aSLionel Sambuc   //   for ( auto __begin = begin-expr,
3309f4a2713aSLionel Sambuc   //         __end = end-expr;
3310f4a2713aSLionel Sambuc   //         __begin != __end;
3311f4a2713aSLionel Sambuc   //         ++__begin ) {
3312f4a2713aSLionel Sambuc   //     for-range-declaration = *__begin;
3313f4a2713aSLionel Sambuc   //     statement
3314f4a2713aSLionel Sambuc   //   }
3315f4a2713aSLionel Sambuc   // }
3316f4a2713aSLionel Sambuc 
3317f4a2713aSLionel Sambuc   // Save local scope position before the addition of the implicit variables.
3318f4a2713aSLionel Sambuc   SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
3319f4a2713aSLionel Sambuc 
3320f4a2713aSLionel Sambuc   // Create local scopes and destructors for range, begin and end variables.
3321f4a2713aSLionel Sambuc   if (Stmt *Range = S->getRangeStmt())
3322f4a2713aSLionel Sambuc     addLocalScopeForStmt(Range);
3323f4a2713aSLionel Sambuc   if (Stmt *BeginEnd = S->getBeginEndStmt())
3324f4a2713aSLionel Sambuc     addLocalScopeForStmt(BeginEnd);
3325f4a2713aSLionel Sambuc   addAutomaticObjDtors(ScopePos, save_scope_pos.get(), S);
3326f4a2713aSLionel Sambuc 
3327f4a2713aSLionel Sambuc   LocalScope::const_iterator ContinueScopePos = ScopePos;
3328f4a2713aSLionel Sambuc 
3329f4a2713aSLionel Sambuc   // "for" is a control-flow statement.  Thus we stop processing the current
3330f4a2713aSLionel Sambuc   // block.
3331*0a6a1f1dSLionel Sambuc   CFGBlock *LoopSuccessor = nullptr;
3332f4a2713aSLionel Sambuc   if (Block) {
3333f4a2713aSLionel Sambuc     if (badCFG)
3334*0a6a1f1dSLionel Sambuc       return nullptr;
3335f4a2713aSLionel Sambuc     LoopSuccessor = Block;
3336f4a2713aSLionel Sambuc   } else
3337f4a2713aSLionel Sambuc     LoopSuccessor = Succ;
3338f4a2713aSLionel Sambuc 
3339f4a2713aSLionel Sambuc   // Save the current value for the break targets.
3340f4a2713aSLionel Sambuc   // All breaks should go to the code following the loop.
3341f4a2713aSLionel Sambuc   SaveAndRestore<JumpTarget> save_break(BreakJumpTarget);
3342f4a2713aSLionel Sambuc   BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
3343f4a2713aSLionel Sambuc 
3344f4a2713aSLionel Sambuc   // The block for the __begin != __end expression.
3345f4a2713aSLionel Sambuc   CFGBlock *ConditionBlock = createBlock(false);
3346f4a2713aSLionel Sambuc   ConditionBlock->setTerminator(S);
3347f4a2713aSLionel Sambuc 
3348f4a2713aSLionel Sambuc   // Now add the actual condition to the condition block.
3349f4a2713aSLionel Sambuc   if (Expr *C = S->getCond()) {
3350f4a2713aSLionel Sambuc     Block = ConditionBlock;
3351f4a2713aSLionel Sambuc     CFGBlock *BeginConditionBlock = addStmt(C);
3352f4a2713aSLionel Sambuc     if (badCFG)
3353*0a6a1f1dSLionel Sambuc       return nullptr;
3354f4a2713aSLionel Sambuc     assert(BeginConditionBlock == ConditionBlock &&
3355f4a2713aSLionel Sambuc            "condition block in for-range was unexpectedly complex");
3356f4a2713aSLionel Sambuc     (void)BeginConditionBlock;
3357f4a2713aSLionel Sambuc   }
3358f4a2713aSLionel Sambuc 
3359f4a2713aSLionel Sambuc   // The condition block is the implicit successor for the loop body as well as
3360f4a2713aSLionel Sambuc   // any code above the loop.
3361f4a2713aSLionel Sambuc   Succ = ConditionBlock;
3362f4a2713aSLionel Sambuc 
3363f4a2713aSLionel Sambuc   // See if this is a known constant.
3364f4a2713aSLionel Sambuc   TryResult KnownVal(true);
3365f4a2713aSLionel Sambuc 
3366f4a2713aSLionel Sambuc   if (S->getCond())
3367f4a2713aSLionel Sambuc     KnownVal = tryEvaluateBool(S->getCond());
3368f4a2713aSLionel Sambuc 
3369f4a2713aSLionel Sambuc   // Now create the loop body.
3370f4a2713aSLionel Sambuc   {
3371f4a2713aSLionel Sambuc     assert(S->getBody());
3372f4a2713aSLionel Sambuc 
3373f4a2713aSLionel Sambuc     // Save the current values for Block, Succ, and continue targets.
3374f4a2713aSLionel Sambuc     SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ);
3375f4a2713aSLionel Sambuc     SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget);
3376f4a2713aSLionel Sambuc 
3377f4a2713aSLionel Sambuc     // Generate increment code in its own basic block.  This is the target of
3378f4a2713aSLionel Sambuc     // continue statements.
3379*0a6a1f1dSLionel Sambuc     Block = nullptr;
3380f4a2713aSLionel Sambuc     Succ = addStmt(S->getInc());
3381f4a2713aSLionel Sambuc     ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos);
3382f4a2713aSLionel Sambuc 
3383f4a2713aSLionel Sambuc     // The starting block for the loop increment is the block that should
3384f4a2713aSLionel Sambuc     // represent the 'loop target' for looping back to the start of the loop.
3385f4a2713aSLionel Sambuc     ContinueJumpTarget.block->setLoopTarget(S);
3386f4a2713aSLionel Sambuc 
3387f4a2713aSLionel Sambuc     // Finish up the increment block and prepare to start the loop body.
3388f4a2713aSLionel Sambuc     assert(Block);
3389f4a2713aSLionel Sambuc     if (badCFG)
3390*0a6a1f1dSLionel Sambuc       return nullptr;
3391*0a6a1f1dSLionel Sambuc     Block = nullptr;
3392f4a2713aSLionel Sambuc 
3393f4a2713aSLionel Sambuc     // Add implicit scope and dtors for loop variable.
3394f4a2713aSLionel Sambuc     addLocalScopeAndDtors(S->getLoopVarStmt());
3395f4a2713aSLionel Sambuc 
3396f4a2713aSLionel Sambuc     // Populate a new block to contain the loop body and loop variable.
3397f4a2713aSLionel Sambuc     addStmt(S->getBody());
3398f4a2713aSLionel Sambuc     if (badCFG)
3399*0a6a1f1dSLionel Sambuc       return nullptr;
3400f4a2713aSLionel Sambuc     CFGBlock *LoopVarStmtBlock = addStmt(S->getLoopVarStmt());
3401f4a2713aSLionel Sambuc     if (badCFG)
3402*0a6a1f1dSLionel Sambuc       return nullptr;
3403f4a2713aSLionel Sambuc 
3404f4a2713aSLionel Sambuc     // This new body block is a successor to our condition block.
3405*0a6a1f1dSLionel Sambuc     addSuccessor(ConditionBlock,
3406*0a6a1f1dSLionel Sambuc                  KnownVal.isFalse() ? nullptr : LoopVarStmtBlock);
3407f4a2713aSLionel Sambuc   }
3408f4a2713aSLionel Sambuc 
3409f4a2713aSLionel Sambuc   // Link up the condition block with the code that follows the loop (the
3410f4a2713aSLionel Sambuc   // false branch).
3411*0a6a1f1dSLionel Sambuc   addSuccessor(ConditionBlock, KnownVal.isTrue() ? nullptr : LoopSuccessor);
3412f4a2713aSLionel Sambuc 
3413f4a2713aSLionel Sambuc   // Add the initialization statements.
3414f4a2713aSLionel Sambuc   Block = createBlock();
3415f4a2713aSLionel Sambuc   addStmt(S->getBeginEndStmt());
3416f4a2713aSLionel Sambuc   return addStmt(S->getRangeStmt());
3417f4a2713aSLionel Sambuc }
3418f4a2713aSLionel Sambuc 
VisitExprWithCleanups(ExprWithCleanups * E,AddStmtChoice asc)3419f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitExprWithCleanups(ExprWithCleanups *E,
3420f4a2713aSLionel Sambuc     AddStmtChoice asc) {
3421f4a2713aSLionel Sambuc   if (BuildOpts.AddTemporaryDtors) {
3422f4a2713aSLionel Sambuc     // If adding implicit destructors visit the full expression for adding
3423f4a2713aSLionel Sambuc     // destructors of temporaries.
3424*0a6a1f1dSLionel Sambuc     TempDtorContext Context;
3425*0a6a1f1dSLionel Sambuc     VisitForTemporaryDtors(E->getSubExpr(), false, Context);
3426f4a2713aSLionel Sambuc 
3427f4a2713aSLionel Sambuc     // Full expression has to be added as CFGStmt so it will be sequenced
3428f4a2713aSLionel Sambuc     // before destructors of it's temporaries.
3429f4a2713aSLionel Sambuc     asc = asc.withAlwaysAdd(true);
3430f4a2713aSLionel Sambuc   }
3431f4a2713aSLionel Sambuc   return Visit(E->getSubExpr(), asc);
3432f4a2713aSLionel Sambuc }
3433f4a2713aSLionel Sambuc 
VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr * E,AddStmtChoice asc)3434f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E,
3435f4a2713aSLionel Sambuc                                                 AddStmtChoice asc) {
3436f4a2713aSLionel Sambuc   if (asc.alwaysAdd(*this, E)) {
3437f4a2713aSLionel Sambuc     autoCreateBlock();
3438f4a2713aSLionel Sambuc     appendStmt(Block, E);
3439f4a2713aSLionel Sambuc 
3440f4a2713aSLionel Sambuc     // We do not want to propagate the AlwaysAdd property.
3441f4a2713aSLionel Sambuc     asc = asc.withAlwaysAdd(false);
3442f4a2713aSLionel Sambuc   }
3443f4a2713aSLionel Sambuc   return Visit(E->getSubExpr(), asc);
3444f4a2713aSLionel Sambuc }
3445f4a2713aSLionel Sambuc 
VisitCXXConstructExpr(CXXConstructExpr * C,AddStmtChoice asc)3446f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitCXXConstructExpr(CXXConstructExpr *C,
3447f4a2713aSLionel Sambuc                                             AddStmtChoice asc) {
3448f4a2713aSLionel Sambuc   autoCreateBlock();
3449f4a2713aSLionel Sambuc   appendStmt(Block, C);
3450f4a2713aSLionel Sambuc 
3451f4a2713aSLionel Sambuc   return VisitChildren(C);
3452f4a2713aSLionel Sambuc }
3453f4a2713aSLionel Sambuc 
VisitCXXNewExpr(CXXNewExpr * NE,AddStmtChoice asc)3454*0a6a1f1dSLionel Sambuc CFGBlock *CFGBuilder::VisitCXXNewExpr(CXXNewExpr *NE,
3455*0a6a1f1dSLionel Sambuc                                       AddStmtChoice asc) {
3456*0a6a1f1dSLionel Sambuc 
3457*0a6a1f1dSLionel Sambuc   autoCreateBlock();
3458*0a6a1f1dSLionel Sambuc   appendStmt(Block, NE);
3459*0a6a1f1dSLionel Sambuc 
3460*0a6a1f1dSLionel Sambuc   if (NE->getInitializer())
3461*0a6a1f1dSLionel Sambuc     Block = Visit(NE->getInitializer());
3462*0a6a1f1dSLionel Sambuc   if (BuildOpts.AddCXXNewAllocator)
3463*0a6a1f1dSLionel Sambuc     appendNewAllocator(Block, NE);
3464*0a6a1f1dSLionel Sambuc   if (NE->isArray())
3465*0a6a1f1dSLionel Sambuc     Block = Visit(NE->getArraySize());
3466*0a6a1f1dSLionel Sambuc   for (CXXNewExpr::arg_iterator I = NE->placement_arg_begin(),
3467*0a6a1f1dSLionel Sambuc        E = NE->placement_arg_end(); I != E; ++I)
3468*0a6a1f1dSLionel Sambuc     Block = Visit(*I);
3469*0a6a1f1dSLionel Sambuc   return Block;
3470*0a6a1f1dSLionel Sambuc }
3471f4a2713aSLionel Sambuc 
VisitCXXDeleteExpr(CXXDeleteExpr * DE,AddStmtChoice asc)3472f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitCXXDeleteExpr(CXXDeleteExpr *DE,
3473f4a2713aSLionel Sambuc                                          AddStmtChoice asc) {
3474f4a2713aSLionel Sambuc   autoCreateBlock();
3475f4a2713aSLionel Sambuc   appendStmt(Block, DE);
3476f4a2713aSLionel Sambuc   QualType DTy = DE->getDestroyedType();
3477f4a2713aSLionel Sambuc   DTy = DTy.getNonReferenceType();
3478f4a2713aSLionel Sambuc   CXXRecordDecl *RD = Context->getBaseElementType(DTy)->getAsCXXRecordDecl();
3479f4a2713aSLionel Sambuc   if (RD) {
3480f4a2713aSLionel Sambuc     if (RD->isCompleteDefinition() && !RD->hasTrivialDestructor())
3481f4a2713aSLionel Sambuc       appendDeleteDtor(Block, RD, DE);
3482f4a2713aSLionel Sambuc   }
3483f4a2713aSLionel Sambuc 
3484f4a2713aSLionel Sambuc   return VisitChildren(DE);
3485f4a2713aSLionel Sambuc }
3486f4a2713aSLionel Sambuc 
VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr * E,AddStmtChoice asc)3487f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E,
3488f4a2713aSLionel Sambuc                                                  AddStmtChoice asc) {
3489f4a2713aSLionel Sambuc   if (asc.alwaysAdd(*this, E)) {
3490f4a2713aSLionel Sambuc     autoCreateBlock();
3491f4a2713aSLionel Sambuc     appendStmt(Block, E);
3492f4a2713aSLionel Sambuc     // We do not want to propagate the AlwaysAdd property.
3493f4a2713aSLionel Sambuc     asc = asc.withAlwaysAdd(false);
3494f4a2713aSLionel Sambuc   }
3495f4a2713aSLionel Sambuc   return Visit(E->getSubExpr(), asc);
3496f4a2713aSLionel Sambuc }
3497f4a2713aSLionel Sambuc 
VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr * C,AddStmtChoice asc)3498f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C,
3499f4a2713aSLionel Sambuc                                                   AddStmtChoice asc) {
3500f4a2713aSLionel Sambuc   autoCreateBlock();
3501f4a2713aSLionel Sambuc   appendStmt(Block, C);
3502f4a2713aSLionel Sambuc   return VisitChildren(C);
3503f4a2713aSLionel Sambuc }
3504f4a2713aSLionel Sambuc 
VisitImplicitCastExpr(ImplicitCastExpr * E,AddStmtChoice asc)3505f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitImplicitCastExpr(ImplicitCastExpr *E,
3506f4a2713aSLionel Sambuc                                             AddStmtChoice asc) {
3507f4a2713aSLionel Sambuc   if (asc.alwaysAdd(*this, E)) {
3508f4a2713aSLionel Sambuc     autoCreateBlock();
3509f4a2713aSLionel Sambuc     appendStmt(Block, E);
3510f4a2713aSLionel Sambuc   }
3511f4a2713aSLionel Sambuc   return Visit(E->getSubExpr(), AddStmtChoice());
3512f4a2713aSLionel Sambuc }
3513f4a2713aSLionel Sambuc 
VisitIndirectGotoStmt(IndirectGotoStmt * I)3514f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt *I) {
3515f4a2713aSLionel Sambuc   // Lazily create the indirect-goto dispatch block if there isn't one already.
3516f4a2713aSLionel Sambuc   CFGBlock *IBlock = cfg->getIndirectGotoBlock();
3517f4a2713aSLionel Sambuc 
3518f4a2713aSLionel Sambuc   if (!IBlock) {
3519f4a2713aSLionel Sambuc     IBlock = createBlock(false);
3520f4a2713aSLionel Sambuc     cfg->setIndirectGotoBlock(IBlock);
3521f4a2713aSLionel Sambuc   }
3522f4a2713aSLionel Sambuc 
3523f4a2713aSLionel Sambuc   // IndirectGoto is a control-flow statement.  Thus we stop processing the
3524f4a2713aSLionel Sambuc   // current block and create a new one.
3525f4a2713aSLionel Sambuc   if (badCFG)
3526*0a6a1f1dSLionel Sambuc     return nullptr;
3527f4a2713aSLionel Sambuc 
3528f4a2713aSLionel Sambuc   Block = createBlock(false);
3529f4a2713aSLionel Sambuc   Block->setTerminator(I);
3530f4a2713aSLionel Sambuc   addSuccessor(Block, IBlock);
3531f4a2713aSLionel Sambuc   return addStmt(I->getTarget());
3532f4a2713aSLionel Sambuc }
3533f4a2713aSLionel Sambuc 
VisitForTemporaryDtors(Stmt * E,bool BindToTemporary,TempDtorContext & Context)3534*0a6a1f1dSLionel Sambuc CFGBlock *CFGBuilder::VisitForTemporaryDtors(Stmt *E, bool BindToTemporary,
3535*0a6a1f1dSLionel Sambuc                                              TempDtorContext &Context) {
3536f4a2713aSLionel Sambuc   assert(BuildOpts.AddImplicitDtors && BuildOpts.AddTemporaryDtors);
3537f4a2713aSLionel Sambuc 
3538f4a2713aSLionel Sambuc tryAgain:
3539f4a2713aSLionel Sambuc   if (!E) {
3540f4a2713aSLionel Sambuc     badCFG = true;
3541*0a6a1f1dSLionel Sambuc     return nullptr;
3542f4a2713aSLionel Sambuc   }
3543f4a2713aSLionel Sambuc   switch (E->getStmtClass()) {
3544f4a2713aSLionel Sambuc     default:
3545*0a6a1f1dSLionel Sambuc       return VisitChildrenForTemporaryDtors(E, Context);
3546f4a2713aSLionel Sambuc 
3547f4a2713aSLionel Sambuc     case Stmt::BinaryOperatorClass:
3548*0a6a1f1dSLionel Sambuc       return VisitBinaryOperatorForTemporaryDtors(cast<BinaryOperator>(E),
3549*0a6a1f1dSLionel Sambuc                                                   Context);
3550f4a2713aSLionel Sambuc 
3551f4a2713aSLionel Sambuc     case Stmt::CXXBindTemporaryExprClass:
3552f4a2713aSLionel Sambuc       return VisitCXXBindTemporaryExprForTemporaryDtors(
3553*0a6a1f1dSLionel Sambuc           cast<CXXBindTemporaryExpr>(E), BindToTemporary, Context);
3554f4a2713aSLionel Sambuc 
3555f4a2713aSLionel Sambuc     case Stmt::BinaryConditionalOperatorClass:
3556f4a2713aSLionel Sambuc     case Stmt::ConditionalOperatorClass:
3557f4a2713aSLionel Sambuc       return VisitConditionalOperatorForTemporaryDtors(
3558*0a6a1f1dSLionel Sambuc           cast<AbstractConditionalOperator>(E), BindToTemporary, Context);
3559f4a2713aSLionel Sambuc 
3560f4a2713aSLionel Sambuc     case Stmt::ImplicitCastExprClass:
3561f4a2713aSLionel Sambuc       // For implicit cast we want BindToTemporary to be passed further.
3562f4a2713aSLionel Sambuc       E = cast<CastExpr>(E)->getSubExpr();
3563f4a2713aSLionel Sambuc       goto tryAgain;
3564f4a2713aSLionel Sambuc 
3565*0a6a1f1dSLionel Sambuc     case Stmt::CXXFunctionalCastExprClass:
3566*0a6a1f1dSLionel Sambuc       // For functional cast we want BindToTemporary to be passed further.
3567*0a6a1f1dSLionel Sambuc       E = cast<CXXFunctionalCastExpr>(E)->getSubExpr();
3568*0a6a1f1dSLionel Sambuc       goto tryAgain;
3569*0a6a1f1dSLionel Sambuc 
3570f4a2713aSLionel Sambuc     case Stmt::ParenExprClass:
3571f4a2713aSLionel Sambuc       E = cast<ParenExpr>(E)->getSubExpr();
3572f4a2713aSLionel Sambuc       goto tryAgain;
3573f4a2713aSLionel Sambuc 
3574*0a6a1f1dSLionel Sambuc     case Stmt::MaterializeTemporaryExprClass: {
3575*0a6a1f1dSLionel Sambuc       const MaterializeTemporaryExpr* MTE = cast<MaterializeTemporaryExpr>(E);
3576*0a6a1f1dSLionel Sambuc       BindToTemporary = (MTE->getStorageDuration() != SD_FullExpression);
3577*0a6a1f1dSLionel Sambuc       SmallVector<const Expr *, 2> CommaLHSs;
3578*0a6a1f1dSLionel Sambuc       SmallVector<SubobjectAdjustment, 2> Adjustments;
3579*0a6a1f1dSLionel Sambuc       // Find the expression whose lifetime needs to be extended.
3580*0a6a1f1dSLionel Sambuc       E = const_cast<Expr *>(
3581*0a6a1f1dSLionel Sambuc           cast<MaterializeTemporaryExpr>(E)
3582*0a6a1f1dSLionel Sambuc               ->GetTemporaryExpr()
3583*0a6a1f1dSLionel Sambuc               ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments));
3584*0a6a1f1dSLionel Sambuc       // Visit the skipped comma operator left-hand sides for other temporaries.
3585*0a6a1f1dSLionel Sambuc       for (const Expr *CommaLHS : CommaLHSs) {
3586*0a6a1f1dSLionel Sambuc         VisitForTemporaryDtors(const_cast<Expr *>(CommaLHS),
3587*0a6a1f1dSLionel Sambuc                                /*BindToTemporary=*/false, Context);
3588*0a6a1f1dSLionel Sambuc       }
3589*0a6a1f1dSLionel Sambuc       goto tryAgain;
3590*0a6a1f1dSLionel Sambuc     }
3591*0a6a1f1dSLionel Sambuc 
3592*0a6a1f1dSLionel Sambuc     case Stmt::BlockExprClass:
3593*0a6a1f1dSLionel Sambuc       // Don't recurse into blocks; their subexpressions don't get evaluated
3594*0a6a1f1dSLionel Sambuc       // here.
3595*0a6a1f1dSLionel Sambuc       return Block;
3596*0a6a1f1dSLionel Sambuc 
3597*0a6a1f1dSLionel Sambuc     case Stmt::LambdaExprClass: {
3598*0a6a1f1dSLionel Sambuc       // For lambda expressions, only recurse into the capture initializers,
3599*0a6a1f1dSLionel Sambuc       // and not the body.
3600*0a6a1f1dSLionel Sambuc       auto *LE = cast<LambdaExpr>(E);
3601*0a6a1f1dSLionel Sambuc       CFGBlock *B = Block;
3602*0a6a1f1dSLionel Sambuc       for (Expr *Init : LE->capture_inits()) {
3603*0a6a1f1dSLionel Sambuc         if (CFGBlock *R = VisitForTemporaryDtors(
3604*0a6a1f1dSLionel Sambuc                 Init, /*BindToTemporary=*/false, Context))
3605*0a6a1f1dSLionel Sambuc           B = R;
3606*0a6a1f1dSLionel Sambuc       }
3607*0a6a1f1dSLionel Sambuc       return B;
3608*0a6a1f1dSLionel Sambuc     }
3609*0a6a1f1dSLionel Sambuc 
3610*0a6a1f1dSLionel Sambuc     case Stmt::CXXDefaultArgExprClass:
3611*0a6a1f1dSLionel Sambuc       E = cast<CXXDefaultArgExpr>(E)->getExpr();
3612*0a6a1f1dSLionel Sambuc       goto tryAgain;
3613*0a6a1f1dSLionel Sambuc 
3614*0a6a1f1dSLionel Sambuc     case Stmt::CXXDefaultInitExprClass:
3615*0a6a1f1dSLionel Sambuc       E = cast<CXXDefaultInitExpr>(E)->getExpr();
3616f4a2713aSLionel Sambuc       goto tryAgain;
3617f4a2713aSLionel Sambuc   }
3618f4a2713aSLionel Sambuc }
3619f4a2713aSLionel Sambuc 
VisitChildrenForTemporaryDtors(Stmt * E,TempDtorContext & Context)3620*0a6a1f1dSLionel Sambuc CFGBlock *CFGBuilder::VisitChildrenForTemporaryDtors(Stmt *E,
3621*0a6a1f1dSLionel Sambuc                                                      TempDtorContext &Context) {
3622*0a6a1f1dSLionel Sambuc   if (isa<LambdaExpr>(E)) {
3623*0a6a1f1dSLionel Sambuc     // Do not visit the children of lambdas; they have their own CFGs.
3624*0a6a1f1dSLionel Sambuc     return Block;
3625*0a6a1f1dSLionel Sambuc   }
3626*0a6a1f1dSLionel Sambuc 
3627f4a2713aSLionel Sambuc   // When visiting children for destructors we want to visit them in reverse
3628f4a2713aSLionel Sambuc   // order that they will appear in the CFG.  Because the CFG is built
3629f4a2713aSLionel Sambuc   // bottom-up, this means we visit them in their natural order, which
3630f4a2713aSLionel Sambuc   // reverses them in the CFG.
3631f4a2713aSLionel Sambuc   CFGBlock *B = Block;
3632f4a2713aSLionel Sambuc   for (Stmt::child_range I = E->children(); I; ++I) {
3633f4a2713aSLionel Sambuc     if (Stmt *Child = *I)
3634*0a6a1f1dSLionel Sambuc       if (CFGBlock *R = VisitForTemporaryDtors(Child, false, Context))
3635f4a2713aSLionel Sambuc         B = R;
3636f4a2713aSLionel Sambuc   }
3637f4a2713aSLionel Sambuc   return B;
3638f4a2713aSLionel Sambuc }
3639f4a2713aSLionel Sambuc 
VisitBinaryOperatorForTemporaryDtors(BinaryOperator * E,TempDtorContext & Context)3640*0a6a1f1dSLionel Sambuc CFGBlock *CFGBuilder::VisitBinaryOperatorForTemporaryDtors(
3641*0a6a1f1dSLionel Sambuc     BinaryOperator *E, TempDtorContext &Context) {
3642f4a2713aSLionel Sambuc   if (E->isLogicalOp()) {
3643*0a6a1f1dSLionel Sambuc     VisitForTemporaryDtors(E->getLHS(), false, Context);
3644*0a6a1f1dSLionel Sambuc     TryResult RHSExecuted = tryEvaluateBool(E->getLHS());
3645*0a6a1f1dSLionel Sambuc     if (RHSExecuted.isKnown() && E->getOpcode() == BO_LOr)
3646*0a6a1f1dSLionel Sambuc       RHSExecuted.negate();
3647f4a2713aSLionel Sambuc 
3648*0a6a1f1dSLionel Sambuc     // We do not know at CFG-construction time whether the right-hand-side was
3649*0a6a1f1dSLionel Sambuc     // executed, thus we add a branch node that depends on the temporary
3650*0a6a1f1dSLionel Sambuc     // constructor call.
3651*0a6a1f1dSLionel Sambuc     TempDtorContext RHSContext(
3652*0a6a1f1dSLionel Sambuc         bothKnownTrue(Context.KnownExecuted, RHSExecuted));
3653*0a6a1f1dSLionel Sambuc     VisitForTemporaryDtors(E->getRHS(), false, RHSContext);
3654*0a6a1f1dSLionel Sambuc     InsertTempDtorDecisionBlock(RHSContext);
3655f4a2713aSLionel Sambuc 
3656*0a6a1f1dSLionel Sambuc     return Block;
3657f4a2713aSLionel Sambuc   }
3658f4a2713aSLionel Sambuc 
3659f4a2713aSLionel Sambuc   if (E->isAssignmentOp()) {
3660f4a2713aSLionel Sambuc     // For assignment operator (=) LHS expression is visited
3661f4a2713aSLionel Sambuc     // before RHS expression. For destructors visit them in reverse order.
3662*0a6a1f1dSLionel Sambuc     CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getRHS(), false, Context);
3663*0a6a1f1dSLionel Sambuc     CFGBlock *LHSBlock = VisitForTemporaryDtors(E->getLHS(), false, Context);
3664f4a2713aSLionel Sambuc     return LHSBlock ? LHSBlock : RHSBlock;
3665f4a2713aSLionel Sambuc   }
3666f4a2713aSLionel Sambuc 
3667f4a2713aSLionel Sambuc   // For any other binary operator RHS expression is visited before
3668f4a2713aSLionel Sambuc   // LHS expression (order of children). For destructors visit them in reverse
3669f4a2713aSLionel Sambuc   // order.
3670*0a6a1f1dSLionel Sambuc   CFGBlock *LHSBlock = VisitForTemporaryDtors(E->getLHS(), false, Context);
3671*0a6a1f1dSLionel Sambuc   CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getRHS(), false, Context);
3672f4a2713aSLionel Sambuc   return RHSBlock ? RHSBlock : LHSBlock;
3673f4a2713aSLionel Sambuc }
3674f4a2713aSLionel Sambuc 
VisitCXXBindTemporaryExprForTemporaryDtors(CXXBindTemporaryExpr * E,bool BindToTemporary,TempDtorContext & Context)3675f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitCXXBindTemporaryExprForTemporaryDtors(
3676*0a6a1f1dSLionel Sambuc     CXXBindTemporaryExpr *E, bool BindToTemporary, TempDtorContext &Context) {
3677f4a2713aSLionel Sambuc   // First add destructors for temporaries in subexpression.
3678*0a6a1f1dSLionel Sambuc   CFGBlock *B = VisitForTemporaryDtors(E->getSubExpr(), false, Context);
3679f4a2713aSLionel Sambuc   if (!BindToTemporary) {
3680f4a2713aSLionel Sambuc     // If lifetime of temporary is not prolonged (by assigning to constant
3681f4a2713aSLionel Sambuc     // reference) add destructor for it.
3682f4a2713aSLionel Sambuc 
3683f4a2713aSLionel Sambuc     const CXXDestructorDecl *Dtor = E->getTemporary()->getDestructor();
3684f4a2713aSLionel Sambuc 
3685*0a6a1f1dSLionel Sambuc     if (Dtor->isNoReturn()) {
3686*0a6a1f1dSLionel Sambuc       // If the destructor is marked as a no-return destructor, we need to
3687*0a6a1f1dSLionel Sambuc       // create a new block for the destructor which does not have as a
3688*0a6a1f1dSLionel Sambuc       // successor anything built thus far. Control won't flow out of this
3689*0a6a1f1dSLionel Sambuc       // block.
3690*0a6a1f1dSLionel Sambuc       if (B) Succ = B;
3691*0a6a1f1dSLionel Sambuc       Block = createNoReturnBlock();
3692*0a6a1f1dSLionel Sambuc     } else if (Context.needsTempDtorBranch()) {
3693*0a6a1f1dSLionel Sambuc       // If we need to introduce a branch, we add a new block that we will hook
3694*0a6a1f1dSLionel Sambuc       // up to a decision block later.
3695*0a6a1f1dSLionel Sambuc       if (B) Succ = B;
3696*0a6a1f1dSLionel Sambuc       Block = createBlock();
3697*0a6a1f1dSLionel Sambuc     } else {
3698*0a6a1f1dSLionel Sambuc       autoCreateBlock();
3699*0a6a1f1dSLionel Sambuc     }
3700*0a6a1f1dSLionel Sambuc     if (Context.needsTempDtorBranch()) {
3701*0a6a1f1dSLionel Sambuc       Context.setDecisionPoint(Succ, E);
3702*0a6a1f1dSLionel Sambuc     }
3703f4a2713aSLionel Sambuc     appendTemporaryDtor(Block, E);
3704*0a6a1f1dSLionel Sambuc 
3705f4a2713aSLionel Sambuc     B = Block;
3706f4a2713aSLionel Sambuc   }
3707f4a2713aSLionel Sambuc   return B;
3708f4a2713aSLionel Sambuc }
3709f4a2713aSLionel Sambuc 
InsertTempDtorDecisionBlock(const TempDtorContext & Context,CFGBlock * FalseSucc)3710*0a6a1f1dSLionel Sambuc void CFGBuilder::InsertTempDtorDecisionBlock(const TempDtorContext &Context,
3711*0a6a1f1dSLionel Sambuc                                              CFGBlock *FalseSucc) {
3712*0a6a1f1dSLionel Sambuc   if (!Context.TerminatorExpr) {
3713*0a6a1f1dSLionel Sambuc     // If no temporary was found, we do not need to insert a decision point.
3714*0a6a1f1dSLionel Sambuc     return;
3715*0a6a1f1dSLionel Sambuc   }
3716*0a6a1f1dSLionel Sambuc   assert(Context.TerminatorExpr);
3717*0a6a1f1dSLionel Sambuc   CFGBlock *Decision = createBlock(false);
3718*0a6a1f1dSLionel Sambuc   Decision->setTerminator(CFGTerminator(Context.TerminatorExpr, true));
3719*0a6a1f1dSLionel Sambuc   addSuccessor(Decision, Block, !Context.KnownExecuted.isFalse());
3720*0a6a1f1dSLionel Sambuc   addSuccessor(Decision, FalseSucc ? FalseSucc : Context.Succ,
3721*0a6a1f1dSLionel Sambuc                !Context.KnownExecuted.isTrue());
3722*0a6a1f1dSLionel Sambuc   Block = Decision;
3723*0a6a1f1dSLionel Sambuc }
3724*0a6a1f1dSLionel Sambuc 
VisitConditionalOperatorForTemporaryDtors(AbstractConditionalOperator * E,bool BindToTemporary,TempDtorContext & Context)3725f4a2713aSLionel Sambuc CFGBlock *CFGBuilder::VisitConditionalOperatorForTemporaryDtors(
3726*0a6a1f1dSLionel Sambuc     AbstractConditionalOperator *E, bool BindToTemporary,
3727*0a6a1f1dSLionel Sambuc     TempDtorContext &Context) {
3728*0a6a1f1dSLionel Sambuc   VisitForTemporaryDtors(E->getCond(), false, Context);
3729*0a6a1f1dSLionel Sambuc   CFGBlock *ConditionBlock = Block;
3730*0a6a1f1dSLionel Sambuc   CFGBlock *ConditionSucc = Succ;
3731*0a6a1f1dSLionel Sambuc   TryResult ConditionVal = tryEvaluateBool(E->getCond());
3732*0a6a1f1dSLionel Sambuc   TryResult NegatedVal = ConditionVal;
3733*0a6a1f1dSLionel Sambuc   if (NegatedVal.isKnown()) NegatedVal.negate();
3734f4a2713aSLionel Sambuc 
3735*0a6a1f1dSLionel Sambuc   TempDtorContext TrueContext(
3736*0a6a1f1dSLionel Sambuc       bothKnownTrue(Context.KnownExecuted, ConditionVal));
3737*0a6a1f1dSLionel Sambuc   VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary, TrueContext);
3738*0a6a1f1dSLionel Sambuc   CFGBlock *TrueBlock = Block;
3739f4a2713aSLionel Sambuc 
3740*0a6a1f1dSLionel Sambuc   Block = ConditionBlock;
3741*0a6a1f1dSLionel Sambuc   Succ = ConditionSucc;
3742*0a6a1f1dSLionel Sambuc   TempDtorContext FalseContext(
3743*0a6a1f1dSLionel Sambuc       bothKnownTrue(Context.KnownExecuted, NegatedVal));
3744*0a6a1f1dSLionel Sambuc   VisitForTemporaryDtors(E->getFalseExpr(), BindToTemporary, FalseContext);
3745f4a2713aSLionel Sambuc 
3746*0a6a1f1dSLionel Sambuc   if (TrueContext.TerminatorExpr && FalseContext.TerminatorExpr) {
3747*0a6a1f1dSLionel Sambuc     InsertTempDtorDecisionBlock(FalseContext, TrueBlock);
3748*0a6a1f1dSLionel Sambuc   } else if (TrueContext.TerminatorExpr) {
3749*0a6a1f1dSLionel Sambuc     Block = TrueBlock;
3750*0a6a1f1dSLionel Sambuc     InsertTempDtorDecisionBlock(TrueContext);
3751f4a2713aSLionel Sambuc   } else {
3752*0a6a1f1dSLionel Sambuc     InsertTempDtorDecisionBlock(FalseContext);
3753f4a2713aSLionel Sambuc   }
3754f4a2713aSLionel Sambuc   return Block;
3755f4a2713aSLionel Sambuc }
3756f4a2713aSLionel Sambuc 
3757f4a2713aSLionel Sambuc } // end anonymous namespace
3758f4a2713aSLionel Sambuc 
3759f4a2713aSLionel Sambuc /// createBlock - Constructs and adds a new CFGBlock to the CFG.  The block has
3760f4a2713aSLionel Sambuc ///  no successors or predecessors.  If this is the first block created in the
3761f4a2713aSLionel Sambuc ///  CFG, it is automatically set to be the Entry and Exit of the CFG.
createBlock()3762f4a2713aSLionel Sambuc CFGBlock *CFG::createBlock() {
3763f4a2713aSLionel Sambuc   bool first_block = begin() == end();
3764f4a2713aSLionel Sambuc 
3765f4a2713aSLionel Sambuc   // Create the block.
3766f4a2713aSLionel Sambuc   CFGBlock *Mem = getAllocator().Allocate<CFGBlock>();
3767f4a2713aSLionel Sambuc   new (Mem) CFGBlock(NumBlockIDs++, BlkBVC, this);
3768f4a2713aSLionel Sambuc   Blocks.push_back(Mem, BlkBVC);
3769f4a2713aSLionel Sambuc 
3770f4a2713aSLionel Sambuc   // If this is the first block, set it as the Entry and Exit.
3771f4a2713aSLionel Sambuc   if (first_block)
3772f4a2713aSLionel Sambuc     Entry = Exit = &back();
3773f4a2713aSLionel Sambuc 
3774f4a2713aSLionel Sambuc   // Return the block.
3775f4a2713aSLionel Sambuc   return &back();
3776f4a2713aSLionel Sambuc }
3777f4a2713aSLionel Sambuc 
3778*0a6a1f1dSLionel Sambuc /// buildCFG - Constructs a CFG from an AST.
buildCFG(const Decl * D,Stmt * Statement,ASTContext * C,const BuildOptions & BO)3779*0a6a1f1dSLionel Sambuc std::unique_ptr<CFG> CFG::buildCFG(const Decl *D, Stmt *Statement,
3780*0a6a1f1dSLionel Sambuc                                    ASTContext *C, const BuildOptions &BO) {
3781f4a2713aSLionel Sambuc   CFGBuilder Builder(C, BO);
3782f4a2713aSLionel Sambuc   return Builder.buildCFG(D, Statement);
3783f4a2713aSLionel Sambuc }
3784f4a2713aSLionel Sambuc 
3785f4a2713aSLionel Sambuc const CXXDestructorDecl *
getDestructorDecl(ASTContext & astContext) const3786f4a2713aSLionel Sambuc CFGImplicitDtor::getDestructorDecl(ASTContext &astContext) const {
3787f4a2713aSLionel Sambuc   switch (getKind()) {
3788f4a2713aSLionel Sambuc     case CFGElement::Statement:
3789f4a2713aSLionel Sambuc     case CFGElement::Initializer:
3790*0a6a1f1dSLionel Sambuc     case CFGElement::NewAllocator:
3791f4a2713aSLionel Sambuc       llvm_unreachable("getDestructorDecl should only be used with "
3792f4a2713aSLionel Sambuc                        "ImplicitDtors");
3793f4a2713aSLionel Sambuc     case CFGElement::AutomaticObjectDtor: {
3794f4a2713aSLionel Sambuc       const VarDecl *var = castAs<CFGAutomaticObjDtor>().getVarDecl();
3795f4a2713aSLionel Sambuc       QualType ty = var->getType();
3796f4a2713aSLionel Sambuc       ty = ty.getNonReferenceType();
3797f4a2713aSLionel Sambuc       while (const ArrayType *arrayType = astContext.getAsArrayType(ty)) {
3798f4a2713aSLionel Sambuc         ty = arrayType->getElementType();
3799f4a2713aSLionel Sambuc       }
3800f4a2713aSLionel Sambuc       const RecordType *recordType = ty->getAs<RecordType>();
3801f4a2713aSLionel Sambuc       const CXXRecordDecl *classDecl =
3802f4a2713aSLionel Sambuc       cast<CXXRecordDecl>(recordType->getDecl());
3803f4a2713aSLionel Sambuc       return classDecl->getDestructor();
3804f4a2713aSLionel Sambuc     }
3805f4a2713aSLionel Sambuc     case CFGElement::DeleteDtor: {
3806f4a2713aSLionel Sambuc       const CXXDeleteExpr *DE = castAs<CFGDeleteDtor>().getDeleteExpr();
3807f4a2713aSLionel Sambuc       QualType DTy = DE->getDestroyedType();
3808f4a2713aSLionel Sambuc       DTy = DTy.getNonReferenceType();
3809f4a2713aSLionel Sambuc       const CXXRecordDecl *classDecl =
3810f4a2713aSLionel Sambuc           astContext.getBaseElementType(DTy)->getAsCXXRecordDecl();
3811f4a2713aSLionel Sambuc       return classDecl->getDestructor();
3812f4a2713aSLionel Sambuc     }
3813f4a2713aSLionel Sambuc     case CFGElement::TemporaryDtor: {
3814f4a2713aSLionel Sambuc       const CXXBindTemporaryExpr *bindExpr =
3815f4a2713aSLionel Sambuc         castAs<CFGTemporaryDtor>().getBindTemporaryExpr();
3816f4a2713aSLionel Sambuc       const CXXTemporary *temp = bindExpr->getTemporary();
3817f4a2713aSLionel Sambuc       return temp->getDestructor();
3818f4a2713aSLionel Sambuc     }
3819f4a2713aSLionel Sambuc     case CFGElement::BaseDtor:
3820f4a2713aSLionel Sambuc     case CFGElement::MemberDtor:
3821f4a2713aSLionel Sambuc 
3822f4a2713aSLionel Sambuc       // Not yet supported.
3823*0a6a1f1dSLionel Sambuc       return nullptr;
3824f4a2713aSLionel Sambuc   }
3825f4a2713aSLionel Sambuc   llvm_unreachable("getKind() returned bogus value");
3826f4a2713aSLionel Sambuc }
3827f4a2713aSLionel Sambuc 
isNoReturn(ASTContext & astContext) const3828f4a2713aSLionel Sambuc bool CFGImplicitDtor::isNoReturn(ASTContext &astContext) const {
3829f4a2713aSLionel Sambuc   if (const CXXDestructorDecl *DD = getDestructorDecl(astContext))
3830f4a2713aSLionel Sambuc     return DD->isNoReturn();
3831f4a2713aSLionel Sambuc   return false;
3832f4a2713aSLionel Sambuc }
3833f4a2713aSLionel Sambuc 
3834f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3835*0a6a1f1dSLionel Sambuc // CFGBlock operations.
3836f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3837f4a2713aSLionel Sambuc 
AdjacentBlock(CFGBlock * B,bool IsReachable)3838*0a6a1f1dSLionel Sambuc CFGBlock::AdjacentBlock::AdjacentBlock(CFGBlock *B, bool IsReachable)
3839*0a6a1f1dSLionel Sambuc   : ReachableBlock(IsReachable ? B : nullptr),
3840*0a6a1f1dSLionel Sambuc     UnreachableBlock(!IsReachable ? B : nullptr,
3841*0a6a1f1dSLionel Sambuc                      B && IsReachable ? AB_Normal : AB_Unreachable) {}
3842*0a6a1f1dSLionel Sambuc 
AdjacentBlock(CFGBlock * B,CFGBlock * AlternateBlock)3843*0a6a1f1dSLionel Sambuc CFGBlock::AdjacentBlock::AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock)
3844*0a6a1f1dSLionel Sambuc   : ReachableBlock(B),
3845*0a6a1f1dSLionel Sambuc     UnreachableBlock(B == AlternateBlock ? nullptr : AlternateBlock,
3846*0a6a1f1dSLionel Sambuc                      B == AlternateBlock ? AB_Alternate : AB_Normal) {}
3847*0a6a1f1dSLionel Sambuc 
addSuccessor(AdjacentBlock Succ,BumpVectorContext & C)3848*0a6a1f1dSLionel Sambuc void CFGBlock::addSuccessor(AdjacentBlock Succ,
3849*0a6a1f1dSLionel Sambuc                             BumpVectorContext &C) {
3850*0a6a1f1dSLionel Sambuc   if (CFGBlock *B = Succ.getReachableBlock())
3851*0a6a1f1dSLionel Sambuc     B->Preds.push_back(AdjacentBlock(this, Succ.isReachable()), C);
3852*0a6a1f1dSLionel Sambuc 
3853*0a6a1f1dSLionel Sambuc   if (CFGBlock *UnreachableB = Succ.getPossiblyUnreachableBlock())
3854*0a6a1f1dSLionel Sambuc     UnreachableB->Preds.push_back(AdjacentBlock(this, false), C);
3855*0a6a1f1dSLionel Sambuc 
3856*0a6a1f1dSLionel Sambuc   Succs.push_back(Succ, C);
3857*0a6a1f1dSLionel Sambuc }
3858*0a6a1f1dSLionel Sambuc 
FilterEdge(const CFGBlock::FilterOptions & F,const CFGBlock * From,const CFGBlock * To)3859f4a2713aSLionel Sambuc bool CFGBlock::FilterEdge(const CFGBlock::FilterOptions &F,
3860f4a2713aSLionel Sambuc         const CFGBlock *From, const CFGBlock *To) {
3861f4a2713aSLionel Sambuc 
3862*0a6a1f1dSLionel Sambuc   if (F.IgnoreNullPredecessors && !From)
3863*0a6a1f1dSLionel Sambuc     return true;
3864*0a6a1f1dSLionel Sambuc 
3865*0a6a1f1dSLionel Sambuc   if (To && From && F.IgnoreDefaultsWithCoveredEnums) {
3866f4a2713aSLionel Sambuc     // If the 'To' has no label or is labeled but the label isn't a
3867f4a2713aSLionel Sambuc     // CaseStmt then filter this edge.
3868f4a2713aSLionel Sambuc     if (const SwitchStmt *S =
3869f4a2713aSLionel Sambuc         dyn_cast_or_null<SwitchStmt>(From->getTerminator().getStmt())) {
3870f4a2713aSLionel Sambuc       if (S->isAllEnumCasesCovered()) {
3871f4a2713aSLionel Sambuc         const Stmt *L = To->getLabel();
3872f4a2713aSLionel Sambuc         if (!L || !isa<CaseStmt>(L))
3873f4a2713aSLionel Sambuc           return true;
3874f4a2713aSLionel Sambuc       }
3875f4a2713aSLionel Sambuc     }
3876f4a2713aSLionel Sambuc   }
3877f4a2713aSLionel Sambuc 
3878f4a2713aSLionel Sambuc   return false;
3879f4a2713aSLionel Sambuc }
3880f4a2713aSLionel Sambuc 
3881f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3882f4a2713aSLionel Sambuc // CFG pretty printing
3883f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3884f4a2713aSLionel Sambuc 
3885f4a2713aSLionel Sambuc namespace {
3886f4a2713aSLionel Sambuc 
3887f4a2713aSLionel Sambuc class StmtPrinterHelper : public PrinterHelper  {
3888f4a2713aSLionel Sambuc   typedef llvm::DenseMap<const Stmt*,std::pair<unsigned,unsigned> > StmtMapTy;
3889f4a2713aSLionel Sambuc   typedef llvm::DenseMap<const Decl*,std::pair<unsigned,unsigned> > DeclMapTy;
3890f4a2713aSLionel Sambuc   StmtMapTy StmtMap;
3891f4a2713aSLionel Sambuc   DeclMapTy DeclMap;
3892f4a2713aSLionel Sambuc   signed currentBlock;
3893f4a2713aSLionel Sambuc   unsigned currStmt;
3894f4a2713aSLionel Sambuc   const LangOptions &LangOpts;
3895f4a2713aSLionel Sambuc public:
3896f4a2713aSLionel Sambuc 
StmtPrinterHelper(const CFG * cfg,const LangOptions & LO)3897f4a2713aSLionel Sambuc   StmtPrinterHelper(const CFG* cfg, const LangOptions &LO)
3898f4a2713aSLionel Sambuc     : currentBlock(0), currStmt(0), LangOpts(LO)
3899f4a2713aSLionel Sambuc   {
3900f4a2713aSLionel Sambuc     for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I ) {
3901f4a2713aSLionel Sambuc       unsigned j = 1;
3902f4a2713aSLionel Sambuc       for (CFGBlock::const_iterator BI = (*I)->begin(), BEnd = (*I)->end() ;
3903f4a2713aSLionel Sambuc            BI != BEnd; ++BI, ++j ) {
3904f4a2713aSLionel Sambuc         if (Optional<CFGStmt> SE = BI->getAs<CFGStmt>()) {
3905f4a2713aSLionel Sambuc           const Stmt *stmt= SE->getStmt();
3906f4a2713aSLionel Sambuc           std::pair<unsigned, unsigned> P((*I)->getBlockID(), j);
3907f4a2713aSLionel Sambuc           StmtMap[stmt] = P;
3908f4a2713aSLionel Sambuc 
3909f4a2713aSLionel Sambuc           switch (stmt->getStmtClass()) {
3910f4a2713aSLionel Sambuc             case Stmt::DeclStmtClass:
3911f4a2713aSLionel Sambuc                 DeclMap[cast<DeclStmt>(stmt)->getSingleDecl()] = P;
3912f4a2713aSLionel Sambuc                 break;
3913f4a2713aSLionel Sambuc             case Stmt::IfStmtClass: {
3914f4a2713aSLionel Sambuc               const VarDecl *var = cast<IfStmt>(stmt)->getConditionVariable();
3915f4a2713aSLionel Sambuc               if (var)
3916f4a2713aSLionel Sambuc                 DeclMap[var] = P;
3917f4a2713aSLionel Sambuc               break;
3918f4a2713aSLionel Sambuc             }
3919f4a2713aSLionel Sambuc             case Stmt::ForStmtClass: {
3920f4a2713aSLionel Sambuc               const VarDecl *var = cast<ForStmt>(stmt)->getConditionVariable();
3921f4a2713aSLionel Sambuc               if (var)
3922f4a2713aSLionel Sambuc                 DeclMap[var] = P;
3923f4a2713aSLionel Sambuc               break;
3924f4a2713aSLionel Sambuc             }
3925f4a2713aSLionel Sambuc             case Stmt::WhileStmtClass: {
3926f4a2713aSLionel Sambuc               const VarDecl *var =
3927f4a2713aSLionel Sambuc                 cast<WhileStmt>(stmt)->getConditionVariable();
3928f4a2713aSLionel Sambuc               if (var)
3929f4a2713aSLionel Sambuc                 DeclMap[var] = P;
3930f4a2713aSLionel Sambuc               break;
3931f4a2713aSLionel Sambuc             }
3932f4a2713aSLionel Sambuc             case Stmt::SwitchStmtClass: {
3933f4a2713aSLionel Sambuc               const VarDecl *var =
3934f4a2713aSLionel Sambuc                 cast<SwitchStmt>(stmt)->getConditionVariable();
3935f4a2713aSLionel Sambuc               if (var)
3936f4a2713aSLionel Sambuc                 DeclMap[var] = P;
3937f4a2713aSLionel Sambuc               break;
3938f4a2713aSLionel Sambuc             }
3939f4a2713aSLionel Sambuc             case Stmt::CXXCatchStmtClass: {
3940f4a2713aSLionel Sambuc               const VarDecl *var =
3941f4a2713aSLionel Sambuc                 cast<CXXCatchStmt>(stmt)->getExceptionDecl();
3942f4a2713aSLionel Sambuc               if (var)
3943f4a2713aSLionel Sambuc                 DeclMap[var] = P;
3944f4a2713aSLionel Sambuc               break;
3945f4a2713aSLionel Sambuc             }
3946f4a2713aSLionel Sambuc             default:
3947f4a2713aSLionel Sambuc               break;
3948f4a2713aSLionel Sambuc           }
3949f4a2713aSLionel Sambuc         }
3950f4a2713aSLionel Sambuc       }
3951f4a2713aSLionel Sambuc     }
3952f4a2713aSLionel Sambuc   }
3953f4a2713aSLionel Sambuc 
3954f4a2713aSLionel Sambuc 
~StmtPrinterHelper()3955f4a2713aSLionel Sambuc   virtual ~StmtPrinterHelper() {}
3956f4a2713aSLionel Sambuc 
getLangOpts() const3957f4a2713aSLionel Sambuc   const LangOptions &getLangOpts() const { return LangOpts; }
setBlockID(signed i)3958f4a2713aSLionel Sambuc   void setBlockID(signed i) { currentBlock = i; }
setStmtID(unsigned i)3959f4a2713aSLionel Sambuc   void setStmtID(unsigned i) { currStmt = i; }
3960f4a2713aSLionel Sambuc 
handledStmt(Stmt * S,raw_ostream & OS)3961*0a6a1f1dSLionel Sambuc   bool handledStmt(Stmt *S, raw_ostream &OS) override {
3962f4a2713aSLionel Sambuc     StmtMapTy::iterator I = StmtMap.find(S);
3963f4a2713aSLionel Sambuc 
3964f4a2713aSLionel Sambuc     if (I == StmtMap.end())
3965f4a2713aSLionel Sambuc       return false;
3966f4a2713aSLionel Sambuc 
3967f4a2713aSLionel Sambuc     if (currentBlock >= 0 && I->second.first == (unsigned) currentBlock
3968f4a2713aSLionel Sambuc                           && I->second.second == currStmt) {
3969f4a2713aSLionel Sambuc       return false;
3970f4a2713aSLionel Sambuc     }
3971f4a2713aSLionel Sambuc 
3972f4a2713aSLionel Sambuc     OS << "[B" << I->second.first << "." << I->second.second << "]";
3973f4a2713aSLionel Sambuc     return true;
3974f4a2713aSLionel Sambuc   }
3975f4a2713aSLionel Sambuc 
handleDecl(const Decl * D,raw_ostream & OS)3976f4a2713aSLionel Sambuc   bool handleDecl(const Decl *D, raw_ostream &OS) {
3977f4a2713aSLionel Sambuc     DeclMapTy::iterator I = DeclMap.find(D);
3978f4a2713aSLionel Sambuc 
3979f4a2713aSLionel Sambuc     if (I == DeclMap.end())
3980f4a2713aSLionel Sambuc       return false;
3981f4a2713aSLionel Sambuc 
3982f4a2713aSLionel Sambuc     if (currentBlock >= 0 && I->second.first == (unsigned) currentBlock
3983f4a2713aSLionel Sambuc                           && I->second.second == currStmt) {
3984f4a2713aSLionel Sambuc       return false;
3985f4a2713aSLionel Sambuc     }
3986f4a2713aSLionel Sambuc 
3987f4a2713aSLionel Sambuc     OS << "[B" << I->second.first << "." << I->second.second << "]";
3988f4a2713aSLionel Sambuc     return true;
3989f4a2713aSLionel Sambuc   }
3990f4a2713aSLionel Sambuc };
3991f4a2713aSLionel Sambuc } // end anonymous namespace
3992f4a2713aSLionel Sambuc 
3993f4a2713aSLionel Sambuc 
3994f4a2713aSLionel Sambuc namespace {
3995f4a2713aSLionel Sambuc class CFGBlockTerminatorPrint
3996f4a2713aSLionel Sambuc   : public StmtVisitor<CFGBlockTerminatorPrint,void> {
3997f4a2713aSLionel Sambuc 
3998f4a2713aSLionel Sambuc   raw_ostream &OS;
3999f4a2713aSLionel Sambuc   StmtPrinterHelper* Helper;
4000f4a2713aSLionel Sambuc   PrintingPolicy Policy;
4001f4a2713aSLionel Sambuc public:
CFGBlockTerminatorPrint(raw_ostream & os,StmtPrinterHelper * helper,const PrintingPolicy & Policy)4002f4a2713aSLionel Sambuc   CFGBlockTerminatorPrint(raw_ostream &os, StmtPrinterHelper* helper,
4003f4a2713aSLionel Sambuc                           const PrintingPolicy &Policy)
4004*0a6a1f1dSLionel Sambuc     : OS(os), Helper(helper), Policy(Policy) {
4005*0a6a1f1dSLionel Sambuc     this->Policy.IncludeNewlines = false;
4006*0a6a1f1dSLionel Sambuc   }
4007f4a2713aSLionel Sambuc 
VisitIfStmt(IfStmt * I)4008f4a2713aSLionel Sambuc   void VisitIfStmt(IfStmt *I) {
4009f4a2713aSLionel Sambuc     OS << "if ";
4010*0a6a1f1dSLionel Sambuc     if (Stmt *C = I->getCond())
4011*0a6a1f1dSLionel Sambuc       C->printPretty(OS, Helper, Policy);
4012f4a2713aSLionel Sambuc   }
4013f4a2713aSLionel Sambuc 
4014f4a2713aSLionel Sambuc   // Default case.
VisitStmt(Stmt * Terminator)4015f4a2713aSLionel Sambuc   void VisitStmt(Stmt *Terminator) {
4016f4a2713aSLionel Sambuc     Terminator->printPretty(OS, Helper, Policy);
4017f4a2713aSLionel Sambuc   }
4018f4a2713aSLionel Sambuc 
VisitDeclStmt(DeclStmt * DS)4019f4a2713aSLionel Sambuc   void VisitDeclStmt(DeclStmt *DS) {
4020f4a2713aSLionel Sambuc     VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
4021f4a2713aSLionel Sambuc     OS << "static init " << VD->getName();
4022f4a2713aSLionel Sambuc   }
4023f4a2713aSLionel Sambuc 
VisitForStmt(ForStmt * F)4024f4a2713aSLionel Sambuc   void VisitForStmt(ForStmt *F) {
4025f4a2713aSLionel Sambuc     OS << "for (" ;
4026f4a2713aSLionel Sambuc     if (F->getInit())
4027f4a2713aSLionel Sambuc       OS << "...";
4028f4a2713aSLionel Sambuc     OS << "; ";
4029f4a2713aSLionel Sambuc     if (Stmt *C = F->getCond())
4030f4a2713aSLionel Sambuc       C->printPretty(OS, Helper, Policy);
4031f4a2713aSLionel Sambuc     OS << "; ";
4032f4a2713aSLionel Sambuc     if (F->getInc())
4033f4a2713aSLionel Sambuc       OS << "...";
4034f4a2713aSLionel Sambuc     OS << ")";
4035f4a2713aSLionel Sambuc   }
4036f4a2713aSLionel Sambuc 
VisitWhileStmt(WhileStmt * W)4037f4a2713aSLionel Sambuc   void VisitWhileStmt(WhileStmt *W) {
4038f4a2713aSLionel Sambuc     OS << "while " ;
4039f4a2713aSLionel Sambuc     if (Stmt *C = W->getCond())
4040f4a2713aSLionel Sambuc       C->printPretty(OS, Helper, Policy);
4041f4a2713aSLionel Sambuc   }
4042f4a2713aSLionel Sambuc 
VisitDoStmt(DoStmt * D)4043f4a2713aSLionel Sambuc   void VisitDoStmt(DoStmt *D) {
4044f4a2713aSLionel Sambuc     OS << "do ... while ";
4045f4a2713aSLionel Sambuc     if (Stmt *C = D->getCond())
4046f4a2713aSLionel Sambuc       C->printPretty(OS, Helper, Policy);
4047f4a2713aSLionel Sambuc   }
4048f4a2713aSLionel Sambuc 
VisitSwitchStmt(SwitchStmt * Terminator)4049f4a2713aSLionel Sambuc   void VisitSwitchStmt(SwitchStmt *Terminator) {
4050f4a2713aSLionel Sambuc     OS << "switch ";
4051f4a2713aSLionel Sambuc     Terminator->getCond()->printPretty(OS, Helper, Policy);
4052f4a2713aSLionel Sambuc   }
4053f4a2713aSLionel Sambuc 
VisitCXXTryStmt(CXXTryStmt * CS)4054f4a2713aSLionel Sambuc   void VisitCXXTryStmt(CXXTryStmt *CS) {
4055f4a2713aSLionel Sambuc     OS << "try ...";
4056f4a2713aSLionel Sambuc   }
4057f4a2713aSLionel Sambuc 
VisitAbstractConditionalOperator(AbstractConditionalOperator * C)4058f4a2713aSLionel Sambuc   void VisitAbstractConditionalOperator(AbstractConditionalOperator* C) {
4059*0a6a1f1dSLionel Sambuc     if (Stmt *Cond = C->getCond())
4060*0a6a1f1dSLionel Sambuc       Cond->printPretty(OS, Helper, Policy);
4061f4a2713aSLionel Sambuc     OS << " ? ... : ...";
4062f4a2713aSLionel Sambuc   }
4063f4a2713aSLionel Sambuc 
VisitChooseExpr(ChooseExpr * C)4064f4a2713aSLionel Sambuc   void VisitChooseExpr(ChooseExpr *C) {
4065f4a2713aSLionel Sambuc     OS << "__builtin_choose_expr( ";
4066*0a6a1f1dSLionel Sambuc     if (Stmt *Cond = C->getCond())
4067*0a6a1f1dSLionel Sambuc       Cond->printPretty(OS, Helper, Policy);
4068f4a2713aSLionel Sambuc     OS << " )";
4069f4a2713aSLionel Sambuc   }
4070f4a2713aSLionel Sambuc 
VisitIndirectGotoStmt(IndirectGotoStmt * I)4071f4a2713aSLionel Sambuc   void VisitIndirectGotoStmt(IndirectGotoStmt *I) {
4072f4a2713aSLionel Sambuc     OS << "goto *";
4073*0a6a1f1dSLionel Sambuc     if (Stmt *T = I->getTarget())
4074*0a6a1f1dSLionel Sambuc       T->printPretty(OS, Helper, Policy);
4075f4a2713aSLionel Sambuc   }
4076f4a2713aSLionel Sambuc 
VisitBinaryOperator(BinaryOperator * B)4077f4a2713aSLionel Sambuc   void VisitBinaryOperator(BinaryOperator* B) {
4078f4a2713aSLionel Sambuc     if (!B->isLogicalOp()) {
4079f4a2713aSLionel Sambuc       VisitExpr(B);
4080f4a2713aSLionel Sambuc       return;
4081f4a2713aSLionel Sambuc     }
4082f4a2713aSLionel Sambuc 
4083*0a6a1f1dSLionel Sambuc     if (B->getLHS())
4084f4a2713aSLionel Sambuc       B->getLHS()->printPretty(OS, Helper, Policy);
4085f4a2713aSLionel Sambuc 
4086f4a2713aSLionel Sambuc     switch (B->getOpcode()) {
4087f4a2713aSLionel Sambuc       case BO_LOr:
4088f4a2713aSLionel Sambuc         OS << " || ...";
4089f4a2713aSLionel Sambuc         return;
4090f4a2713aSLionel Sambuc       case BO_LAnd:
4091f4a2713aSLionel Sambuc         OS << " && ...";
4092f4a2713aSLionel Sambuc         return;
4093f4a2713aSLionel Sambuc       default:
4094f4a2713aSLionel Sambuc         llvm_unreachable("Invalid logical operator.");
4095f4a2713aSLionel Sambuc     }
4096f4a2713aSLionel Sambuc   }
4097f4a2713aSLionel Sambuc 
VisitExpr(Expr * E)4098f4a2713aSLionel Sambuc   void VisitExpr(Expr *E) {
4099f4a2713aSLionel Sambuc     E->printPretty(OS, Helper, Policy);
4100f4a2713aSLionel Sambuc   }
4101*0a6a1f1dSLionel Sambuc 
4102*0a6a1f1dSLionel Sambuc public:
print(CFGTerminator T)4103*0a6a1f1dSLionel Sambuc   void print(CFGTerminator T) {
4104*0a6a1f1dSLionel Sambuc     if (T.isTemporaryDtorsBranch())
4105*0a6a1f1dSLionel Sambuc       OS << "(Temp Dtor) ";
4106*0a6a1f1dSLionel Sambuc     Visit(T.getStmt());
4107*0a6a1f1dSLionel Sambuc   }
4108f4a2713aSLionel Sambuc };
4109f4a2713aSLionel Sambuc } // end anonymous namespace
4110f4a2713aSLionel Sambuc 
print_elem(raw_ostream & OS,StmtPrinterHelper & Helper,const CFGElement & E)4111f4a2713aSLionel Sambuc static void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper,
4112f4a2713aSLionel Sambuc                        const CFGElement &E) {
4113f4a2713aSLionel Sambuc   if (Optional<CFGStmt> CS = E.getAs<CFGStmt>()) {
4114f4a2713aSLionel Sambuc     const Stmt *S = CS->getStmt();
4115*0a6a1f1dSLionel Sambuc     assert(S != nullptr && "Expecting non-null Stmt");
4116f4a2713aSLionel Sambuc 
4117f4a2713aSLionel Sambuc     // special printing for statement-expressions.
4118f4a2713aSLionel Sambuc     if (const StmtExpr *SE = dyn_cast<StmtExpr>(S)) {
4119f4a2713aSLionel Sambuc       const CompoundStmt *Sub = SE->getSubStmt();
4120f4a2713aSLionel Sambuc 
4121f4a2713aSLionel Sambuc       if (Sub->children()) {
4122f4a2713aSLionel Sambuc         OS << "({ ... ; ";
4123f4a2713aSLionel Sambuc         Helper.handledStmt(*SE->getSubStmt()->body_rbegin(),OS);
4124f4a2713aSLionel Sambuc         OS << " })\n";
4125f4a2713aSLionel Sambuc         return;
4126f4a2713aSLionel Sambuc       }
4127f4a2713aSLionel Sambuc     }
4128f4a2713aSLionel Sambuc     // special printing for comma expressions.
4129f4a2713aSLionel Sambuc     if (const BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
4130f4a2713aSLionel Sambuc       if (B->getOpcode() == BO_Comma) {
4131f4a2713aSLionel Sambuc         OS << "... , ";
4132f4a2713aSLionel Sambuc         Helper.handledStmt(B->getRHS(),OS);
4133f4a2713aSLionel Sambuc         OS << '\n';
4134f4a2713aSLionel Sambuc         return;
4135f4a2713aSLionel Sambuc       }
4136f4a2713aSLionel Sambuc     }
4137f4a2713aSLionel Sambuc     S->printPretty(OS, &Helper, PrintingPolicy(Helper.getLangOpts()));
4138f4a2713aSLionel Sambuc 
4139f4a2713aSLionel Sambuc     if (isa<CXXOperatorCallExpr>(S)) {
4140f4a2713aSLionel Sambuc       OS << " (OperatorCall)";
4141f4a2713aSLionel Sambuc     }
4142f4a2713aSLionel Sambuc     else if (isa<CXXBindTemporaryExpr>(S)) {
4143f4a2713aSLionel Sambuc       OS << " (BindTemporary)";
4144f4a2713aSLionel Sambuc     }
4145f4a2713aSLionel Sambuc     else if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(S)) {
4146f4a2713aSLionel Sambuc       OS << " (CXXConstructExpr, " << CCE->getType().getAsString() << ")";
4147f4a2713aSLionel Sambuc     }
4148f4a2713aSLionel Sambuc     else if (const CastExpr *CE = dyn_cast<CastExpr>(S)) {
4149f4a2713aSLionel Sambuc       OS << " (" << CE->getStmtClassName() << ", "
4150f4a2713aSLionel Sambuc          << CE->getCastKindName()
4151f4a2713aSLionel Sambuc          << ", " << CE->getType().getAsString()
4152f4a2713aSLionel Sambuc          << ")";
4153f4a2713aSLionel Sambuc     }
4154f4a2713aSLionel Sambuc 
4155f4a2713aSLionel Sambuc     // Expressions need a newline.
4156f4a2713aSLionel Sambuc     if (isa<Expr>(S))
4157f4a2713aSLionel Sambuc       OS << '\n';
4158f4a2713aSLionel Sambuc 
4159f4a2713aSLionel Sambuc   } else if (Optional<CFGInitializer> IE = E.getAs<CFGInitializer>()) {
4160f4a2713aSLionel Sambuc     const CXXCtorInitializer *I = IE->getInitializer();
4161f4a2713aSLionel Sambuc     if (I->isBaseInitializer())
4162f4a2713aSLionel Sambuc       OS << I->getBaseClass()->getAsCXXRecordDecl()->getName();
4163f4a2713aSLionel Sambuc     else if (I->isDelegatingInitializer())
4164f4a2713aSLionel Sambuc       OS << I->getTypeSourceInfo()->getType()->getAsCXXRecordDecl()->getName();
4165f4a2713aSLionel Sambuc     else OS << I->getAnyMember()->getName();
4166f4a2713aSLionel Sambuc 
4167f4a2713aSLionel Sambuc     OS << "(";
4168f4a2713aSLionel Sambuc     if (Expr *IE = I->getInit())
4169f4a2713aSLionel Sambuc       IE->printPretty(OS, &Helper, PrintingPolicy(Helper.getLangOpts()));
4170f4a2713aSLionel Sambuc     OS << ")";
4171f4a2713aSLionel Sambuc 
4172f4a2713aSLionel Sambuc     if (I->isBaseInitializer())
4173f4a2713aSLionel Sambuc       OS << " (Base initializer)\n";
4174f4a2713aSLionel Sambuc     else if (I->isDelegatingInitializer())
4175f4a2713aSLionel Sambuc       OS << " (Delegating initializer)\n";
4176f4a2713aSLionel Sambuc     else OS << " (Member initializer)\n";
4177f4a2713aSLionel Sambuc 
4178f4a2713aSLionel Sambuc   } else if (Optional<CFGAutomaticObjDtor> DE =
4179f4a2713aSLionel Sambuc                  E.getAs<CFGAutomaticObjDtor>()) {
4180f4a2713aSLionel Sambuc     const VarDecl *VD = DE->getVarDecl();
4181f4a2713aSLionel Sambuc     Helper.handleDecl(VD, OS);
4182f4a2713aSLionel Sambuc 
4183f4a2713aSLionel Sambuc     const Type* T = VD->getType().getTypePtr();
4184f4a2713aSLionel Sambuc     if (const ReferenceType* RT = T->getAs<ReferenceType>())
4185f4a2713aSLionel Sambuc       T = RT->getPointeeType().getTypePtr();
4186f4a2713aSLionel Sambuc     T = T->getBaseElementTypeUnsafe();
4187f4a2713aSLionel Sambuc 
4188f4a2713aSLionel Sambuc     OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()";
4189f4a2713aSLionel Sambuc     OS << " (Implicit destructor)\n";
4190f4a2713aSLionel Sambuc 
4191*0a6a1f1dSLionel Sambuc   } else if (Optional<CFGNewAllocator> NE = E.getAs<CFGNewAllocator>()) {
4192*0a6a1f1dSLionel Sambuc     OS << "CFGNewAllocator(";
4193*0a6a1f1dSLionel Sambuc     if (const CXXNewExpr *AllocExpr = NE->getAllocatorExpr())
4194*0a6a1f1dSLionel Sambuc       AllocExpr->getType().print(OS, PrintingPolicy(Helper.getLangOpts()));
4195*0a6a1f1dSLionel Sambuc     OS << ")\n";
4196f4a2713aSLionel Sambuc   } else if (Optional<CFGDeleteDtor> DE = E.getAs<CFGDeleteDtor>()) {
4197f4a2713aSLionel Sambuc     const CXXRecordDecl *RD = DE->getCXXRecordDecl();
4198f4a2713aSLionel Sambuc     if (!RD)
4199f4a2713aSLionel Sambuc       return;
4200f4a2713aSLionel Sambuc     CXXDeleteExpr *DelExpr =
4201f4a2713aSLionel Sambuc         const_cast<CXXDeleteExpr*>(DE->getDeleteExpr());
4202f4a2713aSLionel Sambuc     Helper.handledStmt(cast<Stmt>(DelExpr->getArgument()), OS);
4203f4a2713aSLionel Sambuc     OS << "->~" << RD->getName().str() << "()";
4204f4a2713aSLionel Sambuc     OS << " (Implicit destructor)\n";
4205f4a2713aSLionel Sambuc   } else if (Optional<CFGBaseDtor> BE = E.getAs<CFGBaseDtor>()) {
4206f4a2713aSLionel Sambuc     const CXXBaseSpecifier *BS = BE->getBaseSpecifier();
4207f4a2713aSLionel Sambuc     OS << "~" << BS->getType()->getAsCXXRecordDecl()->getName() << "()";
4208f4a2713aSLionel Sambuc     OS << " (Base object destructor)\n";
4209f4a2713aSLionel Sambuc 
4210f4a2713aSLionel Sambuc   } else if (Optional<CFGMemberDtor> ME = E.getAs<CFGMemberDtor>()) {
4211f4a2713aSLionel Sambuc     const FieldDecl *FD = ME->getFieldDecl();
4212f4a2713aSLionel Sambuc     const Type *T = FD->getType()->getBaseElementTypeUnsafe();
4213f4a2713aSLionel Sambuc     OS << "this->" << FD->getName();
4214f4a2713aSLionel Sambuc     OS << ".~" << T->getAsCXXRecordDecl()->getName() << "()";
4215f4a2713aSLionel Sambuc     OS << " (Member object destructor)\n";
4216f4a2713aSLionel Sambuc 
4217f4a2713aSLionel Sambuc   } else if (Optional<CFGTemporaryDtor> TE = E.getAs<CFGTemporaryDtor>()) {
4218f4a2713aSLionel Sambuc     const CXXBindTemporaryExpr *BT = TE->getBindTemporaryExpr();
4219f4a2713aSLionel Sambuc     OS << "~";
4220f4a2713aSLionel Sambuc     BT->getType().print(OS, PrintingPolicy(Helper.getLangOpts()));
4221f4a2713aSLionel Sambuc     OS << "() (Temporary object destructor)\n";
4222f4a2713aSLionel Sambuc   }
4223f4a2713aSLionel Sambuc }
4224f4a2713aSLionel Sambuc 
print_block(raw_ostream & OS,const CFG * cfg,const CFGBlock & B,StmtPrinterHelper & Helper,bool print_edges,bool ShowColors)4225f4a2713aSLionel Sambuc static void print_block(raw_ostream &OS, const CFG* cfg,
4226f4a2713aSLionel Sambuc                         const CFGBlock &B,
4227f4a2713aSLionel Sambuc                         StmtPrinterHelper &Helper, bool print_edges,
4228f4a2713aSLionel Sambuc                         bool ShowColors) {
4229f4a2713aSLionel Sambuc 
4230f4a2713aSLionel Sambuc   Helper.setBlockID(B.getBlockID());
4231f4a2713aSLionel Sambuc 
4232f4a2713aSLionel Sambuc   // Print the header.
4233f4a2713aSLionel Sambuc   if (ShowColors)
4234f4a2713aSLionel Sambuc     OS.changeColor(raw_ostream::YELLOW, true);
4235f4a2713aSLionel Sambuc 
4236f4a2713aSLionel Sambuc   OS << "\n [B" << B.getBlockID();
4237f4a2713aSLionel Sambuc 
4238f4a2713aSLionel Sambuc   if (&B == &cfg->getEntry())
4239f4a2713aSLionel Sambuc     OS << " (ENTRY)]\n";
4240f4a2713aSLionel Sambuc   else if (&B == &cfg->getExit())
4241f4a2713aSLionel Sambuc     OS << " (EXIT)]\n";
4242f4a2713aSLionel Sambuc   else if (&B == cfg->getIndirectGotoBlock())
4243f4a2713aSLionel Sambuc     OS << " (INDIRECT GOTO DISPATCH)]\n";
4244*0a6a1f1dSLionel Sambuc   else if (B.hasNoReturnElement())
4245*0a6a1f1dSLionel Sambuc     OS << " (NORETURN)]\n";
4246f4a2713aSLionel Sambuc   else
4247f4a2713aSLionel Sambuc     OS << "]\n";
4248f4a2713aSLionel Sambuc 
4249f4a2713aSLionel Sambuc   if (ShowColors)
4250f4a2713aSLionel Sambuc     OS.resetColor();
4251f4a2713aSLionel Sambuc 
4252f4a2713aSLionel Sambuc   // Print the label of this block.
4253f4a2713aSLionel Sambuc   if (Stmt *Label = const_cast<Stmt*>(B.getLabel())) {
4254f4a2713aSLionel Sambuc 
4255f4a2713aSLionel Sambuc     if (print_edges)
4256f4a2713aSLionel Sambuc       OS << "  ";
4257f4a2713aSLionel Sambuc 
4258f4a2713aSLionel Sambuc     if (LabelStmt *L = dyn_cast<LabelStmt>(Label))
4259f4a2713aSLionel Sambuc       OS << L->getName();
4260f4a2713aSLionel Sambuc     else if (CaseStmt *C = dyn_cast<CaseStmt>(Label)) {
4261f4a2713aSLionel Sambuc       OS << "case ";
4262*0a6a1f1dSLionel Sambuc       if (C->getLHS())
4263f4a2713aSLionel Sambuc         C->getLHS()->printPretty(OS, &Helper,
4264f4a2713aSLionel Sambuc                                  PrintingPolicy(Helper.getLangOpts()));
4265f4a2713aSLionel Sambuc       if (C->getRHS()) {
4266f4a2713aSLionel Sambuc         OS << " ... ";
4267f4a2713aSLionel Sambuc         C->getRHS()->printPretty(OS, &Helper,
4268f4a2713aSLionel Sambuc                                  PrintingPolicy(Helper.getLangOpts()));
4269f4a2713aSLionel Sambuc       }
4270f4a2713aSLionel Sambuc     } else if (isa<DefaultStmt>(Label))
4271f4a2713aSLionel Sambuc       OS << "default";
4272f4a2713aSLionel Sambuc     else if (CXXCatchStmt *CS = dyn_cast<CXXCatchStmt>(Label)) {
4273f4a2713aSLionel Sambuc       OS << "catch (";
4274f4a2713aSLionel Sambuc       if (CS->getExceptionDecl())
4275f4a2713aSLionel Sambuc         CS->getExceptionDecl()->print(OS, PrintingPolicy(Helper.getLangOpts()),
4276f4a2713aSLionel Sambuc                                       0);
4277f4a2713aSLionel Sambuc       else
4278f4a2713aSLionel Sambuc         OS << "...";
4279f4a2713aSLionel Sambuc       OS << ")";
4280f4a2713aSLionel Sambuc 
4281f4a2713aSLionel Sambuc     } else
4282f4a2713aSLionel Sambuc       llvm_unreachable("Invalid label statement in CFGBlock.");
4283f4a2713aSLionel Sambuc 
4284f4a2713aSLionel Sambuc     OS << ":\n";
4285f4a2713aSLionel Sambuc   }
4286f4a2713aSLionel Sambuc 
4287f4a2713aSLionel Sambuc   // Iterate through the statements in the block and print them.
4288f4a2713aSLionel Sambuc   unsigned j = 1;
4289f4a2713aSLionel Sambuc 
4290f4a2713aSLionel Sambuc   for (CFGBlock::const_iterator I = B.begin(), E = B.end() ;
4291f4a2713aSLionel Sambuc        I != E ; ++I, ++j ) {
4292f4a2713aSLionel Sambuc 
4293f4a2713aSLionel Sambuc     // Print the statement # in the basic block and the statement itself.
4294f4a2713aSLionel Sambuc     if (print_edges)
4295f4a2713aSLionel Sambuc       OS << " ";
4296f4a2713aSLionel Sambuc 
4297f4a2713aSLionel Sambuc     OS << llvm::format("%3d", j) << ": ";
4298f4a2713aSLionel Sambuc 
4299f4a2713aSLionel Sambuc     Helper.setStmtID(j);
4300f4a2713aSLionel Sambuc 
4301f4a2713aSLionel Sambuc     print_elem(OS, Helper, *I);
4302f4a2713aSLionel Sambuc   }
4303f4a2713aSLionel Sambuc 
4304f4a2713aSLionel Sambuc   // Print the terminator of this block.
4305f4a2713aSLionel Sambuc   if (B.getTerminator()) {
4306f4a2713aSLionel Sambuc     if (ShowColors)
4307f4a2713aSLionel Sambuc       OS.changeColor(raw_ostream::GREEN);
4308f4a2713aSLionel Sambuc 
4309f4a2713aSLionel Sambuc     OS << "   T: ";
4310f4a2713aSLionel Sambuc 
4311f4a2713aSLionel Sambuc     Helper.setBlockID(-1);
4312f4a2713aSLionel Sambuc 
4313f4a2713aSLionel Sambuc     PrintingPolicy PP(Helper.getLangOpts());
4314f4a2713aSLionel Sambuc     CFGBlockTerminatorPrint TPrinter(OS, &Helper, PP);
4315*0a6a1f1dSLionel Sambuc     TPrinter.print(B.getTerminator());
4316f4a2713aSLionel Sambuc     OS << '\n';
4317f4a2713aSLionel Sambuc 
4318f4a2713aSLionel Sambuc     if (ShowColors)
4319f4a2713aSLionel Sambuc       OS.resetColor();
4320f4a2713aSLionel Sambuc   }
4321f4a2713aSLionel Sambuc 
4322f4a2713aSLionel Sambuc   if (print_edges) {
4323f4a2713aSLionel Sambuc     // Print the predecessors of this block.
4324f4a2713aSLionel Sambuc     if (!B.pred_empty()) {
4325f4a2713aSLionel Sambuc       const raw_ostream::Colors Color = raw_ostream::BLUE;
4326f4a2713aSLionel Sambuc       if (ShowColors)
4327f4a2713aSLionel Sambuc         OS.changeColor(Color);
4328f4a2713aSLionel Sambuc       OS << "   Preds " ;
4329f4a2713aSLionel Sambuc       if (ShowColors)
4330f4a2713aSLionel Sambuc         OS.resetColor();
4331f4a2713aSLionel Sambuc       OS << '(' << B.pred_size() << "):";
4332f4a2713aSLionel Sambuc       unsigned i = 0;
4333f4a2713aSLionel Sambuc 
4334f4a2713aSLionel Sambuc       if (ShowColors)
4335f4a2713aSLionel Sambuc         OS.changeColor(Color);
4336f4a2713aSLionel Sambuc 
4337f4a2713aSLionel Sambuc       for (CFGBlock::const_pred_iterator I = B.pred_begin(), E = B.pred_end();
4338f4a2713aSLionel Sambuc            I != E; ++I, ++i) {
4339f4a2713aSLionel Sambuc 
4340f4a2713aSLionel Sambuc         if (i % 10 == 8)
4341f4a2713aSLionel Sambuc           OS << "\n     ";
4342f4a2713aSLionel Sambuc 
4343*0a6a1f1dSLionel Sambuc         CFGBlock *B = *I;
4344*0a6a1f1dSLionel Sambuc         bool Reachable = true;
4345*0a6a1f1dSLionel Sambuc         if (!B) {
4346*0a6a1f1dSLionel Sambuc           Reachable = false;
4347*0a6a1f1dSLionel Sambuc           B = I->getPossiblyUnreachableBlock();
4348*0a6a1f1dSLionel Sambuc         }
4349*0a6a1f1dSLionel Sambuc 
4350*0a6a1f1dSLionel Sambuc         OS << " B" << B->getBlockID();
4351*0a6a1f1dSLionel Sambuc         if (!Reachable)
4352*0a6a1f1dSLionel Sambuc           OS << "(Unreachable)";
4353f4a2713aSLionel Sambuc       }
4354f4a2713aSLionel Sambuc 
4355f4a2713aSLionel Sambuc       if (ShowColors)
4356f4a2713aSLionel Sambuc         OS.resetColor();
4357f4a2713aSLionel Sambuc 
4358f4a2713aSLionel Sambuc       OS << '\n';
4359f4a2713aSLionel Sambuc     }
4360f4a2713aSLionel Sambuc 
4361f4a2713aSLionel Sambuc     // Print the successors of this block.
4362f4a2713aSLionel Sambuc     if (!B.succ_empty()) {
4363f4a2713aSLionel Sambuc       const raw_ostream::Colors Color = raw_ostream::MAGENTA;
4364f4a2713aSLionel Sambuc       if (ShowColors)
4365f4a2713aSLionel Sambuc         OS.changeColor(Color);
4366f4a2713aSLionel Sambuc       OS << "   Succs ";
4367f4a2713aSLionel Sambuc       if (ShowColors)
4368f4a2713aSLionel Sambuc         OS.resetColor();
4369f4a2713aSLionel Sambuc       OS << '(' << B.succ_size() << "):";
4370f4a2713aSLionel Sambuc       unsigned i = 0;
4371f4a2713aSLionel Sambuc 
4372f4a2713aSLionel Sambuc       if (ShowColors)
4373f4a2713aSLionel Sambuc         OS.changeColor(Color);
4374f4a2713aSLionel Sambuc 
4375f4a2713aSLionel Sambuc       for (CFGBlock::const_succ_iterator I = B.succ_begin(), E = B.succ_end();
4376f4a2713aSLionel Sambuc            I != E; ++I, ++i) {
4377f4a2713aSLionel Sambuc 
4378f4a2713aSLionel Sambuc         if (i % 10 == 8)
4379f4a2713aSLionel Sambuc           OS << "\n    ";
4380f4a2713aSLionel Sambuc 
4381*0a6a1f1dSLionel Sambuc         CFGBlock *B = *I;
4382*0a6a1f1dSLionel Sambuc 
4383*0a6a1f1dSLionel Sambuc         bool Reachable = true;
4384*0a6a1f1dSLionel Sambuc         if (!B) {
4385*0a6a1f1dSLionel Sambuc           Reachable = false;
4386*0a6a1f1dSLionel Sambuc           B = I->getPossiblyUnreachableBlock();
4387*0a6a1f1dSLionel Sambuc         }
4388*0a6a1f1dSLionel Sambuc 
4389*0a6a1f1dSLionel Sambuc         if (B) {
4390*0a6a1f1dSLionel Sambuc           OS << " B" << B->getBlockID();
4391*0a6a1f1dSLionel Sambuc           if (!Reachable)
4392*0a6a1f1dSLionel Sambuc             OS << "(Unreachable)";
4393*0a6a1f1dSLionel Sambuc         }
4394*0a6a1f1dSLionel Sambuc         else {
4395f4a2713aSLionel Sambuc           OS << " NULL";
4396f4a2713aSLionel Sambuc         }
4397*0a6a1f1dSLionel Sambuc       }
4398f4a2713aSLionel Sambuc 
4399f4a2713aSLionel Sambuc       if (ShowColors)
4400f4a2713aSLionel Sambuc         OS.resetColor();
4401f4a2713aSLionel Sambuc       OS << '\n';
4402f4a2713aSLionel Sambuc     }
4403f4a2713aSLionel Sambuc   }
4404f4a2713aSLionel Sambuc }
4405f4a2713aSLionel Sambuc 
4406f4a2713aSLionel Sambuc 
4407f4a2713aSLionel Sambuc /// dump - A simple pretty printer of a CFG that outputs to stderr.
dump(const LangOptions & LO,bool ShowColors) const4408f4a2713aSLionel Sambuc void CFG::dump(const LangOptions &LO, bool ShowColors) const {
4409f4a2713aSLionel Sambuc   print(llvm::errs(), LO, ShowColors);
4410f4a2713aSLionel Sambuc }
4411f4a2713aSLionel Sambuc 
4412f4a2713aSLionel Sambuc /// print - A simple pretty printer of a CFG that outputs to an ostream.
print(raw_ostream & OS,const LangOptions & LO,bool ShowColors) const4413f4a2713aSLionel Sambuc void CFG::print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const {
4414f4a2713aSLionel Sambuc   StmtPrinterHelper Helper(this, LO);
4415f4a2713aSLionel Sambuc 
4416f4a2713aSLionel Sambuc   // Print the entry block.
4417f4a2713aSLionel Sambuc   print_block(OS, this, getEntry(), Helper, true, ShowColors);
4418f4a2713aSLionel Sambuc 
4419f4a2713aSLionel Sambuc   // Iterate through the CFGBlocks and print them one by one.
4420f4a2713aSLionel Sambuc   for (const_iterator I = Blocks.begin(), E = Blocks.end() ; I != E ; ++I) {
4421f4a2713aSLionel Sambuc     // Skip the entry block, because we already printed it.
4422f4a2713aSLionel Sambuc     if (&(**I) == &getEntry() || &(**I) == &getExit())
4423f4a2713aSLionel Sambuc       continue;
4424f4a2713aSLionel Sambuc 
4425f4a2713aSLionel Sambuc     print_block(OS, this, **I, Helper, true, ShowColors);
4426f4a2713aSLionel Sambuc   }
4427f4a2713aSLionel Sambuc 
4428f4a2713aSLionel Sambuc   // Print the exit block.
4429f4a2713aSLionel Sambuc   print_block(OS, this, getExit(), Helper, true, ShowColors);
4430f4a2713aSLionel Sambuc   OS << '\n';
4431f4a2713aSLionel Sambuc   OS.flush();
4432f4a2713aSLionel Sambuc }
4433f4a2713aSLionel Sambuc 
4434f4a2713aSLionel Sambuc /// dump - A simply pretty printer of a CFGBlock that outputs to stderr.
dump(const CFG * cfg,const LangOptions & LO,bool ShowColors) const4435f4a2713aSLionel Sambuc void CFGBlock::dump(const CFG* cfg, const LangOptions &LO,
4436f4a2713aSLionel Sambuc                     bool ShowColors) const {
4437f4a2713aSLionel Sambuc   print(llvm::errs(), cfg, LO, ShowColors);
4438f4a2713aSLionel Sambuc }
4439f4a2713aSLionel Sambuc 
dump() const4440*0a6a1f1dSLionel Sambuc void CFGBlock::dump() const {
4441*0a6a1f1dSLionel Sambuc   dump(getParent(), LangOptions(), false);
4442*0a6a1f1dSLionel Sambuc }
4443*0a6a1f1dSLionel Sambuc 
4444f4a2713aSLionel Sambuc /// print - A simple pretty printer of a CFGBlock that outputs to an ostream.
4445f4a2713aSLionel Sambuc ///   Generally this will only be called from CFG::print.
print(raw_ostream & OS,const CFG * cfg,const LangOptions & LO,bool ShowColors) const4446f4a2713aSLionel Sambuc void CFGBlock::print(raw_ostream &OS, const CFG* cfg,
4447f4a2713aSLionel Sambuc                      const LangOptions &LO, bool ShowColors) const {
4448f4a2713aSLionel Sambuc   StmtPrinterHelper Helper(cfg, LO);
4449f4a2713aSLionel Sambuc   print_block(OS, cfg, *this, Helper, true, ShowColors);
4450f4a2713aSLionel Sambuc   OS << '\n';
4451f4a2713aSLionel Sambuc }
4452f4a2713aSLionel Sambuc 
4453f4a2713aSLionel Sambuc /// printTerminator - A simple pretty printer of the terminator of a CFGBlock.
printTerminator(raw_ostream & OS,const LangOptions & LO) const4454f4a2713aSLionel Sambuc void CFGBlock::printTerminator(raw_ostream &OS,
4455f4a2713aSLionel Sambuc                                const LangOptions &LO) const {
4456*0a6a1f1dSLionel Sambuc   CFGBlockTerminatorPrint TPrinter(OS, nullptr, PrintingPolicy(LO));
4457*0a6a1f1dSLionel Sambuc   TPrinter.print(getTerminator());
4458f4a2713aSLionel Sambuc }
4459f4a2713aSLionel Sambuc 
getTerminatorCondition(bool StripParens)4460*0a6a1f1dSLionel Sambuc Stmt *CFGBlock::getTerminatorCondition(bool StripParens) {
4461f4a2713aSLionel Sambuc   Stmt *Terminator = this->Terminator;
4462f4a2713aSLionel Sambuc   if (!Terminator)
4463*0a6a1f1dSLionel Sambuc     return nullptr;
4464f4a2713aSLionel Sambuc 
4465*0a6a1f1dSLionel Sambuc   Expr *E = nullptr;
4466f4a2713aSLionel Sambuc 
4467f4a2713aSLionel Sambuc   switch (Terminator->getStmtClass()) {
4468f4a2713aSLionel Sambuc     default:
4469f4a2713aSLionel Sambuc       break;
4470f4a2713aSLionel Sambuc 
4471f4a2713aSLionel Sambuc     case Stmt::CXXForRangeStmtClass:
4472f4a2713aSLionel Sambuc       E = cast<CXXForRangeStmt>(Terminator)->getCond();
4473f4a2713aSLionel Sambuc       break;
4474f4a2713aSLionel Sambuc 
4475f4a2713aSLionel Sambuc     case Stmt::ForStmtClass:
4476f4a2713aSLionel Sambuc       E = cast<ForStmt>(Terminator)->getCond();
4477f4a2713aSLionel Sambuc       break;
4478f4a2713aSLionel Sambuc 
4479f4a2713aSLionel Sambuc     case Stmt::WhileStmtClass:
4480f4a2713aSLionel Sambuc       E = cast<WhileStmt>(Terminator)->getCond();
4481f4a2713aSLionel Sambuc       break;
4482f4a2713aSLionel Sambuc 
4483f4a2713aSLionel Sambuc     case Stmt::DoStmtClass:
4484f4a2713aSLionel Sambuc       E = cast<DoStmt>(Terminator)->getCond();
4485f4a2713aSLionel Sambuc       break;
4486f4a2713aSLionel Sambuc 
4487f4a2713aSLionel Sambuc     case Stmt::IfStmtClass:
4488f4a2713aSLionel Sambuc       E = cast<IfStmt>(Terminator)->getCond();
4489f4a2713aSLionel Sambuc       break;
4490f4a2713aSLionel Sambuc 
4491f4a2713aSLionel Sambuc     case Stmt::ChooseExprClass:
4492f4a2713aSLionel Sambuc       E = cast<ChooseExpr>(Terminator)->getCond();
4493f4a2713aSLionel Sambuc       break;
4494f4a2713aSLionel Sambuc 
4495f4a2713aSLionel Sambuc     case Stmt::IndirectGotoStmtClass:
4496f4a2713aSLionel Sambuc       E = cast<IndirectGotoStmt>(Terminator)->getTarget();
4497f4a2713aSLionel Sambuc       break;
4498f4a2713aSLionel Sambuc 
4499f4a2713aSLionel Sambuc     case Stmt::SwitchStmtClass:
4500f4a2713aSLionel Sambuc       E = cast<SwitchStmt>(Terminator)->getCond();
4501f4a2713aSLionel Sambuc       break;
4502f4a2713aSLionel Sambuc 
4503f4a2713aSLionel Sambuc     case Stmt::BinaryConditionalOperatorClass:
4504f4a2713aSLionel Sambuc       E = cast<BinaryConditionalOperator>(Terminator)->getCond();
4505f4a2713aSLionel Sambuc       break;
4506f4a2713aSLionel Sambuc 
4507f4a2713aSLionel Sambuc     case Stmt::ConditionalOperatorClass:
4508f4a2713aSLionel Sambuc       E = cast<ConditionalOperator>(Terminator)->getCond();
4509f4a2713aSLionel Sambuc       break;
4510f4a2713aSLionel Sambuc 
4511f4a2713aSLionel Sambuc     case Stmt::BinaryOperatorClass: // '&&' and '||'
4512f4a2713aSLionel Sambuc       E = cast<BinaryOperator>(Terminator)->getLHS();
4513f4a2713aSLionel Sambuc       break;
4514f4a2713aSLionel Sambuc 
4515f4a2713aSLionel Sambuc     case Stmt::ObjCForCollectionStmtClass:
4516f4a2713aSLionel Sambuc       return Terminator;
4517f4a2713aSLionel Sambuc   }
4518f4a2713aSLionel Sambuc 
4519*0a6a1f1dSLionel Sambuc   if (!StripParens)
4520*0a6a1f1dSLionel Sambuc     return E;
4521*0a6a1f1dSLionel Sambuc 
4522*0a6a1f1dSLionel Sambuc   return E ? E->IgnoreParens() : nullptr;
4523f4a2713aSLionel Sambuc }
4524f4a2713aSLionel Sambuc 
4525f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
4526f4a2713aSLionel Sambuc // CFG Graphviz Visualization
4527f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
4528f4a2713aSLionel Sambuc 
4529f4a2713aSLionel Sambuc 
4530f4a2713aSLionel Sambuc #ifndef NDEBUG
4531f4a2713aSLionel Sambuc static StmtPrinterHelper* GraphHelper;
4532f4a2713aSLionel Sambuc #endif
4533f4a2713aSLionel Sambuc 
viewCFG(const LangOptions & LO) const4534f4a2713aSLionel Sambuc void CFG::viewCFG(const LangOptions &LO) const {
4535f4a2713aSLionel Sambuc #ifndef NDEBUG
4536f4a2713aSLionel Sambuc   StmtPrinterHelper H(this, LO);
4537f4a2713aSLionel Sambuc   GraphHelper = &H;
4538f4a2713aSLionel Sambuc   llvm::ViewGraph(this,"CFG");
4539*0a6a1f1dSLionel Sambuc   GraphHelper = nullptr;
4540f4a2713aSLionel Sambuc #endif
4541f4a2713aSLionel Sambuc }
4542f4a2713aSLionel Sambuc 
4543f4a2713aSLionel Sambuc namespace llvm {
4544f4a2713aSLionel Sambuc template<>
4545f4a2713aSLionel Sambuc struct DOTGraphTraits<const CFG*> : public DefaultDOTGraphTraits {
4546f4a2713aSLionel Sambuc 
DOTGraphTraitsllvm::DOTGraphTraits4547f4a2713aSLionel Sambuc   DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
4548f4a2713aSLionel Sambuc 
getNodeLabelllvm::DOTGraphTraits4549f4a2713aSLionel Sambuc   static std::string getNodeLabel(const CFGBlock *Node, const CFG* Graph) {
4550f4a2713aSLionel Sambuc 
4551f4a2713aSLionel Sambuc #ifndef NDEBUG
4552f4a2713aSLionel Sambuc     std::string OutSStr;
4553f4a2713aSLionel Sambuc     llvm::raw_string_ostream Out(OutSStr);
4554f4a2713aSLionel Sambuc     print_block(Out,Graph, *Node, *GraphHelper, false, false);
4555f4a2713aSLionel Sambuc     std::string& OutStr = Out.str();
4556f4a2713aSLionel Sambuc 
4557f4a2713aSLionel Sambuc     if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
4558f4a2713aSLionel Sambuc 
4559f4a2713aSLionel Sambuc     // Process string output to make it nicer...
4560f4a2713aSLionel Sambuc     for (unsigned i = 0; i != OutStr.length(); ++i)
4561f4a2713aSLionel Sambuc       if (OutStr[i] == '\n') {                            // Left justify
4562f4a2713aSLionel Sambuc         OutStr[i] = '\\';
4563f4a2713aSLionel Sambuc         OutStr.insert(OutStr.begin()+i+1, 'l');
4564f4a2713aSLionel Sambuc       }
4565f4a2713aSLionel Sambuc 
4566f4a2713aSLionel Sambuc     return OutStr;
4567f4a2713aSLionel Sambuc #else
4568f4a2713aSLionel Sambuc     return "";
4569f4a2713aSLionel Sambuc #endif
4570f4a2713aSLionel Sambuc   }
4571f4a2713aSLionel Sambuc };
4572f4a2713aSLionel Sambuc } // end namespace llvm
4573