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