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" 17252723Sdim#include "clang/AST/Attr.h" 18218887Sdim#include "clang/AST/CharUnits.h" 19235633Sdim#include "clang/AST/DeclObjC.h" 20218887Sdim#include "clang/AST/RecordLayout.h" 21252723Sdim#include "clang/Analysis/AnalysisContext.h" 22252723Sdim#include "clang/Analysis/Support/BumpVector.h" 23235633Sdim#include "clang/Basic/SourceManager.h" 24252723Sdim#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); 44226890Sdim 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); 62226890Sdim 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); 83226890Sdim 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); 102226890Sdim 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); 121226890Sdim 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 183245431SdimDefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const { 184226890Sdim ASTContext &Ctx = svalBuilder.getContext(); 185218887Sdim QualType T = getDesugaredValueType(Ctx); 186218887Sdim 187218887Sdim if (isa<VariableArrayType>(T)) 188218887Sdim return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); 189263509Sdim 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 { 198252723Sdim // Force callers to deal with bitfields explicitly. 199252723Sdim if (getDecl()->isBitField()) 200252723Sdim return UnknownVal(); 201252723Sdim 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 229235633SdimObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg) 230235633Sdim : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {} 231235633Sdim 232235633Sdimconst ObjCIvarDecl *ObjCIvarRegion::getDecl() const { 233235633Sdim return cast<ObjCIvarDecl>(D); 234235633Sdim} 235235633Sdim 236235633SdimQualType ObjCIvarRegion::getValueType() const { 237235633Sdim return getDecl()->getType(); 238235633Sdim} 239235633Sdim 240218887SdimQualType CXXBaseObjectRegion::getValueType() const { 241252723Sdim 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 270235633Sdimvoid ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 271235633Sdim const ObjCStringLiteral* Str, 272235633Sdim const MemRegion* superRegion) { 273235633Sdim ID.AddInteger((unsigned) ObjCStringRegionKind); 274235633Sdim ID.AddPointer(Str); 275235633Sdim ID.AddPointer(superRegion); 276235633Sdim} 277235633Sdim 278218887Sdimvoid AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 279226890Sdim const Expr *Ex, unsigned cnt, 280252723Sdim const MemRegion *superRegion) { 281218887Sdim ID.AddInteger((unsigned) AllocaRegionKind); 282218887Sdim ID.AddPointer(Ex); 283218887Sdim ID.AddInteger(cnt); 284252723Sdim 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, 296226890Sdim 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 315235633Sdimvoid ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 316235633Sdim const ObjCIvarDecl *ivd, 317235633Sdim const MemRegion* superRegion) { 318235633Sdim DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind); 319235633Sdim} 320235633Sdim 321226890Sdimvoid 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, 361245431Sdim 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, 373235633Sdim 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, 386263509Sdim unsigned BlkCount, 387218887Sdim const MemRegion *sReg) { 388218887Sdim ID.AddInteger(MemRegion::BlockDataRegionKind); 389218887Sdim ID.AddPointer(BC); 390218887Sdim ID.AddPointer(LC); 391263509Sdim ID.AddInteger(BlkCount); 392218887Sdim ID.AddPointer(sReg); 393218887Sdim} 394218887Sdim 395218887Sdimvoid BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const { 396263509Sdim 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, 411252723Sdim const CXXRecordDecl *RD, 412252723Sdim bool IsVirtual, 413252723Sdim const MemRegion *SReg) { 414252723Sdim ID.AddPointer(RD); 415252723Sdim ID.AddBoolean(IsVirtual); 416252723Sdim ID.AddPointer(SReg); 417218887Sdim} 418218887Sdim 419218887Sdimvoid CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const { 420252723Sdim ProfileRegion(ID, getDecl(), isVirtual(), superRegion); 421218887Sdim} 422218887Sdim 423218887Sdim//===----------------------------------------------------------------------===// 424235633Sdim// Region anchors. 425235633Sdim//===----------------------------------------------------------------------===// 426235633Sdim 427235633Sdimvoid GlobalsSpaceRegion::anchor() { } 428235633Sdimvoid HeapSpaceRegion::anchor() { } 429235633Sdimvoid UnknownSpaceRegion::anchor() { } 430235633Sdimvoid StackLocalsSpaceRegion::anchor() { } 431235633Sdimvoid StackArgumentsSpaceRegion::anchor() { } 432235633Sdimvoid TypedRegion::anchor() { } 433235633Sdimvoid TypedValueRegion::anchor() { } 434235633Sdimvoid CodeTextRegion::anchor() { } 435235633Sdimvoid SubRegion::anchor() { } 436235633Sdim 437235633Sdim//===----------------------------------------------------------------------===// 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 452226890Sdimvoid MemRegion::dumpToStream(raw_ostream &os) const { 453218887Sdim os << "<Unknown Region>"; 454218887Sdim} 455218887Sdim 456226890Sdimvoid AllocaRegion::dumpToStream(raw_ostream &os) const { 457245431Sdim os << "alloca{" << (const void*) Ex << ',' << Cnt << '}'; 458218887Sdim} 459218887Sdim 460226890Sdimvoid FunctionTextRegion::dumpToStream(raw_ostream &os) const { 461218887Sdim os << "code{" << getDecl()->getDeclName().getAsString() << '}'; 462218887Sdim} 463218887Sdim 464226890Sdimvoid BlockTextRegion::dumpToStream(raw_ostream &os) const { 465245431Sdim os << "block_code{" << (const void*) this << '}'; 466218887Sdim} 467218887Sdim 468226890Sdimvoid BlockDataRegion::dumpToStream(raw_ostream &os) const { 469263509Sdim os << "block_data{" << BC; 470263509Sdim os << "; "; 471263509Sdim for (BlockDataRegion::referenced_vars_iterator 472263509Sdim I = referenced_vars_begin(), 473263509Sdim E = referenced_vars_end(); I != E; ++I) 474263509Sdim os << "(" << I.getCapturedRegion() << "," << 475263509Sdim I.getOriginalRegion() << ") "; 476263509Sdim os << '}'; 477218887Sdim} 478218887Sdim 479226890Sdimvoid CompoundLiteralRegion::dumpToStream(raw_ostream &os) const { 480218887Sdim // FIXME: More elaborate pretty-printing. 481245431Sdim os << "{ " << (const void*) CL << " }"; 482218887Sdim} 483218887Sdim 484226890Sdimvoid CXXTempObjectRegion::dumpToStream(raw_ostream &os) const { 485226890Sdim os << "temp_object{" << getValueType().getAsString() << ',' 486245431Sdim << (const void*) Ex << '}'; 487218887Sdim} 488218887Sdim 489226890Sdimvoid CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const { 490252723Sdim os << "base{" << superRegion << ',' << getDecl()->getName() << '}'; 491218887Sdim} 492218887Sdim 493226890Sdimvoid CXXThisRegion::dumpToStream(raw_ostream &os) const { 494218887Sdim os << "this"; 495218887Sdim} 496218887Sdim 497226890Sdimvoid ElementRegion::dumpToStream(raw_ostream &os) const { 498218887Sdim os << "element{" << superRegion << ',' 499218887Sdim << Index << ',' << getElementType().getAsString() << '}'; 500218887Sdim} 501218887Sdim 502226890Sdimvoid FieldRegion::dumpToStream(raw_ostream &os) const { 503226890Sdim os << superRegion << "->" << *getDecl(); 504218887Sdim} 505218887Sdim 506226890Sdimvoid ObjCIvarRegion::dumpToStream(raw_ostream &os) const { 507226890Sdim os << "ivar{" << superRegion << ',' << *getDecl() << '}'; 508218887Sdim} 509218887Sdim 510226890Sdimvoid StringRegion::dumpToStream(raw_ostream &os) const { 511235633Sdim Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts())); 512218887Sdim} 513218887Sdim 514235633Sdimvoid ObjCStringRegion::dumpToStream(raw_ostream &os) const { 515235633Sdim Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts())); 516235633Sdim} 517235633Sdim 518226890Sdimvoid SymbolicRegion::dumpToStream(raw_ostream &os) const { 519218887Sdim os << "SymRegion{" << sym << '}'; 520218887Sdim} 521218887Sdim 522226890Sdimvoid VarRegion::dumpToStream(raw_ostream &os) const { 523226890Sdim os << *cast<VarDecl>(D); 524218887Sdim} 525218887Sdim 526218887Sdimvoid RegionRawOffset::dump() const { 527218887Sdim dumpToStream(llvm::errs()); 528218887Sdim} 529218887Sdim 530226890Sdimvoid RegionRawOffset::dumpToStream(raw_ostream &os) const { 531218887Sdim os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}'; 532218887Sdim} 533218887Sdim 534226890Sdimvoid StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const { 535218887Sdim os << "StaticGlobalsMemSpace{" << CR << '}'; 536218887Sdim} 537218887Sdim 538235633Sdimvoid GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const { 539235633Sdim os << "GlobalInternalSpaceRegion"; 540235633Sdim} 541235633Sdim 542235633Sdimvoid GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const { 543235633Sdim os << "GlobalSystemSpaceRegion"; 544235633Sdim} 545235633Sdim 546235633Sdimvoid GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const { 547235633Sdim os << "GlobalImmutableSpaceRegion"; 548235633Sdim} 549235633Sdim 550245431Sdimvoid HeapSpaceRegion::dumpToStream(raw_ostream &os) const { 551245431Sdim os << "HeapSpaceRegion"; 552245431Sdim} 553245431Sdim 554245431Sdimvoid UnknownSpaceRegion::dumpToStream(raw_ostream &os) const { 555245431Sdim os << "UnknownSpaceRegion"; 556245431Sdim} 557245431Sdim 558245431Sdimvoid StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const { 559245431Sdim os << "StackArgumentsSpaceRegion"; 560245431Sdim} 561245431Sdim 562245431Sdimvoid StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const { 563245431Sdim os << "StackLocalsSpaceRegion"; 564245431Sdim} 565245431Sdim 566245431Sdimbool MemRegion::canPrintPretty() const { 567252723Sdim return canPrintPrettyAsExpr(); 568252723Sdim} 569252723Sdim 570252723Sdimbool MemRegion::canPrintPrettyAsExpr() const { 571245431Sdim return false; 572245431Sdim} 573245431Sdim 574245431Sdimvoid MemRegion::printPretty(raw_ostream &os) const { 575252723Sdim assert(canPrintPretty() && "This region cannot be printed pretty."); 576252723Sdim os << "'"; 577252723Sdim printPrettyAsExpr(os); 578252723Sdim os << "'"; 579235633Sdim return; 580235633Sdim} 581235633Sdim 582252723Sdimvoid MemRegion::printPrettyAsExpr(raw_ostream &os) const { 583252723Sdim llvm_unreachable("This region cannot be printed pretty."); 584252723Sdim return; 585252723Sdim} 586252723Sdim 587252723Sdimbool VarRegion::canPrintPrettyAsExpr() const { 588245431Sdim return true; 589245431Sdim} 590245431Sdim 591252723Sdimvoid VarRegion::printPrettyAsExpr(raw_ostream &os) const { 592235633Sdim os << getDecl()->getName(); 593235633Sdim} 594235633Sdim 595252723Sdimbool ObjCIvarRegion::canPrintPrettyAsExpr() const { 596252723Sdim return true; 597252723Sdim} 598252723Sdim 599252723Sdimvoid ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const { 600252723Sdim os << getDecl()->getName(); 601252723Sdim} 602252723Sdim 603245431Sdimbool FieldRegion::canPrintPretty() const { 604252723Sdim return true; 605235633Sdim} 606235633Sdim 607252723Sdimbool FieldRegion::canPrintPrettyAsExpr() const { 608252723Sdim return superRegion->canPrintPrettyAsExpr(); 609252723Sdim} 610252723Sdim 611252723Sdimvoid FieldRegion::printPrettyAsExpr(raw_ostream &os) const { 612252723Sdim assert(canPrintPrettyAsExpr()); 613252723Sdim superRegion->printPrettyAsExpr(os); 614245431Sdim os << "." << getDecl()->getName(); 615245431Sdim} 616245431Sdim 617252723Sdimvoid FieldRegion::printPretty(raw_ostream &os) const { 618252723Sdim if (canPrintPrettyAsExpr()) { 619252723Sdim os << "\'"; 620252723Sdim printPrettyAsExpr(os); 621252723Sdim os << "'"; 622252723Sdim } else { 623252723Sdim os << "field " << "\'" << getDecl()->getName() << "'"; 624252723Sdim } 625252723Sdim return; 626252723Sdim} 627252723Sdim 628252723Sdimbool CXXBaseObjectRegion::canPrintPrettyAsExpr() const { 629252723Sdim return superRegion->canPrintPrettyAsExpr(); 630252723Sdim} 631252723Sdim 632252723Sdimvoid CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const { 633252723Sdim superRegion->printPrettyAsExpr(os); 634252723Sdim} 635252723Sdim 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 687235633Sdim*MemRegionManager::getGlobalsRegion(MemRegion::Kind K, 688235633Sdim const CodeTextRegion *CR) { 689235633Sdim if (!CR) { 690235633Sdim if (K == MemRegion::GlobalSystemSpaceRegionKind) 691235633Sdim return LazyAllocate(SystemGlobals); 692235633Sdim if (K == MemRegion::GlobalImmutableSpaceRegionKind) 693235633Sdim return LazyAllocate(ImmutableGlobals); 694235633Sdim assert(K == MemRegion::GlobalInternalSpaceRegionKind); 695235633Sdim return LazyAllocate(InternalGlobals); 696235633Sdim } 697218887Sdim 698235633Sdim 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 727235633Sdimconst ObjCStringRegion * 728235633SdimMemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){ 729235633Sdim return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion()); 730235633Sdim} 731235633Sdim 732245431Sdim/// Look through a chain of LocationContexts to either find the 733245431Sdim/// StackFrameContext that matches a DeclContext, or find a VarRegion 734245431Sdim/// for a variable captured by a block. 735245431Sdimstatic llvm::PointerUnion<const StackFrameContext *, const VarRegion *> 736245431SdimgetStackOrCaptureRegionForDeclContext(const LocationContext *LC, 737245431Sdim const DeclContext *DC, 738245431Sdim const VarDecl *VD) { 739245431Sdim while (LC) { 740245431Sdim if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) { 741245431Sdim if (cast<DeclContext>(SFC->getDecl()) == DC) 742245431Sdim return SFC; 743245431Sdim } 744245431Sdim if (const BlockInvocationContext *BC = 745245431Sdim dyn_cast<BlockInvocationContext>(LC)) { 746245431Sdim const BlockDataRegion *BR = 747245431Sdim static_cast<const BlockDataRegion*>(BC->getContextData()); 748245431Sdim // FIXME: This can be made more efficient. 749245431Sdim for (BlockDataRegion::referenced_vars_iterator 750245431Sdim I = BR->referenced_vars_begin(), 751245431Sdim E = BR->referenced_vars_end(); I != E; ++I) { 752245431Sdim if (const VarRegion *VR = dyn_cast<VarRegion>(I.getOriginalRegion())) 753245431Sdim if (VR->getDecl() == VD) 754245431Sdim return cast<VarRegion>(I.getCapturedRegion()); 755245431Sdim } 756245431Sdim } 757245431Sdim 758245431Sdim LC = LC->getParent(); 759245431Sdim } 760245431Sdim return (const StackFrameContext*)0; 761245431Sdim} 762245431Sdim 763218887Sdimconst VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, 764218887Sdim const LocationContext *LC) { 765218887Sdim const MemRegion *sReg = 0; 766218887Sdim 767235633Sdim if (D->hasGlobalStorage() && !D->isStaticLocal()) { 768235633Sdim 769235633Sdim // First handle the globals defined in system headers. 770235633Sdim if (C.getSourceManager().isInSystemHeader(D->getLocation())) { 771235633Sdim // Whitelist the system globals which often DO GET modified, assume the 772235633Sdim // rest are immutable. 773235633Sdim if (D->getName().find("errno") != StringRef::npos) 774235633Sdim sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind); 775235633Sdim else 776235633Sdim sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 777235633Sdim 778235633Sdim // Treat other globals as GlobalInternal unless they are constants. 779235633Sdim } else { 780235633Sdim QualType GQT = D->getType(); 781235633Sdim const Type *GT = GQT.getTypePtrOrNull(); 782235633Sdim // TODO: We could walk the complex types here and see if everything is 783235633Sdim // constified. 784235633Sdim if (GT && GQT.isConstQualified() && GT->isArithmeticType()) 785235633Sdim sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 786235633Sdim else 787235633Sdim sReg = getGlobalsRegion(); 788235633Sdim } 789235633Sdim 790235633Sdim // Finally handle static locals. 791235633Sdim } 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(); 795245431Sdim llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V = 796245431Sdim getStackOrCaptureRegionForDeclContext(LC, DC, D); 797245431Sdim 798245431Sdim if (V.is<const VarRegion*>()) 799245431Sdim return V.get<const VarRegion*>(); 800245431Sdim 801245431Sdim 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()); 813245431Sdim const Decl *STCD = STC->getDecl(); 814245431Sdim if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD)) 815235633Sdim sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, 816245431Sdim getFunctionTextRegion(cast<NamedDecl>(STCD))); 817245431Sdim else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) { 818263509Sdim // FIXME: The fallback type here is totally bogus -- though it should 819263509Sdim // never be queried, it will prevent uniquing with the real 820263509Sdim // BlockTextRegion. Ideally we'd fix the AST so that we always had a 821263509Sdim // signature. 822263509Sdim QualType T; 823263509Sdim if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) 824263509Sdim T = TSI->getType(); 825263509Sdim else 826263509Sdim T = getContext().getFunctionNoProtoType(getContext().VoidTy); 827263509Sdim 828218887Sdim const BlockTextRegion *BTR = 829263509Sdim getBlockTextRegion(BD, C.getCanonicalType(T), 830263509Sdim STC->getAnalysisDeclContext()); 831235633Sdim sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, 832235633Sdim 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, 851263509Sdim const LocationContext *LC, 852263509Sdim unsigned blockCount) { 853218887Sdim const MemRegion *sReg = 0; 854235633Sdim const BlockDecl *BD = BC->getDecl(); 855235633Sdim if (!BD->hasCaptures()) { 856235633Sdim // This handles 'static' blocks. 857235633Sdim sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 858218887Sdim } 859218887Sdim else { 860235633Sdim if (LC) { 861235633Sdim // FIXME: Once we implement scope handling, we want the parent region 862235633Sdim // to be the scope. 863235633Sdim const StackFrameContext *STC = LC->getCurrentStackFrame(); 864235633Sdim assert(STC); 865235633Sdim sReg = getStackLocalsRegion(STC); 866235633Sdim } 867235633Sdim else { 868235633Sdim // We allow 'LC' to be NULL for cases where want BlockDataRegions 869235633Sdim // without context-sensitivity. 870235633Sdim sReg = getUnknownRegion(); 871235633Sdim } 872218887Sdim } 873218887Sdim 874263509Sdim return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg); 875218887Sdim} 876218887Sdim 877263509Sdimconst CXXTempObjectRegion * 878263509SdimMemRegionManager::getCXXStaticTempObjectRegion(const Expr *Ex) { 879263509Sdim return getSubRegion<CXXTempObjectRegion>( 880263509Sdim Ex, getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, NULL)); 881263509Sdim} 882263509Sdim 883218887Sdimconst CompoundLiteralRegion* 884226890SdimMemRegionManager::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, 903226890Sdim ASTContext &Ctx){ 904218887Sdim 905218887Sdim QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType(); 906218887Sdim 907218887Sdim llvm::FoldingSetNodeID ID; 908218887Sdim ElementRegion::ProfileRegion(ID, T, Idx, superRegion); 909218887Sdim 910226890Sdim 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 * 924245431SdimMemRegionManager::getFunctionTextRegion(const NamedDecl *FD) { 925218887Sdim return getSubRegion<FunctionTextRegion>(FD, getCodeRegion()); 926218887Sdim} 927218887Sdim 928218887Sdimconst BlockTextRegion * 929218887SdimMemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy, 930235633Sdim 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 940245431Sdimconst SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) { 941245431Sdim return getSubRegion<SymbolicRegion>(Sym, getHeapRegion()); 942245431Sdim} 943245431Sdim 944218887Sdimconst FieldRegion* 945226890SdimMemRegionManager::getFieldRegion(const FieldDecl *d, 946218887Sdim const MemRegion* superRegion){ 947218887Sdim return getSubRegion<FieldRegion>(d, superRegion); 948218887Sdim} 949218887Sdim 950218887Sdimconst ObjCIvarRegion* 951226890SdimMemRegionManager::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 964252723Sdim/// Checks whether \p BaseClass is a valid virtual or direct non-virtual base 965252723Sdim/// class of the type of \p Super. 966252723Sdimstatic bool isValidBaseClass(const CXXRecordDecl *BaseClass, 967252723Sdim const TypedValueRegion *Super, 968252723Sdim bool IsVirtual) { 969252723Sdim BaseClass = BaseClass->getCanonicalDecl(); 970252723Sdim 971252723Sdim const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl(); 972252723Sdim if (!Class) 973252723Sdim return true; 974252723Sdim 975252723Sdim if (IsVirtual) 976252723Sdim return Class->isVirtuallyDerivedFrom(BaseClass); 977252723Sdim 978252723Sdim for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(), 979252723Sdim E = Class->bases_end(); 980252723Sdim I != E; ++I) { 981252723Sdim if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass) 982252723Sdim return true; 983252723Sdim } 984252723Sdim 985252723Sdim return false; 986252723Sdim} 987252723Sdim 988218887Sdimconst CXXBaseObjectRegion * 989252723SdimMemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD, 990252723Sdim const MemRegion *Super, 991252723Sdim bool IsVirtual) { 992252723Sdim if (isa<TypedValueRegion>(Super)) { 993252723Sdim assert(isValidBaseClass(RD, dyn_cast<TypedValueRegion>(Super), IsVirtual)); 994263509Sdim (void)&isValidBaseClass; 995245431Sdim 996252723Sdim if (IsVirtual) { 997252723Sdim // Virtual base regions should not be layered, since the layout rules 998252723Sdim // are different. 999252723Sdim while (const CXXBaseObjectRegion *Base = 1000252723Sdim dyn_cast<CXXBaseObjectRegion>(Super)) { 1001252723Sdim Super = Base->getSuperRegion(); 1002245431Sdim } 1003252723Sdim assert(Super && !isa<MemSpaceRegion>(Super)); 1004245431Sdim } 1005245431Sdim } 1006245431Sdim 1007252723Sdim 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* 1021226890SdimMemRegionManager::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 1078245431Sdimbool MemRegion::isSubRegionOf(const MemRegion *R) const { 1079245431Sdim return false; 1080245431Sdim} 1081245431Sdim 1082218887Sdim//===----------------------------------------------------------------------===// 1083218887Sdim// View handling. 1084218887Sdim//===----------------------------------------------------------------------===// 1085218887Sdim 1086245431Sdimconst MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const { 1087218887Sdim const MemRegion *R = this; 1088218887Sdim while (true) { 1089245431Sdim switch (R->getKind()) { 1090245431Sdim case ElementRegionKind: { 1091245431Sdim const ElementRegion *ER = cast<ElementRegion>(R); 1092245431Sdim if (!ER->getIndex().isZeroConstant()) 1093245431Sdim return R; 1094245431Sdim R = ER->getSuperRegion(); 1095245431Sdim break; 1096218887Sdim } 1097245431Sdim case CXXBaseObjectRegionKind: 1098245431Sdim if (!StripBaseCasts) 1099245431Sdim return R; 1100245431Sdim R = cast<CXXBaseObjectRegion>(R)->getSuperRegion(); 1101245431Sdim break; 1102245431Sdim default: 1103245431Sdim return R; 1104245431Sdim } 1105218887Sdim } 1106218887Sdim} 1107218887Sdim 1108252723Sdimconst SymbolicRegion *MemRegion::getSymbolicBase() const { 1109252723Sdim const SubRegion *SubR = dyn_cast<SubRegion>(this); 1110252723Sdim 1111252723Sdim while (SubR) { 1112252723Sdim if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR)) 1113252723Sdim return SymR; 1114252723Sdim SubR = dyn_cast<SubRegion>(SubR->getSuperRegion()); 1115252723Sdim } 1116252723Sdim return 0; 1117252723Sdim} 1118252723Sdim 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(); 1143252723Sdim 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 1172252723Sdim 1173252723Sdim/// Returns true if \p Base is an immediate base class of \p Child 1174252723Sdimstatic bool isImmediateBase(const CXXRecordDecl *Child, 1175252723Sdim const CXXRecordDecl *Base) { 1176252723Sdim // Note that we do NOT canonicalize the base class here, because 1177252723Sdim // ASTRecordLayout doesn't either. If that leads us down the wrong path, 1178252723Sdim // so be it; at least we won't crash. 1179252723Sdim for (CXXRecordDecl::base_class_const_iterator I = Child->bases_begin(), 1180252723Sdim E = Child->bases_end(); 1181252723Sdim I != E; ++I) { 1182252723Sdim if (I->getType()->getAsCXXRecordDecl() == Base) 1183252723Sdim return true; 1184252723Sdim } 1185252723Sdim 1186252723Sdim return false; 1187252723Sdim} 1188252723Sdim 1189218887SdimRegionOffset MemRegion::getAsOffset() const { 1190218887Sdim const MemRegion *R = this; 1191245431Sdim const MemRegion *SymbolicOffsetBase = 0; 1192218887Sdim int64_t Offset = 0; 1193218887Sdim 1194218887Sdim while (1) { 1195218887Sdim switch (R->getKind()) { 1196252723Sdim case GenericMemSpaceRegionKind: 1197252723Sdim case StackLocalsSpaceRegionKind: 1198252723Sdim case StackArgumentsSpaceRegionKind: 1199252723Sdim case HeapSpaceRegionKind: 1200252723Sdim case UnknownSpaceRegionKind: 1201252723Sdim case StaticGlobalSpaceRegionKind: 1202252723Sdim case GlobalInternalSpaceRegionKind: 1203252723Sdim case GlobalSystemSpaceRegionKind: 1204252723Sdim case GlobalImmutableSpaceRegionKind: 1205252723Sdim // Stores can bind directly to a region space to set a default value. 1206252723Sdim assert(Offset == 0 && !SymbolicOffsetBase); 1207252723Sdim goto Finish; 1208245431Sdim 1209252723Sdim case FunctionTextRegionKind: 1210252723Sdim case BlockTextRegionKind: 1211252723Sdim case BlockDataRegionKind: 1212252723Sdim // These will never have bindings, but may end up having values requested 1213252723Sdim // if the user does some strange casting. 1214252723Sdim if (Offset != 0) 1215252723Sdim SymbolicOffsetBase = R; 1216252723Sdim goto Finish; 1217252723Sdim 1218218887Sdim case SymbolicRegionKind: 1219218887Sdim case AllocaRegionKind: 1220218887Sdim case CompoundLiteralRegionKind: 1221218887Sdim case CXXThisRegionKind: 1222218887Sdim case StringRegionKind: 1223252723Sdim case ObjCStringRegionKind: 1224218887Sdim case VarRegionKind: 1225218887Sdim case CXXTempObjectRegionKind: 1226252723Sdim // Usual base regions. 1227218887Sdim goto Finish; 1228245431Sdim 1229245431Sdim case ObjCIvarRegionKind: 1230245431Sdim // This is a little strange, but it's a compromise between 1231245431Sdim // ObjCIvarRegions having unknown compile-time offsets (when using the 1232245431Sdim // non-fragile runtime) and yet still being distinct, non-overlapping 1233245431Sdim // regions. Thus we treat them as "like" base regions for the purposes 1234245431Sdim // of computing offsets. 1235245431Sdim goto Finish; 1236245431Sdim 1237245431Sdim case CXXBaseObjectRegionKind: { 1238245431Sdim const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R); 1239245431Sdim R = BOR->getSuperRegion(); 1240245431Sdim 1241245431Sdim QualType Ty; 1242252723Sdim bool RootIsSymbolic = false; 1243245431Sdim if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) { 1244245431Sdim Ty = TVR->getDesugaredValueType(getContext()); 1245245431Sdim } else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) { 1246245431Sdim // If our base region is symbolic, we don't know what type it really is. 1247245431Sdim // Pretend the type of the symbol is the true dynamic type. 1248245431Sdim // (This will at least be self-consistent for the life of the symbol.) 1249245431Sdim Ty = SR->getSymbol()->getType()->getPointeeType(); 1250252723Sdim RootIsSymbolic = true; 1251245431Sdim } 1252245431Sdim 1253245431Sdim const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl(); 1254245431Sdim if (!Child) { 1255245431Sdim // We cannot compute the offset of the base class. 1256245431Sdim SymbolicOffsetBase = R; 1257245431Sdim } 1258245431Sdim 1259252723Sdim if (RootIsSymbolic) { 1260252723Sdim // Base layers on symbolic regions may not be type-correct. 1261252723Sdim // Double-check the inheritance here, and revert to a symbolic offset 1262252723Sdim // if it's invalid (e.g. due to a reinterpret_cast). 1263252723Sdim if (BOR->isVirtual()) { 1264252723Sdim if (!Child->isVirtuallyDerivedFrom(BOR->getDecl())) 1265252723Sdim SymbolicOffsetBase = R; 1266252723Sdim } else { 1267252723Sdim if (!isImmediateBase(Child, BOR->getDecl())) 1268252723Sdim SymbolicOffsetBase = R; 1269252723Sdim } 1270252723Sdim } 1271252723Sdim 1272245431Sdim // Don't bother calculating precise offsets if we already have a 1273245431Sdim // symbolic offset somewhere in the chain. 1274245431Sdim if (SymbolicOffsetBase) 1275245431Sdim continue; 1276245431Sdim 1277252723Sdim CharUnits BaseOffset; 1278245431Sdim const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child); 1279252723Sdim if (BOR->isVirtual()) 1280252723Sdim BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl()); 1281245431Sdim else 1282252723Sdim BaseOffset = Layout.getBaseClassOffset(BOR->getDecl()); 1283245431Sdim 1284245431Sdim // The base offset is in chars, not in bits. 1285245431Sdim Offset += BaseOffset.getQuantity() * getContext().getCharWidth(); 1286245431Sdim break; 1287245431Sdim } 1288218887Sdim case ElementRegionKind: { 1289218887Sdim const ElementRegion *ER = cast<ElementRegion>(R); 1290245431Sdim R = ER->getSuperRegion(); 1291245431Sdim 1292218887Sdim QualType EleTy = ER->getValueType(); 1293245431Sdim if (!IsCompleteType(getContext(), EleTy)) { 1294245431Sdim // We cannot compute the offset of the base class. 1295245431Sdim SymbolicOffsetBase = R; 1296245431Sdim continue; 1297245431Sdim } 1298218887Sdim 1299218887Sdim SVal Index = ER->getIndex(); 1300252723Sdim if (Optional<nonloc::ConcreteInt> CI = 1301252723Sdim Index.getAs<nonloc::ConcreteInt>()) { 1302245431Sdim // Don't bother calculating precise offsets if we already have a 1303245431Sdim // symbolic offset somewhere in the chain. 1304245431Sdim if (SymbolicOffsetBase) 1305245431Sdim continue; 1306245431Sdim 1307218887Sdim int64_t i = CI->getValue().getSExtValue(); 1308245431Sdim // This type size is in bits. 1309245431Sdim Offset += i * getContext().getTypeSize(EleTy); 1310218887Sdim } else { 1311218887Sdim // We cannot compute offset for non-concrete index. 1312245431Sdim SymbolicOffsetBase = R; 1313218887Sdim } 1314218887Sdim break; 1315218887Sdim } 1316218887Sdim case FieldRegionKind: { 1317218887Sdim const FieldRegion *FR = cast<FieldRegion>(R); 1318245431Sdim R = FR->getSuperRegion(); 1319245431Sdim 1320218887Sdim const RecordDecl *RD = FR->getDecl()->getParent(); 1321245431Sdim if (RD->isUnion() || !RD->isCompleteDefinition()) { 1322218887Sdim // We cannot compute offset for incomplete type. 1323245431Sdim // For unions, we could treat everything as offset 0, but we'd rather 1324245431Sdim // treat each field as a symbolic offset so they aren't stored on top 1325245431Sdim // of each other, since we depend on things in typed regions actually 1326245431Sdim // matching their types. 1327245431Sdim SymbolicOffsetBase = R; 1328245431Sdim } 1329245431Sdim 1330245431Sdim // Don't bother calculating precise offsets if we already have a 1331245431Sdim // symbolic offset somewhere in the chain. 1332245431Sdim if (SymbolicOffsetBase) 1333245431Sdim continue; 1334245431Sdim 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: 1351245431Sdim if (SymbolicOffsetBase) 1352245431Sdim return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic); 1353218887Sdim return RegionOffset(R, Offset); 1354218887Sdim} 1355218887Sdim 1356218887Sdim//===----------------------------------------------------------------------===// 1357218887Sdim// BlockDataRegion 1358218887Sdim//===----------------------------------------------------------------------===// 1359218887Sdim 1360252723Sdimstd::pair<const VarRegion *, const VarRegion *> 1361252723SdimBlockDataRegion::getCaptureRegions(const VarDecl *VD) { 1362252723Sdim MemRegionManager &MemMgr = *getMemRegionManager(); 1363252723Sdim const VarRegion *VR = 0; 1364252723Sdim const VarRegion *OriginalVR = 0; 1365252723Sdim 1366252723Sdim if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage()) { 1367252723Sdim VR = MemMgr.getVarRegion(VD, this); 1368252723Sdim OriginalVR = MemMgr.getVarRegion(VD, LC); 1369252723Sdim } 1370252723Sdim else { 1371252723Sdim if (LC) { 1372252723Sdim VR = MemMgr.getVarRegion(VD, LC); 1373252723Sdim OriginalVR = VR; 1374252723Sdim } 1375252723Sdim else { 1376252723Sdim VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion()); 1377252723Sdim OriginalVR = MemMgr.getVarRegion(VD, LC); 1378252723Sdim } 1379252723Sdim } 1380252723Sdim return std::make_pair(VR, OriginalVR); 1381252723Sdim} 1382252723Sdim 1383218887Sdimvoid BlockDataRegion::LazyInitializeReferencedVars() { 1384218887Sdim if (ReferencedVars) 1385218887Sdim return; 1386218887Sdim 1387235633Sdim AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext(); 1388235633Sdim 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); 1403245431Sdim VarVec *BVOriginal = (VarVec*) A.Allocate<VarVec>(); 1404245431Sdim new (BVOriginal) VarVec(BC, E - I); 1405218887Sdim 1406218887Sdim for ( ; I != E; ++I) { 1407218887Sdim const VarRegion *VR = 0; 1408245431Sdim const VarRegion *OriginalVR = 0; 1409252723Sdim llvm::tie(VR, OriginalVR) = getCaptureRegions(*I); 1410218887Sdim assert(VR); 1411245431Sdim assert(OriginalVR); 1412218887Sdim BV->push_back(VR, BC); 1413245431Sdim BVOriginal->push_back(OriginalVR, BC); 1414218887Sdim } 1415218887Sdim 1416218887Sdim ReferencedVars = BV; 1417245431Sdim 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 1427245431Sdim if (Vec == (void*) 0x1) 1428245431Sdim return BlockDataRegion::referenced_vars_iterator(0, 0); 1429245431Sdim 1430245431Sdim BumpVector<const MemRegion*> *VecOriginal = 1431245431Sdim static_cast<BumpVector<const MemRegion*>*>(OriginalVars); 1432245431Sdim 1433245431Sdim return BlockDataRegion::referenced_vars_iterator(Vec->begin(), 1434245431Sdim 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 1444245431Sdim if (Vec == (void*) 0x1) 1445245431Sdim return BlockDataRegion::referenced_vars_iterator(0, 0); 1446245431Sdim 1447245431Sdim BumpVector<const MemRegion*> *VecOriginal = 1448245431Sdim static_cast<BumpVector<const MemRegion*>*>(OriginalVars); 1449245431Sdim 1450245431Sdim return BlockDataRegion::referenced_vars_iterator(Vec->end(), 1451245431Sdim VecOriginal->end()); 1452218887Sdim} 1453252723Sdim 1454252723Sdimconst VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const { 1455252723Sdim for (referenced_vars_iterator I = referenced_vars_begin(), 1456252723Sdim E = referenced_vars_end(); 1457252723Sdim I != E; ++I) { 1458252723Sdim if (I.getCapturedRegion() == R) 1459252723Sdim return I.getOriginalRegion(); 1460252723Sdim } 1461252723Sdim return 0; 1462252723Sdim} 1463263509Sdim 1464263509Sdim//===----------------------------------------------------------------------===// 1465263509Sdim// RegionAndSymbolInvalidationTraits 1466263509Sdim//===----------------------------------------------------------------------===// 1467263509Sdim 1468263509Sdimvoid RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym, 1469263509Sdim InvalidationKinds IK) { 1470263509Sdim SymTraitsMap[Sym] |= IK; 1471263509Sdim} 1472263509Sdim 1473263509Sdimvoid RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR, 1474263509Sdim InvalidationKinds IK) { 1475263509Sdim assert(MR); 1476263509Sdim if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) 1477263509Sdim setTrait(SR->getSymbol(), IK); 1478263509Sdim else 1479263509Sdim MRTraitsMap[MR] |= IK; 1480263509Sdim} 1481263509Sdim 1482263509Sdimbool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym, 1483263509Sdim InvalidationKinds IK) { 1484263509Sdim const_symbol_iterator I = SymTraitsMap.find(Sym); 1485263509Sdim if (I != SymTraitsMap.end()) 1486263509Sdim return I->second & IK; 1487263509Sdim 1488263509Sdim return false; 1489263509Sdim} 1490263509Sdim 1491263509Sdimbool RegionAndSymbolInvalidationTraits::hasTrait(const MemRegion *MR, 1492263509Sdim InvalidationKinds IK) { 1493263509Sdim if (!MR) 1494263509Sdim return false; 1495263509Sdim 1496263509Sdim if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) 1497263509Sdim return hasTrait(SR->getSymbol(), IK); 1498263509Sdim 1499263509Sdim const_region_iterator I = MRTraitsMap.find(MR); 1500263509Sdim if (I != MRTraitsMap.end()) 1501263509Sdim return I->second & IK; 1502263509Sdim 1503263509Sdim return false; 1504263509Sdim} 1505