1218887Sdim//== SymbolManager.h - Management of Symbolic Values ------------*- C++ -*--==// 2218887Sdim// 3218887Sdim// The LLVM Compiler Infrastructure 4218887Sdim// 5218887Sdim// This file is distributed under the University of Illinois Open Source 6218887Sdim// License. See LICENSE.TXT for details. 7218887Sdim// 8218887Sdim//===----------------------------------------------------------------------===// 9218887Sdim// 10218887Sdim// This file defines SymbolManager, a class that manages symbolic values 11218887Sdim// created for use by ExprEngine and related classes. 12218887Sdim// 13218887Sdim//===----------------------------------------------------------------------===// 14218887Sdim 15218887Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" 16218887Sdim#include "clang/Analysis/Analyses/LiveVariables.h" 17218887Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" 18226633Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" 19218887Sdim#include "llvm/Support/raw_ostream.h" 20218887Sdim 21218887Sdimusing namespace clang; 22218887Sdimusing namespace ento; 23218887Sdim 24234353Sdimvoid SymExpr::anchor() { } 25234353Sdim 26218887Sdimvoid SymExpr::dump() const { 27218887Sdim dumpToStream(llvm::errs()); 28218887Sdim} 29218887Sdim 30226633Sdimvoid SymIntExpr::dumpToStream(raw_ostream &os) const { 31218887Sdim os << '('; 32218887Sdim getLHS()->dumpToStream(os); 33249423Sdim os << ") " 34249423Sdim << BinaryOperator::getOpcodeStr(getOpcode()) << ' ' 35249423Sdim << getRHS().getZExtValue(); 36249423Sdim if (getRHS().isUnsigned()) 37249423Sdim os << 'U'; 38218887Sdim} 39218887Sdim 40234353Sdimvoid IntSymExpr::dumpToStream(raw_ostream &os) const { 41249423Sdim os << getLHS().getZExtValue(); 42249423Sdim if (getLHS().isUnsigned()) 43249423Sdim os << 'U'; 44249423Sdim os << ' ' 45249423Sdim << BinaryOperator::getOpcodeStr(getOpcode()) 46249423Sdim << " ("; 47234353Sdim getRHS()->dumpToStream(os); 48249423Sdim os << ')'; 49234353Sdim} 50234353Sdim 51226633Sdimvoid SymSymExpr::dumpToStream(raw_ostream &os) const { 52218887Sdim os << '('; 53218887Sdim getLHS()->dumpToStream(os); 54249423Sdim os << ") " 55249423Sdim << BinaryOperator::getOpcodeStr(getOpcode()) 56249423Sdim << " ("; 57218887Sdim getRHS()->dumpToStream(os); 58218887Sdim os << ')'; 59218887Sdim} 60218887Sdim 61234353Sdimvoid SymbolCast::dumpToStream(raw_ostream &os) const { 62234353Sdim os << '(' << ToTy.getAsString() << ") ("; 63234353Sdim Operand->dumpToStream(os); 64234353Sdim os << ')'; 65234353Sdim} 66234353Sdim 67226633Sdimvoid SymbolConjured::dumpToStream(raw_ostream &os) const { 68218887Sdim os << "conj_$" << getSymbolID() << '{' << T.getAsString() << '}'; 69218887Sdim} 70218887Sdim 71226633Sdimvoid SymbolDerived::dumpToStream(raw_ostream &os) const { 72218887Sdim os << "derived_$" << getSymbolID() << '{' 73218887Sdim << getParentSymbol() << ',' << getRegion() << '}'; 74218887Sdim} 75218887Sdim 76226633Sdimvoid SymbolExtent::dumpToStream(raw_ostream &os) const { 77218887Sdim os << "extent_$" << getSymbolID() << '{' << getRegion() << '}'; 78218887Sdim} 79218887Sdim 80226633Sdimvoid SymbolMetadata::dumpToStream(raw_ostream &os) const { 81218887Sdim os << "meta_$" << getSymbolID() << '{' 82218887Sdim << getRegion() << ',' << T.getAsString() << '}'; 83218887Sdim} 84218887Sdim 85234353Sdimvoid SymbolData::anchor() { } 86234353Sdim 87226633Sdimvoid SymbolRegionValue::dumpToStream(raw_ostream &os) const { 88218887Sdim os << "reg_$" << getSymbolID() << "<" << R << ">"; 89218887Sdim} 90218887Sdim 91234353Sdimbool SymExpr::symbol_iterator::operator==(const symbol_iterator &X) const { 92234353Sdim return itr == X.itr; 93234353Sdim} 94234353Sdim 95234353Sdimbool SymExpr::symbol_iterator::operator!=(const symbol_iterator &X) const { 96234353Sdim return itr != X.itr; 97234353Sdim} 98234353Sdim 99234353SdimSymExpr::symbol_iterator::symbol_iterator(const SymExpr *SE) { 100234353Sdim itr.push_back(SE); 101234353Sdim} 102234353Sdim 103234353SdimSymExpr::symbol_iterator &SymExpr::symbol_iterator::operator++() { 104234353Sdim assert(!itr.empty() && "attempting to iterate on an 'end' iterator"); 105243830Sdim expand(); 106234353Sdim return *this; 107234353Sdim} 108234353Sdim 109234353SdimSymbolRef SymExpr::symbol_iterator::operator*() { 110234353Sdim assert(!itr.empty() && "attempting to dereference an 'end' iterator"); 111243830Sdim return itr.back(); 112234353Sdim} 113234353Sdim 114234353Sdimvoid SymExpr::symbol_iterator::expand() { 115263508Sdim const SymExpr *SE = itr.pop_back_val(); 116234353Sdim 117234353Sdim switch (SE->getKind()) { 118234353Sdim case SymExpr::RegionValueKind: 119234353Sdim case SymExpr::ConjuredKind: 120234353Sdim case SymExpr::DerivedKind: 121234353Sdim case SymExpr::ExtentKind: 122234353Sdim case SymExpr::MetadataKind: 123234353Sdim return; 124234353Sdim case SymExpr::CastSymbolKind: 125234353Sdim itr.push_back(cast<SymbolCast>(SE)->getOperand()); 126234353Sdim return; 127234353Sdim case SymExpr::SymIntKind: 128234353Sdim itr.push_back(cast<SymIntExpr>(SE)->getLHS()); 129234353Sdim return; 130234353Sdim case SymExpr::IntSymKind: 131234353Sdim itr.push_back(cast<IntSymExpr>(SE)->getRHS()); 132234353Sdim return; 133234353Sdim case SymExpr::SymSymKind: { 134234353Sdim const SymSymExpr *x = cast<SymSymExpr>(SE); 135234353Sdim itr.push_back(x->getLHS()); 136234353Sdim itr.push_back(x->getRHS()); 137234353Sdim return; 138234353Sdim } 139234353Sdim } 140234353Sdim llvm_unreachable("unhandled expansion case"); 141234353Sdim} 142234353Sdim 143239462Sdimunsigned SymExpr::computeComplexity() const { 144239462Sdim unsigned R = 0; 145239462Sdim for (symbol_iterator I = symbol_begin(), E = symbol_end(); I != E; ++I) 146239462Sdim R++; 147239462Sdim return R; 148239462Sdim} 149239462Sdim 150218887Sdimconst SymbolRegionValue* 151226633SdimSymbolManager::getRegionValueSymbol(const TypedValueRegion* R) { 152218887Sdim llvm::FoldingSetNodeID profile; 153218887Sdim SymbolRegionValue::Profile(profile, R); 154226633Sdim void *InsertPos; 155218887Sdim SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos); 156218887Sdim if (!SD) { 157218887Sdim SD = (SymExpr*) BPAlloc.Allocate<SymbolRegionValue>(); 158218887Sdim new (SD) SymbolRegionValue(SymbolCounter, R); 159218887Sdim DataSet.InsertNode(SD, InsertPos); 160218887Sdim ++SymbolCounter; 161218887Sdim } 162218887Sdim 163218887Sdim return cast<SymbolRegionValue>(SD); 164218887Sdim} 165218887Sdim 166243830Sdimconst SymbolConjured* SymbolManager::conjureSymbol(const Stmt *E, 167243830Sdim const LocationContext *LCtx, 168243830Sdim QualType T, 169243830Sdim unsigned Count, 170243830Sdim const void *SymbolTag) { 171218887Sdim llvm::FoldingSetNodeID profile; 172234353Sdim SymbolConjured::Profile(profile, E, T, Count, LCtx, SymbolTag); 173226633Sdim void *InsertPos; 174218887Sdim SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos); 175218887Sdim if (!SD) { 176218887Sdim SD = (SymExpr*) BPAlloc.Allocate<SymbolConjured>(); 177234353Sdim new (SD) SymbolConjured(SymbolCounter, E, LCtx, T, Count, SymbolTag); 178218887Sdim DataSet.InsertNode(SD, InsertPos); 179218887Sdim ++SymbolCounter; 180218887Sdim } 181218887Sdim 182218887Sdim return cast<SymbolConjured>(SD); 183218887Sdim} 184218887Sdim 185218887Sdimconst SymbolDerived* 186218887SdimSymbolManager::getDerivedSymbol(SymbolRef parentSymbol, 187226633Sdim const TypedValueRegion *R) { 188218887Sdim 189218887Sdim llvm::FoldingSetNodeID profile; 190218887Sdim SymbolDerived::Profile(profile, parentSymbol, R); 191226633Sdim void *InsertPos; 192218887Sdim SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos); 193218887Sdim if (!SD) { 194218887Sdim SD = (SymExpr*) BPAlloc.Allocate<SymbolDerived>(); 195218887Sdim new (SD) SymbolDerived(SymbolCounter, parentSymbol, R); 196218887Sdim DataSet.InsertNode(SD, InsertPos); 197218887Sdim ++SymbolCounter; 198218887Sdim } 199218887Sdim 200218887Sdim return cast<SymbolDerived>(SD); 201218887Sdim} 202218887Sdim 203218887Sdimconst SymbolExtent* 204218887SdimSymbolManager::getExtentSymbol(const SubRegion *R) { 205218887Sdim llvm::FoldingSetNodeID profile; 206218887Sdim SymbolExtent::Profile(profile, R); 207226633Sdim void *InsertPos; 208218887Sdim SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos); 209218887Sdim if (!SD) { 210218887Sdim SD = (SymExpr*) BPAlloc.Allocate<SymbolExtent>(); 211218887Sdim new (SD) SymbolExtent(SymbolCounter, R); 212218887Sdim DataSet.InsertNode(SD, InsertPos); 213218887Sdim ++SymbolCounter; 214218887Sdim } 215218887Sdim 216218887Sdim return cast<SymbolExtent>(SD); 217218887Sdim} 218218887Sdim 219218887Sdimconst SymbolMetadata* 220226633SdimSymbolManager::getMetadataSymbol(const MemRegion* R, const Stmt *S, QualType T, 221226633Sdim unsigned Count, const void *SymbolTag) { 222218887Sdim 223218887Sdim llvm::FoldingSetNodeID profile; 224218887Sdim SymbolMetadata::Profile(profile, R, S, T, Count, SymbolTag); 225226633Sdim void *InsertPos; 226218887Sdim SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos); 227218887Sdim if (!SD) { 228218887Sdim SD = (SymExpr*) BPAlloc.Allocate<SymbolMetadata>(); 229218887Sdim new (SD) SymbolMetadata(SymbolCounter, R, S, T, Count, SymbolTag); 230218887Sdim DataSet.InsertNode(SD, InsertPos); 231218887Sdim ++SymbolCounter; 232218887Sdim } 233218887Sdim 234218887Sdim return cast<SymbolMetadata>(SD); 235218887Sdim} 236218887Sdim 237234353Sdimconst SymbolCast* 238234353SdimSymbolManager::getCastSymbol(const SymExpr *Op, 239234353Sdim QualType From, QualType To) { 240234353Sdim llvm::FoldingSetNodeID ID; 241234353Sdim SymbolCast::Profile(ID, Op, From, To); 242234353Sdim void *InsertPos; 243234353Sdim SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos); 244234353Sdim if (!data) { 245234353Sdim data = (SymbolCast*) BPAlloc.Allocate<SymbolCast>(); 246234353Sdim new (data) SymbolCast(Op, From, To); 247234353Sdim DataSet.InsertNode(data, InsertPos); 248234353Sdim } 249234353Sdim 250234353Sdim return cast<SymbolCast>(data); 251234353Sdim} 252234353Sdim 253218887Sdimconst SymIntExpr *SymbolManager::getSymIntExpr(const SymExpr *lhs, 254218887Sdim BinaryOperator::Opcode op, 255218887Sdim const llvm::APSInt& v, 256218887Sdim QualType t) { 257218887Sdim llvm::FoldingSetNodeID ID; 258218887Sdim SymIntExpr::Profile(ID, lhs, op, v, t); 259218887Sdim void *InsertPos; 260218887Sdim SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos); 261218887Sdim 262218887Sdim if (!data) { 263218887Sdim data = (SymIntExpr*) BPAlloc.Allocate<SymIntExpr>(); 264218887Sdim new (data) SymIntExpr(lhs, op, v, t); 265218887Sdim DataSet.InsertNode(data, InsertPos); 266218887Sdim } 267218887Sdim 268218887Sdim return cast<SymIntExpr>(data); 269218887Sdim} 270218887Sdim 271234353Sdimconst IntSymExpr *SymbolManager::getIntSymExpr(const llvm::APSInt& lhs, 272234353Sdim BinaryOperator::Opcode op, 273234353Sdim const SymExpr *rhs, 274234353Sdim QualType t) { 275234353Sdim llvm::FoldingSetNodeID ID; 276234353Sdim IntSymExpr::Profile(ID, lhs, op, rhs, t); 277234353Sdim void *InsertPos; 278234353Sdim SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos); 279234353Sdim 280234353Sdim if (!data) { 281234353Sdim data = (IntSymExpr*) BPAlloc.Allocate<IntSymExpr>(); 282234353Sdim new (data) IntSymExpr(lhs, op, rhs, t); 283234353Sdim DataSet.InsertNode(data, InsertPos); 284234353Sdim } 285234353Sdim 286234353Sdim return cast<IntSymExpr>(data); 287234353Sdim} 288234353Sdim 289218887Sdimconst SymSymExpr *SymbolManager::getSymSymExpr(const SymExpr *lhs, 290218887Sdim BinaryOperator::Opcode op, 291218887Sdim const SymExpr *rhs, 292218887Sdim QualType t) { 293218887Sdim llvm::FoldingSetNodeID ID; 294218887Sdim SymSymExpr::Profile(ID, lhs, op, rhs, t); 295218887Sdim void *InsertPos; 296218887Sdim SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos); 297218887Sdim 298218887Sdim if (!data) { 299218887Sdim data = (SymSymExpr*) BPAlloc.Allocate<SymSymExpr>(); 300218887Sdim new (data) SymSymExpr(lhs, op, rhs, t); 301218887Sdim DataSet.InsertNode(data, InsertPos); 302218887Sdim } 303218887Sdim 304218887Sdim return cast<SymSymExpr>(data); 305218887Sdim} 306218887Sdim 307243830SdimQualType SymbolConjured::getType() const { 308218887Sdim return T; 309218887Sdim} 310218887Sdim 311243830SdimQualType SymbolDerived::getType() const { 312218887Sdim return R->getValueType(); 313218887Sdim} 314218887Sdim 315243830SdimQualType SymbolExtent::getType() const { 316243830Sdim ASTContext &Ctx = R->getMemRegionManager()->getContext(); 317218887Sdim return Ctx.getSizeType(); 318218887Sdim} 319218887Sdim 320243830SdimQualType SymbolMetadata::getType() const { 321218887Sdim return T; 322218887Sdim} 323218887Sdim 324243830SdimQualType SymbolRegionValue::getType() const { 325218887Sdim return R->getValueType(); 326218887Sdim} 327218887Sdim 328226633SdimSymbolManager::~SymbolManager() { 329226633Sdim for (SymbolDependTy::const_iterator I = SymbolDependencies.begin(), 330226633Sdim E = SymbolDependencies.end(); I != E; ++I) { 331226633Sdim delete I->second; 332226633Sdim } 333218887Sdim 334226633Sdim} 335226633Sdim 336218887Sdimbool SymbolManager::canSymbolicate(QualType T) { 337218887Sdim T = T.getCanonicalType(); 338218887Sdim 339218887Sdim if (Loc::isLocType(T)) 340218887Sdim return true; 341218887Sdim 342251662Sdim if (T->isIntegralOrEnumerationType()) 343251662Sdim return true; 344218887Sdim 345218887Sdim if (T->isRecordType() && !T->isUnionType()) 346218887Sdim return true; 347218887Sdim 348218887Sdim return false; 349218887Sdim} 350218887Sdim 351226633Sdimvoid SymbolManager::addSymbolDependency(const SymbolRef Primary, 352226633Sdim const SymbolRef Dependent) { 353226633Sdim SymbolDependTy::iterator I = SymbolDependencies.find(Primary); 354226633Sdim SymbolRefSmallVectorTy *dependencies = 0; 355226633Sdim if (I == SymbolDependencies.end()) { 356226633Sdim dependencies = new SymbolRefSmallVectorTy(); 357226633Sdim SymbolDependencies[Primary] = dependencies; 358226633Sdim } else { 359226633Sdim dependencies = I->second; 360226633Sdim } 361226633Sdim dependencies->push_back(Dependent); 362226633Sdim} 363226633Sdim 364226633Sdimconst SymbolRefSmallVectorTy *SymbolManager::getDependentSymbols( 365226633Sdim const SymbolRef Primary) { 366226633Sdim SymbolDependTy::const_iterator I = SymbolDependencies.find(Primary); 367226633Sdim if (I == SymbolDependencies.end()) 368226633Sdim return 0; 369226633Sdim return I->second; 370226633Sdim} 371226633Sdim 372226633Sdimvoid SymbolReaper::markDependentsLive(SymbolRef sym) { 373226633Sdim // Do not mark dependents more then once. 374226633Sdim SymbolMapTy::iterator LI = TheLiving.find(sym); 375226633Sdim assert(LI != TheLiving.end() && "The primary symbol is not live."); 376226633Sdim if (LI->second == HaveMarkedDependents) 377226633Sdim return; 378226633Sdim LI->second = HaveMarkedDependents; 379226633Sdim 380226633Sdim if (const SymbolRefSmallVectorTy *Deps = SymMgr.getDependentSymbols(sym)) { 381226633Sdim for (SymbolRefSmallVectorTy::const_iterator I = Deps->begin(), 382226633Sdim E = Deps->end(); I != E; ++I) { 383226633Sdim if (TheLiving.find(*I) != TheLiving.end()) 384226633Sdim continue; 385226633Sdim markLive(*I); 386226633Sdim } 387226633Sdim } 388226633Sdim} 389226633Sdim 390218887Sdimvoid SymbolReaper::markLive(SymbolRef sym) { 391226633Sdim TheLiving[sym] = NotProcessed; 392218887Sdim TheDead.erase(sym); 393226633Sdim markDependentsLive(sym); 394218887Sdim} 395218887Sdim 396226633Sdimvoid SymbolReaper::markLive(const MemRegion *region) { 397226633Sdim RegionRoots.insert(region); 398226633Sdim} 399226633Sdim 400218887Sdimvoid SymbolReaper::markInUse(SymbolRef sym) { 401218887Sdim if (isa<SymbolMetadata>(sym)) 402218887Sdim MetadataInUse.insert(sym); 403218887Sdim} 404218887Sdim 405218887Sdimbool SymbolReaper::maybeDead(SymbolRef sym) { 406218887Sdim if (isLive(sym)) 407218887Sdim return false; 408218887Sdim 409218887Sdim TheDead.insert(sym); 410218887Sdim return true; 411218887Sdim} 412218887Sdim 413226633Sdimbool SymbolReaper::isLiveRegion(const MemRegion *MR) { 414226633Sdim if (RegionRoots.count(MR)) 415226633Sdim return true; 416226633Sdim 417218887Sdim MR = MR->getBaseRegion(); 418218887Sdim 419218887Sdim if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) 420226633Sdim return isLive(SR->getSymbol()); 421218887Sdim 422218887Sdim if (const VarRegion *VR = dyn_cast<VarRegion>(MR)) 423226633Sdim return isLive(VR, true); 424218887Sdim 425218887Sdim // FIXME: This is a gross over-approximation. What we really need is a way to 426218887Sdim // tell if anything still refers to this region. Unlike SymbolicRegions, 427218887Sdim // AllocaRegions don't have associated symbols, though, so we don't actually 428218887Sdim // have a way to track their liveness. 429218887Sdim if (isa<AllocaRegion>(MR)) 430218887Sdim return true; 431218887Sdim 432218887Sdim if (isa<CXXThisRegion>(MR)) 433218887Sdim return true; 434218887Sdim 435218887Sdim if (isa<MemSpaceRegion>(MR)) 436218887Sdim return true; 437218887Sdim 438263508Sdim if (isa<CodeTextRegion>(MR)) 439263508Sdim return true; 440263508Sdim 441218887Sdim return false; 442218887Sdim} 443218887Sdim 444218887Sdimbool SymbolReaper::isLive(SymbolRef sym) { 445226633Sdim if (TheLiving.count(sym)) { 446226633Sdim markDependentsLive(sym); 447218887Sdim return true; 448226633Sdim } 449243830Sdim 450243830Sdim bool KnownLive; 451243830Sdim 452243830Sdim switch (sym->getKind()) { 453243830Sdim case SymExpr::RegionValueKind: 454249423Sdim KnownLive = isLiveRegion(cast<SymbolRegionValue>(sym)->getRegion()); 455243830Sdim break; 456243830Sdim case SymExpr::ConjuredKind: 457243830Sdim KnownLive = false; 458243830Sdim break; 459243830Sdim case SymExpr::DerivedKind: 460243830Sdim KnownLive = isLive(cast<SymbolDerived>(sym)->getParentSymbol()); 461243830Sdim break; 462243830Sdim case SymExpr::ExtentKind: 463243830Sdim KnownLive = isLiveRegion(cast<SymbolExtent>(sym)->getRegion()); 464243830Sdim break; 465243830Sdim case SymExpr::MetadataKind: 466243830Sdim KnownLive = MetadataInUse.count(sym) && 467243830Sdim isLiveRegion(cast<SymbolMetadata>(sym)->getRegion()); 468243830Sdim if (KnownLive) 469243830Sdim MetadataInUse.erase(sym); 470243830Sdim break; 471243830Sdim case SymExpr::SymIntKind: 472243830Sdim KnownLive = isLive(cast<SymIntExpr>(sym)->getLHS()); 473243830Sdim break; 474243830Sdim case SymExpr::IntSymKind: 475243830Sdim KnownLive = isLive(cast<IntSymExpr>(sym)->getRHS()); 476243830Sdim break; 477243830Sdim case SymExpr::SymSymKind: 478243830Sdim KnownLive = isLive(cast<SymSymExpr>(sym)->getLHS()) && 479243830Sdim isLive(cast<SymSymExpr>(sym)->getRHS()); 480243830Sdim break; 481243830Sdim case SymExpr::CastSymbolKind: 482243830Sdim KnownLive = isLive(cast<SymbolCast>(sym)->getOperand()); 483243830Sdim break; 484218887Sdim } 485218887Sdim 486243830Sdim if (KnownLive) 487243830Sdim markLive(sym); 488218887Sdim 489243830Sdim return KnownLive; 490218887Sdim} 491218887Sdim 492234353Sdimbool 493234353SdimSymbolReaper::isLive(const Stmt *ExprVal, const LocationContext *ELCtx) const { 494243830Sdim if (LCtx == 0) 495243830Sdim return false; 496243830Sdim 497234353Sdim if (LCtx != ELCtx) { 498234353Sdim // If the reaper's location context is a parent of the expression's 499234353Sdim // location context, then the expression value is now "out of scope". 500234353Sdim if (LCtx->isParentOf(ELCtx)) 501234353Sdim return false; 502234353Sdim return true; 503234353Sdim } 504243830Sdim 505239462Sdim // If no statement is provided, everything is this and parent contexts is live. 506239462Sdim if (!Loc) 507239462Sdim return true; 508234353Sdim 509226633Sdim return LCtx->getAnalysis<RelaxedLiveVariables>()->isLive(Loc, ExprVal); 510218887Sdim} 511218887Sdim 512226633Sdimbool SymbolReaper::isLive(const VarRegion *VR, bool includeStoreBindings) const{ 513218887Sdim const StackFrameContext *VarContext = VR->getStackFrame(); 514243830Sdim 515243830Sdim if (!VarContext) 516243830Sdim return true; 517243830Sdim 518243830Sdim if (!LCtx) 519243830Sdim return false; 520218887Sdim const StackFrameContext *CurrentContext = LCtx->getCurrentStackFrame(); 521218887Sdim 522226633Sdim if (VarContext == CurrentContext) { 523243830Sdim // If no statement is provided, everything is live. 524239462Sdim if (!Loc) 525239462Sdim return true; 526239462Sdim 527226633Sdim if (LCtx->getAnalysis<RelaxedLiveVariables>()->isLive(Loc, VR->getDecl())) 528226633Sdim return true; 529218887Sdim 530226633Sdim if (!includeStoreBindings) 531226633Sdim return false; 532226633Sdim 533226633Sdim unsigned &cachedQuery = 534226633Sdim const_cast<SymbolReaper*>(this)->includedRegionCache[VR]; 535226633Sdim 536226633Sdim if (cachedQuery) { 537226633Sdim return cachedQuery == 1; 538226633Sdim } 539226633Sdim 540226633Sdim // Query the store to see if the region occurs in any live bindings. 541226633Sdim if (Store store = reapedStore.getStore()) { 542226633Sdim bool hasRegion = 543226633Sdim reapedStore.getStoreManager().includedInBindings(store, VR); 544226633Sdim cachedQuery = hasRegion ? 1 : 2; 545226633Sdim return hasRegion; 546226633Sdim } 547226633Sdim 548226633Sdim return false; 549226633Sdim } 550226633Sdim 551218887Sdim return VarContext->isParentOf(CurrentContext); 552218887Sdim} 553218887Sdim 554218887SdimSymbolVisitor::~SymbolVisitor() {} 555