1fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//===--- CFG.cpp - Classes for representing and building CFGs----*- C++ -*-===//
2fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//
3fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//                     The LLVM Compiler Infrastructure
4fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
7fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//
8fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//===----------------------------------------------------------------------===//
9fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//
10fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//  This file defines the CFG and CFGBuilder classes for representing and
11fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//  building Control-Flow Graphs (CFGs) from ASTs.
12fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//
13fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//===----------------------------------------------------------------------===//
14fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
15b2c60b04a597cc5ba4154837cf8e0a155a376fd7Argyrios Kyrtzidis#include "llvm/Support/SaveAndRestore.h"
16e41611aa2237d06a0ef61db4528fb2883a8defcdTed Kremenek#include "clang/Analysis/CFG.h"
17b978a441c7d8bf59e7fede938e1f3b672573b443Mike Stump#include "clang/AST/DeclCXX.h"
18c310e933a9b023a280f3aa02e5a0c75398555e13Ted Kremenek#include "clang/AST/StmtVisitor.h"
1942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#include "clang/AST/PrettyPrinter.h"
20c56c004e0b8030e8ca8614e7febe581221938b75Ted Kremenek#include "clang/AST/CharUnits.h"
21534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith#include "clang/Basic/AttrKinds.h"
227dba8607e59096014b7139ff20ef00870041d518Ted Kremenek#include "llvm/Support/GraphWriter.h"
236cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/Support/Allocator.h"
246cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/Support/Format.h"
256cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/ADT/DenseMap.h"
266cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/ADT/SmallPtrSet.h"
270ba497be27170c2a23c0217366f97eeecefa1ed8Ted Kremenek#include "llvm/ADT/OwningPtr.h"
2883c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek
29fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekusing namespace clang;
30fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
31fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremeneknamespace {
32fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
339c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic SourceLocation GetEndLoc(Decl *D) {
349c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (VarDecl *VD = dyn_cast<VarDecl>(D))
359c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (Expr *Ex = VD->getInit())
36c7eb9031159f30a63db960fad4640d779f1617c8Ted Kremenek      return Ex->getSourceRange().getEnd();
376d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  return D->getLocation();
38c7eb9031159f30a63db960fad4640d779f1617c8Ted Kremenek}
39ad5a894df1841698c824381b414630799adc26caTed Kremenek
403179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenekclass CFGBuilder;
413179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek
4294a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// The CFG builder uses a recursive algorithm to build the CFG.  When
4394a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan///  we process an expression, sometimes we know that we must add the
4494a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan///  subexpressions as block-level expressions.  For example:
4594a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan///
4694a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan///    exp1 || exp2
4794a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan///
4894a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan///  When processing the '||' expression, we know that exp1 and exp2
4994a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan///  need to be added as block-level expressions, even though they
5094a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan///  might not normally need to be.  AddStmtChoice records this
5194a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan///  contextual information.  If AddStmtChoice is 'NotAlwaysAdd', then
5294a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan///  the builder has an option not to add a subexpression as a
5394a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan///  block-level expression.
5494a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan///
55852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenekclass AddStmtChoice {
56852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenekpublic:
57892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  enum Kind { NotAlwaysAdd = 0, AlwaysAdd = 1 };
585ba290a12fb9390a77ea4dca3d98deb53022d182Ted Kremenek
5994a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan  AddStmtChoice(Kind a_kind = NotAlwaysAdd) : kind(a_kind) {}
605ba290a12fb9390a77ea4dca3d98deb53022d182Ted Kremenek
613179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek  bool alwaysAdd(CFGBuilder &builder,
623179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek                 const Stmt *stmt) const;
6394a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan
6494a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan  /// Return a copy of this object, except with the 'always-add' bit
6594a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan  ///  set as specified.
6694a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan  AddStmtChoice withAlwaysAdd(bool alwaysAdd) const {
673179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek    return AddStmtChoice(alwaysAdd ? AlwaysAdd : NotAlwaysAdd);
6894a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan  }
6994a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan
70852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenekprivate:
7194a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan  Kind kind;
72852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek};
736d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
74f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// LocalScope - Node in tree of local scopes created for C++ implicit
75f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// destructor calls generation. It contains list of automatic variables
76f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// declared in the scope and link to position in previous scope this scope
77f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// began in.
78f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski///
79f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// The process of creating local scopes is as follows:
80f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// - Init CFGBuilder::ScopePos with invalid position (equivalent for null),
81f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// - Before processing statements in scope (e.g. CompoundStmt) create
82f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski///   LocalScope object using CFGBuilder::ScopePos as link to previous scope
83f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski///   and set CFGBuilder::ScopePos to the end of new scope,
8435387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// - On every occurrence of VarDecl increase CFGBuilder::ScopePos if it points
85f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski///   at this VarDecl,
86f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// - For every normal (without jump) end of scope add to CFGBlock destructors
87f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski///   for objects in the current scope,
88f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// - For every jump add to CFGBlock destructors for objects
89f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski///   between CFGBuilder::ScopePos and local scope position saved for jump
90f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski///   target. Thanks to C++ restrictions on goto jumps we can be sure that
91f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski///   jump target position will be on the path to root from CFGBuilder::ScopePos
92f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski///   (adding any variable that doesn't need constructor to be called to
93f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski///   LocalScope can break this assumption),
94f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski///
95f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderskiclass LocalScope {
96f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderskipublic:
97fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek  typedef BumpVector<VarDecl*> AutomaticVarsTy;
98f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
99f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  /// const_iterator - Iterates local scope backwards and jumps to previous
10035387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski  /// scope on reaching the beginning of currently iterated scope.
101f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  class const_iterator {
102f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    const LocalScope* Scope;
103f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
104f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    /// VarIter is guaranteed to be greater then 0 for every valid iterator.
105f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    /// Invalid iterator (with null Scope) has VarIter equal to 0.
106f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    unsigned VarIter;
107f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
108f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  public:
109f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    /// Create invalid iterator. Dereferencing invalid iterator is not allowed.
110f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    /// Incrementing invalid iterator is allowed and will result in invalid
111f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    /// iterator.
112f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    const_iterator()
113f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski        : Scope(NULL), VarIter(0) {}
114f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
115f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    /// Create valid iterator. In case when S.Prev is an invalid iterator and
116f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    /// I is equal to 0, this will create invalid iterator.
117f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    const_iterator(const LocalScope& S, unsigned I)
118f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski        : Scope(&S), VarIter(I) {
119f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      // Iterator to "end" of scope is not allowed. Handle it by going up
120f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      // in scopes tree possibly up to invalid iterator in the root.
121f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      if (VarIter == 0 && Scope)
122f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski        *this = Scope->Prev;
123f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    }
124f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
1259c378f705405d37f49795d5e915989de774fe11fTed Kremenek    VarDecl *const* operator->() const {
126f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      assert (Scope && "Dereferencing invalid iterator is not allowed");
127f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      assert (VarIter != 0 && "Iterator has invalid value of VarIter member");
128f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      return &Scope->Vars[VarIter - 1];
129f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    }
1309c378f705405d37f49795d5e915989de774fe11fTed Kremenek    VarDecl *operator*() const {
131f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      return *this->operator->();
132f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    }
133f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
1349c378f705405d37f49795d5e915989de774fe11fTed Kremenek    const_iterator &operator++() {
135f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      if (!Scope)
136f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski        return *this;
137f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
138f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      assert (VarIter != 0 && "Iterator has invalid value of VarIter member");
139f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      --VarIter;
140f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      if (VarIter == 0)
141f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski        *this = Scope->Prev;
142f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      return *this;
143f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    }
14435387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski    const_iterator operator++(int) {
14535387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski      const_iterator P = *this;
14635387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski      ++*this;
14735387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski      return P;
14835387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski    }
149f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
1509c378f705405d37f49795d5e915989de774fe11fTed Kremenek    bool operator==(const const_iterator &rhs) const {
151f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      return Scope == rhs.Scope && VarIter == rhs.VarIter;
152f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    }
1539c378f705405d37f49795d5e915989de774fe11fTed Kremenek    bool operator!=(const const_iterator &rhs) const {
154f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski      return !(*this == rhs);
155f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    }
15635387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski
15735387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski    operator bool() const {
15835387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski      return *this != const_iterator();
15935387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski    }
16035387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski
16135387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski    int distance(const_iterator L);
162f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  };
163f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
164f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  friend class const_iterator;
165f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
166f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderskiprivate:
167fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek  BumpVectorContext ctx;
168fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek
169f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  /// Automatic variables in order of declaration.
170f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  AutomaticVarsTy Vars;
171f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  /// Iterator to variable in previous scope that was declared just before
172f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  /// begin of this scope.
173f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  const_iterator Prev;
174f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
175f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderskipublic:
176f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  /// Constructs empty scope linked to previous scope in specified place.
177fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek  LocalScope(BumpVectorContext &ctx, const_iterator P)
178fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek      : ctx(ctx), Vars(ctx, 4), Prev(P) {}
179f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
180f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  /// Begin of scope in direction of CFG building (backwards).
181f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  const_iterator begin() const { return const_iterator(*this, Vars.size()); }
18235387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski
1839c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void addVar(VarDecl *VD) {
184fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek    Vars.push_back(VD, ctx);
18535387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski  }
186f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski};
187f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
18835387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// distance - Calculates distance from this to L. L must be reachable from this
18935387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// (with use of ++ operator). Cost of calculating the distance is linear w.r.t.
19035387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// number of scopes between this and L.
19135387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderskiint LocalScope::const_iterator::distance(LocalScope::const_iterator L) {
19235387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski  int D = 0;
19335387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski  const_iterator F = *this;
19435387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski  while (F.Scope != L.Scope) {
1955290c80eba2c96aee32912adf77bea6eddb92026Ted Kremenek    assert (F != const_iterator()
1965290c80eba2c96aee32912adf77bea6eddb92026Ted Kremenek        && "L iterator is not reachable from F iterator.");
19735387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski    D += F.VarIter;
19835387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski    F = F.Scope->Prev;
19935387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski  }
20035387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski  D += F.VarIter - L.VarIter;
20135387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski  return D;
20235387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski}
20335387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski
20435387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// BlockScopePosPair - Structure for specifying position in CFG during its
20535387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// build process. It consists of CFGBlock that specifies position in CFG graph
20635387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// and  LocalScope::const_iterator that specifies position in LocalScope graph.
207f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderskistruct BlockScopePosPair {
2089ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek  BlockScopePosPair() : block(0) {}
2099c378f705405d37f49795d5e915989de774fe11fTed Kremenek  BlockScopePosPair(CFGBlock *b, LocalScope::const_iterator scopePos)
2109ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek      : block(b), scopePosition(scopePos) {}
211f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
2129ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek  CFGBlock *block;
2139ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek  LocalScope::const_iterator scopePosition;
214f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski};
215f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
216e71f3d587844110d836c82250830b27b1651afdbTed Kremenek/// TryResult - a class representing a variant over the values
217e71f3d587844110d836c82250830b27b1651afdbTed Kremenek///  'true', 'false', or 'unknown'.  This is returned by tryEvaluateBool,
218e71f3d587844110d836c82250830b27b1651afdbTed Kremenek///  and is used by the CFGBuilder to decide if a branch condition
219e71f3d587844110d836c82250830b27b1651afdbTed Kremenek///  can be decided up front during CFG construction.
220e71f3d587844110d836c82250830b27b1651afdbTed Kremenekclass TryResult {
221e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  int X;
222e71f3d587844110d836c82250830b27b1651afdbTed Kremenekpublic:
223e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  TryResult(bool b) : X(b ? 1 : 0) {}
224e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  TryResult() : X(-1) {}
225e71f3d587844110d836c82250830b27b1651afdbTed Kremenek
226e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  bool isTrue() const { return X == 1; }
227e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  bool isFalse() const { return X == 0; }
228e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  bool isKnown() const { return X >= 0; }
229e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  void negate() {
230e71f3d587844110d836c82250830b27b1651afdbTed Kremenek    assert(isKnown());
231e71f3d587844110d836c82250830b27b1651afdbTed Kremenek    X ^= 0x1;
232e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  }
233e71f3d587844110d836c82250830b27b1651afdbTed Kremenek};
234e71f3d587844110d836c82250830b27b1651afdbTed Kremenek
235a34ea072371154c9042ce86321d17fbb4df1f84dTed Kremenek/// CFGBuilder - This class implements CFG construction from an AST.
236fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///   The builder is stateful: an instance of the builder should be used to only
237fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///   construct a single CFG.
238fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///
239fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///   Example usage:
240fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///
241fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///     CFGBuilder builder;
242fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///     CFG* cfg = builder.BuildAST(stmt1);
243fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///
2446d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump///  CFG construction is done via a recursive walk of an AST.  We actually parse
2456d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump///  the AST in reverse order so that the successor of a basic block is
2466d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump///  constructed prior to its predecessor.  This allows us to nicely capture
2476d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump///  implicit fall-throughs without extra basic blocks.
248c310e933a9b023a280f3aa02e5a0c75398555e13Ted Kremenek///
249ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass CFGBuilder {
250f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  typedef BlockScopePosPair JumpTarget;
251f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  typedef BlockScopePosPair JumpSource;
252f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
253e5af3ce53ec58995b09381ba645ab2117a46647bMike Stump  ASTContext *Context;
2546f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<CFG> cfg;
255ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek
2569c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *Block;
2579c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *Succ;
258f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  JumpTarget ContinueJumpTarget;
259f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  JumpTarget BreakJumpTarget;
2609c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *SwitchTerminatedBlock;
2619c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *DefaultCaseBlock;
2629c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *TryTerminatedBlock;
263e71f3d587844110d836c82250830b27b1651afdbTed Kremenek
264f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  // Current position in local scope.
265f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  LocalScope::const_iterator ScopePos;
266f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
267f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  // LabelMap records the mapping from Label expressions to their jump targets.
268ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner  typedef llvm::DenseMap<LabelDecl*, JumpTarget> LabelMapTy;
2690cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek  LabelMapTy LabelMap;
2706d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2716d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // A list of blocks that end with a "goto" that must be backpatched to their
2726d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // resolved targets upon completion of CFG construction.
273f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  typedef std::vector<JumpSource> BackpatchBlocksTy;
2740cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek  BackpatchBlocksTy BackpatchBlocks;
2756d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
27619bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  // A list of labels whose address has been taken (for indirect gotos).
277ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner  typedef llvm::SmallPtrSet<LabelDecl*, 5> LabelSetTy;
27819bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  LabelSetTy AddressTakenLabels;
2796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
28049b4ef364ba042f7db2ba567310fb49917ad0086Zhongxing Xu  bool badCFG;
281b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek  const CFG::BuildOptions &BuildOpts;
282e71f3d587844110d836c82250830b27b1651afdbTed Kremenek
283e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  // State to track for building switch statements.
284e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  bool switchExclusivelyCovered;
2850498247f87ea0d716e0c2931fea812280649e33dTed Kremenek  Expr::EvalResult *switchCond;
2860d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
2870d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  CFG::BuildOptions::ForcedBlkExprs::value_type *cachedEntry;
288a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek  const Stmt *lastLookup;
28949b4ef364ba042f7db2ba567310fb49917ad0086Zhongxing Xu
2908c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis  // Caches boolean evaluations of expressions to avoid multiple re-evaluations
2918c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis  // during construction of branches for chained logical operators.
2926955da2cad4bce19c541ddb85a6d965d77a1a4abNAKAMURA Takumi  typedef llvm::DenseMap<Expr *, TryResult> CachedBoolEvalsTy;
2936955da2cad4bce19c541ddb85a6d965d77a1a4abNAKAMURA Takumi  CachedBoolEvalsTy CachedBoolEvals;
2948c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis
2956d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stumppublic:
296b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek  explicit CFGBuilder(ASTContext *astContext,
297b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek                      const CFG::BuildOptions &buildOpts)
298b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek    : Context(astContext), cfg(new CFG()), // crew a new CFG
299b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek      Block(NULL), Succ(NULL),
300b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek      SwitchTerminatedBlock(NULL), DefaultCaseBlock(NULL),
301b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek      TryTerminatedBlock(NULL), badCFG(false), BuildOpts(buildOpts),
3020d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek      switchExclusivelyCovered(false), switchCond(0),
303a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek      cachedEntry(0), lastLookup(0) {}
3046d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
305d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // buildCFG - Used by external clients to construct the CFG.
306b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek  CFG* buildCFG(const Decl *D, Stmt *Statement);
3076d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3080d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  bool alwaysAdd(const Stmt *stmt);
3090d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
3104f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenekprivate:
3114f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  // Visitors to walk an AST and construct the CFG.
312852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  CFGBlock *VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc);
313852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  CFGBlock *VisitBinaryOperator(BinaryOperator *B, AddStmtChoice asc);
3144f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *VisitBreakStmt(BreakStmt *B);
3157ea2136685403045f91b3a8b83e34c51ac0e082eTed Kremenek  CFGBlock *VisitCXXCatchStmt(CXXCatchStmt *S);
3164765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall  CFGBlock *VisitExprWithCleanups(ExprWithCleanups *E,
3178599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      AddStmtChoice asc);
3187ea2136685403045f91b3a8b83e34c51ac0e082eTed Kremenek  CFGBlock *VisitCXXThrowExpr(CXXThrowExpr *T);
3197ea2136685403045f91b3a8b83e34c51ac0e082eTed Kremenek  CFGBlock *VisitCXXTryStmt(CXXTryStmt *S);
320ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  CFGBlock *VisitCXXForRangeStmt(CXXForRangeStmt *S);
321a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu  CFGBlock *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E,
322a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu                                      AddStmtChoice asc);
32381bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu  CFGBlock *VisitCXXConstructExpr(CXXConstructExpr *C, AddStmtChoice asc);
324a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu  CFGBlock *VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E,
325a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu                                       AddStmtChoice asc);
32681bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu  CFGBlock *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C,
32781bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu                                        AddStmtChoice asc);
328852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  CFGBlock *VisitCallExpr(CallExpr *C, AddStmtChoice asc);
3294f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *VisitCaseStmt(CaseStmt *C);
330852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  CFGBlock *VisitChooseExpr(ChooseExpr *C, AddStmtChoice asc);
3313fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek  CFGBlock *VisitCompoundStmt(CompoundStmt *C);
33256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  CFGBlock *VisitConditionalOperator(AbstractConditionalOperator *C,
33356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall                                     AddStmtChoice asc);
3343fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek  CFGBlock *VisitContinueStmt(ContinueStmt *C);
3354f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *VisitDeclStmt(DeclStmt *DS);
3369c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *VisitDeclSubExpr(DeclStmt *DS);
3373fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek  CFGBlock *VisitDefaultStmt(DefaultStmt *D);
3383fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek  CFGBlock *VisitDoStmt(DoStmt *D);
33955331da3211151aa67277aa095b7d301342200d4Ted Kremenek  CFGBlock *VisitLambdaExpr(LambdaExpr *E, AddStmtChoice asc);
3403fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek  CFGBlock *VisitForStmt(ForStmt *F);
3419c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *VisitGotoStmt(GotoStmt *G);
3424f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *VisitIfStmt(IfStmt *I);
343a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu  CFGBlock *VisitImplicitCastExpr(ImplicitCastExpr *E, AddStmtChoice asc);
3444f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *VisitIndirectGotoStmt(IndirectGotoStmt *I);
3454f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *VisitLabelStmt(LabelStmt *L);
34683748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek  CFGBlock *VisitLambdaExpr(LambdaExpr *L);
347115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek  CFGBlock *VisitMemberExpr(MemberExpr *M, AddStmtChoice asc);
3484f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *VisitObjCAtCatchStmt(ObjCAtCatchStmt *S);
3498e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek  CFGBlock *VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S);
3504f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S);
3514f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *VisitObjCAtThrowStmt(ObjCAtThrowStmt *S);
3524f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *VisitObjCAtTryStmt(ObjCAtTryStmt *S);
3534f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *VisitObjCForCollectionStmt(ObjCForCollectionStmt *S);
3549c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *VisitReturnStmt(ReturnStmt *R);
3554b9c2d235fb9449e249d74f48ecfec601650de93John McCall  CFGBlock *VisitPseudoObjectExpr(PseudoObjectExpr *E);
356f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne  CFGBlock *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E,
357f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne                                          AddStmtChoice asc);
358852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  CFGBlock *VisitStmtExpr(StmtExpr *S, AddStmtChoice asc);
3594f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *VisitSwitchStmt(SwitchStmt *S);
36099cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan  CFGBlock *VisitUnaryOperator(UnaryOperator *U, AddStmtChoice asc);
3614f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *VisitWhileStmt(WhileStmt *W);
3624f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek
363852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  CFGBlock *Visit(Stmt *S, AddStmtChoice asc = AddStmtChoice::NotAlwaysAdd);
364852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  CFGBlock *VisitStmt(Stmt *S, AddStmtChoice asc);
3659c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *VisitChildren(Stmt *S);
36655331da3211151aa67277aa095b7d301342200d4Ted Kremenek  CFGBlock *VisitNoRecurse(Expr *E, AddStmtChoice asc);
367cd7bf230a77c550115e4a78ee371fc49a7563692Mike Stump
3688599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // Visitors to walk an AST and generate destructors of temporaries in
3698599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // full expression.
3708599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  CFGBlock *VisitForTemporaryDtors(Stmt *E, bool BindToTemporary = false);
3718599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  CFGBlock *VisitChildrenForTemporaryDtors(Stmt *E);
3728599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  CFGBlock *VisitBinaryOperatorForTemporaryDtors(BinaryOperator *E);
3738599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  CFGBlock *VisitCXXBindTemporaryExprForTemporaryDtors(CXXBindTemporaryExpr *E,
3748599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      bool BindToTemporary);
37556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  CFGBlock *
37656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  VisitConditionalOperatorForTemporaryDtors(AbstractConditionalOperator *E,
37756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall                                            bool BindToTemporary);
3788599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
379274f4334f6dd35239e5c3d4b86198f7f5804b059Ted Kremenek  // NYS == Not Yet Supported
3809c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *NYS() {
3814102af916d52310c3deedd84d6fd5e2fd3c09bfeTed Kremenek    badCFG = true;
3824102af916d52310c3deedd84d6fd5e2fd3c09bfeTed Kremenek    return Block;
3834102af916d52310c3deedd84d6fd5e2fd3c09bfeTed Kremenek  }
3846d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3854f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  void autoCreateBlock() { if (!Block) Block = createBlock(); }
3864f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *createBlock(bool add_successor = true);
387dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth  CFGBlock *createNoReturnBlock();
388d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu
389df119892cf291847d6aebb117512225a8e67c0d5Zhongxing Xu  CFGBlock *addStmt(Stmt *S) {
390df119892cf291847d6aebb117512225a8e67c0d5Zhongxing Xu    return Visit(S, AddStmtChoice::AlwaysAdd);
391852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  }
392cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  CFGBlock *addInitializer(CXXCtorInitializer *I);
3936a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xu  void addAutomaticObjDtors(LocalScope::const_iterator B,
3949c378f705405d37f49795d5e915989de774fe11fTed Kremenek                            LocalScope::const_iterator E, Stmt *S);
3957c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  void addImplicitDtorsForDestructor(const CXXDestructorDecl *DD);
396239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
397239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  // Local scopes creation.
398239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  LocalScope* createOrReuseLocalScope(LocalScope* Scope);
399239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
4009c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void addLocalScopeForStmt(Stmt *S);
4019c378f705405d37f49795d5e915989de774fe11fTed Kremenek  LocalScope* addLocalScopeForDeclStmt(DeclStmt *DS, LocalScope* Scope = NULL);
4029c378f705405d37f49795d5e915989de774fe11fTed Kremenek  LocalScope* addLocalScopeForVarDecl(VarDecl *VD, LocalScope* Scope = NULL);
403239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
4049c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void addLocalScopeAndDtors(Stmt *S);
405ad5a894df1841698c824381b414630799adc26caTed Kremenek
406239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  // Interface to CFGBlock - adding CFGElements.
407d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek  void appendStmt(CFGBlock *B, const Stmt *S) {
40874fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek    if (alwaysAdd(S) && cachedEntry)
4090d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek      cachedEntry->second = B;
4100d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
411ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose    // All block-level expressions should have already been IgnoreParens()ed.
412ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose    assert(!isa<Expr>(S) || cast<Expr>(S)->IgnoreParens() == S);
413d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek    B->appendStmt(const_cast<Stmt*>(S), cfg->getBumpVectorContext());
414ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek  }
415cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  void appendInitializer(CFGBlock *B, CXXCtorInitializer *I) {
41682bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski    B->appendInitializer(I, cfg->getBumpVectorContext());
41782bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski  }
4187c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  void appendBaseDtor(CFGBlock *B, const CXXBaseSpecifier *BS) {
4197c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski    B->appendBaseDtor(BS, cfg->getBumpVectorContext());
4207c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  }
4217c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  void appendMemberDtor(CFGBlock *B, FieldDecl *FD) {
4227c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski    B->appendMemberDtor(FD, cfg->getBumpVectorContext());
4237c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  }
4248599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  void appendTemporaryDtor(CFGBlock *B, CXXBindTemporaryExpr *E) {
4258599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    B->appendTemporaryDtor(E, cfg->getBumpVectorContext());
4268599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
427c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  void appendAutomaticObjDtor(CFGBlock *B, VarDecl *VD, Stmt *S) {
428c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth    B->appendAutomaticObjDtor(VD, S, cfg->getBumpVectorContext());
429c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  }
430ad5a894df1841698c824381b414630799adc26caTed Kremenek
4319c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void prependAutomaticObjDtorsWithTerminator(CFGBlock *Blk,
43253de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski      LocalScope::const_iterator B, LocalScope::const_iterator E);
43353de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski
4340a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  void addSuccessor(CFGBlock *B, CFGBlock *S) {
435ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek    B->addSuccessor(S, cfg->getBumpVectorContext());
436ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek  }
4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
438e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  /// Try and evaluate an expression to an integer constant.
439e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  bool tryEvaluate(Expr *S, Expr::EvalResult &outResult) {
440e71f3d587844110d836c82250830b27b1651afdbTed Kremenek    if (!BuildOpts.PruneTriviallyFalseEdges)
441e71f3d587844110d836c82250830b27b1651afdbTed Kremenek      return false;
442e71f3d587844110d836c82250830b27b1651afdbTed Kremenek    return !S->isTypeDependent() &&
443f8adeefa9e9882bff402e092024dd457f8574673Ted Kremenek           !S->isValueDependent() &&
44451f4708c00110940ca3f337961915f2ca1668375Richard Smith           S->EvaluateAsRValue(outResult, *Context);
445e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  }
4461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4470a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  /// tryEvaluateBool - Try and evaluate the Stmt and return 0 or 1
44800998a068e50945118f334c98af05ed44d7c22a6Mike Stump  /// if we can evaluate to a known value, otherwise return -1.
4490a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  TryResult tryEvaluateBool(Expr *S) {
45085df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith    if (!BuildOpts.PruneTriviallyFalseEdges ||
4518c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis        S->isTypeDependent() || S->isValueDependent())
452e71f3d587844110d836c82250830b27b1651afdbTed Kremenek      return TryResult();
4538c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis
4548c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis    if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(S)) {
4558c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis      if (Bop->isLogicalOp()) {
4568c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis        // Check the cache first.
4576955da2cad4bce19c541ddb85a6d965d77a1a4abNAKAMURA Takumi        CachedBoolEvalsTy::iterator I = CachedBoolEvals.find(S);
4586955da2cad4bce19c541ddb85a6d965d77a1a4abNAKAMURA Takumi        if (I != CachedBoolEvals.end())
4598c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis          return I->second; // already in map;
4609260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi
4619260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi        // Retrieve result at first, or the map might be updated.
4629260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi        TryResult Result = evaluateAsBooleanConditionNoCache(S);
4639260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi        CachedBoolEvals[S] = Result; // update or insert
4649260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi        return Result;
4658c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis      }
4668c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis    }
4678c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis
4688c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis    return evaluateAsBooleanConditionNoCache(S);
4698c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis  }
4708c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis
4718c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis  /// \brief Evaluate as boolean \param E without using the cache.
4728c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis  TryResult evaluateAsBooleanConditionNoCache(Expr *E) {
4738c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis    if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(E)) {
4748c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis      if (Bop->isLogicalOp()) {
4758c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis        TryResult LHS = tryEvaluateBool(Bop->getLHS());
4768c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis        if (LHS.isKnown()) {
4778c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis          // We were able to evaluate the LHS, see if we can get away with not
4788c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis          // evaluating the RHS: 0 && X -> 0, 1 || X -> 1
4798c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis          if (LHS.isTrue() == (Bop->getOpcode() == BO_LOr))
4808c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis            return LHS.isTrue();
4818c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis
4828c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis          TryResult RHS = tryEvaluateBool(Bop->getRHS());
4838c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis          if (RHS.isKnown()) {
4848c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis            if (Bop->getOpcode() == BO_LOr)
4858c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis              return LHS.isTrue() || RHS.isTrue();
4868c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis            else
4878c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis              return LHS.isTrue() && RHS.isTrue();
4888c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis          }
4898c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis        } else {
4908c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis          TryResult RHS = tryEvaluateBool(Bop->getRHS());
4918c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis          if (RHS.isKnown()) {
4928c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis            // We can't evaluate the LHS; however, sometimes the result
4938c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis            // is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
4948c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis            if (RHS.isTrue() == (Bop->getOpcode() == BO_LOr))
4958c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis              return RHS.isTrue();
4968c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis          }
4978c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis        }
4988c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis
4998c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis        return TryResult();
5008c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis      }
5018c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis    }
5028c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis
5038c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis    bool Result;
5048c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis    if (E->EvaluateAsBooleanCondition(Result, *Context))
5058c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis      return Result;
5068c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis
5078c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis    return TryResult();
50800998a068e50945118f334c98af05ed44d7c22a6Mike Stump  }
509e71f3d587844110d836c82250830b27b1651afdbTed Kremenek
510d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek};
5116d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
5120d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenekinline bool AddStmtChoice::alwaysAdd(CFGBuilder &builder,
5130d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek                                     const Stmt *stmt) const {
5140d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  return builder.alwaysAdd(stmt) || kind == AlwaysAdd;
5150d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek}
516a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek
5170d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenekbool CFGBuilder::alwaysAdd(const Stmt *stmt) {
51874fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek  bool shouldAdd = BuildOpts.alwaysAdd(stmt);
51974fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek
5200d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  if (!BuildOpts.forcedBlkExprs)
52174fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek    return shouldAdd;
522a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek
523a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek  if (lastLookup == stmt) {
524a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek    if (cachedEntry) {
525a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek      assert(cachedEntry->first == stmt);
526a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek      return true;
527a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek    }
52874fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek    return shouldAdd;
529a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek  }
5300d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
531a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek  lastLookup = stmt;
532a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek
533a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek  // Perform the lookup!
5340d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  CFG::BuildOptions::ForcedBlkExprs *fb = *BuildOpts.forcedBlkExprs;
5350d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
536a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek  if (!fb) {
537a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek    // No need to update 'cachedEntry', since it will always be null.
538a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek    assert(cachedEntry == 0);
53974fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek    return shouldAdd;
540a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek  }
5410d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek
5420d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  CFG::BuildOptions::ForcedBlkExprs::iterator itr = fb->find(stmt);
543a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek  if (itr == fb->end()) {
544a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek    cachedEntry = 0;
54574fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek    return shouldAdd;
546a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek  }
547a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek
5480d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  cachedEntry = &*itr;
5490d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek  return true;
5503179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek}
5513179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek
552898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor// FIXME: Add support for dependent-sized array types in C++?
553898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor// Does it even make sense to build a CFG for an uninstantiated template?
554f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCallstatic const VariableArrayType *FindVA(const Type *t) {
555f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  while (const ArrayType *vt = dyn_cast<ArrayType>(t)) {
556f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall    if (const VariableArrayType *vat = dyn_cast<VariableArrayType>(vt))
557610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek      if (vat->getSizeExpr())
558610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek        return vat;
5596d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
560610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek    t = vt->getElementType().getTypePtr();
561610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek  }
5626d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
563610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek  return 0;
564610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek}
5656d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
5666d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// BuildCFG - Constructs a CFG from an AST (a Stmt*).  The AST can represent an
5676d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump///  arbitrary statement.  Examples include a single expression or a function
5686d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump///  body (compound statement).  The ownership of the returned CFG is
5696d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump///  transferred to the caller.  If CFG construction fails, this method returns
5706d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump///  NULL.
5719c378f705405d37f49795d5e915989de774fe11fTed KremenekCFG* CFGBuilder::buildCFG(const Decl *D, Stmt *Statement) {
5720ba497be27170c2a23c0217366f97eeecefa1ed8Ted Kremenek  assert(cfg.get());
5734f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  if (!Statement)
5744f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    return NULL;
575d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
5766d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Create an empty block that will serve as the exit block for the CFG.  Since
5776d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // this is the first block added to the CFG, it will be implicitly registered
5786d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // as the exit block.
57949af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  Succ = createBlock();
580ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek  assert(Succ == &cfg->getExit());
58149af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  Block = NULL;  // the EXIT block is empty.  Create all other blocks lazily.
5826d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
5837c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  if (BuildOpts.AddImplicitDtors)
5847c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski    if (const CXXDestructorDecl *DD = dyn_cast_or_null<CXXDestructorDecl>(D))
5857c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski      addImplicitDtorsForDestructor(DD);
5867c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski
587d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Visit the statements and create the CFG.
5881b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu  CFGBlock *B = addStmt(Statement);
5891b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu
5901b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu  if (badCFG)
5911b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu    return NULL;
5921b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu
59382bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski  // For C++ constructor add initializers to CFG.
594b978a441c7d8bf59e7fede938e1f3b672573b443Mike Stump  if (const CXXConstructorDecl *CD = dyn_cast_or_null<CXXConstructorDecl>(D)) {
59582bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski    for (CXXConstructorDecl::init_const_reverse_iterator I = CD->init_rbegin(),
59682bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski        E = CD->init_rend(); I != E; ++I) {
59782bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski      B = addInitializer(*I);
59882bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski      if (badCFG)
59982bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski        return NULL;
60082bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski    }
601b978a441c7d8bf59e7fede938e1f3b672573b443Mike Stump  }
6026d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
60382bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski  if (B)
60482bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski    Succ = B;
60582bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski
6061b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu  // Backpatch the gotos whose label -> block mappings we didn't know when we
6071b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu  // encountered them.
6081b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu  for (BackpatchBlocksTy::iterator I = BackpatchBlocks.begin(),
6091b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu                                   E = BackpatchBlocks.end(); I != E; ++I ) {
610c3daac59e26b63c08208de2fbaceb1ff01be3492Daniel Dunbar
6119c378f705405d37f49795d5e915989de774fe11fTed Kremenek    CFGBlock *B = I->block;
6129c378f705405d37f49795d5e915989de774fe11fTed Kremenek    GotoStmt *G = cast<GotoStmt>(B->getTerminator());
6131b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu    LabelMapTy::iterator LI = LabelMap.find(G->getLabel());
6146d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
6151b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu    // If there is no target for the goto, then we are looking at an
6161b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu    // incomplete AST.  Handle this by not registering a successor.
6171b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu    if (LI == LabelMap.end()) continue;
618d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
619f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    JumpTarget JT = LI->second;
6209ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek    prependAutomaticObjDtorsWithTerminator(B, I->scopePosition,
6219ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek                                           JT.scopePosition);
6229ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek    addSuccessor(B, JT.block);
6231b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu  }
6246d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
6251b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu  // Add successors to the Indirect Goto Dispatch block (if we have one).
6269c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (CFGBlock *B = cfg->getIndirectGotoBlock())
6271b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu    for (LabelSetTy::iterator I = AddressTakenLabels.begin(),
6281b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu                              E = AddressTakenLabels.end(); I != E; ++I ) {
6291b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu
6301b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu      // Lookup the target block.
6311b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu      LabelMapTy::iterator LI = LabelMap.find(*I);
6321b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu
6331b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu      // If there is no target block that contains label, then we are looking
6341b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu      // at an incomplete AST.  Handle this by not registering a successor.
6351b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu      if (LI == LabelMap.end()) continue;
6361b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu
6379ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek      addSuccessor(B, LI->second.block);
638c3daac59e26b63c08208de2fbaceb1ff01be3492Daniel Dunbar    }
6396d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
6406d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Create an empty entry block that has no predecessors.
641322f58d3830da13b419646c071e3ab801518a09cTed Kremenek  cfg->setEntry(createBlock());
6426d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
6431b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu  return cfg.take();
644d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
6456d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
646d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek/// createBlock - Used to lazily create blocks that are connected
647d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek///  to the current (global) succcessor.
6489c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::createBlock(bool add_successor) {
6499c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *B = cfg->createBlock();
6504f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  if (add_successor && Succ)
6510a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    addSuccessor(B, Succ);
652d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  return B;
653d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
6546d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
655dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth/// createNoReturnBlock - Used to create a block is a 'noreturn' point in the
656dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth/// CFG. It is *not* connected to the current (global) successor, and instead
657dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth/// directly tied to the exit block in order to be reachable.
658dba3fb5413437dc613734fa4ffac892b11a37d25Chandler CarruthCFGBlock *CFGBuilder::createNoReturnBlock() {
659dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth  CFGBlock *B = createBlock(false);
66083754162f698a5dafad93fb89be0953651a604d0Chandler Carruth  B->setHasNoReturnElement();
661dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth  addSuccessor(B, &cfg->getExit());
662dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth  return B;
663dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth}
664dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth
66582bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski/// addInitializer - Add C++ base or member initializer element to CFG.
666cbb67480094b3bcb5b715acd827cbad55e2a204cSean HuntCFGBlock *CFGBuilder::addInitializer(CXXCtorInitializer *I) {
66782bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski  if (!BuildOpts.AddInitializers)
66882bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski    return Block;
66982bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski
6708599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  bool IsReference = false;
6718599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  bool HasTemporaries = false;
67282bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski
6738599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // Destructors of temporaries in initialization expression should be called
6748599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // after initialization finishes.
6758599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  Expr *Init = I->getInit();
6768599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  if (Init) {
67700eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet    if (FieldDecl *FD = I->getAnyMember())
6788599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      IsReference = FD->getType()->isReferenceType();
6794765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall    HasTemporaries = isa<ExprWithCleanups>(Init);
68082bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski
6818599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    if (BuildOpts.AddImplicitDtors && HasTemporaries) {
6828599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // Generate destructors for temporaries in initialization expression.
6834765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall      VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
6848599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski          IsReference);
6858599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    }
68682bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski  }
6878599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
6888599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  autoCreateBlock();
6898599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  appendInitializer(Block, I);
6908599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
6918599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  if (Init) {
692892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    if (HasTemporaries) {
6938599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // For expression with temporaries go directly to subexpression to omit
6948599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // generating destructors for the second time.
695892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      return Visit(cast<ExprWithCleanups>(Init)->getSubExpr());
696892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    }
697892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    return Visit(Init);
6988599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
6998599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
70082bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski  return Block;
70182bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski}
70282bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski
7032d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor/// \brief Retrieve the type of the temporary object whose lifetime was
7042d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor/// extended by a local reference with the given initializer.
7052d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregorstatic QualType getReferenceInitTemporaryType(ASTContext &Context,
7062d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor                                              const Expr *Init) {
7072d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor  while (true) {
7082d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    // Skip parentheses.
7092d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    Init = Init->IgnoreParens();
7102d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor
7112d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    // Skip through cleanups.
7122d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Init)) {
7132d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor      Init = EWC->getSubExpr();
7142d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor      continue;
7152d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    }
7162d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor
7172d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    // Skip through the temporary-materialization expression.
7182d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    if (const MaterializeTemporaryExpr *MTE
7192d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor          = dyn_cast<MaterializeTemporaryExpr>(Init)) {
7202d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor      Init = MTE->GetTemporaryExpr();
7212d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor      continue;
7222d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    }
7232d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor
7242d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    // Skip derived-to-base and no-op casts.
7252d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    if (const CastExpr *CE = dyn_cast<CastExpr>(Init)) {
7262d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor      if ((CE->getCastKind() == CK_DerivedToBase ||
7272d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor           CE->getCastKind() == CK_UncheckedDerivedToBase ||
7282d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor           CE->getCastKind() == CK_NoOp) &&
7292d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor          Init->getType()->isRecordType()) {
7302d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor        Init = CE->getSubExpr();
7312d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor        continue;
7322d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor      }
7332d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    }
7342d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor
7352d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    // Skip member accesses into rvalues.
7362d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    if (const MemberExpr *ME = dyn_cast<MemberExpr>(Init)) {
7372d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor      if (!ME->isArrow() && ME->getBase()->isRValue()) {
7382d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor        Init = ME->getBase();
7392d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor        continue;
7402d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor      }
7412d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    }
7422d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor
7432d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    break;
7442d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor  }
7452d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor
7462d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor  return Init->getType();
7472d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor}
7482d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor
749239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addAutomaticObjDtors - Add to current block automatic objects destructors
750239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// for objects in range of local scope positions. Use S as trigger statement
751239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// for destructors.
7526a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xuvoid CFGBuilder::addAutomaticObjDtors(LocalScope::const_iterator B,
7539c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                      LocalScope::const_iterator E, Stmt *S) {
754239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  if (!BuildOpts.AddImplicitDtors)
7556a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xu    return;
7566a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xu
757239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  if (B == E)
7586a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xu    return;
759239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
760c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  // We need to append the destructors in reverse order, but any one of them
761c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  // may be a no-return destructor which changes the CFG. As a result, buffer
762c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  // this sequence up and replay them in reverse order when appending onto the
763c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  // CFGBlock(s).
764c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  SmallVector<VarDecl*, 10> Decls;
765c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  Decls.reserve(B.distance(E));
766c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  for (LocalScope::const_iterator I = B; I != E; ++I)
767c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth    Decls.push_back(*I);
768c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth
769c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  for (SmallVectorImpl<VarDecl*>::reverse_iterator I = Decls.rbegin(),
770c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth                                                   E = Decls.rend();
771c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth       I != E; ++I) {
772c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth    // If this destructor is marked as a no-return destructor, we need to
773c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth    // create a new block for the destructor which does not have as a successor
774c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth    // anything built thus far: control won't flow out of this block.
7752d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    QualType Ty;
7762d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    if ((*I)->getType()->isReferenceType()) {
7772d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor      Ty = getReferenceInitTemporaryType(*Context, (*I)->getInit());
7782d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    } else {
7792d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor      Ty = Context->getBaseElementType((*I)->getType());
7802d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    }
7812d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor
782c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth    const CXXDestructorDecl *Dtor = Ty->getAsCXXRecordDecl()->getDestructor();
78323661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie    if (cast<FunctionType>(Dtor->getType())->getNoReturnAttr())
784dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth      Block = createNoReturnBlock();
785dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth    else
786c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth      autoCreateBlock();
787c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth
788c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth    appendAutomaticObjDtor(Block, *I, S);
789c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  }
790239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski}
791239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
7927c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski/// addImplicitDtorsForDestructor - Add implicit destructors generated for
7937c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski/// base and member objects in destructor.
7947c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderskivoid CFGBuilder::addImplicitDtorsForDestructor(const CXXDestructorDecl *DD) {
7957c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  assert (BuildOpts.AddImplicitDtors
7967c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski      && "Can be called only when dtors should be added");
7977c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  const CXXRecordDecl *RD = DD->getParent();
7987c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski
7997c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  // At the end destroy virtual base objects.
8007c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  for (CXXRecordDecl::base_class_const_iterator VI = RD->vbases_begin(),
8017c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski      VE = RD->vbases_end(); VI != VE; ++VI) {
8027c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski    const CXXRecordDecl *CD = VI->getType()->getAsCXXRecordDecl();
8037c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski    if (!CD->hasTrivialDestructor()) {
8047c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski      autoCreateBlock();
8057c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski      appendBaseDtor(Block, VI);
8067c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski    }
8077c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  }
8087c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski
8097c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  // Before virtual bases destroy direct base objects.
8107c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  for (CXXRecordDecl::base_class_const_iterator BI = RD->bases_begin(),
8117c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski      BE = RD->bases_end(); BI != BE; ++BI) {
81223661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie    if (!BI->isVirtual()) {
81323661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie      const CXXRecordDecl *CD = BI->getType()->getAsCXXRecordDecl();
81423661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie      if (!CD->hasTrivialDestructor()) {
81523661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie        autoCreateBlock();
81623661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie        appendBaseDtor(Block, BI);
81723661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie      }
81823661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie    }
8197c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  }
8207c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski
8217c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  // First destroy member objects.
8227c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
8237c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski      FE = RD->field_end(); FI != FE; ++FI) {
8248c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski    // Check for constant size array. Set type to array element type.
8258c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski    QualType QT = FI->getType();
8268c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski    if (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) {
8278c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski      if (AT->getSize() == 0)
8288c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski        continue;
8298c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski      QT = AT->getElementType();
8308c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski    }
8318c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski
8328c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski    if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl())
8337c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski      if (!CD->hasTrivialDestructor()) {
8347c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski        autoCreateBlock();
8357c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski        appendMemberDtor(Block, *FI);
8367c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski      }
8377c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski  }
8387c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski}
8397c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski
840239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// createOrReuseLocalScope - If Scope is NULL create new LocalScope. Either
841239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// way return valid LocalScope object.
842239a7c42df78abc7fd5611d806d5e199fec994d1Marcin SwiderskiLocalScope* CFGBuilder::createOrReuseLocalScope(LocalScope* Scope) {
843239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  if (!Scope) {
844fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek    llvm::BumpPtrAllocator &alloc = cfg->getAllocator();
845fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek    Scope = alloc.Allocate<LocalScope>();
846fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek    BumpVectorContext ctx(alloc);
847fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek    new (Scope) LocalScope(ctx, ScopePos);
848239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  }
849239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  return Scope;
850239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski}
851239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
852239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addLocalScopeForStmt - Add LocalScope to local scopes tree for statement
85302acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu/// that should create implicit scope (e.g. if/else substatements).
8549c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid CFGBuilder::addLocalScopeForStmt(Stmt *S) {
855239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  if (!BuildOpts.AddImplicitDtors)
85602acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu    return;
85702acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu
85802acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu  LocalScope *Scope = 0;
859239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
860239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  // For compound statement we will be creating explicit scope.
861ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(S)) {
862239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski    for (CompoundStmt::body_iterator BI = CS->body_begin(), BE = CS->body_end()
863239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski        ; BI != BE; ++BI) {
864a1364be341550d71dff27dd8de0c6872ba6c707eChandler Carruth      Stmt *SI = (*BI)->stripLabelLikeStatements();
865ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner      if (DeclStmt *DS = dyn_cast<DeclStmt>(SI))
866239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski        Scope = addLocalScopeForDeclStmt(DS, Scope);
867239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski    }
86802acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu    return;
869239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  }
870239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
871239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  // For any other statement scope will be implicit and as such will be
872239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  // interesting only for DeclStmt.
873a1364be341550d71dff27dd8de0c6872ba6c707eChandler Carruth  if (DeclStmt *DS = dyn_cast<DeclStmt>(S->stripLabelLikeStatements()))
874b6edff55db4ff240d56d33594d68a711e4b1e24aZhongxing Xu    addLocalScopeForDeclStmt(DS);
875239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski}
876239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
877239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addLocalScopeForDeclStmt - Add LocalScope for declaration statement. Will
878239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// reuse Scope if not NULL.
8799c378f705405d37f49795d5e915989de774fe11fTed KremenekLocalScope* CFGBuilder::addLocalScopeForDeclStmt(DeclStmt *DS,
880b6edff55db4ff240d56d33594d68a711e4b1e24aZhongxing Xu                                                 LocalScope* Scope) {
881239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  if (!BuildOpts.AddImplicitDtors)
882239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski    return Scope;
883239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
884239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end()
885239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski      ; DI != DE; ++DI) {
8869c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (VarDecl *VD = dyn_cast<VarDecl>(*DI))
887239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski      Scope = addLocalScopeForVarDecl(VD, Scope);
888239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  }
889239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  return Scope;
890239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski}
891239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
892239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addLocalScopeForVarDecl - Add LocalScope for variable declaration. It will
893239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// create add scope for automatic objects and temporary objects bound to
894239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// const reference. Will reuse Scope if not NULL.
8959c378f705405d37f49795d5e915989de774fe11fTed KremenekLocalScope* CFGBuilder::addLocalScopeForVarDecl(VarDecl *VD,
896b6edff55db4ff240d56d33594d68a711e4b1e24aZhongxing Xu                                                LocalScope* Scope) {
897239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  if (!BuildOpts.AddImplicitDtors)
898239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski    return Scope;
899239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
900239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  // Check if variable is local.
901239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  switch (VD->getStorageClass()) {
902239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  case SC_None:
903239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  case SC_Auto:
904239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  case SC_Register:
905239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski    break;
906239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  default: return Scope;
907239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  }
908239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
909239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  // Check for const references bound to temporary. Set type to pointee.
910239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  QualType QT = VD->getType();
9112d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor  if (QT.getTypePtr()->isReferenceType()) {
91203e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor    if (!VD->extendsLifetimeOfTemporary())
913239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski      return Scope;
9142d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor
9152d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor    QT = getReferenceInitTemporaryType(*Context, VD->getInit());
916239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  }
917239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
918b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski  // Check for constant size array. Set type to array element type.
9192d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor  while (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) {
920b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski    if (AT->getSize() == 0)
921b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski      return Scope;
922b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski    QT = AT->getElementType();
923b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski  }
9244e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu
925b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski  // Check if type is a C++ class with non-trivial destructor.
9269c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl())
92723661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie    if (!CD->hasTrivialDestructor()) {
9284e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu      // Add the variable to scope
9294e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu      Scope = createOrReuseLocalScope(Scope);
9304e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu      Scope->addVar(VD);
9314e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu      ScopePos = Scope->begin();
9324e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu    }
933239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  return Scope;
934239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski}
935239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
936239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addLocalScopeAndDtors - For given statement add local scope for it and
937239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// add destructors that will cleanup the scope. Will reuse Scope if not NULL.
9389c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid CFGBuilder::addLocalScopeAndDtors(Stmt *S) {
939239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  if (!BuildOpts.AddImplicitDtors)
940239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski    return;
941239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
942239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  LocalScope::const_iterator scopeBeginPos = ScopePos;
94302acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu  addLocalScopeForStmt(S);
944239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski  addAutomaticObjDtors(ScopePos, scopeBeginPos, S);
945239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski}
946239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski
94753de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// prependAutomaticObjDtorsWithTerminator - Prepend destructor CFGElements for
94853de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// variables with automatic storage duration to CFGBlock's elements vector.
94953de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// Elements will be prepended to physical beginning of the vector which
95053de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// happens to be logical end. Use blocks terminator as statement that specifies
95153de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// destructors call site.
952c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth/// FIXME: This mechanism for adding automatic destructors doesn't handle
953c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth/// no-return destructors properly.
9549c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid CFGBuilder::prependAutomaticObjDtorsWithTerminator(CFGBlock *Blk,
95553de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski    LocalScope::const_iterator B, LocalScope::const_iterator E) {
956c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  BumpVectorContext &C = cfg->getBumpVectorContext();
957c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  CFGBlock::iterator InsertPos
958c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth    = Blk->beginAutomaticObjDtorsInsert(Blk->end(), B.distance(E), C);
959c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth  for (LocalScope::const_iterator I = B; I != E; ++I)
960c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth    InsertPos = Blk->insertAutomaticObjDtor(InsertPos, *I,
961c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth                                            Blk->getTerminator());
96253de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski}
96353de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski
9644f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// Visit - Walk the subtree of a statement and add extra
9656d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump///   blocks for ternary operators, &&, and ||.  We also process "," and
9666d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump///   DeclStmts (which may contain nested control-flow).
9679c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc) {
968f42e3371079de333c3822a060c008bf6680677c8Ted Kremenek  if (!S) {
969f42e3371079de333c3822a060c008bf6680677c8Ted Kremenek    badCFG = true;
970f42e3371079de333c3822a060c008bf6680677c8Ted Kremenek    return 0;
971f42e3371079de333c3822a060c008bf6680677c8Ted Kremenek  }
972ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose
973ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose  if (Expr *E = dyn_cast<Expr>(S))
974ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose    S = E->IgnoreParens();
975ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose
9764f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  switch (S->getStmtClass()) {
9774f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    default:
978852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      return VisitStmt(S, asc);
9794f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek
9804f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::AddrLabelExprClass:
981852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      return VisitAddrLabelExpr(cast<AddrLabelExpr>(S), asc);
9821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
98356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    case Stmt::BinaryConditionalOperatorClass:
98456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      return VisitConditionalOperator(cast<BinaryConditionalOperator>(S), asc);
98556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall
9864f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::BinaryOperatorClass:
987852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      return VisitBinaryOperator(cast<BinaryOperator>(S), asc);
9881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9894f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::BlockExprClass:
99055331da3211151aa67277aa095b7d301342200d4Ted Kremenek      return VisitNoRecurse(cast<Expr>(S), asc);
9914f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek
9924f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::BreakStmtClass:
9934f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitBreakStmt(cast<BreakStmt>(S));
9941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9954f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::CallExprClass:
996a427f1d8f0848997029d1bdc0c5c137f982f775dTed Kremenek    case Stmt::CXXOperatorCallExprClass:
9971de85338543dd6228eb518185e385d94d377f4cbJohn McCall    case Stmt::CXXMemberCallExprClass:
9989fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith    case Stmt::UserDefinedLiteralClass:
999852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      return VisitCallExpr(cast<CallExpr>(S), asc);
10001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10014f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::CaseStmtClass:
10024f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitCaseStmt(cast<CaseStmt>(S));
10034f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek
10044f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::ChooseExprClass:
1005852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      return VisitChooseExpr(cast<ChooseExpr>(S), asc);
10061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10074f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::CompoundStmtClass:
10084f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitCompoundStmt(cast<CompoundStmt>(S));
10091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10104f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::ConditionalOperatorClass:
1011852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      return VisitConditionalOperator(cast<ConditionalOperator>(S), asc);
10121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10134f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::ContinueStmtClass:
10144f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitContinueStmt(cast<ContinueStmt>(S));
10151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1016021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek    case Stmt::CXXCatchStmtClass:
1017021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek      return VisitCXXCatchStmt(cast<CXXCatchStmt>(S));
1018021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek
10194765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall    case Stmt::ExprWithCleanupsClass:
10204765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall      return VisitExprWithCleanups(cast<ExprWithCleanups>(S), asc);
102147e331ed28c2536bec227c5e2fa094ab3d46eed1Ted Kremenek
1022a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu    case Stmt::CXXBindTemporaryExprClass:
1023a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu      return VisitCXXBindTemporaryExpr(cast<CXXBindTemporaryExpr>(S), asc);
1024a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu
102581bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu    case Stmt::CXXConstructExprClass:
102681bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu      return VisitCXXConstructExpr(cast<CXXConstructExpr>(S), asc);
102781bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu
1028a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu    case Stmt::CXXFunctionalCastExprClass:
1029a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu      return VisitCXXFunctionalCastExpr(cast<CXXFunctionalCastExpr>(S), asc);
1030a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu
103181bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu    case Stmt::CXXTemporaryObjectExprClass:
103281bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu      return VisitCXXTemporaryObjectExpr(cast<CXXTemporaryObjectExpr>(S), asc);
103381bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu
1034021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek    case Stmt::CXXThrowExprClass:
1035021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek      return VisitCXXThrowExpr(cast<CXXThrowExpr>(S));
1036ad5a894df1841698c824381b414630799adc26caTed Kremenek
1037021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek    case Stmt::CXXTryStmtClass:
1038021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek      return VisitCXXTryStmt(cast<CXXTryStmt>(S));
1039ad5a894df1841698c824381b414630799adc26caTed Kremenek
1040ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    case Stmt::CXXForRangeStmtClass:
1041ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith      return VisitCXXForRangeStmt(cast<CXXForRangeStmt>(S));
1042ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
10434f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::DeclStmtClass:
10444f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitDeclStmt(cast<DeclStmt>(S));
10451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10464f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::DefaultStmtClass:
10474f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitDefaultStmt(cast<DefaultStmt>(S));
10481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10494f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::DoStmtClass:
10504f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitDoStmt(cast<DoStmt>(S));
10511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10524f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::ForStmtClass:
10534f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitForStmt(cast<ForStmt>(S));
10541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10554f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::GotoStmtClass:
10564f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitGotoStmt(cast<GotoStmt>(S));
10571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10584f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::IfStmtClass:
10594f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitIfStmt(cast<IfStmt>(S));
10601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1061892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    case Stmt::ImplicitCastExprClass:
1062892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek      return VisitImplicitCastExpr(cast<ImplicitCastExpr>(S), asc);
1063a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu
10644f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::IndirectGotoStmtClass:
10654f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitIndirectGotoStmt(cast<IndirectGotoStmt>(S));
10661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10674f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::LabelStmtClass:
10684f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitLabelStmt(cast<LabelStmt>(S));
10691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
107083748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek    case Stmt::LambdaExprClass:
107183748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek      return VisitLambdaExpr(cast<LambdaExpr>(S), asc);
107283748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek
1073534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith    case Stmt::AttributedStmtClass:
1074534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith      return Visit(cast<AttributedStmt>(S)->getSubStmt(), asc);
1075534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith
1076115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek    case Stmt::MemberExprClass:
1077115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek      return VisitMemberExpr(cast<MemberExpr>(S), asc);
1078115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek
10796a9065a39ab15383082b914af28759da1652db18Ted Kremenek    case Stmt::NullStmtClass:
10806a9065a39ab15383082b914af28759da1652db18Ted Kremenek      return Block;
10816a9065a39ab15383082b914af28759da1652db18Ted Kremenek
10824f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::ObjCAtCatchStmtClass:
10831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return VisitObjCAtCatchStmt(cast<ObjCAtCatchStmt>(S));
10841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10858e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek    case Stmt::ObjCAutoreleasePoolStmtClass:
10868e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek    return VisitObjCAutoreleasePoolStmt(cast<ObjCAutoreleasePoolStmt>(S));
10878e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek
10884f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::ObjCAtSynchronizedStmtClass:
10894f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S));
10901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10914f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::ObjCAtThrowStmtClass:
10924f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(S));
10931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10944f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::ObjCAtTryStmtClass:
10954f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitObjCAtTryStmt(cast<ObjCAtTryStmt>(S));
10961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10974f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::ObjCForCollectionStmtClass:
10984f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S));
10991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11006a9065a39ab15383082b914af28759da1652db18Ted Kremenek    case Stmt::OpaqueValueExprClass:
11014f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return Block;
11021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11034b9c2d235fb9449e249d74f48ecfec601650de93John McCall    case Stmt::PseudoObjectExprClass:
11044b9c2d235fb9449e249d74f48ecfec601650de93John McCall      return VisitPseudoObjectExpr(cast<PseudoObjectExpr>(S));
11054b9c2d235fb9449e249d74f48ecfec601650de93John McCall
11064f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::ReturnStmtClass:
11074f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitReturnStmt(cast<ReturnStmt>(S));
11081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1109f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne    case Stmt::UnaryExprOrTypeTraitExprClass:
1110f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne      return VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
1111f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne                                           asc);
11121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11134f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::StmtExprClass:
1114852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek      return VisitStmtExpr(cast<StmtExpr>(S), asc);
11151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11164f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::SwitchStmtClass:
11174f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitSwitchStmt(cast<SwitchStmt>(S));
11181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
111999cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan    case Stmt::UnaryOperatorClass:
112099cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan      return VisitUnaryOperator(cast<UnaryOperator>(S), asc);
112199cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan
11224f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    case Stmt::WhileStmtClass:
11234f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return VisitWhileStmt(cast<WhileStmt>(S));
11244f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  }
11254f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek}
11261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1127852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekCFGBlock *CFGBuilder::VisitStmt(Stmt *S, AddStmtChoice asc) {
11283179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek  if (asc.alwaysAdd(*this, S)) {
11294f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    autoCreateBlock();
1130247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek    appendStmt(Block, S);
11316d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  }
11321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11334f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  return VisitChildren(S);
11344f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek}
11356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
11364f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// VisitChildren - Visit the children of a Stmt.
11379c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitChildren(Stmt *Terminator) {
1138534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  CFGBlock *lastBlock = Block;
11396b12da9f89b7863e6fc995312355b94197b75657Ted Kremenek  for (Stmt::child_range I = Terminator->children(); I; ++I)
11406b12da9f89b7863e6fc995312355b94197b75657Ted Kremenek    if (Stmt *child = *I)
11416b12da9f89b7863e6fc995312355b94197b75657Ted Kremenek      if (CFGBlock *b = Visit(child))
11426b12da9f89b7863e6fc995312355b94197b75657Ted Kremenek        lastBlock = b;
11436b12da9f89b7863e6fc995312355b94197b75657Ted Kremenek
11446b12da9f89b7863e6fc995312355b94197b75657Ted Kremenek  return lastBlock;
11454f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek}
11461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1147852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekCFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A,
1148852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek                                         AddStmtChoice asc) {
11494f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  AddressTakenLabels.insert(A->getLabel());
11506d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
11513179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek  if (asc.alwaysAdd(*this, A)) {
11524f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    autoCreateBlock();
1153247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek    appendStmt(Block, A);
11546d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  }
11556d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
11564f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  return Block;
11574f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek}
11581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
115999cae5b67b9711ca260e5b364a878a1a91183632Zhanyong WanCFGBlock *CFGBuilder::VisitUnaryOperator(UnaryOperator *U,
1160892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek           AddStmtChoice asc) {
11613179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek  if (asc.alwaysAdd(*this, U)) {
116299cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan    autoCreateBlock();
1163247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek    appendStmt(Block, U);
116499cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan  }
116599cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan
1166892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  return Visit(U->getSubExpr(), AddStmtChoice());
116799cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan}
116899cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan
1169852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekCFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B,
1170852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek                                          AddStmtChoice asc) {
11714f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  if (B->isLogicalOp()) { // && or ||
11729c378f705405d37f49795d5e915989de774fe11fTed Kremenek    CFGBlock *ConfluenceBlock = Block ? Block : createBlock();
1173247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek    appendStmt(ConfluenceBlock, B);
11741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1175d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    if (badCFG)
11764f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      return 0;
11771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11784f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    // create the block evaluating the LHS
11799c378f705405d37f49795d5e915989de774fe11fTed Kremenek    CFGBlock *LHSBlock = createBlock(false);
11804f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    LHSBlock->setTerminator(B);
11811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11824f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    // create the block evaluating the RHS
11834f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    Succ = ConfluenceBlock;
11844f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    Block = NULL;
11859c378f705405d37f49795d5e915989de774fe11fTed Kremenek    CFGBlock *RHSBlock = addStmt(B->getRHS());
1186862b24f8e9b1a3b332399591e48b303f57f01d0aTed Kremenek
1187862b24f8e9b1a3b332399591e48b303f57f01d0aTed Kremenek    if (RHSBlock) {
1188d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu      if (badCFG)
1189862b24f8e9b1a3b332399591e48b303f57f01d0aTed Kremenek        return 0;
119036f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan    } else {
1191862b24f8e9b1a3b332399591e48b303f57f01d0aTed Kremenek      // Create an empty block for cases where the RHS doesn't require
1192862b24f8e9b1a3b332399591e48b303f57f01d0aTed Kremenek      // any explicit statements in the CFG.
1193862b24f8e9b1a3b332399591e48b303f57f01d0aTed Kremenek      RHSBlock = createBlock();
1194862b24f8e9b1a3b332399591e48b303f57f01d0aTed Kremenek    }
11951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11968c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis    // Generate the blocks for evaluating the LHS.
11978c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis    Block = LHSBlock;
11988c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis    CFGBlock *EntryLHSBlock = addStmt(B->getLHS());
11998c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis
120000998a068e50945118f334c98af05ed44d7c22a6Mike Stump    // See if this is a known constant.
12010a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    TryResult KnownVal = tryEvaluateBool(B->getLHS());
12022de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    if (KnownVal.isKnown() && (B->getOpcode() == BO_LOr))
1203941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek      KnownVal.negate();
120400998a068e50945118f334c98af05ed44d7c22a6Mike Stump
12054f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    // Now link the LHSBlock with RHSBlock.
12062de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    if (B->getOpcode() == BO_LOr) {
12070a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      addSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : ConfluenceBlock);
12080a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      addSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : RHSBlock);
12091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    } else {
12102de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      assert(B->getOpcode() == BO_LAnd);
12110a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      addSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : RHSBlock);
12120a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      addSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : ConfluenceBlock);
121319bb356317952445b03ee341c02f6147083c9eeaTed Kremenek    }
12141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12158c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis    return EntryLHSBlock;
12161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
121736f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan
121836f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan  if (B->getOpcode() == BO_Comma) { // ,
12196dc534ecc19a045ebcfe93eefa45da509968e888Ted Kremenek    autoCreateBlock();
1220247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek    appendStmt(Block, B);
12214f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    addStmt(B->getRHS());
12224f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    return addStmt(B->getLHS());
12236d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  }
122436f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan
122536f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan  if (B->isAssignmentOp()) {
12263179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek    if (asc.alwaysAdd(*this, B)) {
1227fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu      autoCreateBlock();
1228247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek      appendStmt(Block, B);
1229fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu    }
1230892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    Visit(B->getLHS());
1231e1667190dff025936a21e5eb43889ac93b570468Marcin Swiderski    return Visit(B->getRHS());
1232fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu  }
12331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12343179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek  if (asc.alwaysAdd(*this, B)) {
1235e1667190dff025936a21e5eb43889ac93b570468Marcin Swiderski    autoCreateBlock();
1236247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek    appendStmt(Block, B);
1237e1667190dff025936a21e5eb43889ac93b570468Marcin Swiderski  }
1238e1667190dff025936a21e5eb43889ac93b570468Marcin Swiderski
1239a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu  CFGBlock *RBlock = Visit(B->getRHS());
1240a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu  CFGBlock *LBlock = Visit(B->getLHS());
1241a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu  // If visiting RHS causes us to finish 'Block', e.g. the RHS is a StmtExpr
1242a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu  // containing a DoStmt, and the LHS doesn't create a new block, then we should
1243a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu  // return RBlock.  Otherwise we'll incorrectly return NULL.
1244a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu  return (LBlock ? LBlock : RBlock);
12454f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek}
12466d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
124755331da3211151aa67277aa095b7d301342200d4Ted KremenekCFGBlock *CFGBuilder::VisitNoRecurse(Expr *E, AddStmtChoice asc) {
12483179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek  if (asc.alwaysAdd(*this, E)) {
1249721903eca33f6115296083aed17685eaa73d3e8cTed Kremenek    autoCreateBlock();
1250247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek    appendStmt(Block, E);
1251721903eca33f6115296083aed17685eaa73d3e8cTed Kremenek  }
1252721903eca33f6115296083aed17685eaa73d3e8cTed Kremenek  return Block;
12534f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek}
1254cd7bf230a77c550115e4a78ee371fc49a7563692Mike Stump
12554f88063677a2d990a44bb0d5f8437d2498b91d7fTed KremenekCFGBlock *CFGBuilder::VisitBreakStmt(BreakStmt *B) {
12564f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  // "break" is a control-flow statement.  Thus we stop processing the current
12574f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  // block.
1258d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
1259d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    return 0;
12601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12614f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  // Now create a new block that ends with the break statement.
12624f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  Block = createBlock(false);
12634f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  Block->setTerminator(B);
12641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12654f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  // If there is no target for the break, then we are looking at an incomplete
12664f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  // AST.  This means that the CFG cannot be constructed.
12679ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek  if (BreakJumpTarget.block) {
12689ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek    addAutomaticObjDtors(ScopePos, BreakJumpTarget.scopePosition, B);
12699ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek    addSuccessor(Block, BreakJumpTarget.block);
1270f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  } else
12714f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    badCFG = true;
12721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12744f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  return Block;
12754f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek}
12761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12778026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redlstatic bool CanThrow(Expr *E, ASTContext &Ctx) {
12784c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump  QualType Ty = E->getType();
12794c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump  if (Ty->isFunctionPointerType())
12804c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump    Ty = Ty->getAs<PointerType>()->getPointeeType();
12814c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump  else if (Ty->isBlockPointerType())
12824c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
1283ad5a894df1841698c824381b414630799adc26caTed Kremenek
12844c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump  const FunctionType *FT = Ty->getAs<FunctionType>();
12854c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump  if (FT) {
12864c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump    if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT))
1287e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith      if (Proto->getExceptionSpecType() != EST_Uninstantiated &&
1288e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith          Proto->isNothrow(Ctx))
12894c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump        return false;
12904c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump  }
12914c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump  return true;
12924c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump}
12934c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump
1294852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekCFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) {
12951de85338543dd6228eb518185e385d94d377f4cbJohn McCall  // Compute the callee type.
12961de85338543dd6228eb518185e385d94d377f4cbJohn McCall  QualType calleeType = C->getCallee()->getType();
12971de85338543dd6228eb518185e385d94d377f4cbJohn McCall  if (calleeType == Context->BoundMemberTy) {
12981de85338543dd6228eb518185e385d94d377f4cbJohn McCall    QualType boundType = Expr::findBoundMemberType(C->getCallee());
12991de85338543dd6228eb518185e385d94d377f4cbJohn McCall
13001de85338543dd6228eb518185e385d94d377f4cbJohn McCall    // We should only get a null bound type if processing a dependent
13011de85338543dd6228eb518185e385d94d377f4cbJohn McCall    // CFG.  Recover by assuming nothing.
13021de85338543dd6228eb518185e385d94d377f4cbJohn McCall    if (!boundType.isNull()) calleeType = boundType;
13032455636163fdd18581d7fdae816433f886d88213Mike Stump  }
13042455636163fdd18581d7fdae816433f886d88213Mike Stump
13051de85338543dd6228eb518185e385d94d377f4cbJohn McCall  // If this is a call to a no-return function, this stops the block here.
13061de85338543dd6228eb518185e385d94d377f4cbJohn McCall  bool NoReturn = getFunctionExtInfo(*calleeType).getNoReturn();
13071de85338543dd6228eb518185e385d94d377f4cbJohn McCall
13084c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump  bool AddEHEdge = false;
1309079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump
1310079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump  // Languages without exceptions are assumed to not throw.
13114e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (Context->getLangOpts().Exceptions) {
13126c52c7850bccb6991470668429a1e1edf01b0873Ted Kremenek    if (BuildOpts.AddEHEdges)
13134c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump      AddEHEdge = true;
1314079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump  }
1315079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump
1316079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump  if (FunctionDecl *FD = C->getDirectCallee()) {
13172455636163fdd18581d7fdae816433f886d88213Mike Stump    if (FD->hasAttr<NoReturnAttr>())
13182455636163fdd18581d7fdae816433f886d88213Mike Stump      NoReturn = true;
1319079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump    if (FD->hasAttr<NoThrowAttr>())
13204c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump      AddEHEdge = false;
1321079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump  }
13222455636163fdd18581d7fdae816433f886d88213Mike Stump
13238026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redl  if (!CanThrow(C->getCallee(), *Context))
13244c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump    AddEHEdge = false;
13254c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump
132694a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan  if (!NoReturn && !AddEHEdge)
132794a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan    return VisitStmt(C, asc.withAlwaysAdd(true));
13281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1329079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump  if (Block) {
1330079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump    Succ = Block;
1331d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    if (badCFG)
1332079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump      return 0;
1333079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump  }
13341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1335dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth  if (NoReturn)
1336dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth    Block = createNoReturnBlock();
1337dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth  else
1338dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth    Block = createBlock();
1339dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth
1340247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek  appendStmt(Block, C);
13412455636163fdd18581d7fdae816433f886d88213Mike Stump
13424c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump  if (AddEHEdge) {
1343079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump    // Add exceptional edges.
1344079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump    if (TryTerminatedBlock)
13450a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      addSuccessor(Block, TryTerminatedBlock);
1346079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump    else
13470a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      addSuccessor(Block, &cfg->getExit());
1348079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump  }
13491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13502455636163fdd18581d7fdae816433f886d88213Mike Stump  return VisitChildren(C);
1351d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
1352d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
1353852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekCFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C,
1354852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek                                      AddStmtChoice asc) {
13559c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *ConfluenceBlock = Block ? Block : createBlock();
1356247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek  appendStmt(ConfluenceBlock, C);
1357d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
13583fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek    return 0;
13591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
136094a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan  AddStmtChoice alwaysAdd = asc.withAlwaysAdd(true);
13613fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek  Succ = ConfluenceBlock;
13623fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek  Block = NULL;
13639c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *LHSBlock = Visit(C->getLHS(), alwaysAdd);
1364d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
13653fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek    return 0;
13661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13673fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek  Succ = ConfluenceBlock;
13683fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek  Block = NULL;
13699c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *RHSBlock = Visit(C->getRHS(), alwaysAdd);
1370d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
13713fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek    return 0;
13721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13733fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek  Block = createBlock(false);
137400998a068e50945118f334c98af05ed44d7c22a6Mike Stump  // See if this is a known constant.
13750a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  const TryResult& KnownVal = tryEvaluateBool(C->getCond());
13760a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  addSuccessor(Block, KnownVal.isFalse() ? NULL : LHSBlock);
13770a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  addSuccessor(Block, KnownVal.isTrue() ? NULL : RHSBlock);
13783fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek  Block->setTerminator(C);
13791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return addStmt(C->getCond());
13803fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek}
13811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13839c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) {
1384fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski  addLocalScopeAndDtors(C);
13859c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *LastBlock = Block;
13864f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek
13874f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend();
13884f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek       I != E; ++I ) {
1389334c19566104d3333cf662f0017088a18eddfa81Ted Kremenek    // If we hit a segment of code just containing ';' (NullStmts), we can
1390334c19566104d3333cf662f0017088a18eddfa81Ted Kremenek    // get a null block back.  In such cases, just use the LastBlock
1391334c19566104d3333cf662f0017088a18eddfa81Ted Kremenek    if (CFGBlock *newBlock = addStmt(*I))
1392334c19566104d3333cf662f0017088a18eddfa81Ted Kremenek      LastBlock = newBlock;
13931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1394e8d6d2b9a2c5d3f0e7e0f88f54f1711bbc6c6f78Ted Kremenek    if (badCFG)
1395e8d6d2b9a2c5d3f0e7e0f88f54f1711bbc6c6f78Ted Kremenek      return NULL;
13961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
1397079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump
13984f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  return LastBlock;
13994f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek}
14001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
140156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCallCFGBlock *CFGBuilder::VisitConditionalOperator(AbstractConditionalOperator *C,
1402852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek                                               AddStmtChoice asc) {
140356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  const BinaryConditionalOperator *BCO = dyn_cast<BinaryConditionalOperator>(C);
140456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  const OpaqueValueExpr *opaqueValue = (BCO ? BCO->getOpaqueValue() : NULL);
140556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall
1406f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  // Create the confluence block that will "merge" the results of the ternary
1407f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  // expression.
14089c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *ConfluenceBlock = Block ? Block : createBlock();
1409247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek  appendStmt(ConfluenceBlock, C);
1410d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
1411f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek    return 0;
14121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
141394a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan  AddStmtChoice alwaysAdd = asc.withAlwaysAdd(true);
1414115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek
1415f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  // Create a block for the LHS expression if there is an LHS expression.  A
1416f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  // GCC extension allows LHS to be NULL, causing the condition to be the
1417f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  // value that is returned instead.
1418f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  //  e.g: x ?: y is shorthand for: x ? x : y;
1419f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  Succ = ConfluenceBlock;
1420f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  Block = NULL;
14219c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *LHSBlock = 0;
142256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  const Expr *trueExpr = C->getTrueExpr();
142356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  if (trueExpr != opaqueValue) {
142456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    LHSBlock = Visit(C->getTrueExpr(), alwaysAdd);
1425d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    if (badCFG)
1426f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek      return 0;
1427f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek    Block = NULL;
1428f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  }
1429f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek  else
1430f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek    LHSBlock = ConfluenceBlock;
14311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1432f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  // Create the block for the RHS expression.
1433f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  Succ = ConfluenceBlock;
14349c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *RHSBlock = Visit(C->getFalseExpr(), alwaysAdd);
1435d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
1436f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek    return 0;
14371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1438f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  // Create the block that will contain the condition.
1439f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  Block = createBlock(false);
14401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
144100998a068e50945118f334c98af05ed44d7c22a6Mike Stump  // See if this is a known constant.
14420a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  const TryResult& KnownVal = tryEvaluateBool(C->getCond());
1443f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek  addSuccessor(Block, KnownVal.isFalse() ? NULL : LHSBlock);
14440a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  addSuccessor(Block, KnownVal.isTrue() ? NULL : RHSBlock);
1445f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek  Block->setTerminator(C);
144656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  Expr *condExpr = C->getCond();
1447d40baf6a77f6353a93f181da5d1347d3730aad37John McCall
1448f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek  if (opaqueValue) {
1449f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek    // Run the condition expression if it's not trivially expressed in
1450f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek    // terms of the opaque value (or if there is no opaque value).
1451f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek    if (condExpr != opaqueValue)
1452f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek      addStmt(condExpr);
1453d40baf6a77f6353a93f181da5d1347d3730aad37John McCall
1454f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek    // Before that, run the common subexpression if there was one.
1455f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek    // At least one of this or the above will be run.
1456f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek    return addStmt(BCO->getCommon());
1457f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek  }
1458f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek
1459f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek  return addStmt(condExpr);
1460f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek}
1461f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek
14624f88063677a2d990a44bb0d5f8437d2498b91d7fTed KremenekCFGBlock *CFGBuilder::VisitDeclStmt(DeclStmt *DS) {
1463bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek  // Check if the Decl is for an __label__.  If so, elide it from the
1464bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek  // CFG entirely.
1465bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek  if (isa<LabelDecl>(*DS->decl_begin()))
1466bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek    return Block;
1467bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek
146829c9e62f412c9db3ee238db2472390685a6303f3Ted Kremenek  // This case also handles static_asserts.
14698599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  if (DS->isSingleDecl())
14708599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    return VisitDeclSubExpr(DS);
14711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14724f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *B = 0;
14731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14744f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  // FIXME: Add a reverse iterator for DeclStmt to avoid this extra copy.
14755f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  typedef SmallVector<Decl*,10> BufTy;
14764f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  BufTy Buf(DS->decl_begin(), DS->decl_end());
14771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14784f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  for (BufTy::reverse_iterator I = Buf.rbegin(), E = Buf.rend(); I != E; ++I) {
14794f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    // Get the alignment of the new DeclStmt, padding out to >=8 bytes.
14804f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    unsigned A = llvm::AlignOf<DeclStmt>::Alignment < 8
14814f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek               ? 8 : llvm::AlignOf<DeclStmt>::Alignment;
14821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14834f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    // Allocate the DeclStmt using the BumpPtrAllocator.  It will get
14844f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    // automatically freed with the CFG.
14854f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    DeclGroupRef DG(*I);
14864f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    Decl *D = *I;
14871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    void *Mem = cfg->getAllocator().Allocate(sizeof(DeclStmt), A);
14884f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    DeclStmt *DSNew = new (Mem) DeclStmt(DG, D->getLocation(), GetEndLoc(D));
14891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14904f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    // Append the fake DeclStmt to block.
14918599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    B = VisitDeclSubExpr(DSNew);
14924f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  }
14931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return B;
14954f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek}
14961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14974f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// VisitDeclSubExpr - Utility method to add block-level expressions for
14988599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski/// DeclStmts and initializers in them.
14999c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) {
15008599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  assert(DS->isSingleDecl() && "Can handle single declarations only.");
150129c9e62f412c9db3ee238db2472390685a6303f3Ted Kremenek  Decl *D = DS->getSingleDecl();
150229c9e62f412c9db3ee238db2472390685a6303f3Ted Kremenek
150329c9e62f412c9db3ee238db2472390685a6303f3Ted Kremenek  if (isa<StaticAssertDecl>(D)) {
150429c9e62f412c9db3ee238db2472390685a6303f3Ted Kremenek    // static_asserts aren't added to the CFG because they do not impact
150529c9e62f412c9db3ee238db2472390685a6303f3Ted Kremenek    // runtime semantics.
150629c9e62f412c9db3ee238db2472390685a6303f3Ted Kremenek    return Block;
150729c9e62f412c9db3ee238db2472390685a6303f3Ted Kremenek  }
150829c9e62f412c9db3ee238db2472390685a6303f3Ted Kremenek
15098599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
15101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15118599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  if (!VD) {
15128599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    autoCreateBlock();
1513892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    appendStmt(Block, DS);
15144f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    return Block;
15158599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
15161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15178599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  bool IsReference = false;
15188599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  bool HasTemporaries = false;
15198599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
15208599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // Destructors of temporaries in initialization expression should be called
15218599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // after initialization finishes.
15224f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  Expr *Init = VD->getInit();
15238599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  if (Init) {
15248599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    IsReference = VD->getType()->isReferenceType();
15254765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall    HasTemporaries = isa<ExprWithCleanups>(Init);
15268599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
15278599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    if (BuildOpts.AddImplicitDtors && HasTemporaries) {
15288599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // Generate destructors for temporaries in initialization expression.
15294765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall      VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
15308599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski          IsReference);
15318599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    }
15328599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
15338599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
15348599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  autoCreateBlock();
1535892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  appendStmt(Block, DS);
1536550f2234fc9218914c325041067052342dfce553Ted Kremenek
1537550f2234fc9218914c325041067052342dfce553Ted Kremenek  // Keep track of the last non-null block, as 'Block' can be nulled out
1538550f2234fc9218914c325041067052342dfce553Ted Kremenek  // if the initializer expression is something like a 'while' in a
1539550f2234fc9218914c325041067052342dfce553Ted Kremenek  // statement-expression.
1540550f2234fc9218914c325041067052342dfce553Ted Kremenek  CFGBlock *LastBlock = Block;
15411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15424f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  if (Init) {
1543550f2234fc9218914c325041067052342dfce553Ted Kremenek    if (HasTemporaries) {
15448599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // For expression with temporaries go directly to subexpression to omit
15458599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // generating destructors for the second time.
1546550f2234fc9218914c325041067052342dfce553Ted Kremenek      ExprWithCleanups *EC = cast<ExprWithCleanups>(Init);
1547550f2234fc9218914c325041067052342dfce553Ted Kremenek      if (CFGBlock *newBlock = Visit(EC->getSubExpr()))
1548550f2234fc9218914c325041067052342dfce553Ted Kremenek        LastBlock = newBlock;
1549550f2234fc9218914c325041067052342dfce553Ted Kremenek    }
1550550f2234fc9218914c325041067052342dfce553Ted Kremenek    else {
1551550f2234fc9218914c325041067052342dfce553Ted Kremenek      if (CFGBlock *newBlock = Visit(Init))
1552550f2234fc9218914c325041067052342dfce553Ted Kremenek        LastBlock = newBlock;
1553550f2234fc9218914c325041067052342dfce553Ted Kremenek    }
15544f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  }
15551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15564f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  // If the type of VD is a VLA, then we must process its size expressions.
1557f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  for (const VariableArrayType* VA = FindVA(VD->getType().getTypePtr());
1558f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall       VA != 0; VA = FindVA(VA->getElementType().getTypePtr()))
15594f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    Block = addStmt(VA->getSizeExpr());
15601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1561fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski  // Remove variable from local scope.
1562fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski  if (ScopePos && VD == *ScopePos)
1563fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski    ++ScopePos;
1564fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski
1565550f2234fc9218914c325041067052342dfce553Ted Kremenek  return Block ? Block : LastBlock;
1566d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
1567fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
15689c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) {
15696d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // We may see an if statement in the middle of a basic block, or it may be the
15706d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // first statement we are processing.  In either case, we create a new basic
15716d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // block.  First, we create the blocks for the then...else statements, and
15726d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // then we create the block containing the if statement.  If we were in the
15736c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  // middle of a block, we stop processing that block.  That block is then the
15746c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  // implicit successor for the "then" and "else" clauses.
15756d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
157604e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski  // Save local scope position because in case of condition variable ScopePos
157704e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski  // won't be restored when traversing AST.
157804e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski  SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
157904e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski
158004e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski  // Create local scope for possible condition variable.
158104e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski  // Store scope position. Add implicit destructor.
15829c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (VarDecl *VD = I->getConditionVariable()) {
158304e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski    LocalScope::const_iterator BeginScopePos = ScopePos;
158404e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski    addLocalScopeForVarDecl(VD);
158504e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski    addAutomaticObjDtors(ScopePos, BeginScopePos, I);
158604e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski  }
158704e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski
1588fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner  // The block we were processing is now finished.  Make it the successor
15896d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // block.
15906d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  if (Block) {
1591d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    Succ = Block;
1592d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    if (badCFG)
15934e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek      return 0;
1594c310e933a9b023a280f3aa02e5a0c75398555e13Ted Kremenek  }
15956d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1596b6f1d782e0dc5fad138a17e6aa0ff6f9bc4788c6Ted Kremenek  // Process the false branch.
15979c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *ElseBlock = Succ;
15986d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
15999c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (Stmt *Else = I->getElse()) {
1600d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    SaveAndRestore<CFGBlock*> sv(Succ);
16016d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1602d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    // NULL out Block so that the recursive call to Visit will
16036d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    // create a new basic block.
1604d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    Block = NULL;
160504e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski
160604e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski    // If branch is not a compound statement create implicit scope
160704e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski    // and add destructors.
160804e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski    if (!isa<CompoundStmt>(Else))
160904e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski      addLocalScopeAndDtors(Else);
161004e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski
16114f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    ElseBlock = addStmt(Else);
16126d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1613b6f7b72047b3fd3f96a5040e1e4d520a9dea01cdTed Kremenek    if (!ElseBlock) // Can occur when the Else body has all NullStmts.
1614b6f7b72047b3fd3f96a5040e1e4d520a9dea01cdTed Kremenek      ElseBlock = sv.get();
16154e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    else if (Block) {
1616d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu      if (badCFG)
16174e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek        return 0;
16184e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    }
1619c310e933a9b023a280f3aa02e5a0c75398555e13Ted Kremenek  }
16206d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1621b6f1d782e0dc5fad138a17e6aa0ff6f9bc4788c6Ted Kremenek  // Process the true branch.
16229c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *ThenBlock;
1623d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  {
16249c378f705405d37f49795d5e915989de774fe11fTed Kremenek    Stmt *Then = I->getThen();
16256db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek    assert(Then);
1626d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    SaveAndRestore<CFGBlock*> sv(Succ);
16276d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    Block = NULL;
162804e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski
162904e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski    // If branch is not a compound statement create implicit scope
163004e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski    // and add destructors.
163104e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski    if (!isa<CompoundStmt>(Then))
163204e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski      addLocalScopeAndDtors(Then);
163304e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski
16344f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    ThenBlock = addStmt(Then);
16356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1636dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek    if (!ThenBlock) {
1637dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek      // We can reach here if the "then" body has all NullStmts.
1638dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek      // Create an empty block so we can distinguish between true and false
1639dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek      // branches in path-sensitive analyses.
1640dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek      ThenBlock = createBlock(false);
16410a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      addSuccessor(ThenBlock, sv.get());
16426d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    } else if (Block) {
1643d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu      if (badCFG)
16444e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek        return 0;
16456d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    }
16460cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek  }
1647d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
16486d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Now create a new block containing the if statement.
1649d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Block = createBlock(false);
16506d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1651d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Set the terminator of the new block to the If statement.
1652d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Block->setTerminator(I);
16536d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
165400998a068e50945118f334c98af05ed44d7c22a6Mike Stump  // See if this is a known constant.
16550a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  const TryResult &KnownVal = tryEvaluateBool(I->getCond());
165600998a068e50945118f334c98af05ed44d7c22a6Mike Stump
1657d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Now add the successors.
16580a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  addSuccessor(Block, KnownVal.isFalse() ? NULL : ThenBlock);
16590a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  addSuccessor(Block, KnownVal.isTrue()? NULL : ElseBlock);
16606d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
16616d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Add the condition as the last statement in the new block.  This may create
16626d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // new blocks as the condition may contain control-flow.  Any newly created
16636d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // blocks will be pointed to be "Block".
166461dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek  Block = addStmt(I->getCond());
1665ad5a894df1841698c824381b414630799adc26caTed Kremenek
166661dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek  // Finally, if the IfStmt contains a condition variable, add both the IfStmt
166761dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek  // and the condition variable initialization to the CFG.
166861dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek  if (VarDecl *VD = I->getConditionVariable()) {
166961dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek    if (Expr *Init = VD->getInit()) {
167061dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek      autoCreateBlock();
1671d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek      appendStmt(Block, I->getConditionVariableDeclStmt());
167261dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek      addStmt(Init);
167361dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek    }
167461dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek  }
1675ad5a894df1841698c824381b414630799adc26caTed Kremenek
167661dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek  return Block;
1677d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
16786d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
16796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
16809c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitReturnStmt(ReturnStmt *R) {
16816c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  // If we were in the middle of a block we stop processing that block.
1682d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  //
16836d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // NOTE: If a "return" appears in the middle of a block, this means that the
16846d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  //       code afterwards is DEAD (unreachable).  We still keep a basic block
16856d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  //       for that code; a simple "mark-and-sweep" from the entry block will be
16866d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  //       able to report such dead blocks.
1687d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
1688d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Create the new block.
1689d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Block = createBlock(false);
16906d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1691d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // The Exit block is the only successor.
1692fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski  addAutomaticObjDtors(ScopePos, LocalScope::const_iterator(), R);
16930a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  addSuccessor(Block, &cfg->getExit());
16946d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
16956d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Add the return statement to the block.  This may create new blocks if R
16966d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // contains control-flow (short-circuit operations).
1697852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  return VisitStmt(R, AddStmtChoice::AlwaysAdd);
1698d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
16990cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek
17009c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitLabelStmt(LabelStmt *L) {
1701d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Get the block of the labeled statement.  Add it to our map.
17024f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  addStmt(L->getSubStmt());
1703ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner  CFGBlock *LabelBlock = Block;
17046d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
17054f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  if (!LabelBlock)              // This can happen when the body is empty, i.e.
17064f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    LabelBlock = createBlock(); // scopes that only contains NullStmts.
17076d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1708ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner  assert(LabelMap.find(L->getDecl()) == LabelMap.end() &&
1709ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner         "label already in map");
1710ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner  LabelMap[L->getDecl()] = JumpTarget(LabelBlock, ScopePos);
17116d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
17126d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Labels partition blocks, so this is the end of the basic block we were
17136d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // processing (L is the block's label).  Because this is label (and we have
17146d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // already processed the substatement) there is no extra control-flow to worry
17156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // about.
17169cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  LabelBlock->setLabel(L);
1717d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
17184e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    return 0;
17196d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
17206d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // We set Block to NULL to allow lazy creation of a new block (if necessary);
1721d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Block = NULL;
17226d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1723d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // This block is now the implicit successor of other blocks.
1724d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Succ = LabelBlock;
17256d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1726d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  return LabelBlock;
1727d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
172831dcd3c8c4df5a656f58f50ea73afc177c101c67Ted Kremenek
172983748e2f41ea0ac7c954946feb5da9ccc6ab8becTed KremenekCFGBlock *CFGBuilder::VisitLambdaExpr(LambdaExpr *E, AddStmtChoice asc) {
173083748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek  CFGBlock *LastBlock = VisitNoRecurse(E, asc);
173183748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek  for (LambdaExpr::capture_init_iterator it = E->capture_init_begin(),
173283748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek       et = E->capture_init_end(); it != et; ++it) {
173383748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek    if (Expr *Init = *it) {
173483748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek      CFGBlock *Tmp = Visit(Init);
173583748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek      if (Tmp != 0)
173683748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek        LastBlock = Tmp;
173783748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek    }
173883748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek  }
173983748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek  return LastBlock;
174083748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek}
174183748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek
17429c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitGotoStmt(GotoStmt *G) {
17436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Goto is a control-flow statement.  Thus we stop processing the current
17446d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // block and create a new one.
17454f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek
1746d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Block = createBlock(false);
1747d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Block->setTerminator(G);
17486d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
17496d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // If we already know the mapping to the label block add the successor now.
1750d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  LabelMapTy::iterator I = LabelMap.find(G->getLabel());
17516d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1752d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  if (I == LabelMap.end())
1753d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    // We will need to backpatch this block later.
1754f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    BackpatchBlocks.push_back(JumpSource(Block, ScopePos));
1755f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  else {
1756f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    JumpTarget JT = I->second;
17579ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek    addAutomaticObjDtors(ScopePos, JT.scopePosition, G);
17589ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek    addSuccessor(Block, JT.block);
1759f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  }
1760d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
17616d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  return Block;
1762d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
1763d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
17649c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) {
17659c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *LoopSuccessor = NULL;
17666d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
176747575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski  // Save local scope position because in case of condition variable ScopePos
176847575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski  // won't be restored when traversing AST.
176947575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski  SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
177047575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski
177147575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski  // Create local scope for init statement and possible condition variable.
177247575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski  // Add destructor for init statement and condition variable.
177347575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski  // Store scope position for continue statement.
17749c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (Stmt *Init = F->getInit())
177547575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski    addLocalScopeForStmt(Init);
1776f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  LocalScope::const_iterator LoopBeginScopePos = ScopePos;
1777f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
17789c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (VarDecl *VD = F->getConditionVariable())
177947575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski    addLocalScopeForVarDecl(VD);
178047575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski  LocalScope::const_iterator ContinueScopePos = ScopePos;
178147575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski
178247575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski  addAutomaticObjDtors(ScopePos, save_scope_pos.get(), F);
178347575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski
1784fefb9f7009702befaf715e7a8debc9505c3c8634Mike Stump  // "for" is a control-flow statement.  Thus we stop processing the current
1785fefb9f7009702befaf715e7a8debc9505c3c8634Mike Stump  // block.
1786d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  if (Block) {
1787d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    if (badCFG)
17884e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek      return 0;
1789d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    LoopSuccessor = Block;
17904f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  } else
17914f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    LoopSuccessor = Succ;
17926d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
17933f64a0e3be2c9408f8256bd3aa9f0ce9e268982cTed Kremenek  // Save the current value for the break targets.
17943f64a0e3be2c9408f8256bd3aa9f0ce9e268982cTed Kremenek  // All breaks should go to the code following the loop.
1795f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  SaveAndRestore<JumpTarget> save_break(BreakJumpTarget);
179647575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski  BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
17973f64a0e3be2c9408f8256bd3aa9f0ce9e268982cTed Kremenek
17986d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Because of short-circuit evaluation, the condition of the loop can span
17996d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that
18006d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // evaluate the condition.
18019c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *ExitConditionBlock = createBlock(false);
18029c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *EntryConditionBlock = ExitConditionBlock;
18036d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
180449af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  // Set the terminator for the "exit" condition block.
18056d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  ExitConditionBlock->setTerminator(F);
18066d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
18076d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Now add the actual condition to the condition block.  Because the condition
18086d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // itself may contain control-flow, new blocks may be created.
18099c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (Stmt *C = F->getCond()) {
181049af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek    Block = ExitConditionBlock;
181149af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek    EntryConditionBlock = addStmt(C);
18129ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek    if (badCFG)
18139ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek      return 0;
18148f3b834471b158d65d490e3458fa16ba659ec105Ted Kremenek    assert(Block == EntryConditionBlock ||
18158f3b834471b158d65d490e3458fa16ba659ec105Ted Kremenek           (Block == 0 && EntryConditionBlock == Succ));
181658b87feeaedce7ef09c2931a39d82e5aea189f41Ted Kremenek
181758b87feeaedce7ef09c2931a39d82e5aea189f41Ted Kremenek    // If this block contains a condition variable, add both the condition
181858b87feeaedce7ef09c2931a39d82e5aea189f41Ted Kremenek    // variable and initializer to the CFG.
181958b87feeaedce7ef09c2931a39d82e5aea189f41Ted Kremenek    if (VarDecl *VD = F->getConditionVariable()) {
182058b87feeaedce7ef09c2931a39d82e5aea189f41Ted Kremenek      if (Expr *Init = VD->getInit()) {
182158b87feeaedce7ef09c2931a39d82e5aea189f41Ted Kremenek        autoCreateBlock();
1822d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek        appendStmt(Block, F->getConditionVariableDeclStmt());
182358b87feeaedce7ef09c2931a39d82e5aea189f41Ted Kremenek        EntryConditionBlock = addStmt(Init);
182458b87feeaedce7ef09c2931a39d82e5aea189f41Ted Kremenek        assert(Block == EntryConditionBlock);
182558b87feeaedce7ef09c2931a39d82e5aea189f41Ted Kremenek      }
182658b87feeaedce7ef09c2931a39d82e5aea189f41Ted Kremenek    }
1827ad5a894df1841698c824381b414630799adc26caTed Kremenek
18284e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    if (Block) {
1829d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu      if (badCFG)
18304e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek        return 0;
18314e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    }
183249af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  }
1833d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
18346d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // The condition block is the implicit successor for the loop body as well as
18356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // any code above the loop.
183649af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  Succ = EntryConditionBlock;
18376d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
183800998a068e50945118f334c98af05ed44d7c22a6Mike Stump  // See if this is a known constant.
1839941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek  TryResult KnownVal(true);
18401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
184100998a068e50945118f334c98af05ed44d7c22a6Mike Stump  if (F->getCond())
18420a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    KnownVal = tryEvaluateBool(F->getCond());
184300998a068e50945118f334c98af05ed44d7c22a6Mike Stump
1844d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Now create the loop body.
1845d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  {
18466db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek    assert(F->getBody());
18476d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
18483f64a0e3be2c9408f8256bd3aa9f0ce9e268982cTed Kremenek   // Save the current values for Block, Succ, and continue targets.
1849f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski   SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ);
1850f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski   SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget);
18516d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1852af603f742491dc4707138c0293d295171fdd51baTed Kremenek    // Create a new block to contain the (bottom) of the loop body.
1853af603f742491dc4707138c0293d295171fdd51baTed Kremenek    Block = NULL;
185447575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski
185547575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski    // Loop body should end with destructor of Condition variable (if any).
185647575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski    addAutomaticObjDtors(ScopePos, LoopBeginScopePos, F);
18576d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
18589c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (Stmt *I = F->getInc()) {
18596d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump      // Generate increment code in its own basic block.  This is the target of
18606d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump      // continue statements.
18614f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek      Succ = addStmt(I);
18626d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    } else {
18636d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump      // No increment code.  Create a special, empty, block that is used as the
18646d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump      // target block for "looping back" to the start of the loop.
18653575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek      assert(Succ == EntryConditionBlock);
186647575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski      Succ = Block ? Block : createBlock();
1867e933450535ab077b95e59f929a4ccb25b6f360e6Ted Kremenek    }
18686d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
18693575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek    // Finish up the increment (or empty) block if it hasn't been already.
18703575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek    if (Block) {
18713575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek      assert(Block == Succ);
1872d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu      if (badCFG)
18734e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek        return 0;
18743575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek      Block = 0;
18753575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek    }
18766d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
187747575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski    ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos);
18786d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
18793575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek    // The starting block for the loop increment is the block that should
18803575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek    // represent the 'loop target' for looping back to the start of the loop.
18819ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek    ContinueJumpTarget.block->setLoopTarget(F);
18823575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek
188347575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski    // If body is not a compound statement create implicit scope
188447575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski    // and add destructors.
188547575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski    if (!isa<CompoundStmt>(F->getBody()))
188647575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski      addLocalScopeAndDtors(F->getBody());
188747575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski
18886d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    // Now populate the body block, and in the process create new blocks as we
18896d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    // walk the body of the loop.
18909c378f705405d37f49795d5e915989de774fe11fTed Kremenek    CFGBlock *BodyBlock = addStmt(F->getBody());
1891af603f742491dc4707138c0293d295171fdd51baTed Kremenek
1892af603f742491dc4707138c0293d295171fdd51baTed Kremenek    if (!BodyBlock)
18939ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek      BodyBlock = ContinueJumpTarget.block;//can happen for "for (...;...;...);"
1894d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    else if (badCFG)
1895941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek      return 0;
18966d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1897941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek    // This new body block is a successor to our "exit" condition block.
18980a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    addSuccessor(ExitConditionBlock, KnownVal.isFalse() ? NULL : BodyBlock);
1899d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  }
19006d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1901941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek  // Link up the condition block with the code that follows the loop.  (the
1902941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek  // false branch).
19030a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  addSuccessor(ExitConditionBlock, KnownVal.isTrue() ? NULL : LoopSuccessor);
19046d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1905d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // If the loop contains initialization, create a new block for those
19066d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // statements.  This block can also contain statements that precede the loop.
19079c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (Stmt *I = F->getInit()) {
1908d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    Block = createBlock();
190949af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek    return addStmt(I);
19102bac4ea765a4a6e1f6149964663f62d4bca6743bTed Kremenek  }
191136f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan
191236f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan  // There is no loop initialization.  We are thus basically a while loop.
191336f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan  // NULL out Block to force lazy block construction.
191436f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan  Block = NULL;
191536f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan  Succ = EntryConditionBlock;
191636f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan  return EntryConditionBlock;
1917d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
1918d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
1919115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted KremenekCFGBlock *CFGBuilder::VisitMemberExpr(MemberExpr *M, AddStmtChoice asc) {
19203179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek  if (asc.alwaysAdd(*this, M)) {
1921115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek    autoCreateBlock();
1922247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek    appendStmt(Block, M);
1923115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek  }
1924892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  return Visit(M->getBase());
1925115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek}
1926115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek
19279c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
1928514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  // Objective-C fast enumeration 'for' statements:
1929514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //  http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC
1930514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //
1931514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //  for ( Type newVariable in collection_expression ) { statements }
1932514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //
1933514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //  becomes:
1934514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //
1935514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //   prologue:
1936514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //     1. collection_expression
1937514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //     T. jump to loop_entry
1938514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //   loop_entry:
19394cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek  //     1. side-effects of element expression
1940514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //     1. ObjCForCollectionStmt [performs binding to newVariable]
1941514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //     T. ObjCForCollectionStmt  TB, FB  [jumps to TB if newVariable != nil]
1942514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //   TB:
1943514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //     statements
1944514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //     T. jump to loop_entry
1945514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //   FB:
1946514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //     what comes after
1947514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //
1948514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //  and
1949514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //
1950514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //  Type existingItem;
1951514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //  for ( existingItem in expression ) { statements }
1952514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //
1953514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //  becomes:
1954514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //
19556d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  //   the same with newVariable replaced with existingItem; the binding works
19566d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  //   the same except that for one ObjCForCollectionStmt::getElement() returns
19576d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  //   a DeclStmt and the other returns a DeclRefExpr.
1958514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  //
19596d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
19609c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *LoopSuccessor = 0;
19616d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
1962514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  if (Block) {
1963d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    if (badCFG)
19644e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek      return 0;
1965514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek    LoopSuccessor = Block;
1966514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek    Block = 0;
19674f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  } else
19684f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    LoopSuccessor = Succ;
19696d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
19704cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek  // Build the condition blocks.
19719c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *ExitConditionBlock = createBlock(false);
19726d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
19734cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek  // Set the terminator for the "exit" condition block.
19746d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  ExitConditionBlock->setTerminator(S);
19756d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
19766d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // The last statement in the block should be the ObjCForCollectionStmt, which
19776d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // performs the actual binding to 'element' and determines if there are any
19786d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // more items in the collection.
1979892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  appendStmt(ExitConditionBlock, S);
19804cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek  Block = ExitConditionBlock;
19816d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
19824cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek  // Walk the 'element' expression to see if there are any side-effects.  We
1983fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner  // generate new blocks as necessary.  We DON'T add the statement by default to
19846d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // the CFG unless it contains control-flow.
1985012614ecf78442368ec82ee30efb3bc047b413e6Ted Kremenek  CFGBlock *EntryConditionBlock = Visit(S->getElement(),
1986012614ecf78442368ec82ee30efb3bc047b413e6Ted Kremenek                                        AddStmtChoice::NotAlwaysAdd);
19876d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  if (Block) {
1988d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    if (badCFG)
19894e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek      return 0;
19904e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    Block = 0;
19914e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek  }
19926d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
19936d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // The condition block is the implicit successor for the loop body as well as
19946d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // any code above the loop.
19954cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek  Succ = EntryConditionBlock;
19966d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
19974cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek  // Now create the true branch.
19986d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  {
19994cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek    // Save the current values for Succ, continue and break targets.
2000f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    SaveAndRestore<CFGBlock*> save_Succ(Succ);
2001f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget),
2002f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski        save_break(BreakJumpTarget);
20036d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2004f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
2005f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    ContinueJumpTarget = JumpTarget(EntryConditionBlock, ScopePos);
20066d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
20079c378f705405d37f49795d5e915989de774fe11fTed Kremenek    CFGBlock *BodyBlock = addStmt(S->getBody());
20086d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
20094cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek    if (!BodyBlock)
20104cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek      BodyBlock = EntryConditionBlock; // can happen for "for (X in Y) ;"
20114e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    else if (Block) {
2012d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu      if (badCFG)
20134e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek        return 0;
20144e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    }
20156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
20164cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek    // This new body block is a successor to our "exit" condition block.
20170a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    addSuccessor(ExitConditionBlock, BodyBlock);
20184cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek  }
20196d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
20204cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek  // Link up the condition block with the code that follows the loop.
20214cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek  // (the false branch).
20220a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  addSuccessor(ExitConditionBlock, LoopSuccessor);
20234cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek
2024514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  // Now create a prologue block to contain the collection expression.
20254cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek  Block = createBlock();
2026514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek  return addStmt(S->getCollection());
20276d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump}
20286d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
20298e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted KremenekCFGBlock *CFGBuilder::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
20308e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek  // Inline the body.
20318e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek  return addStmt(S->getSubStmt());
20328e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek  // TODO: consider adding cleanups for the end of @autoreleasepool scope.
20338e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek}
20348e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek
20359c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
2036b3b0b3624e462c2940f65b86e773bfc300005203Ted Kremenek  // FIXME: Add locking 'primitives' to CFG for @synchronized.
20376d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2038b3b0b3624e462c2940f65b86e773bfc300005203Ted Kremenek  // Inline the body.
20394f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CFGBlock *SyncBlock = addStmt(S->getSynchBody());
20406d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2041da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek  // The sync body starts its own basic block.  This makes it a little easier
2042da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek  // for diagnostic clients.
2043da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek  if (SyncBlock) {
2044d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    if (badCFG)
2045da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek      return 0;
20466d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2047da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek    Block = 0;
2048fadebbafe622752c3c6565b53ce8cd42bbbbd90cTed Kremenek    Succ = SyncBlock;
2049da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek  }
20506d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
20514beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek  // Add the @synchronized to the CFG.
20524beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek  autoCreateBlock();
2053247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek  appendStmt(Block, S);
20544beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek
2055b3b0b3624e462c2940f65b86e773bfc300005203Ted Kremenek  // Inline the sync expression.
20564f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  return addStmt(S->getSynchExpr());
2057b3b0b3624e462c2940f65b86e773bfc300005203Ted Kremenek}
20586d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
20599c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
20604f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  // FIXME
206190658ec72542df44eb462c69056184d2946bdbceTed Kremenek  return NYS();
2062e31c0d206b872b056dc42c3af21b11d5de4edfd9Ted Kremenek}
2063514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek
20644b9c2d235fb9449e249d74f48ecfec601650de93John McCallCFGBlock *CFGBuilder::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
20654b9c2d235fb9449e249d74f48ecfec601650de93John McCall  autoCreateBlock();
20664b9c2d235fb9449e249d74f48ecfec601650de93John McCall
20674b9c2d235fb9449e249d74f48ecfec601650de93John McCall  // Add the PseudoObject as the last thing.
20684b9c2d235fb9449e249d74f48ecfec601650de93John McCall  appendStmt(Block, E);
20694b9c2d235fb9449e249d74f48ecfec601650de93John McCall
20704b9c2d235fb9449e249d74f48ecfec601650de93John McCall  CFGBlock *lastBlock = Block;
20714b9c2d235fb9449e249d74f48ecfec601650de93John McCall
20724b9c2d235fb9449e249d74f48ecfec601650de93John McCall  // Before that, evaluate all of the semantics in order.  In
20734b9c2d235fb9449e249d74f48ecfec601650de93John McCall  // CFG-land, that means appending them in reverse order.
20744b9c2d235fb9449e249d74f48ecfec601650de93John McCall  for (unsigned i = E->getNumSemanticExprs(); i != 0; ) {
20754b9c2d235fb9449e249d74f48ecfec601650de93John McCall    Expr *Semantic = E->getSemanticExpr(--i);
20764b9c2d235fb9449e249d74f48ecfec601650de93John McCall
20774b9c2d235fb9449e249d74f48ecfec601650de93John McCall    // If the semantic is an opaque value, we're being asked to bind
20784b9c2d235fb9449e249d74f48ecfec601650de93John McCall    // it to its source expression.
20794b9c2d235fb9449e249d74f48ecfec601650de93John McCall    if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
20804b9c2d235fb9449e249d74f48ecfec601650de93John McCall      Semantic = OVE->getSourceExpr();
20814b9c2d235fb9449e249d74f48ecfec601650de93John McCall
20824b9c2d235fb9449e249d74f48ecfec601650de93John McCall    if (CFGBlock *B = Visit(Semantic))
20834b9c2d235fb9449e249d74f48ecfec601650de93John McCall      lastBlock = B;
20844b9c2d235fb9449e249d74f48ecfec601650de93John McCall  }
20854b9c2d235fb9449e249d74f48ecfec601650de93John McCall
20864b9c2d235fb9449e249d74f48ecfec601650de93John McCall  return lastBlock;
20874b9c2d235fb9449e249d74f48ecfec601650de93John McCall}
20884b9c2d235fb9449e249d74f48ecfec601650de93John McCall
20899c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitWhileStmt(WhileStmt *W) {
20909c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *LoopSuccessor = NULL;
20916d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
209205adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski  // Save local scope position because in case of condition variable ScopePos
209305adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski  // won't be restored when traversing AST.
209405adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski  SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
209505adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski
209605adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski  // Create local scope for possible condition variable.
209705adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski  // Store scope position for continue statement.
2098f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  LocalScope::const_iterator LoopBeginScopePos = ScopePos;
20999c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (VarDecl *VD = W->getConditionVariable()) {
210005adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski    addLocalScopeForVarDecl(VD);
210105adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski    addAutomaticObjDtors(ScopePos, LoopBeginScopePos, W);
210205adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski  }
2103f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski
2104fefb9f7009702befaf715e7a8debc9505c3c8634Mike Stump  // "while" is a control-flow statement.  Thus we stop processing the current
2105fefb9f7009702befaf715e7a8debc9505c3c8634Mike Stump  // block.
2106d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  if (Block) {
2107d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    if (badCFG)
21084e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek      return 0;
2109d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    LoopSuccessor = Block;
21106b12da9f89b7863e6fc995312355b94197b75657Ted Kremenek    Block = 0;
21114f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  } else
21124f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    LoopSuccessor = Succ;
21136d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
21146d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Because of short-circuit evaluation, the condition of the loop can span
21156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that
21166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // evaluate the condition.
21179c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *ExitConditionBlock = createBlock(false);
21189c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *EntryConditionBlock = ExitConditionBlock;
21196d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
212049af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  // Set the terminator for the "exit" condition block.
212149af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  ExitConditionBlock->setTerminator(W);
21226d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
21236d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Now add the actual condition to the condition block.  Because the condition
21246d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // itself may contain control-flow, new blocks may be created.  Thus we update
21256d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // "Succ" after adding the condition.
21269c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (Stmt *C = W->getCond()) {
212749af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek    Block = ExitConditionBlock;
212849af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek    EntryConditionBlock = addStmt(C);
2129a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu    // The condition might finish the current 'Block'.
2130a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu    Block = EntryConditionBlock;
2131ad5a894df1841698c824381b414630799adc26caTed Kremenek
21324ec010a6ccf4db2ab2ef9e68942642d50f7f193cTed Kremenek    // If this block contains a condition variable, add both the condition
21334ec010a6ccf4db2ab2ef9e68942642d50f7f193cTed Kremenek    // variable and initializer to the CFG.
21344ec010a6ccf4db2ab2ef9e68942642d50f7f193cTed Kremenek    if (VarDecl *VD = W->getConditionVariable()) {
21354ec010a6ccf4db2ab2ef9e68942642d50f7f193cTed Kremenek      if (Expr *Init = VD->getInit()) {
21364ec010a6ccf4db2ab2ef9e68942642d50f7f193cTed Kremenek        autoCreateBlock();
2137d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek        appendStmt(Block, W->getConditionVariableDeclStmt());
21384ec010a6ccf4db2ab2ef9e68942642d50f7f193cTed Kremenek        EntryConditionBlock = addStmt(Init);
21394ec010a6ccf4db2ab2ef9e68942642d50f7f193cTed Kremenek        assert(Block == EntryConditionBlock);
21404ec010a6ccf4db2ab2ef9e68942642d50f7f193cTed Kremenek      }
21414ec010a6ccf4db2ab2ef9e68942642d50f7f193cTed Kremenek    }
21424ec010a6ccf4db2ab2ef9e68942642d50f7f193cTed Kremenek
21434e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    if (Block) {
2144d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu      if (badCFG)
21454e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek        return 0;
21464e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    }
214749af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  }
21486d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
21496d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // The condition block is the implicit successor for the loop body as well as
21506d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // any code above the loop.
215149af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  Succ = EntryConditionBlock;
21526d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
215300998a068e50945118f334c98af05ed44d7c22a6Mike Stump  // See if this is a known constant.
21540a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  const TryResult& KnownVal = tryEvaluateBool(W->getCond());
215500998a068e50945118f334c98af05ed44d7c22a6Mike Stump
2156d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Process the loop body.
2157d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  {
2158f6e8541dd884029b85483a319ce7d32f3e476dccTed Kremenek    assert(W->getBody());
2159d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
2160d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    // Save the current values for Block, Succ, and continue and break targets
2161f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ);
2162f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget),
2163f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski        save_break(BreakJumpTarget);
2164f6e8541dd884029b85483a319ce7d32f3e476dccTed Kremenek
21656d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    // Create an empty block to represent the transition block for looping back
21666d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    // to the head of the loop.
2167f6e8541dd884029b85483a319ce7d32f3e476dccTed Kremenek    Block = 0;
2168f6e8541dd884029b85483a319ce7d32f3e476dccTed Kremenek    assert(Succ == EntryConditionBlock);
2169f6e8541dd884029b85483a319ce7d32f3e476dccTed Kremenek    Succ = createBlock();
2170f6e8541dd884029b85483a319ce7d32f3e476dccTed Kremenek    Succ->setLoopTarget(W);
2171f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    ContinueJumpTarget = JumpTarget(Succ, LoopBeginScopePos);
21726d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2173d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    // All breaks should go to the code following the loop.
217405adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski    BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
21756d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2176d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    // NULL out Block to force lazy instantiation of blocks for the body.
2177f752fcfae84fbf21b78383bf2461633382d51844Ted Kremenek    Block = NULL;
21786d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
217905adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski    // Loop body should end with destructor of Condition variable (if any).
218005adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski    addAutomaticObjDtors(ScopePos, LoopBeginScopePos, W);
218105adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski
218205adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski    // If body is not a compound statement create implicit scope
218305adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski    // and add destructors.
218405adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski    if (!isa<CompoundStmt>(W->getBody()))
218505adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski      addLocalScopeAndDtors(W->getBody());
218605adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski
2187d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    // Create the body.  The returned block is the entry to the loop body.
21889c378f705405d37f49795d5e915989de774fe11fTed Kremenek    CFGBlock *BodyBlock = addStmt(W->getBody());
21896d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2190af603f742491dc4707138c0293d295171fdd51baTed Kremenek    if (!BodyBlock)
21919ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek      BodyBlock = ContinueJumpTarget.block; // can happen for "while(...) ;"
21924e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    else if (Block) {
2193d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu      if (badCFG)
21944e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek        return 0;
21954e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    }
21966d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2197941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek    // Add the loop body entry as a successor to the condition.
21980a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    addSuccessor(ExitConditionBlock, KnownVal.isFalse() ? NULL : BodyBlock);
2199bf15b278a439d73b605ec00a8d3977ef305712f4Ted Kremenek  }
22006d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2201941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek  // Link up the condition block with the code that follows the loop.  (the
2202941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek  // false branch).
22030a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  addSuccessor(ExitConditionBlock, KnownVal.isTrue() ? NULL : LoopSuccessor);
22046d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
22056d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // There can be no more statements in the condition block since we loop back
22066d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // to this block.  NULL out Block to force lazy creation of another block.
2207d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Block = NULL;
22086d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
22094ec010a6ccf4db2ab2ef9e68942642d50f7f193cTed Kremenek  // Return the condition block, which is the dominating block for the loop.
22105482713d70ecbfe608940018046aa248b3d03443Ted Kremenek  Succ = EntryConditionBlock;
221149af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  return EntryConditionBlock;
2212d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
22131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22159c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
22164f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  // FIXME: For now we pretend that @catch and the code it contains does not
22174f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  //  exit.
22184f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  return Block;
22194f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek}
22206d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
22219c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
22222fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek  // FIXME: This isn't complete.  We basically treat @throw like a return
22232fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek  //  statement.
22246d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
22256c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  // If we were in the middle of a block we stop processing that block.
2226d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
22274f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    return 0;
22286d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
22292fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek  // Create the new block.
22302fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek  Block = createBlock(false);
22316d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
22322fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek  // The Exit block is the only successor.
22330a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  addSuccessor(Block, &cfg->getExit());
22346d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
22356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Add the statement to the block.  This may create new blocks if S contains
22366d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // control-flow (short-circuit operations).
2237852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  return VisitStmt(S, AddStmtChoice::AlwaysAdd);
22382fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek}
2239989d52d469df0c202f7de82f54407066c7db2e63Ted Kremenek
22409c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCXXThrowExpr(CXXThrowExpr *T) {
22416c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  // If we were in the middle of a block we stop processing that block.
2242d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
22430979d80615df97c675423de631c1b884819f4712Mike Stump    return 0;
22440979d80615df97c675423de631c1b884819f4712Mike Stump
22450979d80615df97c675423de631c1b884819f4712Mike Stump  // Create the new block.
22460979d80615df97c675423de631c1b884819f4712Mike Stump  Block = createBlock(false);
22470979d80615df97c675423de631c1b884819f4712Mike Stump
22485d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  if (TryTerminatedBlock)
22495d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    // The current try statement is the only successor.
22500a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    addSuccessor(Block, TryTerminatedBlock);
2251ad5a894df1841698c824381b414630799adc26caTed Kremenek  else
22525d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    // otherwise the Exit block is the only successor.
22530a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    addSuccessor(Block, &cfg->getExit());
22540979d80615df97c675423de631c1b884819f4712Mike Stump
22550979d80615df97c675423de631c1b884819f4712Mike Stump  // Add the statement to the block.  This may create new blocks if S contains
22560979d80615df97c675423de631c1b884819f4712Mike Stump  // control-flow (short-circuit operations).
2257852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  return VisitStmt(T, AddStmtChoice::AlwaysAdd);
22580979d80615df97c675423de631c1b884819f4712Mike Stump}
22590979d80615df97c675423de631c1b884819f4712Mike Stump
22609c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitDoStmt(DoStmt *D) {
22619c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *LoopSuccessor = NULL;
22626d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
22638f9893a2beeacd5149bd2d3d4c6e130516915068Mike Stump  // "do...while" is a control-flow statement.  Thus we stop processing the
22648f9893a2beeacd5149bd2d3d4c6e130516915068Mike Stump  // current block.
2265d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  if (Block) {
2266d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    if (badCFG)
22674e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek      return 0;
2268d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    LoopSuccessor = Block;
22694f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  } else
22704f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    LoopSuccessor = Succ;
22716d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
22726d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Because of short-circuit evaluation, the condition of the loop can span
22736d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that
22746d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // evaluate the condition.
22759c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *ExitConditionBlock = createBlock(false);
22769c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *EntryConditionBlock = ExitConditionBlock;
22776d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
227849af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  // Set the terminator for the "exit" condition block.
22796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  ExitConditionBlock->setTerminator(D);
22806d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
22816d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Now add the actual condition to the condition block.  Because the condition
22826d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // itself may contain control-flow, new blocks may be created.
22839c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (Stmt *C = D->getCond()) {
228449af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek    Block = ExitConditionBlock;
228549af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek    EntryConditionBlock = addStmt(C);
22864e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    if (Block) {
2287d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu      if (badCFG)
22884e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek        return 0;
22894e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    }
229049af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  }
22916d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
22925482713d70ecbfe608940018046aa248b3d03443Ted Kremenek  // The condition block is the implicit successor for the loop body.
229349af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  Succ = EntryConditionBlock;
229449af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek
229500998a068e50945118f334c98af05ed44d7c22a6Mike Stump  // See if this is a known constant.
22960a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  const TryResult &KnownVal = tryEvaluateBool(D->getCond());
229700998a068e50945118f334c98af05ed44d7c22a6Mike Stump
2298d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Process the loop body.
22999c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *BodyBlock = NULL;
2300d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  {
23016db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek    assert(D->getBody());
23026d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2303d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    // Save the current values for Block, Succ, and continue and break targets
2304f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ);
2305f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget),
2306f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski        save_break(BreakJumpTarget);
23076d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2308d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    // All continues within this loop should go to the condition block
2309f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    ContinueJumpTarget = JumpTarget(EntryConditionBlock, ScopePos);
23106d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2311d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    // All breaks should go to the code following the loop.
2312f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski    BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
23136d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2314d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    // NULL out Block to force lazy instantiation of blocks for the body.
2315b5c13b0f4e438391b31dacb87641be7a1b990b57Ted Kremenek    Block = NULL;
23166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
231705adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski    // If body is not a compound statement create implicit scope
231805adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski    // and add destructors.
231905adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski    if (!isa<CompoundStmt>(D->getBody()))
232005adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski      addLocalScopeAndDtors(D->getBody());
232105adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski
2322d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    // Create the body.  The returned block is the entry to the loop body.
23234f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    BodyBlock = addStmt(D->getBody());
23246d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2325af603f742491dc4707138c0293d295171fdd51baTed Kremenek    if (!BodyBlock)
2326a9d996dbeb719200c4a9d86f68166a237583025fTed Kremenek      BodyBlock = EntryConditionBlock; // can happen for "do ; while(...)"
23274e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    else if (Block) {
2328d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu      if (badCFG)
23294e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek        return 0;
23304e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    }
23316d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2332d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek    if (!KnownVal.isFalse()) {
2333d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek      // Add an intermediate block between the BodyBlock and the
2334d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek      // ExitConditionBlock to represent the "loop back" transition.  Create an
2335d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek      // empty block to represent the transition block for looping back to the
2336d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek      // head of the loop.
2337d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek      // FIXME: Can we do this more efficiently without adding another block?
2338d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek      Block = NULL;
2339d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek      Succ = BodyBlock;
2340d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek      CFGBlock *LoopBackBlock = createBlock();
2341d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek      LoopBackBlock->setLoopTarget(D);
2342d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek
2343d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek      // Add the loop body entry as a successor to the condition.
23440a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      addSuccessor(ExitConditionBlock, LoopBackBlock);
2345d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek    }
2346d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek    else
23470a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      addSuccessor(ExitConditionBlock, NULL);
2348b5c13b0f4e438391b31dacb87641be7a1b990b57Ted Kremenek  }
23496d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2350941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek  // Link up the condition block with the code that follows the loop.
2351941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek  // (the false branch).
23520a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  addSuccessor(ExitConditionBlock, KnownVal.isTrue() ? NULL : LoopSuccessor);
23536d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
23546d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // There can be no more statements in the body block(s) since we loop back to
23556d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // the body.  NULL out Block to force lazy creation of another block.
2356d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Block = NULL;
23576d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2358d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Return the loop body, which is the dominating block for the loop.
23595482713d70ecbfe608940018046aa248b3d03443Ted Kremenek  Succ = BodyBlock;
2360d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  return BodyBlock;
2361d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
2362d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
23639c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitContinueStmt(ContinueStmt *C) {
2364d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // "continue" is a control-flow statement.  Thus we stop processing the
2365d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // current block.
2366d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
2367d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    return 0;
23686d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2369d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Now create a new block that ends with the continue statement.
2370d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Block = createBlock(false);
2371d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Block->setTerminator(C);
23726d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2373d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // If there is no target for the continue, then we are looking at an
2374235c5ed8bee5bbcb45de1707d6988635e49b10b8Ted Kremenek  // incomplete AST.  This means the CFG cannot be constructed.
23759ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek  if (ContinueJumpTarget.block) {
23769ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek    addAutomaticObjDtors(ScopePos, ContinueJumpTarget.scopePosition, C);
23779ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek    addSuccessor(Block, ContinueJumpTarget.block);
2378f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  } else
2379235c5ed8bee5bbcb45de1707d6988635e49b10b8Ted Kremenek    badCFG = true;
23806d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2381d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  return Block;
2382d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
23831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2384f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter CollingbourneCFGBlock *CFGBuilder::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E,
2385f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne                                                    AddStmtChoice asc) {
238613fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek
23873179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek  if (asc.alwaysAdd(*this, E)) {
238813fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek    autoCreateBlock();
2389892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    appendStmt(Block, E);
239013fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek  }
23911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23924f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  // VLA types have expressions that must be evaluated.
239397e50714c262cc421f960303171d2c1afbc9bb4fTed Kremenek  CFGBlock *lastBlock = Block;
239497e50714c262cc421f960303171d2c1afbc9bb4fTed Kremenek
23954f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  if (E->isArgumentType()) {
2396f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall    for (const VariableArrayType *VA =FindVA(E->getArgumentType().getTypePtr());
23974f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek         VA != 0; VA = FindVA(VA->getElementType().getTypePtr()))
239897e50714c262cc421f960303171d2c1afbc9bb4fTed Kremenek      lastBlock = addStmt(VA->getSizeExpr());
2399f91a5b008d1a63630ae483247204c2651e512fa1Ted Kremenek  }
240097e50714c262cc421f960303171d2c1afbc9bb4fTed Kremenek  return lastBlock;
2401d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
24021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24034f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// VisitStmtExpr - Utility method to handle (nested) statement
24044f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek///  expressions (a GCC extension).
24059c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitStmtExpr(StmtExpr *SE, AddStmtChoice asc) {
24063179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek  if (asc.alwaysAdd(*this, SE)) {
240713fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek    autoCreateBlock();
2408892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    appendStmt(Block, SE);
240913fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek  }
24104f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  return VisitCompoundStmt(SE->getSubStmt());
24114f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek}
2412d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
24139c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) {
24146d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // "switch" is a control-flow statement.  Thus we stop processing the current
24156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // block.
24169c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *SwitchSuccessor = NULL;
24176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
24188ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski  // Save local scope position because in case of condition variable ScopePos
24198ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski  // won't be restored when traversing AST.
24208ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski  SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
24218ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski
24228ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski  // Create local scope for possible condition variable.
24238ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski  // Store scope position. Add implicit destructor.
24249c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (VarDecl *VD = Terminator->getConditionVariable()) {
24258ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski    LocalScope::const_iterator SwitchBeginScopePos = ScopePos;
24268ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski    addLocalScopeForVarDecl(VD);
24278ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski    addAutomaticObjDtors(ScopePos, SwitchBeginScopePos, Terminator);
24288ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski  }
24298ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski
2430d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  if (Block) {
2431d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    if (badCFG)
24324e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek      return 0;
2433d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    SwitchSuccessor = Block;
24346d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  } else SwitchSuccessor = Succ;
2435d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
2436d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Save the current "switch" context.
2437d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  SaveAndRestore<CFGBlock*> save_switch(SwitchTerminatedBlock),
2438eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek                            save_default(DefaultCaseBlock);
2439f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  SaveAndRestore<JumpTarget> save_break(BreakJumpTarget);
2440eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek
24416d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Set the "default" case to be the block after the switch statement.  If the
24426d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // switch statement contains a "default:", this value will be overwritten with
24436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // the block for that code.
2444eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek  DefaultCaseBlock = SwitchSuccessor;
24456d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2446d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Create a new block that will contain the switch statement.
2447d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  SwitchTerminatedBlock = createBlock(false);
24486d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2449d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Now process the switch body.  The code after the switch is the implicit
2450d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // successor.
2451d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Succ = SwitchSuccessor;
2452f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski  BreakJumpTarget = JumpTarget(SwitchSuccessor, ScopePos);
24536d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
24546d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // When visiting the body, the case statements should automatically get linked
24556d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // up to the switch.  We also don't keep a pointer to the body, since all
24566d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // control-flow from the switch goes to case/default statements.
24576db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek  assert(Terminator->getBody() && "switch must contain a non-NULL body");
245849af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  Block = NULL;
24598ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski
2460e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  // For pruning unreachable case statements, save the current state
2461e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  // for tracking the condition value.
2462e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  SaveAndRestore<bool> save_switchExclusivelyCovered(switchExclusivelyCovered,
2463e71f3d587844110d836c82250830b27b1651afdbTed Kremenek                                                     false);
24640498247f87ea0d716e0c2931fea812280649e33dTed Kremenek
2465e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  // Determine if the switch condition can be explicitly evaluated.
2466e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  assert(Terminator->getCond() && "switch condition must be non-NULL");
24670498247f87ea0d716e0c2931fea812280649e33dTed Kremenek  Expr::EvalResult result;
2468e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek  bool b = tryEvaluate(Terminator->getCond(), result);
2469e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek  SaveAndRestore<Expr::EvalResult*> save_switchCond(switchCond,
2470e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek                                                    b ? &result : 0);
24710498247f87ea0d716e0c2931fea812280649e33dTed Kremenek
24728ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski  // If body is not a compound statement create implicit scope
24738ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski  // and add destructors.
24748ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski  if (!isa<CompoundStmt>(Terminator->getBody()))
24758ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski    addLocalScopeAndDtors(Terminator->getBody());
24768ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski
2477d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  addStmt(Terminator->getBody());
24784e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek  if (Block) {
2479d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    if (badCFG)
24804e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek      return 0;
24814e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek  }
248249af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek
24836d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // If we have no "default:" case, the default transition is to the code
2484432c478fe0fec3946610d5dc7905daf5fbadf47bTed Kremenek  // following the switch body.  Moreover, take into account if all the
2485432c478fe0fec3946610d5dc7905daf5fbadf47bTed Kremenek  // cases of a switch are covered (e.g., switching on an enum value).
2486e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  addSuccessor(SwitchTerminatedBlock,
2487432c478fe0fec3946610d5dc7905daf5fbadf47bTed Kremenek               switchExclusivelyCovered || Terminator->isAllEnumCasesCovered()
2488432c478fe0fec3946610d5dc7905daf5fbadf47bTed Kremenek               ? 0 : DefaultCaseBlock);
24896d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
249049af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek  // Add the terminator and condition in the switch block.
2491411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek  SwitchTerminatedBlock->setTerminator(Terminator);
2492d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Block = SwitchTerminatedBlock;
24936b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek  Block = addStmt(Terminator->getCond());
2494ad5a894df1841698c824381b414630799adc26caTed Kremenek
24956b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek  // Finally, if the SwitchStmt contains a condition variable, add both the
24966b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek  // SwitchStmt and the condition variable initialization to the CFG.
24976b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek  if (VarDecl *VD = Terminator->getConditionVariable()) {
24986b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek    if (Expr *Init = VD->getInit()) {
24996b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek      autoCreateBlock();
2500d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek      appendStmt(Block, Terminator->getConditionVariableDeclStmt());
25016b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek      addStmt(Init);
25026b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek    }
25036b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek  }
2504ad5a894df1841698c824381b414630799adc26caTed Kremenek
25056b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek  return Block;
2506d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
2507e71f3d587844110d836c82250830b27b1651afdbTed Kremenek
2508e71f3d587844110d836c82250830b27b1651afdbTed Kremenekstatic bool shouldAddCase(bool &switchExclusivelyCovered,
2509e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek                          const Expr::EvalResult *switchCond,
2510e71f3d587844110d836c82250830b27b1651afdbTed Kremenek                          const CaseStmt *CS,
2511e71f3d587844110d836c82250830b27b1651afdbTed Kremenek                          ASTContext &Ctx) {
2512e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek  if (!switchCond)
2513e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek    return true;
2514e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek
2515e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  bool addCase = false;
25160498247f87ea0d716e0c2931fea812280649e33dTed Kremenek
2517e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  if (!switchExclusivelyCovered) {
2518e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek    if (switchCond->Val.isInt()) {
2519e71f3d587844110d836c82250830b27b1651afdbTed Kremenek      // Evaluate the LHS of the case value.
252085df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith      const llvm::APSInt &lhsInt = CS->getLHS()->EvaluateKnownConstInt(Ctx);
2521e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek      const llvm::APSInt &condInt = switchCond->Val.getInt();
2522e71f3d587844110d836c82250830b27b1651afdbTed Kremenek
2523e71f3d587844110d836c82250830b27b1651afdbTed Kremenek      if (condInt == lhsInt) {
2524e71f3d587844110d836c82250830b27b1651afdbTed Kremenek        addCase = true;
2525e71f3d587844110d836c82250830b27b1651afdbTed Kremenek        switchExclusivelyCovered = true;
2526e71f3d587844110d836c82250830b27b1651afdbTed Kremenek      }
2527e71f3d587844110d836c82250830b27b1651afdbTed Kremenek      else if (condInt < lhsInt) {
2528e71f3d587844110d836c82250830b27b1651afdbTed Kremenek        if (const Expr *RHS = CS->getRHS()) {
2529e71f3d587844110d836c82250830b27b1651afdbTed Kremenek          // Evaluate the RHS of the case value.
253085df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith          const llvm::APSInt &V2 = RHS->EvaluateKnownConstInt(Ctx);
253185df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith          if (V2 <= condInt) {
2532e71f3d587844110d836c82250830b27b1651afdbTed Kremenek            addCase = true;
2533e71f3d587844110d836c82250830b27b1651afdbTed Kremenek            switchExclusivelyCovered = true;
2534e71f3d587844110d836c82250830b27b1651afdbTed Kremenek          }
2535e71f3d587844110d836c82250830b27b1651afdbTed Kremenek        }
2536e71f3d587844110d836c82250830b27b1651afdbTed Kremenek      }
2537e71f3d587844110d836c82250830b27b1651afdbTed Kremenek    }
2538e71f3d587844110d836c82250830b27b1651afdbTed Kremenek    else
2539e71f3d587844110d836c82250830b27b1651afdbTed Kremenek      addCase = true;
2540e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  }
2541e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  return addCase;
2542e71f3d587844110d836c82250830b27b1651afdbTed Kremenek}
2543d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
25449c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCaseStmt(CaseStmt *CS) {
25456d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // CaseStmts are essentially labels, so they are the first statement in a
25466d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // block.
25470fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek  CFGBlock *TopBlock = 0, *LastBlock = 0;
25480498247f87ea0d716e0c2931fea812280649e33dTed Kremenek
25490fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek  if (Stmt *Sub = CS->getSubStmt()) {
25500fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek    // For deeply nested chains of CaseStmts, instead of doing a recursion
25510fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek    // (which can blow out the stack), manually unroll and create blocks
25520fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek    // along the way.
25530fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek    while (isa<CaseStmt>(Sub)) {
25540a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      CFGBlock *currentBlock = createBlock(false);
25550a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      currentBlock->setLabel(CS);
25560fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek
25570fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek      if (TopBlock)
25580a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek        addSuccessor(LastBlock, currentBlock);
25590fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek      else
25600a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek        TopBlock = currentBlock;
25610fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek
2562e71f3d587844110d836c82250830b27b1651afdbTed Kremenek      addSuccessor(SwitchTerminatedBlock,
2563e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek                   shouldAddCase(switchExclusivelyCovered, switchCond,
2564e71f3d587844110d836c82250830b27b1651afdbTed Kremenek                                 CS, *Context)
2565e71f3d587844110d836c82250830b27b1651afdbTed Kremenek                   ? currentBlock : 0);
25660fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek
2567e71f3d587844110d836c82250830b27b1651afdbTed Kremenek      LastBlock = currentBlock;
25680fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek      CS = cast<CaseStmt>(Sub);
25690fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek      Sub = CS->getSubStmt();
25700fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek    }
257129ccaa186ac27bcb414c5acb069f6438b27dd5e7Ted Kremenek
25720fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek    addStmt(Sub);
25730fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek  }
25741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
25759c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *CaseBlock = Block;
25764f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  if (!CaseBlock)
25774f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    CaseBlock = createBlock();
25786d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
25796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Cases statements partition blocks, so this is the top of the basic block we
25806d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // were processing (the "case XXX:" is the label).
25814f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  CaseBlock->setLabel(CS);
25824f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek
2583d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
25844e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    return 0;
25856d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
25866d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Add this block to the list of successors for the block with the switch
25876d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // statement.
25884f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  assert(SwitchTerminatedBlock);
2589e71f3d587844110d836c82250830b27b1651afdbTed Kremenek  addSuccessor(SwitchTerminatedBlock,
2590e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek               shouldAddCase(switchExclusivelyCovered, switchCond,
2591e71f3d587844110d836c82250830b27b1651afdbTed Kremenek                             CS, *Context)
2592e71f3d587844110d836c82250830b27b1651afdbTed Kremenek               ? CaseBlock : 0);
25936d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2594d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // We set Block to NULL to allow lazy creation of a new block (if necessary)
2595d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  Block = NULL;
25966d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
25970fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek  if (TopBlock) {
25980a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    addSuccessor(LastBlock, CaseBlock);
25990fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek    Succ = TopBlock;
260036f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan  } else {
26010fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek    // This block is now the implicit successor of other blocks.
26020fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek    Succ = CaseBlock;
26030fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek  }
26046d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
26050fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek  return Succ;
2606d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}
26076d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
26089c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitDefaultStmt(DefaultStmt *Terminator) {
26094f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  if (Terminator->getSubStmt())
26104f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    addStmt(Terminator->getSubStmt());
26111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2612eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek  DefaultCaseBlock = Block;
26134f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek
26144f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek  if (!DefaultCaseBlock)
26154f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    DefaultCaseBlock = createBlock();
26166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
26176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Default statements partition blocks, so this is the top of the basic block
26186d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // we were processing (the "default:" is the label).
2619411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek  DefaultCaseBlock->setLabel(Terminator);
26201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2621d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
26224e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek    return 0;
2623eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek
26246d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Unlike case statements, we don't add the default block to the successors
26256d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // for the switch statement immediately.  This is done when we finish
26266d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // processing the switch statement.  This allows for the default case
26276d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // (including a fall-through to the code after the switch statement) to always
26286d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // be the last successor of a switch-terminated block.
26296d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2630eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek  // We set Block to NULL to allow lazy creation of a new block (if necessary)
2631eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek  Block = NULL;
26326d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
2633eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek  // This block is now the implicit successor of other blocks.
2634eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek  Succ = DefaultCaseBlock;
26356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
26366d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  return DefaultCaseBlock;
2637295222c1f0926d84de77f076e79903523eeb5dbfTed Kremenek}
2638d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek
26395d1d20227878cd03db8b2dd23efd4cedfe874feeMike StumpCFGBlock *CFGBuilder::VisitCXXTryStmt(CXXTryStmt *Terminator) {
26405d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  // "try"/"catch" is a control-flow statement.  Thus we stop processing the
26415d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  // current block.
26429c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *TrySuccessor = NULL;
26435d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
26445d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  if (Block) {
2645d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu    if (badCFG)
26465d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump      return 0;
26475d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    TrySuccessor = Block;
26485d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  } else TrySuccessor = Succ;
26495d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
2650a1f93631a84621d77aeb627691da85a8991af188Mike Stump  CFGBlock *PrevTryTerminatedBlock = TryTerminatedBlock;
26515d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
26525d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  // Create a new block that will contain the try statement.
2653f00cca5e05bb9ea51a3a21c8014ff9f3508d46e9Mike Stump  CFGBlock *NewTryTerminatedBlock = createBlock(false);
26545d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  // Add the terminator in the try block.
2655f00cca5e05bb9ea51a3a21c8014ff9f3508d46e9Mike Stump  NewTryTerminatedBlock->setTerminator(Terminator);
26565d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
2657a1f93631a84621d77aeb627691da85a8991af188Mike Stump  bool HasCatchAll = false;
26585d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  for (unsigned h = 0; h <Terminator->getNumHandlers(); ++h) {
26595d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    // The code after the try is the implicit successor.
26605d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    Succ = TrySuccessor;
26615d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    CXXCatchStmt *CS = Terminator->getHandler(h);
2662a1f93631a84621d77aeb627691da85a8991af188Mike Stump    if (CS->getExceptionDecl() == 0) {
2663a1f93631a84621d77aeb627691da85a8991af188Mike Stump      HasCatchAll = true;
2664a1f93631a84621d77aeb627691da85a8991af188Mike Stump    }
26655d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    Block = NULL;
26665d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    CFGBlock *CatchBlock = VisitCXXCatchStmt(CS);
26675d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    if (CatchBlock == 0)
26685d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump      return 0;
26695d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    // Add this block to the list of successors for the block with the try
26705d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    // statement.
26710a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    addSuccessor(NewTryTerminatedBlock, CatchBlock);
26725d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  }
2673a1f93631a84621d77aeb627691da85a8991af188Mike Stump  if (!HasCatchAll) {
2674a1f93631a84621d77aeb627691da85a8991af188Mike Stump    if (PrevTryTerminatedBlock)
26750a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      addSuccessor(NewTryTerminatedBlock, PrevTryTerminatedBlock);
2676a1f93631a84621d77aeb627691da85a8991af188Mike Stump    else
26770a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      addSuccessor(NewTryTerminatedBlock, &cfg->getExit());
2678a1f93631a84621d77aeb627691da85a8991af188Mike Stump  }
26795d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
26805d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  // The code after the try is the implicit successor.
26815d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  Succ = TrySuccessor;
26825d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
2683f00cca5e05bb9ea51a3a21c8014ff9f3508d46e9Mike Stump  // Save the current "try" context.
2684f0e71aede7ccf3e311feac6a414c431f7a0fc3c8Ted Kremenek  SaveAndRestore<CFGBlock*> save_try(TryTerminatedBlock, NewTryTerminatedBlock);
2685f0e71aede7ccf3e311feac6a414c431f7a0fc3c8Ted Kremenek  cfg->addTryDispatchBlock(TryTerminatedBlock);
2686f00cca5e05bb9ea51a3a21c8014ff9f3508d46e9Mike Stump
26876db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek  assert(Terminator->getTryBlock() && "try must contain a non-NULL body");
26885d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  Block = NULL;
26893fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek  Block = addStmt(Terminator->getTryBlock());
26905d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  return Block;
26915d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump}
26925d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
26939c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCXXCatchStmt(CXXCatchStmt *CS) {
26945d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  // CXXCatchStmt are treated like labels, so they are the first statement in a
26955d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  // block.
26965d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
26970e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski  // Save local scope position because in case of exception variable ScopePos
26980e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski  // won't be restored when traversing AST.
26990e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski  SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
27000e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski
27010e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski  // Create local scope for possible exception variable.
27020e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski  // Store scope position. Add implicit destructor.
27039c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (VarDecl *VD = CS->getExceptionDecl()) {
27040e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski    LocalScope::const_iterator BeginScopePos = ScopePos;
27050e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski    addLocalScopeForVarDecl(VD);
27060e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski    addAutomaticObjDtors(ScopePos, BeginScopePos, CS);
27070e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski  }
27080e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski
27095d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  if (CS->getHandlerBlock())
27105d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    addStmt(CS->getHandlerBlock());
27115d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
27129c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *CatchBlock = Block;
27135d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  if (!CatchBlock)
27145d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    CatchBlock = createBlock();
2715337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek
2716337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek  // CXXCatchStmt is more than just a label.  They have semantic meaning
2717337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek  // as well, as they implicitly "initialize" the catch variable.  Add
2718337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek  // it to the CFG as a CFGElement so that the control-flow of these
2719337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek  // semantics gets captured.
2720337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek  appendStmt(CatchBlock, CS);
2721337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek
2722337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek  // Also add the CXXCatchStmt as a label, to mirror handling of regular
2723337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek  // labels.
27245d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  CatchBlock->setLabel(CS);
27255d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
2726337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek  // Bail out if the CFG is bad.
2727d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
27285d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    return 0;
27295d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
27305d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  // We set Block to NULL to allow lazy creation of a new block (if necessary)
27315d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  Block = NULL;
27325d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
27335d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  return CatchBlock;
27345d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump}
27355d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
27369c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
2737ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // C++0x for-range statements are specified as [stmt.ranged]:
2738ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  //
2739ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // {
2740ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  //   auto && __range = range-init;
2741ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  //   for ( auto __begin = begin-expr,
2742ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  //         __end = end-expr;
2743ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  //         __begin != __end;
2744ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  //         ++__begin ) {
2745ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  //     for-range-declaration = *__begin;
2746ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  //     statement
2747ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  //   }
2748ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // }
2749ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2750ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // Save local scope position before the addition of the implicit variables.
2751ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos);
2752ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2753ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // Create local scopes and destructors for range, begin and end variables.
2754ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  if (Stmt *Range = S->getRangeStmt())
2755ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    addLocalScopeForStmt(Range);
2756ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  if (Stmt *BeginEnd = S->getBeginEndStmt())
2757ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    addLocalScopeForStmt(BeginEnd);
2758ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  addAutomaticObjDtors(ScopePos, save_scope_pos.get(), S);
2759ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2760ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  LocalScope::const_iterator ContinueScopePos = ScopePos;
2761ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2762ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // "for" is a control-flow statement.  Thus we stop processing the current
2763ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // block.
27649c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *LoopSuccessor = NULL;
2765ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  if (Block) {
2766ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    if (badCFG)
2767ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith      return 0;
2768ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    LoopSuccessor = Block;
2769ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  } else
2770ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    LoopSuccessor = Succ;
2771ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2772ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // Save the current value for the break targets.
2773ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // All breaks should go to the code following the loop.
2774ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  SaveAndRestore<JumpTarget> save_break(BreakJumpTarget);
2775ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
2776ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2777ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // The block for the __begin != __end expression.
27789c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *ConditionBlock = createBlock(false);
2779ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  ConditionBlock->setTerminator(S);
2780ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2781ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // Now add the actual condition to the condition block.
2782ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  if (Expr *C = S->getCond()) {
2783ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    Block = ConditionBlock;
2784ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    CFGBlock *BeginConditionBlock = addStmt(C);
2785ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    if (badCFG)
2786ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith      return 0;
2787ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    assert(BeginConditionBlock == ConditionBlock &&
2788ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith           "condition block in for-range was unexpectedly complex");
2789ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    (void)BeginConditionBlock;
2790ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  }
2791ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2792ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // The condition block is the implicit successor for the loop body as well as
2793ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // any code above the loop.
2794ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  Succ = ConditionBlock;
2795ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2796ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // See if this is a known constant.
2797ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  TryResult KnownVal(true);
2798ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2799ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  if (S->getCond())
2800ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    KnownVal = tryEvaluateBool(S->getCond());
2801ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2802ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // Now create the loop body.
2803ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  {
2804ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    assert(S->getBody());
2805ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2806ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    // Save the current values for Block, Succ, and continue targets.
2807ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ);
2808ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget);
2809ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2810ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    // Generate increment code in its own basic block.  This is the target of
2811ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    // continue statements.
2812ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    Block = 0;
2813ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    Succ = addStmt(S->getInc());
2814ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos);
2815ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2816ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    // The starting block for the loop increment is the block that should
2817ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    // represent the 'loop target' for looping back to the start of the loop.
2818ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    ContinueJumpTarget.block->setLoopTarget(S);
2819ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2820ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    // Finish up the increment block and prepare to start the loop body.
2821ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    assert(Block);
2822ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    if (badCFG)
2823ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith      return 0;
2824ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    Block = 0;
2825ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2826ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2827ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    // Add implicit scope and dtors for loop variable.
2828ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    addLocalScopeAndDtors(S->getLoopVarStmt());
2829ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2830ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    // Populate a new block to contain the loop body and loop variable.
2831ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    Block = addStmt(S->getBody());
2832ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    if (badCFG)
2833ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith      return 0;
2834ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    Block = addStmt(S->getLoopVarStmt());
2835ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    if (badCFG)
2836ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith      return 0;
2837ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2838ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    // This new body block is a successor to our condition block.
2839ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith    addSuccessor(ConditionBlock, KnownVal.isFalse() ? 0 : Block);
2840ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  }
2841ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2842ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // Link up the condition block with the code that follows the loop (the
2843ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // false branch).
2844ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  addSuccessor(ConditionBlock, KnownVal.isTrue() ? 0 : LoopSuccessor);
2845ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
2846ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  // Add the initialization statements.
2847ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith  Block = createBlock();
2848b403d6d746239095a2c7bac958c924d92434e2b4Richard Smith  addStmt(S->getBeginEndStmt());
2849b403d6d746239095a2c7bac958c924d92434e2b4Richard Smith  return addStmt(S->getRangeStmt());
2850ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith}
2851ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith
28524765fa05b5652fcc4356371c2f481d0ea9a1b007John McCallCFGBlock *CFGBuilder::VisitExprWithCleanups(ExprWithCleanups *E,
28538599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    AddStmtChoice asc) {
28548599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  if (BuildOpts.AddImplicitDtors) {
28558599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    // If adding implicit destructors visit the full expression for adding
28568599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    // destructors of temporaries.
28578599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    VisitForTemporaryDtors(E->getSubExpr());
28588599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
28598599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    // Full expression has to be added as CFGStmt so it will be sequenced
28608599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    // before destructors of it's temporaries.
286194a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan    asc = asc.withAlwaysAdd(true);
28628599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
28638599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  return Visit(E->getSubExpr(), asc);
28648599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski}
28658599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
2866a725ed468585b881c43654eeb56b28554a84808aZhongxing XuCFGBlock *CFGBuilder::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E,
2867a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu                                                AddStmtChoice asc) {
28683179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek  if (asc.alwaysAdd(*this, E)) {
2869a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu    autoCreateBlock();
2870247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek    appendStmt(Block, E);
2871a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu
2872a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu    // We do not want to propagate the AlwaysAdd property.
287394a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan    asc = asc.withAlwaysAdd(false);
2874a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu  }
2875a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu  return Visit(E->getSubExpr(), asc);
2876a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu}
2877a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu
287881bc7d07b701042371a5723b6f394cd2482ed7beZhongxing XuCFGBlock *CFGBuilder::VisitCXXConstructExpr(CXXConstructExpr *C,
287981bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu                                            AddStmtChoice asc) {
288081bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu  autoCreateBlock();
288197a72c35a62304c3781aa280e28cb97a59afd585Zhongxing Xu  appendStmt(Block, C);
288294a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan
288381bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu  return VisitChildren(C);
288481bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu}
288581bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu
2886a725ed468585b881c43654eeb56b28554a84808aZhongxing XuCFGBlock *CFGBuilder::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E,
2887a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu                                                 AddStmtChoice asc) {
28883179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek  if (asc.alwaysAdd(*this, E)) {
2889a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu    autoCreateBlock();
2890247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek    appendStmt(Block, E);
2891a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu    // We do not want to propagate the AlwaysAdd property.
289294a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan    asc = asc.withAlwaysAdd(false);
2893a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu  }
2894a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu  return Visit(E->getSubExpr(), asc);
2895a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu}
2896a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu
289781bc7d07b701042371a5723b6f394cd2482ed7beZhongxing XuCFGBlock *CFGBuilder::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C,
289881bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu                                                  AddStmtChoice asc) {
289981bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu  autoCreateBlock();
2900247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek  appendStmt(Block, C);
290181bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu  return VisitChildren(C);
290281bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu}
290381bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu
2904a725ed468585b881c43654eeb56b28554a84808aZhongxing XuCFGBlock *CFGBuilder::VisitImplicitCastExpr(ImplicitCastExpr *E,
2905a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu                                            AddStmtChoice asc) {
29063179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek  if (asc.alwaysAdd(*this, E)) {
2907a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu    autoCreateBlock();
2908247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek    appendStmt(Block, E);
2909a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu  }
2910892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  return Visit(E->getSubExpr(), AddStmtChoice());
2911a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu}
2912a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu
29139c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt *I) {
29146d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Lazily create the indirect-goto dispatch block if there isn't one already.
29159c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlock *IBlock = cfg->getIndirectGotoBlock();
29166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
291719bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  if (!IBlock) {
291819bb356317952445b03ee341c02f6147083c9eeaTed Kremenek    IBlock = createBlock(false);
291919bb356317952445b03ee341c02f6147083c9eeaTed Kremenek    cfg->setIndirectGotoBlock(IBlock);
292019bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  }
29216d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
292219bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  // IndirectGoto is a control-flow statement.  Thus we stop processing the
292319bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  // current block and create a new one.
2924d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu  if (badCFG)
29254f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek    return 0;
29264f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek
292719bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  Block = createBlock(false);
292819bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  Block->setTerminator(I);
29290a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  addSuccessor(Block, IBlock);
293019bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  return addStmt(I->getTarget());
293119bb356317952445b03ee341c02f6147083c9eeaTed Kremenek}
293219bb356317952445b03ee341c02f6147083c9eeaTed Kremenek
29338599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskiCFGBlock *CFGBuilder::VisitForTemporaryDtors(Stmt *E, bool BindToTemporary) {
29348599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskitryAgain:
29358599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  if (!E) {
29368599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    badCFG = true;
29378599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    return NULL;
29388599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
29398599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  switch (E->getStmtClass()) {
29408599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    default:
29418599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      return VisitChildrenForTemporaryDtors(E);
29428599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
29438599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    case Stmt::BinaryOperatorClass:
29448599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      return VisitBinaryOperatorForTemporaryDtors(cast<BinaryOperator>(E));
29458599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
29468599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    case Stmt::CXXBindTemporaryExprClass:
29478599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      return VisitCXXBindTemporaryExprForTemporaryDtors(
29488599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski          cast<CXXBindTemporaryExpr>(E), BindToTemporary);
29498599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
295056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    case Stmt::BinaryConditionalOperatorClass:
29518599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    case Stmt::ConditionalOperatorClass:
29528599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      return VisitConditionalOperatorForTemporaryDtors(
295356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall          cast<AbstractConditionalOperator>(E), BindToTemporary);
29548599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
29558599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    case Stmt::ImplicitCastExprClass:
29568599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // For implicit cast we want BindToTemporary to be passed further.
29578599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      E = cast<CastExpr>(E)->getSubExpr();
29588599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      goto tryAgain;
29598599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
29608599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    case Stmt::ParenExprClass:
29618599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      E = cast<ParenExpr>(E)->getSubExpr();
29628599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      goto tryAgain;
296303e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor
296403e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor    case Stmt::MaterializeTemporaryExprClass:
296503e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor      E = cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr();
296603e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor      goto tryAgain;
29678599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
29688599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski}
29698599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
29708599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskiCFGBlock *CFGBuilder::VisitChildrenForTemporaryDtors(Stmt *E) {
29718599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // When visiting children for destructors we want to visit them in reverse
29728599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // order. Because there's no reverse iterator for children must to reverse
29738599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // them in helper vector.
29745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  typedef SmallVector<Stmt *, 4> ChildrenVect;
29758599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  ChildrenVect ChildrenRev;
29767502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  for (Stmt::child_range I = E->children(); I; ++I) {
29778599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    if (*I) ChildrenRev.push_back(*I);
29788599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
29798599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
29808599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  CFGBlock *B = Block;
29818599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  for (ChildrenVect::reverse_iterator I = ChildrenRev.rbegin(),
29828599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      L = ChildrenRev.rend(); I != L; ++I) {
29838599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    if (CFGBlock *R = VisitForTemporaryDtors(*I))
29848599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      B = R;
29858599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
29868599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  return B;
29878599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski}
29888599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
29898599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskiCFGBlock *CFGBuilder::VisitBinaryOperatorForTemporaryDtors(BinaryOperator *E) {
29908599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  if (E->isLogicalOp()) {
29918599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    // Destructors for temporaries in LHS expression should be called after
29928599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    // those for RHS expression. Even if this will unnecessarily create a block,
29938599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    // this block will be used at least by the full expression.
29948599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    autoCreateBlock();
29958599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    CFGBlock *ConfluenceBlock = VisitForTemporaryDtors(E->getLHS());
29968599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    if (badCFG)
29978599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      return NULL;
29988599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
29998599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    Succ = ConfluenceBlock;
30008599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    Block = NULL;
30018599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getRHS());
30028599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
30038599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    if (RHSBlock) {
30048599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      if (badCFG)
30058599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski        return NULL;
30068599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
30078599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // If RHS expression did produce destructors we need to connect created
30088599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // blocks to CFG in same manner as for binary operator itself.
30098599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      CFGBlock *LHSBlock = createBlock(false);
30108599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      LHSBlock->setTerminator(CFGTerminator(E, true));
30118599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
30128599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // For binary operator LHS block is before RHS in list of predecessors
30138599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // of ConfluenceBlock.
30148599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      std::reverse(ConfluenceBlock->pred_begin(),
30158599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski          ConfluenceBlock->pred_end());
30168599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
30178599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // See if this is a known constant.
30180a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek      TryResult KnownVal = tryEvaluateBool(E->getLHS());
30198599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      if (KnownVal.isKnown() && (E->getOpcode() == BO_LOr))
30208599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski        KnownVal.negate();
30218599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
30228599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // Link LHSBlock with RHSBlock exactly the same way as for binary operator
30238599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      // itself.
30248599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      if (E->getOpcode() == BO_LOr) {
30250a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek        addSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : ConfluenceBlock);
30260a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek        addSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : RHSBlock);
30278599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      } else {
30288599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski        assert (E->getOpcode() == BO_LAnd);
30290a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek        addSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : RHSBlock);
30300a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek        addSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : ConfluenceBlock);
30318599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      }
30328599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
30338599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      Block = LHSBlock;
30348599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      return LHSBlock;
30358599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    }
30368599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
30378599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    Block = ConfluenceBlock;
30388599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    return ConfluenceBlock;
30398599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
30408599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
304136f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan  if (E->isAssignmentOp()) {
30428599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    // For assignment operator (=) LHS expression is visited
30438599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    // before RHS expression. For destructors visit them in reverse order.
30448599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getRHS());
30458599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    CFGBlock *LHSBlock = VisitForTemporaryDtors(E->getLHS());
30468599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    return LHSBlock ? LHSBlock : RHSBlock;
30478599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
30488599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
30498599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // For any other binary operator RHS expression is visited before
30508599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // LHS expression (order of children). For destructors visit them in reverse
30518599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // order.
30528599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  CFGBlock *LHSBlock = VisitForTemporaryDtors(E->getLHS());
30538599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getRHS());
30548599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  return RHSBlock ? RHSBlock : LHSBlock;
30558599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski}
30568599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
30578599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskiCFGBlock *CFGBuilder::VisitCXXBindTemporaryExprForTemporaryDtors(
30588599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    CXXBindTemporaryExpr *E, bool BindToTemporary) {
30598599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // First add destructors for temporaries in subexpression.
30608599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  CFGBlock *B = VisitForTemporaryDtors(E->getSubExpr());
3061249c9458e2cc5b671634baefe8517d7598883a20Zhongxing Xu  if (!BindToTemporary) {
30628599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    // If lifetime of temporary is not prolonged (by assigning to constant
30638599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    // reference) add destructor for it.
3064c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth
3065c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth    // If the destructor is marked as a no-return destructor, we need to create
3066c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth    // a new block for the destructor which does not have as a successor
3067c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth    // anything built thus far. Control won't flow out of this block.
3068c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth    const CXXDestructorDecl *Dtor = E->getTemporary()->getDestructor();
3069dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth    if (cast<FunctionType>(Dtor->getType())->getNoReturnAttr())
3070dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth      Block = createNoReturnBlock();
3071dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth    else
3072c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth      autoCreateBlock();
3073c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth
30748599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    appendTemporaryDtor(Block, E);
30758599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    B = Block;
30768599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
30778599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  return B;
30788599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski}
30798599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
30808599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskiCFGBlock *CFGBuilder::VisitConditionalOperatorForTemporaryDtors(
308156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    AbstractConditionalOperator *E, bool BindToTemporary) {
30828599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // First add destructors for condition expression.  Even if this will
30838599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // unnecessarily create a block, this block will be used at least by the full
30848599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // expression.
30858599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  autoCreateBlock();
30868599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  CFGBlock *ConfluenceBlock = VisitForTemporaryDtors(E->getCond());
30878599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  if (badCFG)
30888599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    return NULL;
308956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  if (BinaryConditionalOperator *BCO
309056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        = dyn_cast<BinaryConditionalOperator>(E)) {
309156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    ConfluenceBlock = VisitForTemporaryDtors(BCO->getCommon());
30928599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    if (badCFG)
30938599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski      return NULL;
30948599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
30958599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
309656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  // Try to add block with destructors for LHS expression.
309756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  CFGBlock *LHSBlock = NULL;
309856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  Succ = ConfluenceBlock;
309956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  Block = NULL;
310056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  LHSBlock = VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary);
310156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  if (badCFG)
310256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    return NULL;
310356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall
31048599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // Try to add block with destructors for RHS expression;
31058599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  Succ = ConfluenceBlock;
31068599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  Block = NULL;
310756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getFalseExpr(),
310856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall                                              BindToTemporary);
31098599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  if (badCFG)
31108599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    return NULL;
31118599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
31128599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  if (!RHSBlock && !LHSBlock) {
31138599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    // If neither LHS nor RHS expression had temporaries to destroy don't create
31148599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    // more blocks.
31158599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    Block = ConfluenceBlock;
31168599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    return Block;
31178599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
31188599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
31198599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  Block = createBlock(false);
31208599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  Block->setTerminator(CFGTerminator(E, true));
31218599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
31228599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  // See if this is a known constant.
31230a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  const TryResult &KnownVal = tryEvaluateBool(E->getCond());
31248599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
31258599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  if (LHSBlock) {
31260a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    addSuccessor(Block, KnownVal.isFalse() ? NULL : LHSBlock);
31278599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  } else if (KnownVal.isFalse()) {
31280a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    addSuccessor(Block, NULL);
31298599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  } else {
31300a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    addSuccessor(Block, ConfluenceBlock);
31318599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    std::reverse(ConfluenceBlock->pred_begin(), ConfluenceBlock->pred_end());
31328599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  }
31338599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
31348599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  if (!RHSBlock)
31358599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    RHSBlock = ConfluenceBlock;
31360a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  addSuccessor(Block, KnownVal.isTrue() ? NULL : RHSBlock);
31378599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
31388599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski  return Block;
31398599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski}
31408599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
3141befef2f69759d7338e2b7c5ce6c8b6f47fe6e667Ted Kremenek} // end anonymous namespace
3142026473c2175424a039f51ca8949937268721b965Ted Kremenek
31436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// createBlock - Constructs and adds a new CFGBlock to the CFG.  The block has
31446d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump///  no successors or predecessors.  If this is the first block created in the
31456d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump///  CFG, it is automatically set to be the Entry and Exit of the CFG.
31469c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFG::createBlock() {
3147026473c2175424a039f51ca8949937268721b965Ted Kremenek  bool first_block = begin() == end();
3148026473c2175424a039f51ca8949937268721b965Ted Kremenek
3149026473c2175424a039f51ca8949937268721b965Ted Kremenek  // Create the block.
3150ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek  CFGBlock *Mem = getAllocator().Allocate<CFGBlock>();
315102f34c5003b2c5067675f89ffce0a84c28faf722Anna Zaks  new (Mem) CFGBlock(NumBlockIDs++, BlkBVC, this);
3152ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek  Blocks.push_back(Mem, BlkBVC);
3153026473c2175424a039f51ca8949937268721b965Ted Kremenek
3154026473c2175424a039f51ca8949937268721b965Ted Kremenek  // If this is the first block, set it as the Entry and Exit.
3155ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek  if (first_block)
3156ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek    Entry = Exit = &back();
3157026473c2175424a039f51ca8949937268721b965Ted Kremenek
3158026473c2175424a039f51ca8949937268721b965Ted Kremenek  // Return the block.
3159ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek  return &back();
3160026473c2175424a039f51ca8949937268721b965Ted Kremenek}
3161026473c2175424a039f51ca8949937268721b965Ted Kremenek
3162026473c2175424a039f51ca8949937268721b965Ted Kremenek/// buildCFG - Constructs a CFG from an AST.  Ownership of the returned
3163026473c2175424a039f51ca8949937268721b965Ted Kremenek///  CFG is returned to the caller.
31649c378f705405d37f49795d5e915989de774fe11fTed KremenekCFG* CFG::buildCFG(const Decl *D, Stmt *Statement, ASTContext *C,
3165b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek    const BuildOptions &BO) {
3166b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek  CFGBuilder Builder(C, BO);
3167b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek  return Builder.buildCFG(D, Statement);
3168fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek}
3169fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
3170c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenekconst CXXDestructorDecl *
3171c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed KremenekCFGImplicitDtor::getDestructorDecl(ASTContext &astContext) const {
3172c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek  switch (getKind()) {
3173c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek    case CFGElement::Invalid:
3174c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek    case CFGElement::Statement:
3175c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek    case CFGElement::Initializer:
3176c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      llvm_unreachable("getDestructorDecl should only be used with "
3177c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek                       "ImplicitDtors");
3178c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek    case CFGElement::AutomaticObjectDtor: {
3179c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      const VarDecl *var = cast<CFGAutomaticObjDtor>(this)->getVarDecl();
3180c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      QualType ty = var->getType();
3181697d42db6cba7a5994d955ce31be2c097902cf0cTed Kremenek      ty = ty.getNonReferenceType();
31824cf225382a8b061dce41733c962d62b6db9721f8Ted Kremenek      while (const ArrayType *arrayType = astContext.getAsArrayType(ty)) {
3183c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenek        ty = arrayType->getElementType();
3184c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenek      }
3185c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      const RecordType *recordType = ty->getAs<RecordType>();
3186c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      const CXXRecordDecl *classDecl =
3187697d42db6cba7a5994d955ce31be2c097902cf0cTed Kremenek      cast<CXXRecordDecl>(recordType->getDecl());
3188c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      return classDecl->getDestructor();
3189c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek    }
3190c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek    case CFGElement::TemporaryDtor: {
3191c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      const CXXBindTemporaryExpr *bindExpr =
3192c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek        cast<CFGTemporaryDtor>(this)->getBindTemporaryExpr();
3193c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      const CXXTemporary *temp = bindExpr->getTemporary();
3194c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      return temp->getDestructor();
3195c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek    }
3196c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek    case CFGElement::BaseDtor:
3197c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek    case CFGElement::MemberDtor:
3198c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek
3199c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      // Not yet supported.
3200c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek      return 0;
3201c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek  }
3202697d42db6cba7a5994d955ce31be2c097902cf0cTed Kremenek  llvm_unreachable("getKind() returned bogus value");
3203c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek}
3204c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek
3205c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenekbool CFGImplicitDtor::isNoReturn(ASTContext &astContext) const {
3206c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenek  if (const CXXDestructorDecl *cdecl = getDestructorDecl(astContext)) {
3207c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek    QualType ty = cdecl->getType();
3208c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek    return cast<FunctionType>(ty)->getNoReturnAttr();
3209c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek  }
3210c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek  return false;
32113c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek}
32123c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek
321363f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek//===----------------------------------------------------------------------===//
321463f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek// CFG: Queries for BlkExprs.
321563f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek//===----------------------------------------------------------------------===//
321663f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek
321763f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremeneknamespace {
321886946745225096243f6969dc745267b78fc211a6Ted Kremenek  typedef llvm::DenseMap<const Stmt*,unsigned> BlkExprMapTy;
321963f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek}
322063f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek
3221f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenekstatic void FindSubExprAssignments(const Stmt *S,
3222f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek                                   llvm::SmallPtrSet<const Expr*,50>& Set) {
32238a69366a1cd8fe1e9fd312048c0d5ce58eabeeb2Ted Kremenek  if (!S)
322433d4aab80f31bd06257526fe2883ea920529456bTed Kremenek    return;
32256d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3226f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek  for (Stmt::const_child_range I = S->children(); I; ++I) {
3227f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek    const Stmt *child = *I;
32288a69366a1cd8fe1e9fd312048c0d5ce58eabeeb2Ted Kremenek    if (!child)
32298a69366a1cd8fe1e9fd312048c0d5ce58eabeeb2Ted Kremenek      continue;
3230ad5a894df1841698c824381b414630799adc26caTed Kremenek
3231f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek    if (const BinaryOperator* B = dyn_cast<BinaryOperator>(child))
323233d4aab80f31bd06257526fe2883ea920529456bTed Kremenek      if (B->isAssignmentOp()) Set.insert(B);
32336d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
32348a69366a1cd8fe1e9fd312048c0d5ce58eabeeb2Ted Kremenek    FindSubExprAssignments(child, Set);
323533d4aab80f31bd06257526fe2883ea920529456bTed Kremenek  }
323633d4aab80f31bd06257526fe2883ea920529456bTed Kremenek}
323733d4aab80f31bd06257526fe2883ea920529456bTed Kremenek
323863f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenekstatic BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) {
323963f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  BlkExprMapTy* M = new BlkExprMapTy();
32406d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
32416d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // Look for assignments that are used as subexpressions.  These are the only
32426d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // assignments that we want to *possibly* register as a block-level
32436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // expression.  Basically, if an assignment occurs both in a subexpression and
32446d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  // at the block-level, it is a block-level expression.
3245f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek  llvm::SmallPtrSet<const Expr*,50> SubExprAssignments;
32466d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
324763f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I)
3248ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek    for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI)
32493c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek      if (const CFGStmt *S = BI->getAs<CFGStmt>())
32503c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek        FindSubExprAssignments(S->getStmt(), SubExprAssignments);
325186946745225096243f6969dc745267b78fc211a6Ted Kremenek
3252411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek  for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) {
32536d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
32546d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    // Iterate over the statements again on identify the Expr* and Stmt* at the
32556d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    // block-level that are block-level expressions.
3256411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek
3257b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu    for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI) {
32583c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek      const CFGStmt *CS = BI->getAs<CFGStmt>();
32593c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek      if (!CS)
3260b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu        continue;
3261f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek      if (const Expr *Exp = dyn_cast<Expr>(CS->getStmt())) {
3262ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose        assert((Exp->IgnoreParens() == Exp) && "No parens on block-level exps");
32636d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3264f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek        if (const BinaryOperator* B = dyn_cast<BinaryOperator>(Exp)) {
326533d4aab80f31bd06257526fe2883ea920529456bTed Kremenek          // Assignment expressions that are not nested within another
32666d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump          // expression are really "statements" whose value is never used by
32676d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump          // another expression.
3268411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek          if (B->isAssignmentOp() && !SubExprAssignments.count(Exp))
326933d4aab80f31bd06257526fe2883ea920529456bTed Kremenek            continue;
32709c378f705405d37f49795d5e915989de774fe11fTed Kremenek        } else if (const StmtExpr *SE = dyn_cast<StmtExpr>(Exp)) {
32716d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump          // Special handling for statement expressions.  The last statement in
32726d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump          // the statement expression is also a block-level expr.
32739c378f705405d37f49795d5e915989de774fe11fTed Kremenek          const CompoundStmt *C = SE->getSubStmt();
327486946745225096243f6969dc745267b78fc211a6Ted Kremenek          if (!C->body_empty()) {
3275ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose            const Stmt *Last = C->body_back();
3276ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose            if (const Expr *LastEx = dyn_cast<Expr>(Last))
3277ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose              Last = LastEx->IgnoreParens();
327833d4aab80f31bd06257526fe2883ea920529456bTed Kremenek            unsigned x = M->size();
3279ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose            (*M)[Last] = x;
328086946745225096243f6969dc745267b78fc211a6Ted Kremenek          }
328186946745225096243f6969dc745267b78fc211a6Ted Kremenek        }
3282e2dcd783a04f654c50bd8b13fb08a440afbd67e7Ted Kremenek
328333d4aab80f31bd06257526fe2883ea920529456bTed Kremenek        unsigned x = M->size();
3284411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek        (*M)[Exp] = x;
328533d4aab80f31bd06257526fe2883ea920529456bTed Kremenek      }
3286b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu    }
32876d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3288411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    // Look at terminators.  The condition is a block-level expression.
32896d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
32909c378f705405d37f49795d5e915989de774fe11fTed Kremenek    Stmt *S = (*I)->getTerminatorCondition();
32916d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3292390e48b15ad93f85bfd1e33b9992c198fa0db475Ted Kremenek    if (S && M->find(S) == M->end()) {
3293ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose      unsigned x = M->size();
3294ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose      (*M)[S] = x;
3295411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    }
3296411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek  }
32976d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
329886946745225096243f6969dc745267b78fc211a6Ted Kremenek  return M;
329963f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek}
330063f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek
33019c378f705405d37f49795d5e915989de774fe11fTed KremenekCFG::BlkExprNumTy CFG::getBlkExprNum(const Stmt *S) {
330286946745225096243f6969dc745267b78fc211a6Ted Kremenek  assert(S != NULL);
330363f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  if (!BlkExprMap) { BlkExprMap = (void*) PopulateBlkExprMap(*this); }
33046d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
330563f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  BlkExprMapTy* M = reinterpret_cast<BlkExprMapTy*>(BlkExprMap);
330686946745225096243f6969dc745267b78fc211a6Ted Kremenek  BlkExprMapTy::iterator I = M->find(S);
33073fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek  return (I == M->end()) ? CFG::BlkExprNumTy() : CFG::BlkExprNumTy(I->second);
330863f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek}
33097dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
331063f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenekunsigned CFG::getNumBlkExprs() {
331163f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  if (const BlkExprMapTy* M = reinterpret_cast<const BlkExprMapTy*>(BlkExprMap))
331263f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek    return M->size();
331336f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan
331436f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan  // We assume callers interested in the number of BlkExprs will want
331536f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan  // the map constructed if it doesn't already exist.
331636f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan  BlkExprMap = (void*) PopulateBlkExprMap(*this);
331736f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan  return reinterpret_cast<BlkExprMapTy*>(BlkExprMap)->size();
331863f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek}
331963f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek
3320274f4334f6dd35239e5c3d4b86198f7f5804b059Ted Kremenek//===----------------------------------------------------------------------===//
3321ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek// Filtered walking of the CFG.
3322ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek//===----------------------------------------------------------------------===//
3323ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek
3324ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenekbool CFGBlock::FilterEdge(const CFGBlock::FilterOptions &F,
3325be39a566a914df8561d7a1e9654708297f0908c1Ted Kremenek        const CFGBlock *From, const CFGBlock *To) {
3326ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek
33276e40035988965340555c942d6e7afb6c7527beb1Ted Kremenek  if (To && F.IgnoreDefaultsWithCoveredEnums) {
3328ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek    // If the 'To' has no label or is labeled but the label isn't a
3329ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek    // CaseStmt then filter this edge.
3330ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek    if (const SwitchStmt *S =
33316e40035988965340555c942d6e7afb6c7527beb1Ted Kremenek        dyn_cast_or_null<SwitchStmt>(From->getTerminator().getStmt())) {
3332ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek      if (S->isAllEnumCasesCovered()) {
33336e40035988965340555c942d6e7afb6c7527beb1Ted Kremenek        const Stmt *L = To->getLabel();
33346e40035988965340555c942d6e7afb6c7527beb1Ted Kremenek        if (!L || !isa<CaseStmt>(L))
33356e40035988965340555c942d6e7afb6c7527beb1Ted Kremenek          return true;
3336ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek      }
3337ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek    }
3338ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek  }
3339ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek
3340ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek  return false;
3341ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek}
3342ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek
3343ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek//===----------------------------------------------------------------------===//
3344274f4334f6dd35239e5c3d4b86198f7f5804b059Ted Kremenek// Cleanup: CFG dstor.
3345274f4334f6dd35239e5c3d4b86198f7f5804b059Ted Kremenek//===----------------------------------------------------------------------===//
3346274f4334f6dd35239e5c3d4b86198f7f5804b059Ted Kremenek
334763f5887f316fb52d243fcbb3631c039de6c4b993Ted KremenekCFG::~CFG() {
334863f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  delete reinterpret_cast<const BlkExprMapTy*>(BlkExprMap);
334963f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek}
33506d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
33517dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===//
33527dba8607e59096014b7139ff20ef00870041d518Ted Kremenek// CFG pretty printing
33537dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===//
33547dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
335542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremeneknamespace {
33562bac4ea765a4a6e1f6149964663f62d4bca6743bTed Kremenek
3357ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass StmtPrinterHelper : public PrinterHelper  {
33583c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek  typedef llvm::DenseMap<const Stmt*,std::pair<unsigned,unsigned> > StmtMapTy;
33593c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek  typedef llvm::DenseMap<const Decl*,std::pair<unsigned,unsigned> > DeclMapTy;
336042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  StmtMapTy StmtMap;
33611cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski  DeclMapTy DeclMap;
33620a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  signed currentBlock;
33630a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  unsigned currentStmt;
3364e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  const LangOptions &LangOpts;
336542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenekpublic:
33661c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek
3367e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  StmtPrinterHelper(const CFG* cfg, const LangOptions &LO)
33683c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek    : currentBlock(0), currentStmt(0), LangOpts(LO)
33693c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek  {
337042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek    for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I ) {
337142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek      unsigned j = 1;
3372ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek      for (CFGBlock::const_iterator BI = (*I)->begin(), BEnd = (*I)->end() ;
33731cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski           BI != BEnd; ++BI, ++j ) {
33743c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek        if (const CFGStmt *SE = BI->getAs<CFGStmt>()) {
33753c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek          const Stmt *stmt= SE->getStmt();
33761cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski          std::pair<unsigned, unsigned> P((*I)->getBlockID(), j);
33773c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek          StmtMap[stmt] = P;
33783c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek
33793c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek          switch (stmt->getStmtClass()) {
33803c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            case Stmt::DeclStmtClass:
33813c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek                DeclMap[cast<DeclStmt>(stmt)->getSingleDecl()] = P;
33823c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek                break;
33833c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            case Stmt::IfStmtClass: {
33843c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              const VarDecl *var = cast<IfStmt>(stmt)->getConditionVariable();
33853c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              if (var)
33863c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek                DeclMap[var] = P;
33873c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              break;
33883c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            }
33893c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            case Stmt::ForStmtClass: {
33903c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              const VarDecl *var = cast<ForStmt>(stmt)->getConditionVariable();
33913c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              if (var)
33923c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek                DeclMap[var] = P;
33933c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              break;
33943c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            }
33953c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            case Stmt::WhileStmtClass: {
33963c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              const VarDecl *var =
33973c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek                cast<WhileStmt>(stmt)->getConditionVariable();
33983c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              if (var)
33993c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek                DeclMap[var] = P;
34003c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              break;
34013c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            }
34023c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            case Stmt::SwitchStmtClass: {
34033c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              const VarDecl *var =
34043c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek                cast<SwitchStmt>(stmt)->getConditionVariable();
34053c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              if (var)
34063c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek                DeclMap[var] = P;
34073c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              break;
34083c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            }
34093c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            case Stmt::CXXCatchStmtClass: {
34103c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              const VarDecl *var =
34113c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek                cast<CXXCatchStmt>(stmt)->getExceptionDecl();
34123c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              if (var)
34133c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek                DeclMap[var] = P;
34143c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              break;
34153c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            }
34163c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            default:
34173c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek              break;
34181cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski          }
34191cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski        }
342042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek      }
3421b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu    }
3422fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  }
34233c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek
34246d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
342542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  virtual ~StmtPrinterHelper() {}
34266d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3427e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  const LangOptions &getLangOpts() const { return LangOpts; }
34280a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  void setBlockID(signed i) { currentBlock = i; }
34290a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  void setStmtID(unsigned i) { currentStmt = i; }
34306d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
34319c378f705405d37f49795d5e915989de774fe11fTed Kremenek  virtual bool handledStmt(Stmt *S, raw_ostream &OS) {
34321cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    StmtMapTy::iterator I = StmtMap.find(S);
3433fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
343442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek    if (I == StmtMap.end())
343542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek      return false;
34366d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
34370a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    if (currentBlock >= 0 && I->second.first == (unsigned) currentBlock
34380a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek                          && I->second.second == currentStmt) {
343942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek      return false;
34403fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek    }
34416d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
34423fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek    OS << "[B" << I->second.first << "." << I->second.second << "]";
34431c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek    return true;
344442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  }
34451cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski
34469c378f705405d37f49795d5e915989de774fe11fTed Kremenek  bool handleDecl(const Decl *D, raw_ostream &OS) {
34471cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    DeclMapTy::iterator I = DeclMap.find(D);
34481cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski
34491cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    if (I == DeclMap.end())
34501cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski      return false;
34511cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski
34520a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek    if (currentBlock >= 0 && I->second.first == (unsigned) currentBlock
34530a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek                          && I->second.second == currentStmt) {
34541cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski      return false;
34551cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    }
34561cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski
34571cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    OS << "[B" << I->second.first << "." << I->second.second << "]";
34581cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    return true;
34591cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski  }
346042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek};
3461e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner} // end anonymous namespace
3462e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner
3463e8ee26b49d68ae3ffdf9a990ff7511ef55afa04cTed Kremenek
3464e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnernamespace {
3465ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass CFGBlockTerminatorPrint
34666fa9b88e2c3d47d606a273df2f8d03509bcff0b9Ted Kremenek  : public StmtVisitor<CFGBlockTerminatorPrint,void> {
34676d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
34689c378f705405d37f49795d5e915989de774fe11fTed Kremenek  raw_ostream &OS;
346942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  StmtPrinterHelper* Helper;
3470d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  PrintingPolicy Policy;
3471d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenekpublic:
34729c378f705405d37f49795d5e915989de774fe11fTed Kremenek  CFGBlockTerminatorPrint(raw_ostream &os, StmtPrinterHelper* helper,
3473e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner                          const PrintingPolicy &Policy)
3474d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    : OS(os), Helper(helper), Policy(Policy) {}
34756d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
34769c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void VisitIfStmt(IfStmt *I) {
3477d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    OS << "if ";
3478d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    I->getCond()->printPretty(OS,Helper,Policy);
3479d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  }
34806d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3481d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  // Default case.
34829c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void VisitStmt(Stmt *Terminator) {
34836d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    Terminator->printPretty(OS, Helper, Policy);
34846d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  }
34856d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
34869c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void VisitForStmt(ForStmt *F) {
3487d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    OS << "for (" ;
34883fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek    if (F->getInit())
34893fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek      OS << "...";
3490535bb20b6e252809bc17cc59b5d71b5e5e549e70Ted Kremenek    OS << "; ";
34919c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (Stmt *C = F->getCond())
34923fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek      C->printPretty(OS, Helper, Policy);
3493535bb20b6e252809bc17cc59b5d71b5e5e549e70Ted Kremenek    OS << "; ";
34943fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek    if (F->getInc())
34953fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek      OS << "...";
3496a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek    OS << ")";
3497d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  }
34986d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
34999c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void VisitWhileStmt(WhileStmt *W) {
3500d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    OS << "while " ;
35019c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (Stmt *C = W->getCond())
35023fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek      C->printPretty(OS, Helper, Policy);
3503d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek  }
35046d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
35059c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void VisitDoStmt(DoStmt *D) {
3506d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek    OS << "do ... while ";
35079c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (Stmt *C = D->getCond())
35083fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek      C->printPretty(OS, Helper, Policy);
35099da2fb773c473b989c78c513c5ce61641e9bbb4dTed Kremenek  }
35106d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
35119c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void VisitSwitchStmt(SwitchStmt *Terminator) {
35129da2fb773c473b989c78c513c5ce61641e9bbb4dTed Kremenek    OS << "switch ";
3513d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    Terminator->getCond()->printPretty(OS, Helper, Policy);
35149da2fb773c473b989c78c513c5ce61641e9bbb4dTed Kremenek  }
35156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
35169c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void VisitCXXTryStmt(CXXTryStmt *CS) {
35175d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    OS << "try ...";
35185d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump  }
35195d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
352056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  void VisitAbstractConditionalOperator(AbstractConditionalOperator* C) {
3521d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    C->getCond()->printPretty(OS, Helper, Policy);
35226d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    OS << " ? ... : ...";
3523805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek  }
35246d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
35259c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void VisitChooseExpr(ChooseExpr *C) {
3526aeddbf689eb3e3afca5117ca83c7b2e18260b0d8Ted Kremenek    OS << "__builtin_choose_expr( ";
3527d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    C->getCond()->printPretty(OS, Helper, Policy);
3528a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek    OS << " )";
3529aeddbf689eb3e3afca5117ca83c7b2e18260b0d8Ted Kremenek  }
35306d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
35319c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void VisitIndirectGotoStmt(IndirectGotoStmt *I) {
35321c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek    OS << "goto *";
3533d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    I->getTarget()->printPretty(OS, Helper, Policy);
35341c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek  }
35356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3536805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek  void VisitBinaryOperator(BinaryOperator* B) {
3537805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek    if (!B->isLogicalOp()) {
3538805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek      VisitExpr(B);
3539805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek      return;
3540805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek    }
35416d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3542d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    B->getLHS()->printPretty(OS, Helper, Policy);
35436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3544805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek    switch (B->getOpcode()) {
35452de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      case BO_LOr:
3546a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek        OS << " || ...";
3547805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek        return;
35482de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall      case BO_LAnd:
3549a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek        OS << " && ...";
3550805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek        return;
3551805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek      default:
3552b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie        llvm_unreachable("Invalid logical operator.");
35536d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    }
3554805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek  }
35556d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
35569c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void VisitExpr(Expr *E) {
3557d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor    E->printPretty(OS, Helper, Policy);
35586d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump  }
3559d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek};
3560e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner} // end anonymous namespace
3561e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner
35625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic void print_elem(raw_ostream &OS, StmtPrinterHelper* Helper,
3563079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump                       const CFGElement &E) {
35643c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek  if (const CFGStmt *CS = E.getAs<CFGStmt>()) {
3565f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek    const Stmt *S = CS->getStmt();
35661cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski
35671cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    if (Helper) {
35681cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski
35691cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski      // special printing for statement-expressions.
3570f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek      if (const StmtExpr *SE = dyn_cast<StmtExpr>(S)) {
3571f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek        const CompoundStmt *Sub = SE->getSubStmt();
35721cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski
35737502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall        if (Sub->children()) {
35741cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski          OS << "({ ... ; ";
35751cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski          Helper->handledStmt(*SE->getSubStmt()->body_rbegin(),OS);
35761cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski          OS << " })\n";
35771cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski          return;
35781cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski        }
35791cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski      }
35801cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski      // special printing for comma expressions.
3581f1d10d939739f1a4544926d807e4f0f9fb64be61Ted Kremenek      if (const BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
35821cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski        if (B->getOpcode() == BO_Comma) {
35831cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski          OS << "... , ";
35841cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski          Helper->handledStmt(B->getRHS(),OS);
35851cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski          OS << '\n';
35861cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski          return;
35871cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski        }
35881c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek      }
35891c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek    }
35901cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    S->printPretty(OS, Helper, PrintingPolicy(Helper->getLangOpts()));
35916d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
35921cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    if (isa<CXXOperatorCallExpr>(S)) {
359336f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan      OS << " (OperatorCall)";
3594893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek    }
3595893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek    else if (isa<CXXBindTemporaryExpr>(S)) {
359636f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan      OS << " (BindTemporary)";
35976d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump    }
35983b7a48fbc681c6fb59e5304a210c30dbb49dabeaTed Kremenek    else if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(S)) {
35993b7a48fbc681c6fb59e5304a210c30dbb49dabeaTed Kremenek      OS << " (CXXConstructExpr, " << CCE->getType().getAsString() << ")";
36003b7a48fbc681c6fb59e5304a210c30dbb49dabeaTed Kremenek    }
3601893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek    else if (const CastExpr *CE = dyn_cast<CastExpr>(S)) {
3602893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek      OS << " (" << CE->getStmtClassName() << ", "
3603893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek         << CE->getCastKindName()
3604893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek         << ", " << CE->getType().getAsString()
3605893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek         << ")";
3606893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek    }
36076d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
36081cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    // Expressions need a newline.
36091cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    if (isa<Expr>(S))
36101cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski      OS << '\n';
36114e0cfa8eacf76f203d6ee6ce164162ccd4275ccdTed Kremenek
36123c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek  } else if (const CFGInitializer *IE = E.getAs<CFGInitializer>()) {
36133c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek    const CXXCtorInitializer *I = IE->getInitializer();
36141cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    if (I->isBaseInitializer())
36151cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski      OS << I->getBaseClass()->getAsCXXRecordDecl()->getName();
361600eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet    else OS << I->getAnyMember()->getName();
36176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
36181cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    OS << "(";
36199c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (Expr *IE = I->getInit())
36201cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski      IE->printPretty(OS, Helper, PrintingPolicy(Helper->getLangOpts()));
36211cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    OS << ")";
36221cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski
36231cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    if (I->isBaseInitializer())
36241cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski      OS << " (Base initializer)\n";
36251cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    else OS << " (Member initializer)\n";
36261cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski
36273c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek  } else if (const CFGAutomaticObjDtor *DE = E.getAs<CFGAutomaticObjDtor>()){
36289c378f705405d37f49795d5e915989de774fe11fTed Kremenek    const VarDecl *VD = DE->getVarDecl();
36291cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    Helper->handleDecl(VD, OS);
36301cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski
3631b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski    const Type* T = VD->getType().getTypePtr();
36321cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    if (const ReferenceType* RT = T->getAs<ReferenceType>())
36331cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski      T = RT->getPointeeType().getTypePtr();
3634b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski    else if (const Type *ET = T->getArrayElementTypeNoTypeQual())
3635b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski      T = ET;
36361cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski
36371cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()";
36381cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski    OS << " (Implicit destructor)\n";
36397c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski
36403c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek  } else if (const CFGBaseDtor *BE = E.getAs<CFGBaseDtor>()) {
36413c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek    const CXXBaseSpecifier *BS = BE->getBaseSpecifier();
36427c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski    OS << "~" << BS->getType()->getAsCXXRecordDecl()->getName() << "()";
36434e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu    OS << " (Base object destructor)\n";
36447c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski
36453c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek  } else if (const CFGMemberDtor *ME = E.getAs<CFGMemberDtor>()) {
36463c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek    const FieldDecl *FD = ME->getFieldDecl();
36478c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski
36488c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski    const Type *T = FD->getType().getTypePtr();
36498c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski    if (const Type *ET = T->getArrayElementTypeNoTypeQual())
36508c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski      T = ET;
36518c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski
36527c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski    OS << "this->" << FD->getName();
36538c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski    OS << ".~" << T->getAsCXXRecordDecl()->getName() << "()";
36544e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu    OS << " (Member object destructor)\n";
36558599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski
36563c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek  } else if (const CFGTemporaryDtor *TE = E.getAs<CFGTemporaryDtor>()) {
36573c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek    const CXXBindTemporaryExpr *BT = TE->getBindTemporaryExpr();
36588599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    OS << "~" << BT->getType()->getAsCXXRecordDecl()->getName() << "()";
36598599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski    OS << " (Temporary object destructor)\n";
36601cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski  }
366181bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu}
36626d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
36639c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic void print_block(raw_ostream &OS, const CFG* cfg,
36649c378f705405d37f49795d5e915989de774fe11fTed Kremenek                        const CFGBlock &B,
3665682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek                        StmtPrinterHelper* Helper, bool print_edges,
3666682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek                        bool ShowColors) {
36676d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3668682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek  if (Helper)
3669682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    Helper->setBlockID(B.getBlockID());
36706d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
36717dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  // Print the header.
3672682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek  if (ShowColors)
3673682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    OS.changeColor(raw_ostream::YELLOW, true);
3674682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek
3675682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek  OS << "\n [B" << B.getBlockID();
36766d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
367742a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  if (&B == &cfg->getEntry())
3678682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    OS << " (ENTRY)]\n";
367942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  else if (&B == &cfg->getExit())
3680682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    OS << " (EXIT)]\n";
368142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  else if (&B == cfg->getIndirectGotoBlock())
3682682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    OS << " (INDIRECT GOTO DISPATCH)]\n";
368342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  else
3684682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    OS << "]\n";
3685682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek
3686682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek  if (ShowColors)
3687682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    OS.resetColor();
36886d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
36899cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  // Print the label of this block.
36909c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (Stmt *Label = const_cast<Stmt*>(B.getLabel())) {
369142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek
369242a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek    if (print_edges)
3693682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      OS << "  ";
36946d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
36959c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (LabelStmt *L = dyn_cast<LabelStmt>(Label))
36969cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek      OS << L->getName();
36979c378f705405d37f49795d5e915989de774fe11fTed Kremenek    else if (CaseStmt *C = dyn_cast<CaseStmt>(Label)) {
36989cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek      OS << "case ";
3699e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner      C->getLHS()->printPretty(OS, Helper,
3700e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner                               PrintingPolicy(Helper->getLangOpts()));
37019cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek      if (C->getRHS()) {
37029cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek        OS << " ... ";
3703e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner        C->getRHS()->printPretty(OS, Helper,
3704e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner                                 PrintingPolicy(Helper->getLangOpts()));
37059cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek      }
3706079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump    } else if (isa<DefaultStmt>(Label))
37079cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek      OS << "default";
3708079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump    else if (CXXCatchStmt *CS = dyn_cast<CXXCatchStmt>(Label)) {
37095d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump      OS << "catch (";
3710a1f93631a84621d77aeb627691da85a8991af188Mike Stump      if (CS->getExceptionDecl())
3711a1f93631a84621d77aeb627691da85a8991af188Mike Stump        CS->getExceptionDecl()->print(OS, PrintingPolicy(Helper->getLangOpts()),
3712a1f93631a84621d77aeb627691da85a8991af188Mike Stump                                      0);
3713a1f93631a84621d77aeb627691da85a8991af188Mike Stump      else
3714a1f93631a84621d77aeb627691da85a8991af188Mike Stump        OS << "...";
37155d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump      OS << ")";
37165d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump
37175d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump    } else
3718b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("Invalid label statement in CFGBlock.");
37196d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
37209cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek    OS << ":\n";
37219cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  }
37226d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3723fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  // Iterate through the statements in the block and print them.
3724fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  unsigned j = 1;
37256d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
372642a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  for (CFGBlock::const_iterator I = B.begin(), E = B.end() ;
372742a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek       I != E ; ++I, ++j ) {
37286d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
37299cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek    // Print the statement # in the basic block and the statement itself.
373042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek    if (print_edges)
3731682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      OS << " ";
37326d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3733a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek    OS << llvm::format("%3d", j) << ": ";
37346d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
373542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek    if (Helper)
373642a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek      Helper->setStmtID(j);
37376d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3738682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    print_elem(OS, Helper, *I);
3739fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  }
37406d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
37419cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  // Print the terminator of this block.
374242a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  if (B.getTerminator()) {
3743682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    if (ShowColors)
3744682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      OS.changeColor(raw_ostream::GREEN);
37456d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3746682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    OS << "   T: ";
37476d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
374842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek    if (Helper) Helper->setBlockID(-1);
37496d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3750e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner    CFGBlockTerminatorPrint TPrinter(OS, Helper,
3751e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner                                     PrintingPolicy(Helper->getLangOpts()));
37524ba72a0b28135209c435630682febe1f854ccfa6Marcin Swiderski    TPrinter.Visit(const_cast<Stmt*>(B.getTerminator().getStmt()));
3753a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek    OS << '\n';
3754682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek
3755682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    if (ShowColors)
3756682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      OS.resetColor();
3757fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  }
37586d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
37599cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  if (print_edges) {
37609cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek    // Print the predecessors of this block.
3761682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    if (!B.pred_empty()) {
3762682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      const raw_ostream::Colors Color = raw_ostream::BLUE;
3763682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      if (ShowColors)
3764682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek        OS.changeColor(Color);
3765682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      OS << "   Preds " ;
3766682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      if (ShowColors)
3767682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek        OS.resetColor();
3768682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      OS << '(' << B.pred_size() << "):";
3769682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      unsigned i = 0;
3770682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek
3771682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      if (ShowColors)
3772682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek        OS.changeColor(Color);
3773682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek
3774682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      for (CFGBlock::const_pred_iterator I = B.pred_begin(), E = B.pred_end();
3775682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek           I != E; ++I, ++i) {
377642a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek
3777682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek        if (i == 8 || (i-8) == 0)
3778682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek          OS << "\n     ";
37796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3780682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek        OS << " B" << (*I)->getBlockID();
3781682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      }
3782682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek
3783682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      if (ShowColors)
3784682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek        OS.resetColor();
37856d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3786682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      OS << '\n';
37879cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek    }
37886d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
37899cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek    // Print the successors of this block.
3790682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    if (!B.succ_empty()) {
3791682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      const raw_ostream::Colors Color = raw_ostream::MAGENTA;
3792682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      if (ShowColors)
3793682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek        OS.changeColor(Color);
3794682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      OS << "   Succs ";
3795682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      if (ShowColors)
3796682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek        OS.resetColor();
3797682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      OS << '(' << B.succ_size() << "):";
3798682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      unsigned i = 0;
3799682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek
3800682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      if (ShowColors)
3801682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek        OS.changeColor(Color);
3802682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek
3803682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      for (CFGBlock::const_succ_iterator I = B.succ_begin(), E = B.succ_end();
3804682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek           I != E; ++I, ++i) {
3805682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek
3806682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek        if (i == 8 || (i-8) % 10 == 0)
3807682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek          OS << "\n    ";
3808682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek
3809682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek        if (*I)
3810682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek          OS << " B" << (*I)->getBlockID();
3811682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek        else
3812682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek          OS  << " NULL";
3813682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      }
3814682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek
3815682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      if (ShowColors)
3816682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek        OS.resetColor();
3817682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek      OS << '\n';
3818fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    }
3819fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  }
38206d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump}
382142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek
382242a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek
382342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// dump - A simple pretty printer of a CFG that outputs to stderr.
3824682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenekvoid CFG::dump(const LangOptions &LO, bool ShowColors) const {
3825682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek  print(llvm::errs(), LO, ShowColors);
3826682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek}
382742a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek
382842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// print - A simple pretty printer of a CFG that outputs to an ostream.
3829682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenekvoid CFG::print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const {
3830e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  StmtPrinterHelper Helper(this, LO);
38316d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
383242a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  // Print the entry block.
3833682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek  print_block(OS, this, getEntry(), &Helper, true, ShowColors);
38346d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
383542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  // Iterate through the CFGBlocks and print them one by one.
383642a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  for (const_iterator I = Blocks.begin(), E = Blocks.end() ; I != E ; ++I) {
383742a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek    // Skip the entry block, because we already printed it.
3838ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek    if (&(**I) == &getEntry() || &(**I) == &getExit())
383942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek      continue;
38406d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3841682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    print_block(OS, this, **I, &Helper, true, ShowColors);
384242a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  }
38436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
384442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  // Print the exit block.
3845682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek  print_block(OS, this, getExit(), &Helper, true, ShowColors);
3846682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek  OS << '\n';
3847d0172439194b28bae62a94a0a25d58e6d21e7a14Ted Kremenek  OS.flush();
38486d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump}
384942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek
385042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// dump - A simply pretty printer of a CFGBlock that outputs to stderr.
3851682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenekvoid CFGBlock::dump(const CFG* cfg, const LangOptions &LO,
3852682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek                    bool ShowColors) const {
3853682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek  print(llvm::errs(), cfg, LO, ShowColors);
3854e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner}
385542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek
385642a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// print - A simple pretty printer of a CFGBlock that outputs to an ostream.
385742a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek///   Generally this will only be called from CFG::print.
38589c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid CFGBlock::print(raw_ostream &OS, const CFG* cfg,
3859682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek                     const LangOptions &LO, bool ShowColors) const {
3860e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  StmtPrinterHelper Helper(cfg, LO);
3861682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek  print_block(OS, cfg, *this, &Helper, true, ShowColors);
3862682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek  OS << '\n';
3863026473c2175424a039f51ca8949937268721b965Ted Kremenek}
38647dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3865a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek/// printTerminator - A simple pretty printer of the terminator of a CFGBlock.
38665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid CFGBlock::printTerminator(raw_ostream &OS,
38676d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump                               const LangOptions &LO) const {
3868e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  CFGBlockTerminatorPrint TPrinter(OS, NULL, PrintingPolicy(LO));
38694ba72a0b28135209c435630682febe1f854ccfa6Marcin Swiderski  TPrinter.Visit(const_cast<Stmt*>(getTerminator().getStmt()));
3870a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek}
3871a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek
38729c378f705405d37f49795d5e915989de774fe11fTed KremenekStmt *CFGBlock::getTerminatorCondition() {
38734ba72a0b28135209c435630682febe1f854ccfa6Marcin Swiderski  Stmt *Terminator = this->Terminator;
3874411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek  if (!Terminator)
3875411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    return NULL;
38766d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
38779c378f705405d37f49795d5e915989de774fe11fTed Kremenek  Expr *E = NULL;
38786d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3879411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek  switch (Terminator->getStmtClass()) {
3880411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    default:
3881411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      break;
38826d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3883411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    case Stmt::ForStmtClass:
3884411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      E = cast<ForStmt>(Terminator)->getCond();
3885411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      break;
38866d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3887411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    case Stmt::WhileStmtClass:
3888411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      E = cast<WhileStmt>(Terminator)->getCond();
3889411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      break;
38906d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3891411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    case Stmt::DoStmtClass:
3892411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      E = cast<DoStmt>(Terminator)->getCond();
3893411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      break;
38946d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3895411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    case Stmt::IfStmtClass:
3896411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      E = cast<IfStmt>(Terminator)->getCond();
3897411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      break;
38986d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3899411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    case Stmt::ChooseExprClass:
3900411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      E = cast<ChooseExpr>(Terminator)->getCond();
3901411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      break;
39026d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3903411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    case Stmt::IndirectGotoStmtClass:
3904411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      E = cast<IndirectGotoStmt>(Terminator)->getTarget();
3905411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      break;
39066d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3907411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    case Stmt::SwitchStmtClass:
3908411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      E = cast<SwitchStmt>(Terminator)->getCond();
3909411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      break;
39106d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
391156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    case Stmt::BinaryConditionalOperatorClass:
391256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      E = cast<BinaryConditionalOperator>(Terminator)->getCond();
391356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      break;
391456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall
3915411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    case Stmt::ConditionalOperatorClass:
3916411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      E = cast<ConditionalOperator>(Terminator)->getCond();
3917411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      break;
39186d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3919411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    case Stmt::BinaryOperatorClass: // '&&' and '||'
3920411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek      E = cast<BinaryOperator>(Terminator)->getLHS();
3921390e48b15ad93f85bfd1e33b9992c198fa0db475Ted Kremenek      break;
39226d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3923390e48b15ad93f85bfd1e33b9992c198fa0db475Ted Kremenek    case Stmt::ObjCForCollectionStmtClass:
39246d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump      return Terminator;
3925411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek  }
39266d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
3927411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek  return E ? E->IgnoreParens() : NULL;
3928411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek}
3929411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek
39307dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===//
39317dba8607e59096014b7139ff20ef00870041d518Ted Kremenek// CFG Graphviz Visualization
39327dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===//
39337dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
393442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek
393542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#ifndef NDEBUG
39366d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stumpstatic StmtPrinterHelper* GraphHelper;
393742a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#endif
393842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek
3939e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnervoid CFG::viewCFG(const LangOptions &LO) const {
394042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#ifndef NDEBUG
3941e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  StmtPrinterHelper H(this, LO);
394242a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  GraphHelper = &H;
394342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  llvm::ViewGraph(this,"CFG");
394442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  GraphHelper = NULL;
394542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#endif
394642a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek}
394742a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek
39487dba8607e59096014b7139ff20ef00870041d518Ted Kremeneknamespace llvm {
39497dba8607e59096014b7139ff20ef00870041d518Ted Kremenektemplate<>
39507dba8607e59096014b7139ff20ef00870041d518Ted Kremenekstruct DOTGraphTraits<const CFG*> : public DefaultDOTGraphTraits {
3951006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser
3952006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser  DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
3953006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser
39549c378f705405d37f49795d5e915989de774fe11fTed Kremenek  static std::string getNodeLabel(const CFGBlock *Node, const CFG* Graph) {
39557dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3956bd250b44d60622e7c0b60c6def6f6fe7e347addfHartmut Kaiser#ifndef NDEBUG
3957a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek    std::string OutSStr;
3958a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek    llvm::raw_string_ostream Out(OutSStr);
3959682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek    print_block(Out,Graph, *Node, GraphHelper, false, false);
3960a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek    std::string& OutStr = Out.str();
39617dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
39627dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
39637dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
39647dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    // Process string output to make it nicer...
39657dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    for (unsigned i = 0; i != OutStr.length(); ++i)
39667dba8607e59096014b7139ff20ef00870041d518Ted Kremenek      if (OutStr[i] == '\n') {                            // Left justify
39677dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        OutStr[i] = '\\';
39687dba8607e59096014b7139ff20ef00870041d518Ted Kremenek        OutStr.insert(OutStr.begin()+i+1, 'l');
39697dba8607e59096014b7139ff20ef00870041d518Ted Kremenek      }
39706d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump
39717dba8607e59096014b7139ff20ef00870041d518Ted Kremenek    return OutStr;
3972bd250b44d60622e7c0b60c6def6f6fe7e347addfHartmut Kaiser#else
3973bd250b44d60622e7c0b60c6def6f6fe7e347addfHartmut Kaiser    return "";
3974bd250b44d60622e7c0b60c6def6f6fe7e347addfHartmut Kaiser#endif
39757dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  }
39767dba8607e59096014b7139ff20ef00870041d518Ted Kremenek};
39777dba8607e59096014b7139ff20ef00870041d518Ted Kremenek} // end namespace llvm
3978