1218887Sdim//== MemRegion.cpp - Abstract memory regions for static analysis --*- 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 MemRegion and its subclasses. MemRegion defines a 11218887Sdim// partially-typed abstraction of memory useful for path-sensitive dataflow 12218887Sdim// analyses. 13218887Sdim// 14218887Sdim//===----------------------------------------------------------------------===// 15218887Sdim 16218887Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" 17249423Sdim#include "clang/AST/Attr.h" 18218887Sdim#include "clang/AST/CharUnits.h" 19234353Sdim#include "clang/AST/DeclObjC.h" 20218887Sdim#include "clang/AST/RecordLayout.h" 21249423Sdim#include "clang/Analysis/AnalysisContext.h" 22249423Sdim#include "clang/Analysis/Support/BumpVector.h" 23234353Sdim#include "clang/Basic/SourceManager.h" 24249423Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" 25218887Sdim#include "llvm/Support/raw_ostream.h" 26218887Sdim 27218887Sdimusing namespace clang; 28218887Sdimusing namespace ento; 29218887Sdim 30218887Sdim//===----------------------------------------------------------------------===// 31218887Sdim// MemRegion Construction. 32218887Sdim//===----------------------------------------------------------------------===// 33218887Sdim 34218887Sdimtemplate<typename RegionTy> struct MemRegionManagerTrait; 35218887Sdim 36218887Sdimtemplate <typename RegionTy, typename A1> 37218887SdimRegionTy* MemRegionManager::getRegion(const A1 a1) { 38218887Sdim 39218887Sdim const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion = 40218887Sdim MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1); 41218887Sdim 42218887Sdim llvm::FoldingSetNodeID ID; 43218887Sdim RegionTy::ProfileRegion(ID, a1, superRegion); 44226633Sdim void *InsertPos; 45218887Sdim RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 46218887Sdim InsertPos)); 47218887Sdim 48218887Sdim if (!R) { 49218887Sdim R = (RegionTy*) A.Allocate<RegionTy>(); 50218887Sdim new (R) RegionTy(a1, superRegion); 51218887Sdim Regions.InsertNode(R, InsertPos); 52218887Sdim } 53218887Sdim 54218887Sdim return R; 55218887Sdim} 56218887Sdim 57218887Sdimtemplate <typename RegionTy, typename A1> 58218887SdimRegionTy* MemRegionManager::getSubRegion(const A1 a1, 59218887Sdim const MemRegion *superRegion) { 60218887Sdim llvm::FoldingSetNodeID ID; 61218887Sdim RegionTy::ProfileRegion(ID, a1, superRegion); 62226633Sdim void *InsertPos; 63218887Sdim RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 64218887Sdim InsertPos)); 65218887Sdim 66218887Sdim if (!R) { 67218887Sdim R = (RegionTy*) A.Allocate<RegionTy>(); 68218887Sdim new (R) RegionTy(a1, superRegion); 69218887Sdim Regions.InsertNode(R, InsertPos); 70218887Sdim } 71218887Sdim 72218887Sdim return R; 73218887Sdim} 74218887Sdim 75218887Sdimtemplate <typename RegionTy, typename A1, typename A2> 76218887SdimRegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) { 77218887Sdim 78218887Sdim const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion = 79218887Sdim MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2); 80218887Sdim 81218887Sdim llvm::FoldingSetNodeID ID; 82218887Sdim RegionTy::ProfileRegion(ID, a1, a2, superRegion); 83226633Sdim void *InsertPos; 84218887Sdim RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 85218887Sdim InsertPos)); 86218887Sdim 87218887Sdim if (!R) { 88218887Sdim R = (RegionTy*) A.Allocate<RegionTy>(); 89218887Sdim new (R) RegionTy(a1, a2, superRegion); 90218887Sdim Regions.InsertNode(R, InsertPos); 91218887Sdim } 92218887Sdim 93218887Sdim return R; 94218887Sdim} 95218887Sdim 96218887Sdimtemplate <typename RegionTy, typename A1, typename A2> 97218887SdimRegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, 98218887Sdim const MemRegion *superRegion) { 99218887Sdim 100218887Sdim llvm::FoldingSetNodeID ID; 101218887Sdim RegionTy::ProfileRegion(ID, a1, a2, superRegion); 102226633Sdim void *InsertPos; 103218887Sdim RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 104218887Sdim InsertPos)); 105218887Sdim 106218887Sdim if (!R) { 107218887Sdim R = (RegionTy*) A.Allocate<RegionTy>(); 108218887Sdim new (R) RegionTy(a1, a2, superRegion); 109218887Sdim Regions.InsertNode(R, InsertPos); 110218887Sdim } 111218887Sdim 112218887Sdim return R; 113218887Sdim} 114218887Sdim 115218887Sdimtemplate <typename RegionTy, typename A1, typename A2, typename A3> 116218887SdimRegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3, 117218887Sdim const MemRegion *superRegion) { 118218887Sdim 119218887Sdim llvm::FoldingSetNodeID ID; 120218887Sdim RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion); 121226633Sdim void *InsertPos; 122218887Sdim RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 123218887Sdim InsertPos)); 124218887Sdim 125218887Sdim if (!R) { 126218887Sdim R = (RegionTy*) A.Allocate<RegionTy>(); 127218887Sdim new (R) RegionTy(a1, a2, a3, superRegion); 128218887Sdim Regions.InsertNode(R, InsertPos); 129218887Sdim } 130218887Sdim 131218887Sdim return R; 132218887Sdim} 133218887Sdim 134218887Sdim//===----------------------------------------------------------------------===// 135218887Sdim// Object destruction. 136218887Sdim//===----------------------------------------------------------------------===// 137218887Sdim 138218887SdimMemRegion::~MemRegion() {} 139218887Sdim 140218887SdimMemRegionManager::~MemRegionManager() { 141218887Sdim // All regions and their data are BumpPtrAllocated. No need to call 142218887Sdim // their destructors. 143218887Sdim} 144218887Sdim 145218887Sdim//===----------------------------------------------------------------------===// 146218887Sdim// Basic methods. 147218887Sdim//===----------------------------------------------------------------------===// 148218887Sdim 149218887Sdimbool SubRegion::isSubRegionOf(const MemRegion* R) const { 150218887Sdim const MemRegion* r = getSuperRegion(); 151218887Sdim while (r != 0) { 152218887Sdim if (r == R) 153218887Sdim return true; 154218887Sdim if (const SubRegion* sr = dyn_cast<SubRegion>(r)) 155218887Sdim r = sr->getSuperRegion(); 156218887Sdim else 157218887Sdim break; 158218887Sdim } 159218887Sdim return false; 160218887Sdim} 161218887Sdim 162218887SdimMemRegionManager* SubRegion::getMemRegionManager() const { 163218887Sdim const SubRegion* r = this; 164218887Sdim do { 165218887Sdim const MemRegion *superRegion = r->getSuperRegion(); 166218887Sdim if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) { 167218887Sdim r = sr; 168218887Sdim continue; 169218887Sdim } 170218887Sdim return superRegion->getMemRegionManager(); 171218887Sdim } while (1); 172218887Sdim} 173218887Sdim 174218887Sdimconst StackFrameContext *VarRegion::getStackFrame() const { 175218887Sdim const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace()); 176218887Sdim return SSR ? SSR->getStackFrame() : NULL; 177218887Sdim} 178218887Sdim 179218887Sdim//===----------------------------------------------------------------------===// 180218887Sdim// Region extents. 181218887Sdim//===----------------------------------------------------------------------===// 182218887Sdim 183239462SdimDefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const { 184226633Sdim ASTContext &Ctx = svalBuilder.getContext(); 185218887Sdim QualType T = getDesugaredValueType(Ctx); 186218887Sdim 187218887Sdim if (isa<VariableArrayType>(T)) 188218887Sdim return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); 189263508Sdim if (T->isIncompleteType()) 190218887Sdim return UnknownVal(); 191218887Sdim 192218887Sdim CharUnits size = Ctx.getTypeSizeInChars(T); 193218887Sdim QualType sizeTy = svalBuilder.getArrayIndexType(); 194218887Sdim return svalBuilder.makeIntVal(size.getQuantity(), sizeTy); 195218887Sdim} 196218887Sdim 197218887SdimDefinedOrUnknownSVal FieldRegion::getExtent(SValBuilder &svalBuilder) const { 198249423Sdim // Force callers to deal with bitfields explicitly. 199249423Sdim if (getDecl()->isBitField()) 200249423Sdim return UnknownVal(); 201249423Sdim 202218887Sdim DefinedOrUnknownSVal Extent = DeclRegion::getExtent(svalBuilder); 203218887Sdim 204218887Sdim // A zero-length array at the end of a struct often stands for dynamically- 205218887Sdim // allocated extra memory. 206218887Sdim if (Extent.isZeroConstant()) { 207218887Sdim QualType T = getDesugaredValueType(svalBuilder.getContext()); 208218887Sdim 209218887Sdim if (isa<ConstantArrayType>(T)) 210218887Sdim return UnknownVal(); 211218887Sdim } 212218887Sdim 213218887Sdim return Extent; 214218887Sdim} 215218887Sdim 216218887SdimDefinedOrUnknownSVal AllocaRegion::getExtent(SValBuilder &svalBuilder) const { 217218887Sdim return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); 218218887Sdim} 219218887Sdim 220218887SdimDefinedOrUnknownSVal SymbolicRegion::getExtent(SValBuilder &svalBuilder) const { 221218887Sdim return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); 222218887Sdim} 223218887Sdim 224218887SdimDefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const { 225218887Sdim return svalBuilder.makeIntVal(getStringLiteral()->getByteLength()+1, 226218887Sdim svalBuilder.getArrayIndexType()); 227218887Sdim} 228218887Sdim 229234353SdimObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg) 230234353Sdim : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {} 231234353Sdim 232234353Sdimconst ObjCIvarDecl *ObjCIvarRegion::getDecl() const { 233234353Sdim return cast<ObjCIvarDecl>(D); 234234353Sdim} 235234353Sdim 236234353SdimQualType ObjCIvarRegion::getValueType() const { 237234353Sdim return getDecl()->getType(); 238234353Sdim} 239234353Sdim 240218887SdimQualType CXXBaseObjectRegion::getValueType() const { 241249423Sdim return QualType(getDecl()->getTypeForDecl(), 0); 242218887Sdim} 243218887Sdim 244218887Sdim//===----------------------------------------------------------------------===// 245218887Sdim// FoldingSet profiling. 246218887Sdim//===----------------------------------------------------------------------===// 247218887Sdim 248218887Sdimvoid MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const { 249218887Sdim ID.AddInteger((unsigned)getKind()); 250218887Sdim} 251218887Sdim 252218887Sdimvoid StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const { 253218887Sdim ID.AddInteger((unsigned)getKind()); 254218887Sdim ID.AddPointer(getStackFrame()); 255218887Sdim} 256218887Sdim 257218887Sdimvoid StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const { 258218887Sdim ID.AddInteger((unsigned)getKind()); 259218887Sdim ID.AddPointer(getCodeRegion()); 260218887Sdim} 261218887Sdim 262218887Sdimvoid StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 263218887Sdim const StringLiteral* Str, 264218887Sdim const MemRegion* superRegion) { 265218887Sdim ID.AddInteger((unsigned) StringRegionKind); 266218887Sdim ID.AddPointer(Str); 267218887Sdim ID.AddPointer(superRegion); 268218887Sdim} 269218887Sdim 270234353Sdimvoid ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 271234353Sdim const ObjCStringLiteral* Str, 272234353Sdim const MemRegion* superRegion) { 273234353Sdim ID.AddInteger((unsigned) ObjCStringRegionKind); 274234353Sdim ID.AddPointer(Str); 275234353Sdim ID.AddPointer(superRegion); 276234353Sdim} 277234353Sdim 278218887Sdimvoid AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 279226633Sdim const Expr *Ex, unsigned cnt, 280249423Sdim const MemRegion *superRegion) { 281218887Sdim ID.AddInteger((unsigned) AllocaRegionKind); 282218887Sdim ID.AddPointer(Ex); 283218887Sdim ID.AddInteger(cnt); 284249423Sdim ID.AddPointer(superRegion); 285218887Sdim} 286218887Sdim 287218887Sdimvoid AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const { 288218887Sdim ProfileRegion(ID, Ex, Cnt, superRegion); 289218887Sdim} 290218887Sdim 291218887Sdimvoid CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const { 292218887Sdim CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion); 293218887Sdim} 294218887Sdim 295218887Sdimvoid CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 296226633Sdim const CompoundLiteralExpr *CL, 297218887Sdim const MemRegion* superRegion) { 298218887Sdim ID.AddInteger((unsigned) CompoundLiteralRegionKind); 299218887Sdim ID.AddPointer(CL); 300218887Sdim ID.AddPointer(superRegion); 301218887Sdim} 302218887Sdim 303218887Sdimvoid CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, 304218887Sdim const PointerType *PT, 305218887Sdim const MemRegion *sRegion) { 306218887Sdim ID.AddInteger((unsigned) CXXThisRegionKind); 307218887Sdim ID.AddPointer(PT); 308218887Sdim ID.AddPointer(sRegion); 309218887Sdim} 310218887Sdim 311218887Sdimvoid CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const { 312218887Sdim CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion); 313218887Sdim} 314218887Sdim 315234353Sdimvoid ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 316234353Sdim const ObjCIvarDecl *ivd, 317234353Sdim const MemRegion* superRegion) { 318234353Sdim DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind); 319234353Sdim} 320234353Sdim 321226633Sdimvoid DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D, 322218887Sdim const MemRegion* superRegion, Kind k) { 323218887Sdim ID.AddInteger((unsigned) k); 324218887Sdim ID.AddPointer(D); 325218887Sdim ID.AddPointer(superRegion); 326218887Sdim} 327218887Sdim 328218887Sdimvoid DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const { 329218887Sdim DeclRegion::ProfileRegion(ID, D, superRegion, getKind()); 330218887Sdim} 331218887Sdim 332218887Sdimvoid VarRegion::Profile(llvm::FoldingSetNodeID &ID) const { 333218887Sdim VarRegion::ProfileRegion(ID, getDecl(), superRegion); 334218887Sdim} 335218887Sdim 336218887Sdimvoid SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym, 337218887Sdim const MemRegion *sreg) { 338218887Sdim ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind); 339218887Sdim ID.Add(sym); 340218887Sdim ID.AddPointer(sreg); 341218887Sdim} 342218887Sdim 343218887Sdimvoid SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const { 344218887Sdim SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion()); 345218887Sdim} 346218887Sdim 347218887Sdimvoid ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 348218887Sdim QualType ElementType, SVal Idx, 349218887Sdim const MemRegion* superRegion) { 350218887Sdim ID.AddInteger(MemRegion::ElementRegionKind); 351218887Sdim ID.Add(ElementType); 352218887Sdim ID.AddPointer(superRegion); 353218887Sdim Idx.Profile(ID); 354218887Sdim} 355218887Sdim 356218887Sdimvoid ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const { 357218887Sdim ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion); 358218887Sdim} 359218887Sdim 360218887Sdimvoid FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 361243830Sdim const NamedDecl *FD, 362218887Sdim const MemRegion*) { 363218887Sdim ID.AddInteger(MemRegion::FunctionTextRegionKind); 364218887Sdim ID.AddPointer(FD); 365218887Sdim} 366218887Sdim 367218887Sdimvoid FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const { 368218887Sdim FunctionTextRegion::ProfileRegion(ID, FD, superRegion); 369218887Sdim} 370218887Sdim 371218887Sdimvoid BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 372218887Sdim const BlockDecl *BD, CanQualType, 373234353Sdim const AnalysisDeclContext *AC, 374218887Sdim const MemRegion*) { 375218887Sdim ID.AddInteger(MemRegion::BlockTextRegionKind); 376218887Sdim ID.AddPointer(BD); 377218887Sdim} 378218887Sdim 379218887Sdimvoid BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const { 380218887Sdim BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion); 381218887Sdim} 382218887Sdim 383218887Sdimvoid BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 384218887Sdim const BlockTextRegion *BC, 385218887Sdim const LocationContext *LC, 386263508Sdim unsigned BlkCount, 387218887Sdim const MemRegion *sReg) { 388218887Sdim ID.AddInteger(MemRegion::BlockDataRegionKind); 389218887Sdim ID.AddPointer(BC); 390218887Sdim ID.AddPointer(LC); 391263508Sdim ID.AddInteger(BlkCount); 392218887Sdim ID.AddPointer(sReg); 393218887Sdim} 394218887Sdim 395218887Sdimvoid BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const { 396263508Sdim BlockDataRegion::ProfileRegion(ID, BC, LC, BlockCount, getSuperRegion()); 397218887Sdim} 398218887Sdim 399218887Sdimvoid CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, 400218887Sdim Expr const *Ex, 401218887Sdim const MemRegion *sReg) { 402218887Sdim ID.AddPointer(Ex); 403218887Sdim ID.AddPointer(sReg); 404218887Sdim} 405218887Sdim 406218887Sdimvoid CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const { 407218887Sdim ProfileRegion(ID, Ex, getSuperRegion()); 408218887Sdim} 409218887Sdim 410218887Sdimvoid CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, 411249423Sdim const CXXRecordDecl *RD, 412249423Sdim bool IsVirtual, 413249423Sdim const MemRegion *SReg) { 414249423Sdim ID.AddPointer(RD); 415249423Sdim ID.AddBoolean(IsVirtual); 416249423Sdim ID.AddPointer(SReg); 417218887Sdim} 418218887Sdim 419218887Sdimvoid CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const { 420249423Sdim ProfileRegion(ID, getDecl(), isVirtual(), superRegion); 421218887Sdim} 422218887Sdim 423218887Sdim//===----------------------------------------------------------------------===// 424234353Sdim// Region anchors. 425234353Sdim//===----------------------------------------------------------------------===// 426234353Sdim 427234353Sdimvoid GlobalsSpaceRegion::anchor() { } 428234353Sdimvoid HeapSpaceRegion::anchor() { } 429234353Sdimvoid UnknownSpaceRegion::anchor() { } 430234353Sdimvoid StackLocalsSpaceRegion::anchor() { } 431234353Sdimvoid StackArgumentsSpaceRegion::anchor() { } 432234353Sdimvoid TypedRegion::anchor() { } 433234353Sdimvoid TypedValueRegion::anchor() { } 434234353Sdimvoid CodeTextRegion::anchor() { } 435234353Sdimvoid SubRegion::anchor() { } 436234353Sdim 437234353Sdim//===----------------------------------------------------------------------===// 438218887Sdim// Region pretty-printing. 439218887Sdim//===----------------------------------------------------------------------===// 440218887Sdim 441218887Sdimvoid MemRegion::dump() const { 442218887Sdim dumpToStream(llvm::errs()); 443218887Sdim} 444218887Sdim 445218887Sdimstd::string MemRegion::getString() const { 446218887Sdim std::string s; 447218887Sdim llvm::raw_string_ostream os(s); 448218887Sdim dumpToStream(os); 449218887Sdim return os.str(); 450218887Sdim} 451218887Sdim 452226633Sdimvoid MemRegion::dumpToStream(raw_ostream &os) const { 453218887Sdim os << "<Unknown Region>"; 454218887Sdim} 455218887Sdim 456226633Sdimvoid AllocaRegion::dumpToStream(raw_ostream &os) const { 457243830Sdim os << "alloca{" << (const void*) Ex << ',' << Cnt << '}'; 458218887Sdim} 459218887Sdim 460226633Sdimvoid FunctionTextRegion::dumpToStream(raw_ostream &os) const { 461218887Sdim os << "code{" << getDecl()->getDeclName().getAsString() << '}'; 462218887Sdim} 463218887Sdim 464226633Sdimvoid BlockTextRegion::dumpToStream(raw_ostream &os) const { 465243830Sdim os << "block_code{" << (const void*) this << '}'; 466218887Sdim} 467218887Sdim 468226633Sdimvoid BlockDataRegion::dumpToStream(raw_ostream &os) const { 469263508Sdim os << "block_data{" << BC; 470263508Sdim os << "; "; 471263508Sdim for (BlockDataRegion::referenced_vars_iterator 472263508Sdim I = referenced_vars_begin(), 473263508Sdim E = referenced_vars_end(); I != E; ++I) 474263508Sdim os << "(" << I.getCapturedRegion() << "," << 475263508Sdim I.getOriginalRegion() << ") "; 476263508Sdim os << '}'; 477218887Sdim} 478218887Sdim 479226633Sdimvoid CompoundLiteralRegion::dumpToStream(raw_ostream &os) const { 480218887Sdim // FIXME: More elaborate pretty-printing. 481243830Sdim os << "{ " << (const void*) CL << " }"; 482218887Sdim} 483218887Sdim 484226633Sdimvoid CXXTempObjectRegion::dumpToStream(raw_ostream &os) const { 485226633Sdim os << "temp_object{" << getValueType().getAsString() << ',' 486243830Sdim << (const void*) Ex << '}'; 487218887Sdim} 488218887Sdim 489226633Sdimvoid CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const { 490249423Sdim os << "base{" << superRegion << ',' << getDecl()->getName() << '}'; 491218887Sdim} 492218887Sdim 493226633Sdimvoid CXXThisRegion::dumpToStream(raw_ostream &os) const { 494218887Sdim os << "this"; 495218887Sdim} 496218887Sdim 497226633Sdimvoid ElementRegion::dumpToStream(raw_ostream &os) const { 498218887Sdim os << "element{" << superRegion << ',' 499218887Sdim << Index << ',' << getElementType().getAsString() << '}'; 500218887Sdim} 501218887Sdim 502226633Sdimvoid FieldRegion::dumpToStream(raw_ostream &os) const { 503226633Sdim os << superRegion << "->" << *getDecl(); 504218887Sdim} 505218887Sdim 506226633Sdimvoid ObjCIvarRegion::dumpToStream(raw_ostream &os) const { 507226633Sdim os << "ivar{" << superRegion << ',' << *getDecl() << '}'; 508218887Sdim} 509218887Sdim 510226633Sdimvoid StringRegion::dumpToStream(raw_ostream &os) const { 511234353Sdim Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts())); 512218887Sdim} 513218887Sdim 514234353Sdimvoid ObjCStringRegion::dumpToStream(raw_ostream &os) const { 515234353Sdim Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts())); 516234353Sdim} 517234353Sdim 518226633Sdimvoid SymbolicRegion::dumpToStream(raw_ostream &os) const { 519218887Sdim os << "SymRegion{" << sym << '}'; 520218887Sdim} 521218887Sdim 522226633Sdimvoid VarRegion::dumpToStream(raw_ostream &os) const { 523226633Sdim os << *cast<VarDecl>(D); 524218887Sdim} 525218887Sdim 526218887Sdimvoid RegionRawOffset::dump() const { 527218887Sdim dumpToStream(llvm::errs()); 528218887Sdim} 529218887Sdim 530226633Sdimvoid RegionRawOffset::dumpToStream(raw_ostream &os) const { 531218887Sdim os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}'; 532218887Sdim} 533218887Sdim 534226633Sdimvoid StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const { 535218887Sdim os << "StaticGlobalsMemSpace{" << CR << '}'; 536218887Sdim} 537218887Sdim 538234353Sdimvoid GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const { 539234353Sdim os << "GlobalInternalSpaceRegion"; 540234353Sdim} 541234353Sdim 542234353Sdimvoid GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const { 543234353Sdim os << "GlobalSystemSpaceRegion"; 544234353Sdim} 545234353Sdim 546234353Sdimvoid GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const { 547234353Sdim os << "GlobalImmutableSpaceRegion"; 548234353Sdim} 549234353Sdim 550239462Sdimvoid HeapSpaceRegion::dumpToStream(raw_ostream &os) const { 551239462Sdim os << "HeapSpaceRegion"; 552239462Sdim} 553239462Sdim 554239462Sdimvoid UnknownSpaceRegion::dumpToStream(raw_ostream &os) const { 555239462Sdim os << "UnknownSpaceRegion"; 556239462Sdim} 557239462Sdim 558239462Sdimvoid StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const { 559239462Sdim os << "StackArgumentsSpaceRegion"; 560239462Sdim} 561239462Sdim 562239462Sdimvoid StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const { 563239462Sdim os << "StackLocalsSpaceRegion"; 564239462Sdim} 565239462Sdim 566239462Sdimbool MemRegion::canPrintPretty() const { 567251662Sdim return canPrintPrettyAsExpr(); 568251662Sdim} 569251662Sdim 570251662Sdimbool MemRegion::canPrintPrettyAsExpr() const { 571239462Sdim return false; 572239462Sdim} 573239462Sdim 574239462Sdimvoid MemRegion::printPretty(raw_ostream &os) const { 575251662Sdim assert(canPrintPretty() && "This region cannot be printed pretty."); 576251662Sdim os << "'"; 577251662Sdim printPrettyAsExpr(os); 578251662Sdim os << "'"; 579234353Sdim return; 580234353Sdim} 581234353Sdim 582251662Sdimvoid MemRegion::printPrettyAsExpr(raw_ostream &os) const { 583251662Sdim llvm_unreachable("This region cannot be printed pretty."); 584251662Sdim return; 585251662Sdim} 586251662Sdim 587251662Sdimbool VarRegion::canPrintPrettyAsExpr() const { 588239462Sdim return true; 589239462Sdim} 590239462Sdim 591251662Sdimvoid VarRegion::printPrettyAsExpr(raw_ostream &os) const { 592234353Sdim os << getDecl()->getName(); 593234353Sdim} 594234353Sdim 595251662Sdimbool ObjCIvarRegion::canPrintPrettyAsExpr() const { 596249423Sdim return true; 597249423Sdim} 598249423Sdim 599251662Sdimvoid ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const { 600249423Sdim os << getDecl()->getName(); 601249423Sdim} 602249423Sdim 603239462Sdimbool FieldRegion::canPrintPretty() const { 604251662Sdim return true; 605234353Sdim} 606234353Sdim 607251662Sdimbool FieldRegion::canPrintPrettyAsExpr() const { 608251662Sdim return superRegion->canPrintPrettyAsExpr(); 609251662Sdim} 610251662Sdim 611251662Sdimvoid FieldRegion::printPrettyAsExpr(raw_ostream &os) const { 612251662Sdim assert(canPrintPrettyAsExpr()); 613251662Sdim superRegion->printPrettyAsExpr(os); 614239462Sdim os << "." << getDecl()->getName(); 615239462Sdim} 616239462Sdim 617251662Sdimvoid FieldRegion::printPretty(raw_ostream &os) const { 618251662Sdim if (canPrintPrettyAsExpr()) { 619251662Sdim os << "\'"; 620251662Sdim printPrettyAsExpr(os); 621251662Sdim os << "'"; 622251662Sdim } else { 623251662Sdim os << "field " << "\'" << getDecl()->getName() << "'"; 624251662Sdim } 625251662Sdim return; 626251662Sdim} 627251662Sdim 628251662Sdimbool CXXBaseObjectRegion::canPrintPrettyAsExpr() const { 629251662Sdim return superRegion->canPrintPrettyAsExpr(); 630251662Sdim} 631251662Sdim 632251662Sdimvoid CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const { 633251662Sdim superRegion->printPrettyAsExpr(os); 634251662Sdim} 635251662Sdim 636218887Sdim//===----------------------------------------------------------------------===// 637218887Sdim// MemRegionManager methods. 638218887Sdim//===----------------------------------------------------------------------===// 639218887Sdim 640218887Sdimtemplate <typename REG> 641218887Sdimconst REG *MemRegionManager::LazyAllocate(REG*& region) { 642218887Sdim if (!region) { 643218887Sdim region = (REG*) A.Allocate<REG>(); 644218887Sdim new (region) REG(this); 645218887Sdim } 646218887Sdim 647218887Sdim return region; 648218887Sdim} 649218887Sdim 650218887Sdimtemplate <typename REG, typename ARG> 651218887Sdimconst REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) { 652218887Sdim if (!region) { 653218887Sdim region = (REG*) A.Allocate<REG>(); 654218887Sdim new (region) REG(this, a); 655218887Sdim } 656218887Sdim 657218887Sdim return region; 658218887Sdim} 659218887Sdim 660218887Sdimconst StackLocalsSpaceRegion* 661218887SdimMemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) { 662218887Sdim assert(STC); 663218887Sdim StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC]; 664218887Sdim 665218887Sdim if (R) 666218887Sdim return R; 667218887Sdim 668218887Sdim R = A.Allocate<StackLocalsSpaceRegion>(); 669218887Sdim new (R) StackLocalsSpaceRegion(this, STC); 670218887Sdim return R; 671218887Sdim} 672218887Sdim 673218887Sdimconst StackArgumentsSpaceRegion * 674218887SdimMemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) { 675218887Sdim assert(STC); 676218887Sdim StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC]; 677218887Sdim 678218887Sdim if (R) 679218887Sdim return R; 680218887Sdim 681218887Sdim R = A.Allocate<StackArgumentsSpaceRegion>(); 682218887Sdim new (R) StackArgumentsSpaceRegion(this, STC); 683218887Sdim return R; 684218887Sdim} 685218887Sdim 686218887Sdimconst GlobalsSpaceRegion 687234353Sdim*MemRegionManager::getGlobalsRegion(MemRegion::Kind K, 688234353Sdim const CodeTextRegion *CR) { 689234353Sdim if (!CR) { 690234353Sdim if (K == MemRegion::GlobalSystemSpaceRegionKind) 691234353Sdim return LazyAllocate(SystemGlobals); 692234353Sdim if (K == MemRegion::GlobalImmutableSpaceRegionKind) 693234353Sdim return LazyAllocate(ImmutableGlobals); 694234353Sdim assert(K == MemRegion::GlobalInternalSpaceRegionKind); 695234353Sdim return LazyAllocate(InternalGlobals); 696234353Sdim } 697218887Sdim 698234353Sdim assert(K == MemRegion::StaticGlobalSpaceRegionKind); 699218887Sdim StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR]; 700218887Sdim if (R) 701218887Sdim return R; 702218887Sdim 703218887Sdim R = A.Allocate<StaticGlobalSpaceRegion>(); 704218887Sdim new (R) StaticGlobalSpaceRegion(this, CR); 705218887Sdim return R; 706218887Sdim} 707218887Sdim 708218887Sdimconst HeapSpaceRegion *MemRegionManager::getHeapRegion() { 709218887Sdim return LazyAllocate(heap); 710218887Sdim} 711218887Sdim 712218887Sdimconst MemSpaceRegion *MemRegionManager::getUnknownRegion() { 713218887Sdim return LazyAllocate(unknown); 714218887Sdim} 715218887Sdim 716218887Sdimconst MemSpaceRegion *MemRegionManager::getCodeRegion() { 717218887Sdim return LazyAllocate(code); 718218887Sdim} 719218887Sdim 720218887Sdim//===----------------------------------------------------------------------===// 721218887Sdim// Constructing regions. 722218887Sdim//===----------------------------------------------------------------------===// 723218887Sdimconst StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){ 724218887Sdim return getSubRegion<StringRegion>(Str, getGlobalsRegion()); 725218887Sdim} 726218887Sdim 727234353Sdimconst ObjCStringRegion * 728234353SdimMemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){ 729234353Sdim return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion()); 730234353Sdim} 731234353Sdim 732239462Sdim/// Look through a chain of LocationContexts to either find the 733239462Sdim/// StackFrameContext that matches a DeclContext, or find a VarRegion 734239462Sdim/// for a variable captured by a block. 735239462Sdimstatic llvm::PointerUnion<const StackFrameContext *, const VarRegion *> 736239462SdimgetStackOrCaptureRegionForDeclContext(const LocationContext *LC, 737239462Sdim const DeclContext *DC, 738239462Sdim const VarDecl *VD) { 739239462Sdim while (LC) { 740239462Sdim if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) { 741239462Sdim if (cast<DeclContext>(SFC->getDecl()) == DC) 742239462Sdim return SFC; 743239462Sdim } 744239462Sdim if (const BlockInvocationContext *BC = 745239462Sdim dyn_cast<BlockInvocationContext>(LC)) { 746239462Sdim const BlockDataRegion *BR = 747239462Sdim static_cast<const BlockDataRegion*>(BC->getContextData()); 748239462Sdim // FIXME: This can be made more efficient. 749239462Sdim for (BlockDataRegion::referenced_vars_iterator 750239462Sdim I = BR->referenced_vars_begin(), 751239462Sdim E = BR->referenced_vars_end(); I != E; ++I) { 752239462Sdim if (const VarRegion *VR = dyn_cast<VarRegion>(I.getOriginalRegion())) 753239462Sdim if (VR->getDecl() == VD) 754239462Sdim return cast<VarRegion>(I.getCapturedRegion()); 755239462Sdim } 756239462Sdim } 757239462Sdim 758239462Sdim LC = LC->getParent(); 759239462Sdim } 760239462Sdim return (const StackFrameContext*)0; 761239462Sdim} 762239462Sdim 763218887Sdimconst VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, 764218887Sdim const LocationContext *LC) { 765218887Sdim const MemRegion *sReg = 0; 766218887Sdim 767234353Sdim if (D->hasGlobalStorage() && !D->isStaticLocal()) { 768234353Sdim 769234353Sdim // First handle the globals defined in system headers. 770234353Sdim if (C.getSourceManager().isInSystemHeader(D->getLocation())) { 771234353Sdim // Whitelist the system globals which often DO GET modified, assume the 772234353Sdim // rest are immutable. 773234353Sdim if (D->getName().find("errno") != StringRef::npos) 774234353Sdim sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind); 775234353Sdim else 776234353Sdim sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 777234353Sdim 778234353Sdim // Treat other globals as GlobalInternal unless they are constants. 779234353Sdim } else { 780234353Sdim QualType GQT = D->getType(); 781234353Sdim const Type *GT = GQT.getTypePtrOrNull(); 782234353Sdim // TODO: We could walk the complex types here and see if everything is 783234353Sdim // constified. 784234353Sdim if (GT && GQT.isConstQualified() && GT->isArithmeticType()) 785234353Sdim sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 786234353Sdim else 787234353Sdim sReg = getGlobalsRegion(); 788234353Sdim } 789234353Sdim 790234353Sdim // Finally handle static locals. 791234353Sdim } else { 792218887Sdim // FIXME: Once we implement scope handling, we will need to properly lookup 793218887Sdim // 'D' to the proper LocationContext. 794218887Sdim const DeclContext *DC = D->getDeclContext(); 795239462Sdim llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V = 796239462Sdim getStackOrCaptureRegionForDeclContext(LC, DC, D); 797239462Sdim 798239462Sdim if (V.is<const VarRegion*>()) 799239462Sdim return V.get<const VarRegion*>(); 800239462Sdim 801239462Sdim const StackFrameContext *STC = V.get<const StackFrameContext*>(); 802218887Sdim 803218887Sdim if (!STC) 804218887Sdim sReg = getUnknownRegion(); 805218887Sdim else { 806218887Sdim if (D->hasLocalStorage()) { 807218887Sdim sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) 808218887Sdim ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC)) 809218887Sdim : static_cast<const MemRegion*>(getStackLocalsRegion(STC)); 810218887Sdim } 811218887Sdim else { 812218887Sdim assert(D->isStaticLocal()); 813243830Sdim const Decl *STCD = STC->getDecl(); 814243830Sdim if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD)) 815234353Sdim sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, 816243830Sdim getFunctionTextRegion(cast<NamedDecl>(STCD))); 817243830Sdim else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) { 818263508Sdim // FIXME: The fallback type here is totally bogus -- though it should 819263508Sdim // never be queried, it will prevent uniquing with the real 820263508Sdim // BlockTextRegion. Ideally we'd fix the AST so that we always had a 821263508Sdim // signature. 822263508Sdim QualType T; 823263508Sdim if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) 824263508Sdim T = TSI->getType(); 825263508Sdim else 826263508Sdim T = getContext().getFunctionNoProtoType(getContext().VoidTy); 827263508Sdim 828218887Sdim const BlockTextRegion *BTR = 829263508Sdim getBlockTextRegion(BD, C.getCanonicalType(T), 830263508Sdim STC->getAnalysisDeclContext()); 831234353Sdim sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, 832234353Sdim BTR); 833218887Sdim } 834218887Sdim else { 835218887Sdim sReg = getGlobalsRegion(); 836218887Sdim } 837218887Sdim } 838218887Sdim } 839218887Sdim } 840218887Sdim 841218887Sdim return getSubRegion<VarRegion>(D, sReg); 842218887Sdim} 843218887Sdim 844218887Sdimconst VarRegion *MemRegionManager::getVarRegion(const VarDecl *D, 845218887Sdim const MemRegion *superR) { 846218887Sdim return getSubRegion<VarRegion>(D, superR); 847218887Sdim} 848218887Sdim 849218887Sdimconst BlockDataRegion * 850218887SdimMemRegionManager::getBlockDataRegion(const BlockTextRegion *BC, 851263508Sdim const LocationContext *LC, 852263508Sdim unsigned blockCount) { 853218887Sdim const MemRegion *sReg = 0; 854234353Sdim const BlockDecl *BD = BC->getDecl(); 855234353Sdim if (!BD->hasCaptures()) { 856234353Sdim // This handles 'static' blocks. 857234353Sdim sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 858218887Sdim } 859218887Sdim else { 860234353Sdim if (LC) { 861234353Sdim // FIXME: Once we implement scope handling, we want the parent region 862234353Sdim // to be the scope. 863234353Sdim const StackFrameContext *STC = LC->getCurrentStackFrame(); 864234353Sdim assert(STC); 865234353Sdim sReg = getStackLocalsRegion(STC); 866234353Sdim } 867234353Sdim else { 868234353Sdim // We allow 'LC' to be NULL for cases where want BlockDataRegions 869234353Sdim // without context-sensitivity. 870234353Sdim sReg = getUnknownRegion(); 871234353Sdim } 872218887Sdim } 873218887Sdim 874263508Sdim return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg); 875218887Sdim} 876218887Sdim 877263508Sdimconst CXXTempObjectRegion * 878263508SdimMemRegionManager::getCXXStaticTempObjectRegion(const Expr *Ex) { 879263508Sdim return getSubRegion<CXXTempObjectRegion>( 880263508Sdim Ex, getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, NULL)); 881263508Sdim} 882263508Sdim 883218887Sdimconst CompoundLiteralRegion* 884226633SdimMemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL, 885218887Sdim const LocationContext *LC) { 886218887Sdim 887218887Sdim const MemRegion *sReg = 0; 888218887Sdim 889218887Sdim if (CL->isFileScope()) 890218887Sdim sReg = getGlobalsRegion(); 891218887Sdim else { 892218887Sdim const StackFrameContext *STC = LC->getCurrentStackFrame(); 893218887Sdim assert(STC); 894218887Sdim sReg = getStackLocalsRegion(STC); 895218887Sdim } 896218887Sdim 897218887Sdim return getSubRegion<CompoundLiteralRegion>(CL, sReg); 898218887Sdim} 899218887Sdim 900218887Sdimconst ElementRegion* 901218887SdimMemRegionManager::getElementRegion(QualType elementType, NonLoc Idx, 902218887Sdim const MemRegion* superRegion, 903226633Sdim ASTContext &Ctx){ 904218887Sdim 905218887Sdim QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType(); 906218887Sdim 907218887Sdim llvm::FoldingSetNodeID ID; 908218887Sdim ElementRegion::ProfileRegion(ID, T, Idx, superRegion); 909218887Sdim 910226633Sdim void *InsertPos; 911218887Sdim MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos); 912218887Sdim ElementRegion* R = cast_or_null<ElementRegion>(data); 913218887Sdim 914218887Sdim if (!R) { 915218887Sdim R = (ElementRegion*) A.Allocate<ElementRegion>(); 916218887Sdim new (R) ElementRegion(T, Idx, superRegion); 917218887Sdim Regions.InsertNode(R, InsertPos); 918218887Sdim } 919218887Sdim 920218887Sdim return R; 921218887Sdim} 922218887Sdim 923218887Sdimconst FunctionTextRegion * 924243830SdimMemRegionManager::getFunctionTextRegion(const NamedDecl *FD) { 925218887Sdim return getSubRegion<FunctionTextRegion>(FD, getCodeRegion()); 926218887Sdim} 927218887Sdim 928218887Sdimconst BlockTextRegion * 929218887SdimMemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy, 930234353Sdim AnalysisDeclContext *AC) { 931218887Sdim return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion()); 932218887Sdim} 933218887Sdim 934218887Sdim 935218887Sdim/// getSymbolicRegion - Retrieve or create a "symbolic" memory region. 936218887Sdimconst SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) { 937218887Sdim return getSubRegion<SymbolicRegion>(sym, getUnknownRegion()); 938218887Sdim} 939218887Sdim 940239462Sdimconst SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) { 941239462Sdim return getSubRegion<SymbolicRegion>(Sym, getHeapRegion()); 942239462Sdim} 943239462Sdim 944218887Sdimconst FieldRegion* 945226633SdimMemRegionManager::getFieldRegion(const FieldDecl *d, 946218887Sdim const MemRegion* superRegion){ 947218887Sdim return getSubRegion<FieldRegion>(d, superRegion); 948218887Sdim} 949218887Sdim 950218887Sdimconst ObjCIvarRegion* 951226633SdimMemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d, 952218887Sdim const MemRegion* superRegion) { 953218887Sdim return getSubRegion<ObjCIvarRegion>(d, superRegion); 954218887Sdim} 955218887Sdim 956218887Sdimconst CXXTempObjectRegion* 957218887SdimMemRegionManager::getCXXTempObjectRegion(Expr const *E, 958218887Sdim LocationContext const *LC) { 959218887Sdim const StackFrameContext *SFC = LC->getCurrentStackFrame(); 960218887Sdim assert(SFC); 961218887Sdim return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC)); 962218887Sdim} 963218887Sdim 964249423Sdim/// Checks whether \p BaseClass is a valid virtual or direct non-virtual base 965249423Sdim/// class of the type of \p Super. 966249423Sdimstatic bool isValidBaseClass(const CXXRecordDecl *BaseClass, 967249423Sdim const TypedValueRegion *Super, 968249423Sdim bool IsVirtual) { 969249423Sdim BaseClass = BaseClass->getCanonicalDecl(); 970249423Sdim 971249423Sdim const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl(); 972249423Sdim if (!Class) 973249423Sdim return true; 974249423Sdim 975249423Sdim if (IsVirtual) 976249423Sdim return Class->isVirtuallyDerivedFrom(BaseClass); 977249423Sdim 978249423Sdim for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(), 979249423Sdim E = Class->bases_end(); 980249423Sdim I != E; ++I) { 981249423Sdim if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass) 982249423Sdim return true; 983249423Sdim } 984249423Sdim 985249423Sdim return false; 986249423Sdim} 987249423Sdim 988218887Sdimconst CXXBaseObjectRegion * 989249423SdimMemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD, 990249423Sdim const MemRegion *Super, 991249423Sdim bool IsVirtual) { 992249423Sdim if (isa<TypedValueRegion>(Super)) { 993249423Sdim assert(isValidBaseClass(RD, dyn_cast<TypedValueRegion>(Super), IsVirtual)); 994263508Sdim (void)&isValidBaseClass; 995239462Sdim 996249423Sdim if (IsVirtual) { 997249423Sdim // Virtual base regions should not be layered, since the layout rules 998249423Sdim // are different. 999249423Sdim while (const CXXBaseObjectRegion *Base = 1000249423Sdim dyn_cast<CXXBaseObjectRegion>(Super)) { 1001249423Sdim Super = Base->getSuperRegion(); 1002239462Sdim } 1003249423Sdim assert(Super && !isa<MemSpaceRegion>(Super)); 1004239462Sdim } 1005239462Sdim } 1006239462Sdim 1007249423Sdim return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super); 1008218887Sdim} 1009218887Sdim 1010218887Sdimconst CXXThisRegion* 1011218887SdimMemRegionManager::getCXXThisRegion(QualType thisPointerTy, 1012218887Sdim const LocationContext *LC) { 1013218887Sdim const StackFrameContext *STC = LC->getCurrentStackFrame(); 1014218887Sdim assert(STC); 1015218887Sdim const PointerType *PT = thisPointerTy->getAs<PointerType>(); 1016218887Sdim assert(PT); 1017218887Sdim return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC)); 1018218887Sdim} 1019218887Sdim 1020218887Sdimconst AllocaRegion* 1021226633SdimMemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt, 1022218887Sdim const LocationContext *LC) { 1023218887Sdim const StackFrameContext *STC = LC->getCurrentStackFrame(); 1024218887Sdim assert(STC); 1025218887Sdim return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC)); 1026218887Sdim} 1027218887Sdim 1028218887Sdimconst MemSpaceRegion *MemRegion::getMemorySpace() const { 1029218887Sdim const MemRegion *R = this; 1030218887Sdim const SubRegion* SR = dyn_cast<SubRegion>(this); 1031218887Sdim 1032218887Sdim while (SR) { 1033218887Sdim R = SR->getSuperRegion(); 1034218887Sdim SR = dyn_cast<SubRegion>(R); 1035218887Sdim } 1036218887Sdim 1037218887Sdim return dyn_cast<MemSpaceRegion>(R); 1038218887Sdim} 1039218887Sdim 1040218887Sdimbool MemRegion::hasStackStorage() const { 1041218887Sdim return isa<StackSpaceRegion>(getMemorySpace()); 1042218887Sdim} 1043218887Sdim 1044218887Sdimbool MemRegion::hasStackNonParametersStorage() const { 1045218887Sdim return isa<StackLocalsSpaceRegion>(getMemorySpace()); 1046218887Sdim} 1047218887Sdim 1048218887Sdimbool MemRegion::hasStackParametersStorage() const { 1049218887Sdim return isa<StackArgumentsSpaceRegion>(getMemorySpace()); 1050218887Sdim} 1051218887Sdim 1052218887Sdimbool MemRegion::hasGlobalsOrParametersStorage() const { 1053218887Sdim const MemSpaceRegion *MS = getMemorySpace(); 1054218887Sdim return isa<StackArgumentsSpaceRegion>(MS) || 1055218887Sdim isa<GlobalsSpaceRegion>(MS); 1056218887Sdim} 1057218887Sdim 1058218887Sdim// getBaseRegion strips away all elements and fields, and get the base region 1059218887Sdim// of them. 1060218887Sdimconst MemRegion *MemRegion::getBaseRegion() const { 1061218887Sdim const MemRegion *R = this; 1062218887Sdim while (true) { 1063218887Sdim switch (R->getKind()) { 1064218887Sdim case MemRegion::ElementRegionKind: 1065218887Sdim case MemRegion::FieldRegionKind: 1066218887Sdim case MemRegion::ObjCIvarRegionKind: 1067218887Sdim case MemRegion::CXXBaseObjectRegionKind: 1068218887Sdim R = cast<SubRegion>(R)->getSuperRegion(); 1069218887Sdim continue; 1070218887Sdim default: 1071218887Sdim break; 1072218887Sdim } 1073218887Sdim break; 1074218887Sdim } 1075218887Sdim return R; 1076218887Sdim} 1077218887Sdim 1078243830Sdimbool MemRegion::isSubRegionOf(const MemRegion *R) const { 1079243830Sdim return false; 1080243830Sdim} 1081243830Sdim 1082218887Sdim//===----------------------------------------------------------------------===// 1083218887Sdim// View handling. 1084218887Sdim//===----------------------------------------------------------------------===// 1085218887Sdim 1086239462Sdimconst MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const { 1087218887Sdim const MemRegion *R = this; 1088218887Sdim while (true) { 1089239462Sdim switch (R->getKind()) { 1090239462Sdim case ElementRegionKind: { 1091239462Sdim const ElementRegion *ER = cast<ElementRegion>(R); 1092239462Sdim if (!ER->getIndex().isZeroConstant()) 1093239462Sdim return R; 1094239462Sdim R = ER->getSuperRegion(); 1095239462Sdim break; 1096218887Sdim } 1097239462Sdim case CXXBaseObjectRegionKind: 1098239462Sdim if (!StripBaseCasts) 1099239462Sdim return R; 1100239462Sdim R = cast<CXXBaseObjectRegion>(R)->getSuperRegion(); 1101239462Sdim break; 1102239462Sdim default: 1103239462Sdim return R; 1104239462Sdim } 1105218887Sdim } 1106218887Sdim} 1107218887Sdim 1108251662Sdimconst SymbolicRegion *MemRegion::getSymbolicBase() const { 1109251662Sdim const SubRegion *SubR = dyn_cast<SubRegion>(this); 1110251662Sdim 1111251662Sdim while (SubR) { 1112251662Sdim if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR)) 1113251662Sdim return SymR; 1114251662Sdim SubR = dyn_cast<SubRegion>(SubR->getSuperRegion()); 1115251662Sdim } 1116251662Sdim return 0; 1117251662Sdim} 1118251662Sdim 1119218887Sdim// FIXME: Merge with the implementation of the same method in Store.cpp 1120218887Sdimstatic bool IsCompleteType(ASTContext &Ctx, QualType Ty) { 1121218887Sdim if (const RecordType *RT = Ty->getAs<RecordType>()) { 1122218887Sdim const RecordDecl *D = RT->getDecl(); 1123218887Sdim if (!D->getDefinition()) 1124218887Sdim return false; 1125218887Sdim } 1126218887Sdim 1127218887Sdim return true; 1128218887Sdim} 1129218887Sdim 1130218887SdimRegionRawOffset ElementRegion::getAsArrayOffset() const { 1131218887Sdim CharUnits offset = CharUnits::Zero(); 1132218887Sdim const ElementRegion *ER = this; 1133218887Sdim const MemRegion *superR = NULL; 1134218887Sdim ASTContext &C = getContext(); 1135218887Sdim 1136218887Sdim // FIXME: Handle multi-dimensional arrays. 1137218887Sdim 1138218887Sdim while (ER) { 1139218887Sdim superR = ER->getSuperRegion(); 1140218887Sdim 1141218887Sdim // FIXME: generalize to symbolic offsets. 1142218887Sdim SVal index = ER->getIndex(); 1143249423Sdim if (Optional<nonloc::ConcreteInt> CI = index.getAs<nonloc::ConcreteInt>()) { 1144218887Sdim // Update the offset. 1145218887Sdim int64_t i = CI->getValue().getSExtValue(); 1146218887Sdim 1147218887Sdim if (i != 0) { 1148218887Sdim QualType elemType = ER->getElementType(); 1149218887Sdim 1150218887Sdim // If we are pointing to an incomplete type, go no further. 1151218887Sdim if (!IsCompleteType(C, elemType)) { 1152218887Sdim superR = ER; 1153218887Sdim break; 1154218887Sdim } 1155218887Sdim 1156218887Sdim CharUnits size = C.getTypeSizeInChars(elemType); 1157218887Sdim offset += (i * size); 1158218887Sdim } 1159218887Sdim 1160218887Sdim // Go to the next ElementRegion (if any). 1161218887Sdim ER = dyn_cast<ElementRegion>(superR); 1162218887Sdim continue; 1163218887Sdim } 1164218887Sdim 1165218887Sdim return NULL; 1166218887Sdim } 1167218887Sdim 1168218887Sdim assert(superR && "super region cannot be NULL"); 1169218887Sdim return RegionRawOffset(superR, offset); 1170218887Sdim} 1171218887Sdim 1172249423Sdim 1173249423Sdim/// Returns true if \p Base is an immediate base class of \p Child 1174249423Sdimstatic bool isImmediateBase(const CXXRecordDecl *Child, 1175249423Sdim const CXXRecordDecl *Base) { 1176249423Sdim // Note that we do NOT canonicalize the base class here, because 1177249423Sdim // ASTRecordLayout doesn't either. If that leads us down the wrong path, 1178249423Sdim // so be it; at least we won't crash. 1179249423Sdim for (CXXRecordDecl::base_class_const_iterator I = Child->bases_begin(), 1180249423Sdim E = Child->bases_end(); 1181249423Sdim I != E; ++I) { 1182249423Sdim if (I->getType()->getAsCXXRecordDecl() == Base) 1183249423Sdim return true; 1184249423Sdim } 1185249423Sdim 1186249423Sdim return false; 1187249423Sdim} 1188249423Sdim 1189218887SdimRegionOffset MemRegion::getAsOffset() const { 1190218887Sdim const MemRegion *R = this; 1191239462Sdim const MemRegion *SymbolicOffsetBase = 0; 1192218887Sdim int64_t Offset = 0; 1193218887Sdim 1194218887Sdim while (1) { 1195218887Sdim switch (R->getKind()) { 1196249423Sdim case GenericMemSpaceRegionKind: 1197249423Sdim case StackLocalsSpaceRegionKind: 1198249423Sdim case StackArgumentsSpaceRegionKind: 1199249423Sdim case HeapSpaceRegionKind: 1200249423Sdim case UnknownSpaceRegionKind: 1201249423Sdim case StaticGlobalSpaceRegionKind: 1202249423Sdim case GlobalInternalSpaceRegionKind: 1203249423Sdim case GlobalSystemSpaceRegionKind: 1204249423Sdim case GlobalImmutableSpaceRegionKind: 1205249423Sdim // Stores can bind directly to a region space to set a default value. 1206249423Sdim assert(Offset == 0 && !SymbolicOffsetBase); 1207249423Sdim goto Finish; 1208239462Sdim 1209249423Sdim case FunctionTextRegionKind: 1210249423Sdim case BlockTextRegionKind: 1211249423Sdim case BlockDataRegionKind: 1212249423Sdim // These will never have bindings, but may end up having values requested 1213249423Sdim // if the user does some strange casting. 1214249423Sdim if (Offset != 0) 1215249423Sdim SymbolicOffsetBase = R; 1216249423Sdim goto Finish; 1217249423Sdim 1218218887Sdim case SymbolicRegionKind: 1219218887Sdim case AllocaRegionKind: 1220218887Sdim case CompoundLiteralRegionKind: 1221218887Sdim case CXXThisRegionKind: 1222218887Sdim case StringRegionKind: 1223249423Sdim case ObjCStringRegionKind: 1224218887Sdim case VarRegionKind: 1225218887Sdim case CXXTempObjectRegionKind: 1226249423Sdim // Usual base regions. 1227218887Sdim goto Finish; 1228239462Sdim 1229239462Sdim case ObjCIvarRegionKind: 1230239462Sdim // This is a little strange, but it's a compromise between 1231239462Sdim // ObjCIvarRegions having unknown compile-time offsets (when using the 1232239462Sdim // non-fragile runtime) and yet still being distinct, non-overlapping 1233239462Sdim // regions. Thus we treat them as "like" base regions for the purposes 1234239462Sdim // of computing offsets. 1235239462Sdim goto Finish; 1236239462Sdim 1237239462Sdim case CXXBaseObjectRegionKind: { 1238239462Sdim const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R); 1239239462Sdim R = BOR->getSuperRegion(); 1240239462Sdim 1241239462Sdim QualType Ty; 1242249423Sdim bool RootIsSymbolic = false; 1243239462Sdim if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) { 1244239462Sdim Ty = TVR->getDesugaredValueType(getContext()); 1245239462Sdim } else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) { 1246239462Sdim // If our base region is symbolic, we don't know what type it really is. 1247239462Sdim // Pretend the type of the symbol is the true dynamic type. 1248239462Sdim // (This will at least be self-consistent for the life of the symbol.) 1249243830Sdim Ty = SR->getSymbol()->getType()->getPointeeType(); 1250249423Sdim RootIsSymbolic = true; 1251239462Sdim } 1252239462Sdim 1253239462Sdim const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl(); 1254239462Sdim if (!Child) { 1255239462Sdim // We cannot compute the offset of the base class. 1256239462Sdim SymbolicOffsetBase = R; 1257239462Sdim } 1258239462Sdim 1259249423Sdim if (RootIsSymbolic) { 1260249423Sdim // Base layers on symbolic regions may not be type-correct. 1261249423Sdim // Double-check the inheritance here, and revert to a symbolic offset 1262249423Sdim // if it's invalid (e.g. due to a reinterpret_cast). 1263249423Sdim if (BOR->isVirtual()) { 1264249423Sdim if (!Child->isVirtuallyDerivedFrom(BOR->getDecl())) 1265249423Sdim SymbolicOffsetBase = R; 1266249423Sdim } else { 1267249423Sdim if (!isImmediateBase(Child, BOR->getDecl())) 1268249423Sdim SymbolicOffsetBase = R; 1269249423Sdim } 1270249423Sdim } 1271249423Sdim 1272239462Sdim // Don't bother calculating precise offsets if we already have a 1273239462Sdim // symbolic offset somewhere in the chain. 1274239462Sdim if (SymbolicOffsetBase) 1275239462Sdim continue; 1276239462Sdim 1277249423Sdim CharUnits BaseOffset; 1278239462Sdim const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child); 1279249423Sdim if (BOR->isVirtual()) 1280249423Sdim BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl()); 1281239462Sdim else 1282249423Sdim BaseOffset = Layout.getBaseClassOffset(BOR->getDecl()); 1283239462Sdim 1284239462Sdim // The base offset is in chars, not in bits. 1285239462Sdim Offset += BaseOffset.getQuantity() * getContext().getCharWidth(); 1286239462Sdim break; 1287239462Sdim } 1288218887Sdim case ElementRegionKind: { 1289218887Sdim const ElementRegion *ER = cast<ElementRegion>(R); 1290239462Sdim R = ER->getSuperRegion(); 1291239462Sdim 1292218887Sdim QualType EleTy = ER->getValueType(); 1293239462Sdim if (!IsCompleteType(getContext(), EleTy)) { 1294239462Sdim // We cannot compute the offset of the base class. 1295239462Sdim SymbolicOffsetBase = R; 1296239462Sdim continue; 1297239462Sdim } 1298218887Sdim 1299218887Sdim SVal Index = ER->getIndex(); 1300249423Sdim if (Optional<nonloc::ConcreteInt> CI = 1301249423Sdim Index.getAs<nonloc::ConcreteInt>()) { 1302239462Sdim // Don't bother calculating precise offsets if we already have a 1303239462Sdim // symbolic offset somewhere in the chain. 1304239462Sdim if (SymbolicOffsetBase) 1305239462Sdim continue; 1306239462Sdim 1307218887Sdim int64_t i = CI->getValue().getSExtValue(); 1308239462Sdim // This type size is in bits. 1309239462Sdim Offset += i * getContext().getTypeSize(EleTy); 1310218887Sdim } else { 1311218887Sdim // We cannot compute offset for non-concrete index. 1312239462Sdim SymbolicOffsetBase = R; 1313218887Sdim } 1314218887Sdim break; 1315218887Sdim } 1316218887Sdim case FieldRegionKind: { 1317218887Sdim const FieldRegion *FR = cast<FieldRegion>(R); 1318239462Sdim R = FR->getSuperRegion(); 1319239462Sdim 1320218887Sdim const RecordDecl *RD = FR->getDecl()->getParent(); 1321243830Sdim if (RD->isUnion() || !RD->isCompleteDefinition()) { 1322218887Sdim // We cannot compute offset for incomplete type. 1323243830Sdim // For unions, we could treat everything as offset 0, but we'd rather 1324243830Sdim // treat each field as a symbolic offset so they aren't stored on top 1325243830Sdim // of each other, since we depend on things in typed regions actually 1326243830Sdim // matching their types. 1327239462Sdim SymbolicOffsetBase = R; 1328239462Sdim } 1329239462Sdim 1330239462Sdim // Don't bother calculating precise offsets if we already have a 1331239462Sdim // symbolic offset somewhere in the chain. 1332239462Sdim if (SymbolicOffsetBase) 1333239462Sdim continue; 1334239462Sdim 1335218887Sdim // Get the field number. 1336218887Sdim unsigned idx = 0; 1337218887Sdim for (RecordDecl::field_iterator FI = RD->field_begin(), 1338218887Sdim FE = RD->field_end(); FI != FE; ++FI, ++idx) 1339218887Sdim if (FR->getDecl() == *FI) 1340218887Sdim break; 1341218887Sdim 1342218887Sdim const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 1343218887Sdim // This is offset in bits. 1344218887Sdim Offset += Layout.getFieldOffset(idx); 1345218887Sdim break; 1346218887Sdim } 1347218887Sdim } 1348218887Sdim } 1349218887Sdim 1350218887Sdim Finish: 1351239462Sdim if (SymbolicOffsetBase) 1352239462Sdim return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic); 1353218887Sdim return RegionOffset(R, Offset); 1354218887Sdim} 1355218887Sdim 1356218887Sdim//===----------------------------------------------------------------------===// 1357218887Sdim// BlockDataRegion 1358218887Sdim//===----------------------------------------------------------------------===// 1359218887Sdim 1360249423Sdimstd::pair<const VarRegion *, const VarRegion *> 1361249423SdimBlockDataRegion::getCaptureRegions(const VarDecl *VD) { 1362249423Sdim MemRegionManager &MemMgr = *getMemRegionManager(); 1363249423Sdim const VarRegion *VR = 0; 1364249423Sdim const VarRegion *OriginalVR = 0; 1365249423Sdim 1366249423Sdim if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage()) { 1367249423Sdim VR = MemMgr.getVarRegion(VD, this); 1368249423Sdim OriginalVR = MemMgr.getVarRegion(VD, LC); 1369249423Sdim } 1370249423Sdim else { 1371249423Sdim if (LC) { 1372249423Sdim VR = MemMgr.getVarRegion(VD, LC); 1373249423Sdim OriginalVR = VR; 1374249423Sdim } 1375249423Sdim else { 1376249423Sdim VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion()); 1377249423Sdim OriginalVR = MemMgr.getVarRegion(VD, LC); 1378249423Sdim } 1379249423Sdim } 1380249423Sdim return std::make_pair(VR, OriginalVR); 1381249423Sdim} 1382249423Sdim 1383218887Sdimvoid BlockDataRegion::LazyInitializeReferencedVars() { 1384218887Sdim if (ReferencedVars) 1385218887Sdim return; 1386218887Sdim 1387234353Sdim AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext(); 1388234353Sdim AnalysisDeclContext::referenced_decls_iterator I, E; 1389218887Sdim llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl()); 1390218887Sdim 1391218887Sdim if (I == E) { 1392218887Sdim ReferencedVars = (void*) 0x1; 1393218887Sdim return; 1394218887Sdim } 1395218887Sdim 1396218887Sdim MemRegionManager &MemMgr = *getMemRegionManager(); 1397218887Sdim llvm::BumpPtrAllocator &A = MemMgr.getAllocator(); 1398218887Sdim BumpVectorContext BC(A); 1399218887Sdim 1400218887Sdim typedef BumpVector<const MemRegion*> VarVec; 1401218887Sdim VarVec *BV = (VarVec*) A.Allocate<VarVec>(); 1402218887Sdim new (BV) VarVec(BC, E - I); 1403239462Sdim VarVec *BVOriginal = (VarVec*) A.Allocate<VarVec>(); 1404239462Sdim new (BVOriginal) VarVec(BC, E - I); 1405218887Sdim 1406218887Sdim for ( ; I != E; ++I) { 1407218887Sdim const VarRegion *VR = 0; 1408239462Sdim const VarRegion *OriginalVR = 0; 1409249423Sdim llvm::tie(VR, OriginalVR) = getCaptureRegions(*I); 1410218887Sdim assert(VR); 1411239462Sdim assert(OriginalVR); 1412218887Sdim BV->push_back(VR, BC); 1413239462Sdim BVOriginal->push_back(OriginalVR, BC); 1414218887Sdim } 1415218887Sdim 1416218887Sdim ReferencedVars = BV; 1417239462Sdim OriginalVars = BVOriginal; 1418218887Sdim} 1419218887Sdim 1420218887SdimBlockDataRegion::referenced_vars_iterator 1421218887SdimBlockDataRegion::referenced_vars_begin() const { 1422218887Sdim const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); 1423218887Sdim 1424218887Sdim BumpVector<const MemRegion*> *Vec = 1425218887Sdim static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); 1426218887Sdim 1427239462Sdim if (Vec == (void*) 0x1) 1428239462Sdim return BlockDataRegion::referenced_vars_iterator(0, 0); 1429239462Sdim 1430239462Sdim BumpVector<const MemRegion*> *VecOriginal = 1431239462Sdim static_cast<BumpVector<const MemRegion*>*>(OriginalVars); 1432239462Sdim 1433239462Sdim return BlockDataRegion::referenced_vars_iterator(Vec->begin(), 1434239462Sdim VecOriginal->begin()); 1435218887Sdim} 1436218887Sdim 1437218887SdimBlockDataRegion::referenced_vars_iterator 1438218887SdimBlockDataRegion::referenced_vars_end() const { 1439218887Sdim const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); 1440218887Sdim 1441218887Sdim BumpVector<const MemRegion*> *Vec = 1442218887Sdim static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); 1443218887Sdim 1444239462Sdim if (Vec == (void*) 0x1) 1445239462Sdim return BlockDataRegion::referenced_vars_iterator(0, 0); 1446239462Sdim 1447239462Sdim BumpVector<const MemRegion*> *VecOriginal = 1448239462Sdim static_cast<BumpVector<const MemRegion*>*>(OriginalVars); 1449239462Sdim 1450239462Sdim return BlockDataRegion::referenced_vars_iterator(Vec->end(), 1451239462Sdim VecOriginal->end()); 1452218887Sdim} 1453249423Sdim 1454249423Sdimconst VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const { 1455249423Sdim for (referenced_vars_iterator I = referenced_vars_begin(), 1456249423Sdim E = referenced_vars_end(); 1457249423Sdim I != E; ++I) { 1458249423Sdim if (I.getCapturedRegion() == R) 1459249423Sdim return I.getOriginalRegion(); 1460249423Sdim } 1461249423Sdim return 0; 1462249423Sdim} 1463263508Sdim 1464263508Sdim//===----------------------------------------------------------------------===// 1465263508Sdim// RegionAndSymbolInvalidationTraits 1466263508Sdim//===----------------------------------------------------------------------===// 1467263508Sdim 1468263508Sdimvoid RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym, 1469263508Sdim InvalidationKinds IK) { 1470263508Sdim SymTraitsMap[Sym] |= IK; 1471263508Sdim} 1472263508Sdim 1473263508Sdimvoid RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR, 1474263508Sdim InvalidationKinds IK) { 1475263508Sdim assert(MR); 1476263508Sdim if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) 1477263508Sdim setTrait(SR->getSymbol(), IK); 1478263508Sdim else 1479263508Sdim MRTraitsMap[MR] |= IK; 1480263508Sdim} 1481263508Sdim 1482263508Sdimbool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym, 1483263508Sdim InvalidationKinds IK) { 1484263508Sdim const_symbol_iterator I = SymTraitsMap.find(Sym); 1485263508Sdim if (I != SymTraitsMap.end()) 1486263508Sdim return I->second & IK; 1487263508Sdim 1488263508Sdim return false; 1489263508Sdim} 1490263508Sdim 1491263508Sdimbool RegionAndSymbolInvalidationTraits::hasTrait(const MemRegion *MR, 1492263508Sdim InvalidationKinds IK) { 1493263508Sdim if (!MR) 1494263508Sdim return false; 1495263508Sdim 1496263508Sdim if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) 1497263508Sdim return hasTrait(SR->getSymbol(), IK); 1498263508Sdim 1499263508Sdim const_region_iterator I = MRTraitsMap.find(MR); 1500263508Sdim if (I != MRTraitsMap.end()) 1501263508Sdim return I->second & IK; 1502263508Sdim 1503263508Sdim return false; 1504263508Sdim} 1505