SymbolManager.cpp revision 249423
1168404Spjd//== SymbolManager.h - Management of Symbolic Values ------------*- C++ -*--==//
2168404Spjd//
3168404Spjd//                     The LLVM Compiler Infrastructure
4168404Spjd//
5168404Spjd// This file is distributed under the University of Illinois Open Source
6168404Spjd// License. See LICENSE.TXT for details.
7168404Spjd//
8168404Spjd//===----------------------------------------------------------------------===//
9168404Spjd//
10168404Spjd//  This file defines SymbolManager, a class that manages symbolic values
11168404Spjd//  created for use by ExprEngine and related classes.
12168404Spjd//
13168404Spjd//===----------------------------------------------------------------------===//
14168404Spjd
15168404Spjd#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
16168404Spjd#include "clang/Analysis/Analyses/LiveVariables.h"
17168404Spjd#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
18168404Spjd#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
19168404Spjd#include "llvm/Support/raw_ostream.h"
20168404Spjd
21168404Spjdusing namespace clang;
22219089Spjdusing namespace ento;
23168404Spjd
24168404Spjdvoid SymExpr::anchor() { }
25169195Spjd
26226943Smmvoid SymExpr::dump() const {
27169195Spjd  dumpToStream(llvm::errs());
28168404Spjd}
29168404Spjd
30168404Spjdvoid SymIntExpr::dumpToStream(raw_ostream &os) const {
31168404Spjd  os << '(';
32168404Spjd  getLHS()->dumpToStream(os);
33168404Spjd  os << ") "
34168404Spjd     << BinaryOperator::getOpcodeStr(getOpcode()) << ' '
35168404Spjd     << getRHS().getZExtValue();
36185029Spjd  if (getRHS().isUnsigned())
37185029Spjd    os << 'U';
38168404Spjd}
39168404Spjd
40168404Spjdvoid IntSymExpr::dumpToStream(raw_ostream &os) const {
41168404Spjd  os << getLHS().getZExtValue();
42168404Spjd  if (getLHS().isUnsigned())
43168404Spjd    os << 'U';
44168404Spjd  os << ' '
45168404Spjd     << BinaryOperator::getOpcodeStr(getOpcode())
46168404Spjd     << " (";
47168404Spjd  getRHS()->dumpToStream(os);
48168404Spjd  os << ')';
49185029Spjd}
50219089Spjd
51168404Spjdvoid SymSymExpr::dumpToStream(raw_ostream &os) const {
52185029Spjd  os << '(';
53168404Spjd  getLHS()->dumpToStream(os);
54168404Spjd  os << ") "
55168404Spjd     << BinaryOperator::getOpcodeStr(getOpcode())
56168404Spjd     << " (";
57168404Spjd  getRHS()->dumpToStream(os);
58168404Spjd  os << ')';
59168404Spjd}
60219089Spjd
61219089Spjdvoid SymbolCast::dumpToStream(raw_ostream &os) const {
62219089Spjd  os << '(' << ToTy.getAsString() << ") (";
63168404Spjd  Operand->dumpToStream(os);
64168404Spjd  os << ')';
65185029Spjd}
66219089Spjd
67185029Spjdvoid SymbolConjured::dumpToStream(raw_ostream &os) const {
68173268Slulf  os << "conj_$" << getSymbolID() << '{' << T.getAsString() << '}';
69173268Slulf}
70173268Slulf
71173268Slulfvoid SymbolDerived::dumpToStream(raw_ostream &os) const {
72168404Spjd  os << "derived_$" << getSymbolID() << '{'
73185029Spjd     << getParentSymbol() << ',' << getRegion() << '}';
74185029Spjd}
75185029Spjd
76185029Spjdvoid SymbolExtent::dumpToStream(raw_ostream &os) const {
77185029Spjd  os << "extent_$" << getSymbolID() << '{' << getRegion() << '}';
78185029Spjd}
79185029Spjd
80185029Spjdvoid SymbolMetadata::dumpToStream(raw_ostream &os) const {
81185029Spjd  os << "meta_$" << getSymbolID() << '{'
82185029Spjd     << getRegion() << ',' << T.getAsString() << '}';
83185029Spjd}
84185029Spjd
85185029Spjdvoid SymbolData::anchor() { }
86185029Spjd
87168404Spjdvoid SymbolRegionValue::dumpToStream(raw_ostream &os) const {
88168404Spjd  os << "reg_$" << getSymbolID() << "<" << R << ">";
89168404Spjd}
90168404Spjd
91168404Spjdbool SymExpr::symbol_iterator::operator==(const symbol_iterator &X) const {
92210470Smm  return itr == X.itr;
93210470Smm}
94210470Smm
95210470Smmbool SymExpr::symbol_iterator::operator!=(const symbol_iterator &X) const {
96210470Smm  return itr != X.itr;
97210470Smm}
98185029Spjd
99168404SpjdSymExpr::symbol_iterator::symbol_iterator(const SymExpr *SE) {
100168404Spjd  itr.push_back(SE);
101168404Spjd}
102185029Spjd
103168404SpjdSymExpr::symbol_iterator &SymExpr::symbol_iterator::operator++() {
104185029Spjd  assert(!itr.empty() && "attempting to iterate on an 'end' iterator");
105185029Spjd  expand();
106185029Spjd  return *this;
107185029Spjd}
108185029Spjd
109168404SpjdSymbolRef SymExpr::symbol_iterator::operator*() {
110168404Spjd  assert(!itr.empty() && "attempting to dereference an 'end' iterator");
111168404Spjd  return itr.back();
112168404Spjd}
113209962Smm
114168404Spjdvoid SymExpr::symbol_iterator::expand() {
115168404Spjd  const SymExpr *SE = itr.back();
116168404Spjd  itr.pop_back();
117168404Spjd
118168404Spjd  switch (SE->getKind()) {
119168404Spjd    case SymExpr::RegionValueKind:
120168404Spjd    case SymExpr::ConjuredKind:
121219089Spjd    case SymExpr::DerivedKind:
122168404Spjd    case SymExpr::ExtentKind:
123185029Spjd    case SymExpr::MetadataKind:
124168404Spjd      return;
125168404Spjd    case SymExpr::CastSymbolKind:
126169196Spjd      itr.push_back(cast<SymbolCast>(SE)->getOperand());
127185029Spjd      return;
128168404Spjd    case SymExpr::SymIntKind:
129168404Spjd      itr.push_back(cast<SymIntExpr>(SE)->getLHS());
130185029Spjd      return;
131185029Spjd    case SymExpr::IntSymKind:
132185029Spjd      itr.push_back(cast<IntSymExpr>(SE)->getRHS());
133199156Spjd      return;
134199156Spjd    case SymExpr::SymSymKind: {
135199156Spjd      const SymSymExpr *x = cast<SymSymExpr>(SE);
136199156Spjd      itr.push_back(x->getLHS());
137199156Spjd      itr.push_back(x->getRHS());
138199156Spjd      return;
139199156Spjd    }
140199156Spjd  }
141199156Spjd  llvm_unreachable("unhandled expansion case");
142219089Spjd}
143199156Spjd
144199156Spjdunsigned SymExpr::computeComplexity() const {
145199156Spjd  unsigned R = 0;
146185029Spjd  for (symbol_iterator I = symbol_begin(), E = symbol_end(); I != E; ++I)
147185029Spjd    R++;
148185029Spjd  return R;
149168404Spjd}
150168404Spjd
151168404Spjdconst SymbolRegionValue*
152168404SpjdSymbolManager::getRegionValueSymbol(const TypedValueRegion* R) {
153168404Spjd  llvm::FoldingSetNodeID profile;
154168404Spjd  SymbolRegionValue::Profile(profile, R);
155168404Spjd  void *InsertPos;
156168404Spjd  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
157168404Spjd  if (!SD) {
158185029Spjd    SD = (SymExpr*) BPAlloc.Allocate<SymbolRegionValue>();
159211932Smm    new (SD) SymbolRegionValue(SymbolCounter, R);
160219089Spjd    DataSet.InsertNode(SD, InsertPos);
161168404Spjd    ++SymbolCounter;
162168404Spjd  }
163168404Spjd
164168404Spjd  return cast<SymbolRegionValue>(SD);
165168404Spjd}
166185029Spjd
167168404Spjdconst SymbolConjured* SymbolManager::conjureSymbol(const Stmt *E,
168168404Spjd                                                   const LocationContext *LCtx,
169168404Spjd                                                   QualType T,
170185029Spjd                                                   unsigned Count,
171185029Spjd                                                   const void *SymbolTag) {
172185029Spjd  llvm::FoldingSetNodeID profile;
173185029Spjd  SymbolConjured::Profile(profile, E, T, Count, LCtx, SymbolTag);
174168404Spjd  void *InsertPos;
175168404Spjd  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
176168404Spjd  if (!SD) {
177168404Spjd    SD = (SymExpr*) BPAlloc.Allocate<SymbolConjured>();
178185029Spjd    new (SD) SymbolConjured(SymbolCounter, E, LCtx, T, Count, SymbolTag);
179168404Spjd    DataSet.InsertNode(SD, InsertPos);
180168404Spjd    ++SymbolCounter;
181185029Spjd  }
182211932Smm
183168404Spjd  return cast<SymbolConjured>(SD);
184168404Spjd}
185185029Spjd
186185029Spjdconst SymbolDerived*
187185029SpjdSymbolManager::getDerivedSymbol(SymbolRef parentSymbol,
188210470Smm                                const TypedValueRegion *R) {
189185029Spjd
190210470Smm  llvm::FoldingSetNodeID profile;
191185029Spjd  SymbolDerived::Profile(profile, parentSymbol, R);
192185029Spjd  void *InsertPos;
193185029Spjd  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
194185029Spjd  if (!SD) {
195185029Spjd    SD = (SymExpr*) BPAlloc.Allocate<SymbolDerived>();
196185029Spjd    new (SD) SymbolDerived(SymbolCounter, parentSymbol, R);
197219089Spjd    DataSet.InsertNode(SD, InsertPos);
198185029Spjd    ++SymbolCounter;
199185029Spjd  }
200185029Spjd
201185029Spjd  return cast<SymbolDerived>(SD);
202185029Spjd}
203185029Spjd
204185029Spjdconst SymbolExtent*
205185029SpjdSymbolManager::getExtentSymbol(const SubRegion *R) {
206185029Spjd  llvm::FoldingSetNodeID profile;
207185029Spjd  SymbolExtent::Profile(profile, R);
208185029Spjd  void *InsertPos;
209185029Spjd  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
210185029Spjd  if (!SD) {
211185029Spjd    SD = (SymExpr*) BPAlloc.Allocate<SymbolExtent>();
212185029Spjd    new (SD) SymbolExtent(SymbolCounter, R);
213185029Spjd    DataSet.InsertNode(SD, InsertPos);
214185029Spjd    ++SymbolCounter;
215185029Spjd  }
216185029Spjd
217185029Spjd  return cast<SymbolExtent>(SD);
218185029Spjd}
219185029Spjd
220185029Spjdconst SymbolMetadata*
221185029SpjdSymbolManager::getMetadataSymbol(const MemRegion* R, const Stmt *S, QualType T,
222185029Spjd                                 unsigned Count, const void *SymbolTag) {
223185029Spjd
224219089Spjd  llvm::FoldingSetNodeID profile;
225219089Spjd  SymbolMetadata::Profile(profile, R, S, T, Count, SymbolTag);
226219089Spjd  void *InsertPos;
227219089Spjd  SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
228219089Spjd  if (!SD) {
229219089Spjd    SD = (SymExpr*) BPAlloc.Allocate<SymbolMetadata>();
230219089Spjd    new (SD) SymbolMetadata(SymbolCounter, R, S, T, Count, SymbolTag);
231219089Spjd    DataSet.InsertNode(SD, InsertPos);
232219089Spjd    ++SymbolCounter;
233185029Spjd  }
234211932Smm
235211932Smm  return cast<SymbolMetadata>(SD);
236211932Smm}
237211932Smm
238211932Smmconst SymbolCast*
239211932SmmSymbolManager::getCastSymbol(const SymExpr *Op,
240211932Smm                             QualType From, QualType To) {
241211932Smm  llvm::FoldingSetNodeID ID;
242211932Smm  SymbolCast::Profile(ID, Op, From, To);
243219089Spjd  void *InsertPos;
244185029Spjd  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
245185029Spjd  if (!data) {
246185029Spjd    data = (SymbolCast*) BPAlloc.Allocate<SymbolCast>();
247185029Spjd    new (data) SymbolCast(Op, From, To);
248185029Spjd    DataSet.InsertNode(data, InsertPos);
249185029Spjd  }
250185029Spjd
251219089Spjd  return cast<SymbolCast>(data);
252185029Spjd}
253219089Spjd
254219089Spjdconst SymIntExpr *SymbolManager::getSymIntExpr(const SymExpr *lhs,
255219089Spjd                                               BinaryOperator::Opcode op,
256219089Spjd                                               const llvm::APSInt& v,
257219089Spjd                                               QualType t) {
258219089Spjd  llvm::FoldingSetNodeID ID;
259185029Spjd  SymIntExpr::Profile(ID, lhs, op, v, t);
260185029Spjd  void *InsertPos;
261185029Spjd  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
262185029Spjd
263185029Spjd  if (!data) {
264185029Spjd    data = (SymIntExpr*) BPAlloc.Allocate<SymIntExpr>();
265185029Spjd    new (data) SymIntExpr(lhs, op, v, t);
266185029Spjd    DataSet.InsertNode(data, InsertPos);
267185029Spjd  }
268185029Spjd
269185029Spjd  return cast<SymIntExpr>(data);
270185029Spjd}
271185029Spjd
272185029Spjdconst IntSymExpr *SymbolManager::getIntSymExpr(const llvm::APSInt& lhs,
273185029Spjd                                               BinaryOperator::Opcode op,
274185029Spjd                                               const SymExpr *rhs,
275185029Spjd                                               QualType t) {
276185029Spjd  llvm::FoldingSetNodeID ID;
277185029Spjd  IntSymExpr::Profile(ID, lhs, op, rhs, t);
278185029Spjd  void *InsertPos;
279185029Spjd  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
280185029Spjd
281185029Spjd  if (!data) {
282185029Spjd    data = (IntSymExpr*) BPAlloc.Allocate<IntSymExpr>();
283185029Spjd    new (data) IntSymExpr(lhs, op, rhs, t);
284210470Smm    DataSet.InsertNode(data, InsertPos);
285210470Smm  }
286210470Smm
287210470Smm  return cast<IntSymExpr>(data);
288185029Spjd}
289210470Smm
290210470Smmconst SymSymExpr *SymbolManager::getSymSymExpr(const SymExpr *lhs,
291210470Smm                                               BinaryOperator::Opcode op,
292210470Smm                                               const SymExpr *rhs,
293210470Smm                                               QualType t) {
294210470Smm  llvm::FoldingSetNodeID ID;
295210470Smm  SymSymExpr::Profile(ID, lhs, op, rhs, t);
296210470Smm  void *InsertPos;
297210470Smm  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
298210470Smm
299210470Smm  if (!data) {
300210470Smm    data = (SymSymExpr*) BPAlloc.Allocate<SymSymExpr>();
301210470Smm    new (data) SymSymExpr(lhs, op, rhs, t);
302209962Smm    DataSet.InsertNode(data, InsertPos);
303209962Smm  }
304209962Smm
305210470Smm  return cast<SymSymExpr>(data);
306185029Spjd}
307185029Spjd
308185029SpjdQualType SymbolConjured::getType() const {
309210470Smm  return T;
310185029Spjd}
311185029Spjd
312185029SpjdQualType SymbolDerived::getType() const {
313185029Spjd  return R->getValueType();
314185029Spjd}
315185029Spjd
316185029SpjdQualType SymbolExtent::getType() const {
317185029Spjd  ASTContext &Ctx = R->getMemRegionManager()->getContext();
318185029Spjd  return Ctx.getSizeType();
319210470Smm}
320185029Spjd
321185029SpjdQualType SymbolMetadata::getType() const {
322185029Spjd  return T;
323185029Spjd}
324185029Spjd
325185029SpjdQualType SymbolRegionValue::getType() const {
326185029Spjd  return R->getValueType();
327185029Spjd}
328185029Spjd
329185029SpjdSymbolManager::~SymbolManager() {
330185029Spjd  for (SymbolDependTy::const_iterator I = SymbolDependencies.begin(),
331185029Spjd       E = SymbolDependencies.end(); I != E; ++I) {
332185029Spjd    delete I->second;
333185029Spjd  }
334185029Spjd
335185029Spjd}
336185029Spjd
337185029Spjdbool SymbolManager::canSymbolicate(QualType T) {
338185029Spjd  T = T.getCanonicalType();
339185029Spjd
340185029Spjd  if (Loc::isLocType(T))
341185029Spjd    return true;
342185029Spjd
343185029Spjd  if (T->isIntegerType())
344185029Spjd    return T->isScalarType();
345185029Spjd
346185029Spjd  if (T->isRecordType() && !T->isUnionType())
347185029Spjd    return true;
348185029Spjd
349185029Spjd  return false;
350185029Spjd}
351185029Spjd
352185029Spjdvoid SymbolManager::addSymbolDependency(const SymbolRef Primary,
353185029Spjd                                        const SymbolRef Dependent) {
354185029Spjd  SymbolDependTy::iterator I = SymbolDependencies.find(Primary);
355185029Spjd  SymbolRefSmallVectorTy *dependencies = 0;
356185029Spjd  if (I == SymbolDependencies.end()) {
357185029Spjd    dependencies = new SymbolRefSmallVectorTy();
358185029Spjd    SymbolDependencies[Primary] = dependencies;
359185029Spjd  } else {
360185029Spjd    dependencies = I->second;
361185029Spjd  }
362185029Spjd  dependencies->push_back(Dependent);
363185029Spjd}
364185029Spjd
365185029Spjdconst SymbolRefSmallVectorTy *SymbolManager::getDependentSymbols(
366185029Spjd                                                     const SymbolRef Primary) {
367185029Spjd  SymbolDependTy::const_iterator I = SymbolDependencies.find(Primary);
368185029Spjd  if (I == SymbolDependencies.end())
369185029Spjd    return 0;
370168404Spjd  return I->second;
371168404Spjd}
372168404Spjd
373168404Spjdvoid SymbolReaper::markDependentsLive(SymbolRef sym) {
374168404Spjd  // Do not mark dependents more then once.
375168404Spjd  SymbolMapTy::iterator LI = TheLiving.find(sym);
376210470Smm  assert(LI != TheLiving.end() && "The primary symbol is not live.");
377168404Spjd  if (LI->second == HaveMarkedDependents)
378168404Spjd    return;
379168404Spjd  LI->second = HaveMarkedDependents;
380168404Spjd
381185029Spjd  if (const SymbolRefSmallVectorTy *Deps = SymMgr.getDependentSymbols(sym)) {
382168404Spjd    for (SymbolRefSmallVectorTy::const_iterator I = Deps->begin(),
383168404Spjd                                                E = Deps->end(); I != E; ++I) {
384168404Spjd      if (TheLiving.find(*I) != TheLiving.end())
385168404Spjd        continue;
386168404Spjd      markLive(*I);
387219089Spjd    }
388168404Spjd  }
389219089Spjd}
390219089Spjd
391219089Spjdvoid SymbolReaper::markLive(SymbolRef sym) {
392219089Spjd  TheLiving[sym] = NotProcessed;
393219089Spjd  TheDead.erase(sym);
394219089Spjd  markDependentsLive(sym);
395168404Spjd}
396168404Spjd
397168404Spjdvoid SymbolReaper::markLive(const MemRegion *region) {
398168404Spjd  RegionRoots.insert(region);
399168404Spjd}
400210470Smm
401168404Spjdvoid SymbolReaper::markInUse(SymbolRef sym) {
402168404Spjd  if (isa<SymbolMetadata>(sym))
403219089Spjd    MetadataInUse.insert(sym);
404219089Spjd}
405219089Spjd
406219089Spjdbool SymbolReaper::maybeDead(SymbolRef sym) {
407219089Spjd  if (isLive(sym))
408219089Spjd    return false;
409219089Spjd
410219089Spjd  TheDead.insert(sym);
411219089Spjd  return true;
412219089Spjd}
413219089Spjd
414219089Spjdbool SymbolReaper::isLiveRegion(const MemRegion *MR) {
415219089Spjd  if (RegionRoots.count(MR))
416219089Spjd    return true;
417219089Spjd
418219089Spjd  MR = MR->getBaseRegion();
419219089Spjd
420219089Spjd  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
421219089Spjd    return isLive(SR->getSymbol());
422219089Spjd
423219089Spjd  if (const VarRegion *VR = dyn_cast<VarRegion>(MR))
424219089Spjd    return isLive(VR, true);
425219089Spjd
426219089Spjd  // FIXME: This is a gross over-approximation. What we really need is a way to
427219089Spjd  // tell if anything still refers to this region. Unlike SymbolicRegions,
428219089Spjd  // AllocaRegions don't have associated symbols, though, so we don't actually
429219089Spjd  // have a way to track their liveness.
430219089Spjd  if (isa<AllocaRegion>(MR))
431219089Spjd    return true;
432219089Spjd
433219089Spjd  if (isa<CXXThisRegion>(MR))
434219089Spjd    return true;
435219089Spjd
436219089Spjd  if (isa<MemSpaceRegion>(MR))
437219089Spjd    return true;
438219089Spjd
439219089Spjd  return false;
440219089Spjd}
441219089Spjd
442219089Spjdbool SymbolReaper::isLive(SymbolRef sym) {
443219089Spjd  if (TheLiving.count(sym)) {
444219089Spjd    markDependentsLive(sym);
445219089Spjd    return true;
446219089Spjd  }
447219089Spjd
448219089Spjd  bool KnownLive;
449219089Spjd
450219089Spjd  switch (sym->getKind()) {
451219089Spjd  case SymExpr::RegionValueKind:
452168404Spjd    KnownLive = isLiveRegion(cast<SymbolRegionValue>(sym)->getRegion());
453219089Spjd    break;
454219089Spjd  case SymExpr::ConjuredKind:
455219089Spjd    KnownLive = false;
456219089Spjd    break;
457219089Spjd  case SymExpr::DerivedKind:
458219089Spjd    KnownLive = isLive(cast<SymbolDerived>(sym)->getParentSymbol());
459219089Spjd    break;
460219089Spjd  case SymExpr::ExtentKind:
461219089Spjd    KnownLive = isLiveRegion(cast<SymbolExtent>(sym)->getRegion());
462219089Spjd    break;
463219089Spjd  case SymExpr::MetadataKind:
464219089Spjd    KnownLive = MetadataInUse.count(sym) &&
465219089Spjd                isLiveRegion(cast<SymbolMetadata>(sym)->getRegion());
466219089Spjd    if (KnownLive)
467219089Spjd      MetadataInUse.erase(sym);
468219089Spjd    break;
469219089Spjd  case SymExpr::SymIntKind:
470219089Spjd    KnownLive = isLive(cast<SymIntExpr>(sym)->getLHS());
471219089Spjd    break;
472219089Spjd  case SymExpr::IntSymKind:
473219089Spjd    KnownLive = isLive(cast<IntSymExpr>(sym)->getRHS());
474219089Spjd    break;
475219089Spjd  case SymExpr::SymSymKind:
476219089Spjd    KnownLive = isLive(cast<SymSymExpr>(sym)->getLHS()) &&
477219089Spjd                isLive(cast<SymSymExpr>(sym)->getRHS());
478219089Spjd    break;
479219089Spjd  case SymExpr::CastSymbolKind:
480219089Spjd    KnownLive = isLive(cast<SymbolCast>(sym)->getOperand());
481219089Spjd    break;
482219089Spjd  }
483219089Spjd
484219089Spjd  if (KnownLive)
485219089Spjd    markLive(sym);
486219089Spjd
487219089Spjd  return KnownLive;
488219089Spjd}
489219089Spjd
490219089Spjdbool
491219089SpjdSymbolReaper::isLive(const Stmt *ExprVal, const LocationContext *ELCtx) const {
492219089Spjd  if (LCtx == 0)
493219089Spjd    return false;
494219089Spjd
495219089Spjd  if (LCtx != ELCtx) {
496219089Spjd    // If the reaper's location context is a parent of the expression's
497219089Spjd    // location context, then the expression value is now "out of scope".
498209962Smm    if (LCtx->isParentOf(ELCtx))
499168404Spjd      return false;
500209962Smm    return true;
501209962Smm  }
502209962Smm
503209962Smm  // If no statement is provided, everything is this and parent contexts is live.
504209962Smm  if (!Loc)
505209962Smm    return true;
506168404Spjd
507209962Smm  return LCtx->getAnalysis<RelaxedLiveVariables>()->isLive(Loc, ExprVal);
508209962Smm}
509209962Smm
510209962Smmbool SymbolReaper::isLive(const VarRegion *VR, bool includeStoreBindings) const{
511209962Smm  const StackFrameContext *VarContext = VR->getStackFrame();
512168404Spjd
513209962Smm  if (!VarContext)
514209962Smm    return true;
515219089Spjd
516219089Spjd  if (!LCtx)
517209962Smm    return false;
518209962Smm  const StackFrameContext *CurrentContext = LCtx->getCurrentStackFrame();
519209962Smm
520219089Spjd  if (VarContext == CurrentContext) {
521168404Spjd    // If no statement is provided, everything is live.
522209962Smm    if (!Loc)
523209962Smm      return true;
524185029Spjd
525209962Smm    if (LCtx->getAnalysis<RelaxedLiveVariables>()->isLive(Loc, VR->getDecl()))
526209962Smm      return true;
527168404Spjd
528209962Smm    if (!includeStoreBindings)
529209962Smm      return false;
530219089Spjd
531209962Smm    unsigned &cachedQuery =
532209962Smm      const_cast<SymbolReaper*>(this)->includedRegionCache[VR];
533209962Smm
534209962Smm    if (cachedQuery) {
535209962Smm      return cachedQuery == 1;
536168404Spjd    }
537209962Smm
538209962Smm    // Query the store to see if the region occurs in any live bindings.
539209962Smm    if (Store store = reapedStore.getStore()) {
540209962Smm      bool hasRegion =
541209962Smm        reapedStore.getStoreManager().includedInBindings(store, VR);
542219089Spjd      cachedQuery = hasRegion ? 1 : 2;
543209962Smm      return hasRegion;
544209962Smm    }
545168404Spjd
546209962Smm    return false;
547168404Spjd  }
548168404Spjd
549168404Spjd  return VarContext->isParentOf(CurrentContext);
550168404Spjd}
551168404Spjd
552168404SpjdSymbolVisitor::~SymbolVisitor() {}
553168404Spjd