Environment.cpp revision dc84cd5efdd3430efb22546b4ac656aa0540b210
1b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//== Environment.cpp - Map from Stmt* to Locations/Values -------*- C++ -*--==//
2b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//
3b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//                     The LLVM Compiler Infrastructure
4b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//
5b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar// This file is distributed under the University of Illinois Open Source
6b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar// License. See LICENSE.TXT for details.
7b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//
8b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//===----------------------------------------------------------------------===//
9b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//
10b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//  This file defined the Environment and EnvironmentManager classes.
11b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//
12b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//===----------------------------------------------------------------------===//
13b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "clang/AST/ExprCXX.h"
15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "clang/AST/ExprObjC.h"
16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "clang/Analysis/AnalysisContext.h"
17b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "clang/Analysis/CFG.h"
18b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
19b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "llvm/Support/raw_ostream.h"
20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
21b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbarusing namespace clang;
22b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbarusing namespace ento;
23b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
24b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbarstatic const Expr *ignoreTransparentExprs(const Expr *E) {
25b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  E = E->IgnoreParens();
26b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
27b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  switch (E->getStmtClass()) {
28b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::OpaqueValueExprClass:
29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    E = cast<OpaqueValueExpr>(E)->getSourceExpr();
30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    break;
31b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::ExprWithCleanupsClass:
32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    E = cast<ExprWithCleanups>(E)->getSubExpr();
33b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    break;
34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::CXXBindTemporaryExprClass:
35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    E = cast<CXXBindTemporaryExpr>(E)->getSubExpr();
36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    break;
37b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::SubstNonTypeTemplateParmExprClass:
38b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    E = cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement();
39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    break;
40b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  default:
41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    // This is the base case: we can't look through more than we already have.
42b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return E;
43b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  }
44b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
45b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  return ignoreTransparentExprs(E);
46b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar}
47b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
48b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbarstatic const Stmt *ignoreTransparentExprs(const Stmt *S) {
49b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  if (const Expr *E = dyn_cast<Expr>(S))
50b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return ignoreTransparentExprs(E);
51b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  return S;
52b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar}
53b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
54b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel DunbarEnvironmentEntry::EnvironmentEntry(const Stmt *S, const LocationContext *L)
55b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  : std::pair<const Stmt *,
56b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar              const StackFrameContext *>(ignoreTransparentExprs(S),
57b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                                         L ? L->getCurrentStackFrame() : 0) {}
58b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
59b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel DunbarSVal Environment::lookupExpr(const EnvironmentEntry &E) const {
60b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  const SVal* X = ExprBindings.lookup(E);
61b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  if (X) {
62b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    SVal V = *X;
63b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return V;
64b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  }
65b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  return UnknownVal();
66b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar}
67b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
68b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel DunbarSVal Environment::getSVal(const EnvironmentEntry &Entry,
69b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                          SValBuilder& svalBuilder) const {
70b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  const Stmt *S = Entry.getStmt();
71b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  const LocationContext *LCtx = Entry.getLocationContext();
72b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
73b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  switch (S->getStmtClass()) {
74b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::CXXBindTemporaryExprClass:
75b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::ExprWithCleanupsClass:
76b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::GenericSelectionExprClass:
77b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::OpaqueValueExprClass:
78b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::ParenExprClass:
79b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::SubstNonTypeTemplateParmExprClass:
80b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    llvm_unreachable("Should have been handled by ignoreTransparentExprs");
81b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
82b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::AddrLabelExprClass:
83b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return svalBuilder.makeLoc(cast<AddrLabelExpr>(S));
84b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
85b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::CharacterLiteralClass: {
86b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    const CharacterLiteral *C = cast<CharacterLiteral>(S);
87b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return svalBuilder.makeIntVal(C->getValue(), C->getType());
88b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  }
89b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
90b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::CXXBoolLiteralExprClass:
91b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return svalBuilder.makeBoolVal(cast<CXXBoolLiteralExpr>(S));
92b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
93b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::CXXScalarValueInitExprClass:
94b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::ImplicitValueInitExprClass: {
95b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    QualType Ty = cast<Expr>(S)->getType();
96b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return svalBuilder.makeZeroVal(Ty);
97b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  }
98b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
99b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::IntegerLiteralClass:
100b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return svalBuilder.makeIntVal(cast<IntegerLiteral>(S));
101b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
102b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::ObjCBoolLiteralExprClass:
103b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return svalBuilder.makeBoolVal(cast<ObjCBoolLiteralExpr>(S));
104b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
105b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  // For special C0xx nullptr case, make a null pointer SVal.
106b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::CXXNullPtrLiteralExprClass:
107b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return svalBuilder.makeNull();
108b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
109b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::ObjCStringLiteralClass: {
110b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    MemRegionManager &MRMgr = svalBuilder.getRegionManager();
111b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    const ObjCStringLiteral *SL = cast<ObjCStringLiteral>(S);
112b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return svalBuilder.makeLoc(MRMgr.getObjCStringRegion(SL));
113b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  }
114b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
115b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::StringLiteralClass: {
116b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    MemRegionManager &MRMgr = svalBuilder.getRegionManager();
117b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    const StringLiteral *SL = cast<StringLiteral>(S);
118b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return svalBuilder.makeLoc(MRMgr.getStringRegion(SL));
119b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  }
120b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
121b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  case Stmt::ReturnStmtClass: {
122b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    const ReturnStmt *RS = cast<ReturnStmt>(S);
123b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    if (const Expr *RE = RS->getRetValue())
124b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      return getSVal(EnvironmentEntry(RE, LCtx), svalBuilder);
125b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return UndefinedVal();
126b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  }
127b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
128b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  // Handle all other Stmt* using a lookup.
129b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  default:
130b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    break;
131b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  }
132b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
133b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  return lookupExpr(EnvironmentEntry(S, LCtx));
134b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar}
135b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
136b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel DunbarEnvironment EnvironmentManager::bindExpr(Environment Env,
137b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                                         const EnvironmentEntry &E,
138b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                                         SVal V,
139b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                                         bool Invalidate) {
140b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  if (V.isUnknown()) {
141b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    if (Invalidate)
142b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      return Environment(F.remove(Env.ExprBindings, E));
143b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    else
144b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      return Env;
145b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  }
146b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  return Environment(F.add(Env.ExprBindings, E, V));
147b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar}
148b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
149b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbarnamespace {
150b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbarclass MarkLiveCallback : public SymbolVisitor {
151b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  SymbolReaper &SymReaper;
152b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbarpublic:
153b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  MarkLiveCallback(SymbolReaper &symreaper) : SymReaper(symreaper) {}
154b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  bool VisitSymbol(SymbolRef sym) {
155b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    SymReaper.markLive(sym);
156b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return true;
157b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  }
158b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  bool VisitMemRegion(const MemRegion *R) {
159b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    SymReaper.markLive(R);
160b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    return true;
161b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  }
162b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar};
163b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} // end anonymous namespace
164b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
165b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar// removeDeadBindings:
166b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//  - Remove subexpression bindings.
167b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//  - Remove dead block expression bindings.
168b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//  - Keep live block expression bindings:
169b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//   - Mark their reachable symbols live in SymbolReaper,
170b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//     see ScanReachableSymbols.
171b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar//   - Mark the region in DRoots if the binding is a loc::MemRegionVal.
172b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel DunbarEnvironment
173b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel DunbarEnvironmentManager::removeDeadBindings(Environment Env,
174b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                                       SymbolReaper &SymReaper,
175b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                                       ProgramStateRef ST) {
176b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
177b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  // We construct a new Environment object entirely, as this is cheaper than
178b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  // individually removing all the subexpression bindings (which will greatly
179b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  // outnumber block-level expression bindings).
180b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  Environment NewEnv = getInitialEnvironment();
181b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
182b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  MarkLiveCallback CB(SymReaper);
183b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  ScanReachableSymbols RSScaner(ST, CB);
184b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
185b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  llvm::ImmutableMapRef<EnvironmentEntry,SVal>
186b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    EBMapRef(NewEnv.ExprBindings.getRootWithoutRetain(),
187b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar             F.getTreeFactory());
188b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
189b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  // Iterate over the block-expr bindings.
190b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  for (Environment::iterator I = Env.begin(), E = Env.end();
191b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar       I != E; ++I) {
192b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
193b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    const EnvironmentEntry &BlkExpr = I.getKey();
194b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    const SVal &X = I.getData();
195b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
196b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    if (SymReaper.isLive(BlkExpr.getStmt(), BlkExpr.getLocationContext())) {
197b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      // Copy the binding to the new map.
198b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      EBMapRef = EBMapRef.add(BlkExpr, X);
199b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
200b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      // If the block expr's value is a memory region, then mark that region.
201b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      if (Optional<loc::MemRegionVal> R = X.getAs<loc::MemRegionVal>())
202b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        SymReaper.markLive(R->getRegion());
203b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
204b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      // Mark all symbols in the block expr's value live.
205b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      RSScaner.scan(X);
206b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      continue;
207b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    } else {
208b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      SymExpr::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
209b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      for (; SI != SE; ++SI)
210b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar        SymReaper.maybeDead(*SI);
211b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    }
212b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  }
213b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
214b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  NewEnv.ExprBindings = EBMapRef.asImmutableMap();
215b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  return NewEnv;
216b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar}
217b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
218b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbarvoid Environment::print(raw_ostream &Out, const char *NL,
219b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar                        const char *Sep) const {
220b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  bool isFirst = true;
221b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
222b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  for (Environment::iterator I = begin(), E = end(); I != E; ++I) {
223b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    const EnvironmentEntry &En = I.getKey();
224b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
225b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    if (isFirst) {
226b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      Out << NL << NL
227b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar          << "Expressions:"
228b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar          << NL;
229b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      isFirst = false;
230b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    } else {
231b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      Out << NL;
232b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    }
233b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
234b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    const Stmt *S = En.getStmt();
235b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar
236b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    Out << " (" << (const void*) En.getLocationContext() << ','
237b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar      << (const void*) S << ") ";
238b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    LangOptions LO; // FIXME.
239b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    S->printPretty(Out, 0, PrintingPolicy(LO));
240b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar    Out << " : " << I.getData();
241b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar  }
242b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar}
243b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar