MemRegion.h revision 234353
1194676Sthompsa//== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==// 2194676Sthompsa// 3194676Sthompsa// The LLVM Compiler Infrastructure 4194676Sthompsa// 5194676Sthompsa// This file is distributed under the University of Illinois Open Source 6194676Sthompsa// License. See LICENSE.TXT for details. 7194676Sthompsa// 8194676Sthompsa//===----------------------------------------------------------------------===// 9194676Sthompsa// 10194676Sthompsa// This file defines MemRegion and its subclasses. MemRegion defines a 11194676Sthompsa// partially-typed abstraction of memory useful for path-sensitive dataflow 12194676Sthompsa// analyses. 13194676Sthompsa// 14194676Sthompsa//===----------------------------------------------------------------------===// 15194676Sthompsa 16194676Sthompsa#ifndef LLVM_CLANG_GR_MEMREGION_H 17194676Sthompsa#define LLVM_CLANG_GR_MEMREGION_H 18194676Sthompsa 19194676Sthompsa#include "clang/AST/CharUnits.h" 20194676Sthompsa#include "clang/AST/Decl.h" 21194676Sthompsa#include "clang/AST/ExprObjC.h" 22194676Sthompsa#include "clang/Basic/LLVM.h" 23194676Sthompsa#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 24194676Sthompsa#include "llvm/Support/ErrorHandling.h" 25194676Sthompsa#include "llvm/ADT/FoldingSet.h" 26194676Sthompsa#include <string> 27248236Shselasky 28248236Shselaskynamespace llvm { 29248236Shselaskyclass BumpPtrAllocator; 30203815Swkoszek} 31194676Sthompsa 32194676Sthompsanamespace clang { 33203815Swkoszek 34203815Swkoszekclass LocationContext; 35248236Shselaskyclass StackFrameContext; 36194676Sthompsa 37203815Swkoszeknamespace ento { 38248236Shselasky 39248236Shselaskyclass MemRegionManager; 40248236Shselaskyclass MemSpaceRegion; 41194676Sthompsaclass SValBuilder; 42208020Sthompsaclass VarRegion; 43208020Sthompsaclass CodeTextRegion; 44194676Sthompsa 45194676Sthompsa/// Represent a region's offset within the top level base region. 46194676Sthompsaclass RegionOffset { 47194676Sthompsa /// The base region. 48194676Sthompsa const MemRegion *R; 49194676Sthompsa 50195957Salfred /// The bit offset within the base region. It shouldn't be negative. 51195957Salfred int64_t Offset; 52195957Salfred 53195560Sthompsapublic: 54195560Sthompsa RegionOffset(const MemRegion *r) : R(r), Offset(0) {} 55195957Salfred RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {} 56195560Sthompsa 57195957Salfred const MemRegion *getRegion() const { return R; } 58195957Salfred int64_t getOffset() const { return Offset; } 59195957Salfred}; 60195957Salfred 61195957Salfred//===----------------------------------------------------------------------===// 62195957Salfred// Base region classes. 63195957Salfred//===----------------------------------------------------------------------===// 64195560Sthompsa 65195560Sthompsa/// MemRegion - The root abstract class for all memory regions. 66195560Sthompsaclass MemRegion : public llvm::FoldingSetNode { 67195957Salfred friend class MemRegionManager; 68195957Salfredpublic: 69195957Salfred enum Kind { 70195560Sthompsa // Memory spaces. 71195560Sthompsa GenericMemSpaceRegionKind, 72195560Sthompsa StackLocalsSpaceRegionKind, 73195560Sthompsa StackArgumentsSpaceRegionKind, 74195560Sthompsa HeapSpaceRegionKind, 75195560Sthompsa UnknownSpaceRegionKind, 76195957Salfred StaticGlobalSpaceRegionKind, 77195560Sthompsa GlobalInternalSpaceRegionKind, 78195957Salfred GlobalSystemSpaceRegionKind, 79195957Salfred GlobalImmutableSpaceRegionKind, 80195560Sthompsa BEG_NON_STATIC_GLOBAL_MEMSPACES = GlobalInternalSpaceRegionKind, 81195957Salfred END_NON_STATIC_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind, 82195957Salfred BEG_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind, 83195560Sthompsa END_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind, 84195957Salfred BEG_MEMSPACES = GenericMemSpaceRegionKind, 85195957Salfred END_MEMSPACES = GlobalImmutableSpaceRegionKind, 86195957Salfred // Untyped regions. 87195957Salfred SymbolicRegionKind, 88195560Sthompsa AllocaRegionKind, 89195560Sthompsa BlockDataRegionKind, 90195957Salfred // Typed regions. 91195560Sthompsa BEG_TYPED_REGIONS, 92195560Sthompsa FunctionTextRegionKind = BEG_TYPED_REGIONS, 93195957Salfred BlockTextRegionKind, 94195560Sthompsa BEG_TYPED_VALUE_REGIONS, 95195957Salfred CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS, 96195957Salfred CXXThisRegionKind, 97195560Sthompsa StringRegionKind, 98195957Salfred ObjCStringRegionKind, 99195957Salfred ElementRegionKind, 100195957Salfred // Decl Regions. 101195957Salfred BEG_DECL_REGIONS, 102195957Salfred VarRegionKind = BEG_DECL_REGIONS, 103194676Sthompsa FieldRegionKind, 104194676Sthompsa ObjCIvarRegionKind, 105194676Sthompsa END_DECL_REGIONS = ObjCIvarRegionKind, 106194676Sthompsa CXXTempObjectRegionKind, 107195957Salfred CXXBaseObjectRegionKind, 108194676Sthompsa END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind, 109195957Salfred END_TYPED_REGIONS = CXXBaseObjectRegionKind 110195957Salfred }; 111194676Sthompsa 112195957Salfredprivate: 113195957Salfred const Kind kind; 114195957Salfred 115194676Sthompsaprotected: 116195560Sthompsa MemRegion(Kind k) : kind(k) {} 117194676Sthompsa virtual ~MemRegion(); 118194676Sthompsa 119194676Sthompsapublic: 120195957Salfred ASTContext &getContext() const; 121195957Salfred 122195957Salfred virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0; 123195957Salfred 124195957Salfred virtual MemRegionManager* getMemRegionManager() const = 0; 125195957Salfred 126195957Salfred const MemSpaceRegion *getMemorySpace() const; 127195957Salfred 128195957Salfred const MemRegion *getBaseRegion() const; 129195957Salfred 130195957Salfred const MemRegion *StripCasts() const; 131194676Sthompsa 132194676Sthompsa bool hasGlobalsOrParametersStorage() const; 133194676Sthompsa 134195957Salfred bool hasStackStorage() const; 135195957Salfred 136195957Salfred bool hasStackNonParametersStorage() const; 137195957Salfred 138194676Sthompsa bool hasStackParametersStorage() const; 139195957Salfred 140195957Salfred /// Compute the offset within the top level memory object. 141195957Salfred RegionOffset getAsOffset() const; 142194676Sthompsa 143195957Salfred /// \brief Get a string representation of a region for debug use. 144195957Salfred std::string getString() const; 145195957Salfred 146195957Salfred virtual void dumpToStream(raw_ostream &os) const; 147194676Sthompsa 148195957Salfred void dump() const; 149213849Shselasky 150195957Salfred /// \brief Print the region for use in diagnostics. 151195957Salfred virtual void dumpPretty(raw_ostream &os) const; 152195957Salfred 153195957Salfred Kind getKind() const { return kind; } 154195957Salfred 155194676Sthompsa template<typename RegionTy> const RegionTy* getAs() const; 156195957Salfred 157194676Sthompsa virtual bool isBoundable() const { return false; } 158213849Shselasky 159195957Salfred static bool classof(const MemRegion*) { return true; } 160195957Salfred}; 161194676Sthompsa 162199055Sthompsa/// MemSpaceRegion - A memory region that represents a "memory space"; 163199055Sthompsa/// for example, the set of global variables, the stack frame, etc. 164199055Sthompsaclass MemSpaceRegion : public MemRegion { 165199055Sthompsaprotected: 166199055Sthompsa friend class MemRegionManager; 167195957Salfred 168195957Salfred MemRegionManager *Mgr; 169195957Salfred 170199055Sthompsa MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind) 171199055Sthompsa : MemRegion(k), Mgr(mgr) { 172195957Salfred assert(classof(this)); 173195957Salfred } 174195957Salfred 175195957Salfred MemRegionManager* getMemRegionManager() const { return Mgr; } 176195957Salfred 177194676Sthompsapublic: 178195957Salfred bool isBoundable() const { return false; } 179195957Salfred 180194676Sthompsa void Profile(llvm::FoldingSetNodeID &ID) const; 181195957Salfred 182195957Salfred static bool classof(const MemRegion *R) { 183195957Salfred Kind k = R->getKind(); 184195957Salfred return k >= BEG_MEMSPACES && k <= END_MEMSPACES; 185194676Sthompsa } 186195957Salfred}; 187194676Sthompsa 188195957Salfredclass GlobalsSpaceRegion : public MemSpaceRegion { 189194676Sthompsa virtual void anchor(); 190195957Salfredprotected: 191194676Sthompsa GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) 192195957Salfred : MemSpaceRegion(mgr, k) {} 193194676Sthompsapublic: 194195957Salfred static bool classof(const MemRegion *R) { 195215253Shselasky Kind k = R->getKind(); 196215253Shselasky return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES; 197195957Salfred } 198195957Salfred}; 199194676Sthompsa 200195957Salfred/// \class The region of the static variables within the current CodeTextRegion 201195957Salfred/// scope. 202195957Salfred/// Currently, only the static locals are placed there, so we know that these 203195957Salfred/// variables do not get invalidated by calls to other functions. 204195957Salfredclass StaticGlobalSpaceRegion : public GlobalsSpaceRegion { 205195957Salfred friend class MemRegionManager; 206195957Salfred 207215253Shselasky const CodeTextRegion *CR; 208215253Shselasky 209215253Shselasky StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr) 210195957Salfred : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {} 211195957Salfred 212195957Salfredpublic: 213215253Shselasky void Profile(llvm::FoldingSetNodeID &ID) const; 214215253Shselasky 215195957Salfred void dumpToStream(raw_ostream &os) const; 216195957Salfred 217195957Salfred const CodeTextRegion *getCodeRegion() const { return CR; } 218195957Salfred 219195957Salfred static bool classof(const MemRegion *R) { 220195957Salfred return R->getKind() == StaticGlobalSpaceRegionKind; 221194676Sthompsa } 222194676Sthompsa}; 223195957Salfred 224195957Salfred/// \class The region for all the non-static global variables. 225194676Sthompsa/// 226195957Salfred/// This class is further split into subclasses for efficient implementation of 227194676Sthompsa/// invalidating a set of related global values as is done in 228194676Sthompsa/// RegionStoreManager::invalidateRegions (instead of finding all the dependent 229194676Sthompsa/// globals, we invalidate the whole parent region). 230194676Sthompsaclass NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion { 231194676Sthompsa friend class MemRegionManager; 232195957Salfred 233194676Sthompsaprotected: 234195957Salfred NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k) 235194676Sthompsa : GlobalsSpaceRegion(mgr, k) {} 236195957Salfred 237195957Salfredpublic: 238194676Sthompsa 239194676Sthompsa void dumpToStream(raw_ostream &os) const; 240195957Salfred 241195957Salfred static bool classof(const MemRegion *R) { 242194676Sthompsa Kind k = R->getKind(); 243194676Sthompsa return k >= BEG_NON_STATIC_GLOBAL_MEMSPACES && 244195957Salfred k <= END_NON_STATIC_GLOBAL_MEMSPACES; 245195957Salfred } 246195957Salfred}; 247195957Salfred 248195957Salfred/// \class The region containing globals which are defined in system/external 249195957Salfred/// headers and are considered modifiable by system calls (ex: errno). 250195957Salfredclass GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion { 251194676Sthompsa friend class MemRegionManager; 252194676Sthompsa 253194676Sthompsa GlobalSystemSpaceRegion(MemRegionManager *mgr) 254195957Salfred : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {} 255194676Sthompsa 256195957Salfredpublic: 257195957Salfred 258195957Salfred void dumpToStream(raw_ostream &os) const; 259195957Salfred 260194676Sthompsa static bool classof(const MemRegion *R) { 261194676Sthompsa return R->getKind() == GlobalSystemSpaceRegionKind; 262194676Sthompsa } 263195957Salfred}; 264194676Sthompsa 265195957Salfred/// \class The region containing globals which are considered not to be modified 266195957Salfred/// or point to data which could be modified as a result of a function call 267195957Salfred/// (system or internal). Ex: Const global scalars would be modeled as part of 268195957Salfred/// this region. This region also includes most system globals since they have 269195957Salfred/// low chance of being modified. 270195957Salfredclass GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion { 271194676Sthompsa friend class MemRegionManager; 272194676Sthompsa 273194676Sthompsa GlobalImmutableSpaceRegion(MemRegionManager *mgr) 274195957Salfred : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {} 275194676Sthompsa 276195957Salfredpublic: 277195957Salfred 278194676Sthompsa void dumpToStream(raw_ostream &os) const; 279194676Sthompsa 280194676Sthompsa static bool classof(const MemRegion *R) { 281195957Salfred return R->getKind() == GlobalImmutableSpaceRegionKind; 282194676Sthompsa } 283195957Salfred}; 284195957Salfred 285194676Sthompsa/// \class The region containing globals which can be modified by calls to 286194676Sthompsa/// "internally" defined functions - (for now just) functions other then system 287194676Sthompsa/// calls. 288195957Salfredclass GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion { 289194676Sthompsa friend class MemRegionManager; 290195957Salfred 291195957Salfred GlobalInternalSpaceRegion(MemRegionManager *mgr) 292194676Sthompsa : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {} 293194676Sthompsa 294194676Sthompsapublic: 295195957Salfred 296194676Sthompsa void dumpToStream(raw_ostream &os) const; 297195957Salfred 298195957Salfred static bool classof(const MemRegion *R) { 299194676Sthompsa return R->getKind() == GlobalInternalSpaceRegionKind; 300194676Sthompsa } 301194676Sthompsa}; 302195957Salfred 303194676Sthompsaclass HeapSpaceRegion : public MemSpaceRegion { 304194676Sthompsa virtual void anchor(); 305195957Salfred friend class MemRegionManager; 306194676Sthompsa 307195957Salfred HeapSpaceRegion(MemRegionManager *mgr) 308195560Sthompsa : MemSpaceRegion(mgr, HeapSpaceRegionKind) {} 309194676Sthompsapublic: 310194676Sthompsa static bool classof(const MemRegion *R) { 311195957Salfred return R->getKind() == HeapSpaceRegionKind; 312195957Salfred } 313194676Sthompsa}; 314194676Sthompsa 315236944Shselaskyclass UnknownSpaceRegion : public MemSpaceRegion { 316195957Salfred virtual void anchor(); 317194676Sthompsa friend class MemRegionManager; 318194676Sthompsa UnknownSpaceRegion(MemRegionManager *mgr) 319236944Shselasky : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {} 320236944Shselaskypublic: 321236944Shselasky static bool classof(const MemRegion *R) { 322236944Shselasky return R->getKind() == UnknownSpaceRegionKind; 323236944Shselasky } 324236944Shselasky}; 325195957Salfred 326194676Sthompsaclass StackSpaceRegion : public MemSpaceRegion { 327194676Sthompsaprivate: 328194676Sthompsa const StackFrameContext *SFC; 329195957Salfred 330195957Salfredprotected: 331194676Sthompsa StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc) 332195957Salfred : MemSpaceRegion(mgr, k), SFC(sfc) { 333194676Sthompsa assert(classof(this)); 334194676Sthompsa } 335194676Sthompsa 336194676Sthompsapublic: 337194676Sthompsa const StackFrameContext *getStackFrame() const { return SFC; } 338194676Sthompsa 339261482Shselasky void Profile(llvm::FoldingSetNodeID &ID) const; 340261482Shselasky 341194676Sthompsa static bool classof(const MemRegion *R) { 342261482Shselasky Kind k = R->getKind(); 343195957Salfred return k >= StackLocalsSpaceRegionKind && 344195957Salfred k <= StackArgumentsSpaceRegionKind; 345195957Salfred } 346261482Shselasky}; 347194676Sthompsa 348195957Salfredclass StackLocalsSpaceRegion : public StackSpaceRegion { 349194676Sthompsa virtual void anchor(); 350261482Shselasky friend class MemRegionManager; 351261482Shselasky StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) 352261482Shselasky : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {} 353261482Shselaskypublic: 354261482Shselasky static bool classof(const MemRegion *R) { 355261482Shselasky return R->getKind() == StackLocalsSpaceRegionKind; 356261482Shselasky } 357261482Shselasky}; 358261482Shselasky 359194676Sthompsaclass StackArgumentsSpaceRegion : public StackSpaceRegion { 360195957Salfredprivate: 361194676Sthompsa virtual void anchor(); 362261482Shselasky friend class MemRegionManager; 363195957Salfred StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) 364195957Salfred : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {} 365194676Sthompsapublic: 366194676Sthompsa static bool classof(const MemRegion *R) { 367194676Sthompsa return R->getKind() == StackArgumentsSpaceRegionKind; 368261482Shselasky } 369261482Shselasky}; 370261482Shselasky 371261482Shselasky 372261482Shselasky/// SubRegion - A region that subsets another larger region. Most regions 373261482Shselasky/// are subclasses of SubRegion. 374261482Shselaskyclass SubRegion : public MemRegion { 375261482Shselaskyprivate: 376261482Shselasky virtual void anchor(); 377261482Shselaskyprotected: 378261482Shselasky const MemRegion* superRegion; 379261482Shselasky SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {} 380195957Salfredpublic: 381194676Sthompsa const MemRegion* getSuperRegion() const { 382261482Shselasky return superRegion; 383194676Sthompsa } 384194676Sthompsa 385194676Sthompsa /// getExtent - Returns the size of the region in bytes. 386195957Salfred virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const { 387194676Sthompsa return UnknownVal(); 388195957Salfred } 389194676Sthompsa 390195957Salfred MemRegionManager* getMemRegionManager() const; 391194676Sthompsa 392195957Salfred bool isSubRegionOf(const MemRegion* R) const; 393195957Salfred 394195957Salfred static bool classof(const MemRegion* R) { 395261482Shselasky return R->getKind() > END_MEMSPACES; 396261482Shselasky } 397261482Shselasky}; 398194676Sthompsa 399195957Salfred//===----------------------------------------------------------------------===// 400194676Sthompsa// MemRegion subclasses. 401194676Sthompsa//===----------------------------------------------------------------------===// 402194676Sthompsa 403195957Salfred/// AllocaRegion - A region that represents an untyped blob of bytes created 404194676Sthompsa/// by a call to 'alloca'. 405195957Salfredclass AllocaRegion : public SubRegion { 406195957Salfred friend class MemRegionManager; 407195957Salfredprotected: 408194676Sthompsa unsigned Cnt; // Block counter. Used to distinguish different pieces of 409194676Sthompsa // memory allocated by alloca at the same call site. 410194676Sthompsa const Expr *Ex; 411195957Salfred 412194676Sthompsa AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion) 413194676Sthompsa : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {} 414194676Sthompsa 415195957Salfredpublic: 416194676Sthompsa 417194676Sthompsa const Expr *getExpr() const { return Ex; } 418194676Sthompsa 419194676Sthompsa bool isBoundable() const { return true; } 420194676Sthompsa 421194676Sthompsa DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 422250335Semaste 423195957Salfred void Profile(llvm::FoldingSetNodeID& ID) const; 424194676Sthompsa 425195957Salfred static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex, 426194676Sthompsa unsigned Cnt, const MemRegion *superRegion); 427194676Sthompsa 428194676Sthompsa void dumpToStream(raw_ostream &os) const; 429195957Salfred 430194676Sthompsa static bool classof(const MemRegion* R) { 431195957Salfred return R->getKind() == AllocaRegionKind; 432195957Salfred } 433194676Sthompsa}; 434195957Salfred 435195957Salfred/// TypedRegion - An abstract class representing regions that are typed. 436194676Sthompsaclass TypedRegion : public SubRegion { 437195957Salfredpublic: 438195957Salfred virtual void anchor(); 439195957Salfredprotected: 440194676Sthompsa TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {} 441194676Sthompsa 442195957Salfredpublic: 443195957Salfred virtual QualType getLocationType() const = 0; 444194676Sthompsa 445194676Sthompsa QualType getDesugaredLocationType(ASTContext &Context) const { 446195957Salfred return getLocationType().getDesugaredType(Context); 447195957Salfred } 448250335Semaste 449194676Sthompsa bool isBoundable() const { return true; } 450194676Sthompsa 451194676Sthompsa static bool classof(const MemRegion* R) { 452194676Sthompsa unsigned k = R->getKind(); 453194676Sthompsa return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS; 454194676Sthompsa } 455195957Salfred}; 456194676Sthompsa 457195957Salfred/// TypedValueRegion - An abstract class representing regions having a typed value. 458194676Sthompsaclass TypedValueRegion : public TypedRegion { 459195957Salfredpublic: 460195957Salfred virtual void anchor(); 461195957Salfredprotected: 462194676Sthompsa TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {} 463195957Salfred 464195957Salfredpublic: 465194676Sthompsa virtual QualType getValueType() const = 0; 466195957Salfred 467195957Salfred virtual QualType getLocationType() const { 468194676Sthompsa // FIXME: We can possibly optimize this later to cache this value. 469195957Salfred QualType T = getValueType(); 470194676Sthompsa ASTContext &ctx = getContext(); 471195957Salfred if (T->getAs<ObjCObjectType>()) 472195957Salfred return ctx.getObjCObjectPointerType(T); 473195957Salfred return ctx.getPointerType(getValueType()); 474195957Salfred } 475195957Salfred 476194676Sthompsa QualType getDesugaredValueType(ASTContext &Context) const { 477195957Salfred QualType T = getValueType(); 478195957Salfred return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T; 479194676Sthompsa } 480195957Salfred 481195957Salfred static bool classof(const MemRegion* R) { 482195957Salfred unsigned k = R->getKind(); 483195957Salfred return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS; 484195957Salfred } 485195957Salfred}; 486194676Sthompsa 487195957Salfred 488195957Salfredclass CodeTextRegion : public TypedRegion { 489194676Sthompsapublic: 490195957Salfred virtual void anchor(); 491195957Salfredprotected: 492195957Salfred CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {} 493195957Salfredpublic: 494195957Salfred bool isBoundable() const { return false; } 495194676Sthompsa 496195957Salfred static bool classof(const MemRegion* R) { 497194676Sthompsa Kind k = R->getKind(); 498195957Salfred return k >= FunctionTextRegionKind && k <= BlockTextRegionKind; 499194676Sthompsa } 500195957Salfred}; 501195957Salfred 502194676Sthompsa/// FunctionTextRegion - A region that represents code texts of function. 503194676Sthompsaclass FunctionTextRegion : public CodeTextRegion { 504195957Salfred const FunctionDecl *FD; 505195957Salfredpublic: 506195957Salfred FunctionTextRegion(const FunctionDecl *fd, const MemRegion* sreg) 507195957Salfred : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {} 508194676Sthompsa 509195957Salfred QualType getLocationType() const { 510195957Salfred return getContext().getPointerType(FD->getType()); 511194676Sthompsa } 512194676Sthompsa 513195957Salfred const FunctionDecl *getDecl() const { 514194676Sthompsa return FD; 515234491Shselasky } 516194676Sthompsa 517194676Sthompsa virtual void dumpToStream(raw_ostream &os) const; 518195957Salfred 519195957Salfred void Profile(llvm::FoldingSetNodeID& ID) const; 520194676Sthompsa 521195957Salfred static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD, 522195957Salfred const MemRegion*); 523195957Salfred 524194676Sthompsa static bool classof(const MemRegion* R) { 525194676Sthompsa return R->getKind() == FunctionTextRegionKind; 526194676Sthompsa } 527194676Sthompsa}; 528195957Salfred 529194676Sthompsa 530194676Sthompsa/// BlockTextRegion - A region that represents code texts of blocks (closures). 531194676Sthompsa/// Blocks are represented with two kinds of regions. BlockTextRegions 532194676Sthompsa/// represent the "code", while BlockDataRegions represent instances of blocks, 533194676Sthompsa/// which correspond to "code+data". The distinction is important, because 534194676Sthompsa/// like a closure a block captures the values of externally referenced 535194676Sthompsa/// variables. 536234491Shselaskyclass BlockTextRegion : public CodeTextRegion { 537195957Salfred friend class MemRegionManager; 538234491Shselasky 539194676Sthompsa const BlockDecl *BD; 540194676Sthompsa AnalysisDeclContext *AC; 541194676Sthompsa CanQualType locTy; 542194676Sthompsa 543194676Sthompsa BlockTextRegion(const BlockDecl *bd, CanQualType lTy, 544234491Shselasky AnalysisDeclContext *ac, const MemRegion* sreg) 545194676Sthompsa : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {} 546194676Sthompsa 547195957Salfredpublic: 548194676Sthompsa QualType getLocationType() const { 549194676Sthompsa return locTy; 550194676Sthompsa } 551194676Sthompsa 552195957Salfred const BlockDecl *getDecl() const { 553194676Sthompsa return BD; 554194676Sthompsa } 555195957Salfred 556194676Sthompsa AnalysisDeclContext *getAnalysisDeclContext() const { return AC; } 557194676Sthompsa 558195957Salfred virtual void dumpToStream(raw_ostream &os) const; 559195957Salfred 560194676Sthompsa void Profile(llvm::FoldingSetNodeID& ID) const; 561195957Salfred 562195957Salfred static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD, 563194676Sthompsa CanQualType, const AnalysisDeclContext*, 564195957Salfred const MemRegion*); 565195957Salfred 566194676Sthompsa static bool classof(const MemRegion* R) { 567195957Salfred return R->getKind() == BlockTextRegionKind; 568194676Sthompsa } 569194676Sthompsa}; 570194676Sthompsa 571195957Salfred/// BlockDataRegion - A region that represents a block instance. 572194676Sthompsa/// Blocks are represented with two kinds of regions. BlockTextRegions 573194676Sthompsa/// represent the "code", while BlockDataRegions represent instances of blocks, 574194676Sthompsa/// which correspond to "code+data". The distinction is important, because 575194676Sthompsa/// like a closure a block captures the values of externally referenced 576194676Sthompsa/// variables. 577194676Sthompsaclass BlockDataRegion : public SubRegion { 578194676Sthompsa friend class MemRegionManager; 579195957Salfred const BlockTextRegion *BC; 580195957Salfred const LocationContext *LC; // Can be null */ 581194676Sthompsa void *ReferencedVars; 582194676Sthompsa 583194676Sthompsa BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc, 584194676Sthompsa const MemRegion *sreg) 585195957Salfred : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {} 586195957Salfred 587195560Sthompsapublic: 588194676Sthompsa const BlockTextRegion *getCodeRegion() const { return BC; } 589195957Salfred 590194676Sthompsa const BlockDecl *getDecl() const { return BC->getDecl(); } 591194676Sthompsa 592195560Sthompsa class referenced_vars_iterator { 593194676Sthompsa const MemRegion * const *R; 594194676Sthompsa public: 595194676Sthompsa explicit referenced_vars_iterator(const MemRegion * const *r) : R(r) {} 596194676Sthompsa 597195957Salfred operator const MemRegion * const *() const { 598195957Salfred return R; 599194676Sthompsa } 600194676Sthompsa 601194676Sthompsa const VarRegion* operator*() const { 602194676Sthompsa return cast<VarRegion>(*R); 603194676Sthompsa } 604195957Salfred 605195560Sthompsa bool operator==(const referenced_vars_iterator &I) const { 606194676Sthompsa return I.R == R; 607195957Salfred } 608194676Sthompsa bool operator!=(const referenced_vars_iterator &I) const { 609194676Sthompsa return I.R != R; 610195560Sthompsa } 611194676Sthompsa referenced_vars_iterator &operator++() { 612194676Sthompsa ++R; 613199055Sthompsa return *this; 614199055Sthompsa } 615234491Shselasky }; 616199055Sthompsa 617199055Sthompsa referenced_vars_iterator referenced_vars_begin() const; 618199055Sthompsa referenced_vars_iterator referenced_vars_end() const; 619199055Sthompsa 620199055Sthompsa virtual void dumpToStream(raw_ostream &os) const; 621199055Sthompsa 622199055Sthompsa void Profile(llvm::FoldingSetNodeID& ID) const; 623234491Shselasky 624199055Sthompsa static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *, 625199055Sthompsa const LocationContext *, const MemRegion *); 626199055Sthompsa 627199055Sthompsa static bool classof(const MemRegion* R) { 628199055Sthompsa return R->getKind() == BlockDataRegionKind; 629199055Sthompsa } 630234491Shselaskyprivate: 631199055Sthompsa void LazyInitializeReferencedVars(); 632199055Sthompsa}; 633199055Sthompsa 634199055Sthompsa/// SymbolicRegion - A special, "non-concrete" region. Unlike other region 635199055Sthompsa/// clases, SymbolicRegion represents a region that serves as an alias for 636199055Sthompsa/// either a real region, a NULL pointer, etc. It essentially is used to 637234491Shselasky/// map the concept of symbolic values into the domain of regions. Symbolic 638199055Sthompsa/// regions do not need to be typed. 639199055Sthompsaclass SymbolicRegion : public SubRegion { 640199055Sthompsaprotected: 641199055Sthompsa const SymbolRef sym; 642199055Sthompsa 643199055Sthompsapublic: 644234491Shselasky SymbolicRegion(const SymbolRef s, const MemRegion* sreg) 645199055Sthompsa : SubRegion(sreg, SymbolicRegionKind), sym(s) {} 646199055Sthompsa 647199055Sthompsa SymbolRef getSymbol() const { 648199055Sthompsa return sym; 649199055Sthompsa } 650199055Sthompsa 651234491Shselasky bool isBoundable() const { return true; } 652199055Sthompsa 653199055Sthompsa DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 654199055Sthompsa 655199055Sthompsa void Profile(llvm::FoldingSetNodeID& ID) const; 656199055Sthompsa 657199055Sthompsa static void ProfileRegion(llvm::FoldingSetNodeID& ID, 658199055Sthompsa SymbolRef sym, 659199055Sthompsa const MemRegion* superRegion); 660199055Sthompsa 661199055Sthompsa void dumpToStream(raw_ostream &os) const; 662199055Sthompsa 663199055Sthompsa static bool classof(const MemRegion* R) { 664199055Sthompsa return R->getKind() == SymbolicRegionKind; 665199055Sthompsa } 666199055Sthompsa}; 667199055Sthompsa 668199055Sthompsa/// StringRegion - Region associated with a StringLiteral. 669199055Sthompsaclass StringRegion : public TypedValueRegion { 670199055Sthompsa friend class MemRegionManager; 671199055Sthompsa const StringLiteral* Str; 672199055Sthompsaprotected: 673199055Sthompsa 674199055Sthompsa StringRegion(const StringLiteral* str, const MemRegion* sreg) 675199055Sthompsa : TypedValueRegion(sreg, StringRegionKind), Str(str) {} 676199055Sthompsa 677199055Sthompsa static void ProfileRegion(llvm::FoldingSetNodeID& ID, 678199055Sthompsa const StringLiteral* Str, 679199055Sthompsa const MemRegion* superRegion); 680199055Sthompsa 681199055Sthompsapublic: 682199055Sthompsa 683199055Sthompsa const StringLiteral* getStringLiteral() const { return Str; } 684199055Sthompsa 685199055Sthompsa QualType getValueType() const { 686199055Sthompsa return Str->getType(); 687199055Sthompsa } 688199055Sthompsa 689199055Sthompsa DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 690199055Sthompsa 691199055Sthompsa bool isBoundable() const { return false; } 692199055Sthompsa 693199055Sthompsa void Profile(llvm::FoldingSetNodeID& ID) const { 694199055Sthompsa ProfileRegion(ID, Str, superRegion); 695199055Sthompsa } 696199055Sthompsa 697199055Sthompsa void dumpToStream(raw_ostream &os) const; 698199055Sthompsa 699199055Sthompsa static bool classof(const MemRegion* R) { 700199055Sthompsa return R->getKind() == StringRegionKind; 701199055Sthompsa } 702199055Sthompsa}; 703199055Sthompsa 704199055Sthompsa/// The region associated with an ObjCStringLiteral. 705199055Sthompsaclass ObjCStringRegion : public TypedValueRegion { 706199055Sthompsa friend class MemRegionManager; 707199055Sthompsa const ObjCStringLiteral* Str; 708199055Sthompsaprotected: 709199055Sthompsa 710199055Sthompsa ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg) 711199055Sthompsa : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {} 712199055Sthompsa 713199055Sthompsa static void ProfileRegion(llvm::FoldingSetNodeID& ID, 714199055Sthompsa const ObjCStringLiteral* Str, 715199055Sthompsa const MemRegion* superRegion); 716199055Sthompsa 717199055Sthompsapublic: 718199055Sthompsa 719199055Sthompsa const ObjCStringLiteral* getObjCStringLiteral() const { return Str; } 720199055Sthompsa 721199055Sthompsa QualType getValueType() const { 722199055Sthompsa return Str->getType(); 723199055Sthompsa } 724199055Sthompsa 725199055Sthompsa bool isBoundable() const { return false; } 726199055Sthompsa 727199055Sthompsa void Profile(llvm::FoldingSetNodeID& ID) const { 728199055Sthompsa ProfileRegion(ID, Str, superRegion); 729199055Sthompsa } 730199055Sthompsa 731199055Sthompsa void dumpToStream(raw_ostream &os) const; 732199055Sthompsa 733199055Sthompsa static bool classof(const MemRegion* R) { 734199055Sthompsa return R->getKind() == ObjCStringRegionKind; 735199055Sthompsa } 736199055Sthompsa}; 737199055Sthompsa 738199055Sthompsa/// CompoundLiteralRegion - A memory region representing a compound literal. 739199055Sthompsa/// Compound literals are essentially temporaries that are stack allocated 740199055Sthompsa/// or in the global constant pool. 741199055Sthompsaclass CompoundLiteralRegion : public TypedValueRegion { 742199055Sthompsaprivate: 743199055Sthompsa friend class MemRegionManager; 744199055Sthompsa const CompoundLiteralExpr *CL; 745199055Sthompsa 746199055Sthompsa CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg) 747199055Sthompsa : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {} 748199055Sthompsa 749199055Sthompsa static void ProfileRegion(llvm::FoldingSetNodeID& ID, 750199055Sthompsa const CompoundLiteralExpr *CL, 751199055Sthompsa const MemRegion* superRegion); 752199055Sthompsapublic: 753199055Sthompsa QualType getValueType() const { 754199055Sthompsa return CL->getType(); 755199055Sthompsa } 756199055Sthompsa 757199055Sthompsa bool isBoundable() const { return !CL->isFileScope(); } 758199055Sthompsa 759199055Sthompsa void Profile(llvm::FoldingSetNodeID& ID) const; 760199055Sthompsa 761199055Sthompsa void dumpToStream(raw_ostream &os) const; 762199055Sthompsa 763199055Sthompsa const CompoundLiteralExpr *getLiteralExpr() const { return CL; } 764199055Sthompsa 765199055Sthompsa static bool classof(const MemRegion* R) { 766199055Sthompsa return R->getKind() == CompoundLiteralRegionKind; 767199055Sthompsa } 768199055Sthompsa}; 769199055Sthompsa 770class DeclRegion : public TypedValueRegion { 771protected: 772 const Decl *D; 773 774 DeclRegion(const Decl *d, const MemRegion* sReg, Kind k) 775 : TypedValueRegion(sReg, k), D(d) {} 776 777 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D, 778 const MemRegion* superRegion, Kind k); 779 780public: 781 const Decl *getDecl() const { return D; } 782 void Profile(llvm::FoldingSetNodeID& ID) const; 783 784 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 785 786 static bool classof(const MemRegion* R) { 787 unsigned k = R->getKind(); 788 return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS; 789 } 790}; 791 792class VarRegion : public DeclRegion { 793 friend class MemRegionManager; 794 795 // Constructors and private methods. 796 VarRegion(const VarDecl *vd, const MemRegion* sReg) 797 : DeclRegion(vd, sReg, VarRegionKind) {} 798 799 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD, 800 const MemRegion *superRegion) { 801 DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind); 802 } 803 804 void Profile(llvm::FoldingSetNodeID& ID) const; 805 806public: 807 const VarDecl *getDecl() const { return cast<VarDecl>(D); } 808 809 const StackFrameContext *getStackFrame() const; 810 811 QualType getValueType() const { 812 // FIXME: We can cache this if needed. 813 return getDecl()->getType(); 814 } 815 816 void dumpToStream(raw_ostream &os) const; 817 818 static bool classof(const MemRegion* R) { 819 return R->getKind() == VarRegionKind; 820 } 821 822 void dumpPretty(raw_ostream &os) const; 823}; 824 825/// CXXThisRegion - Represents the region for the implicit 'this' parameter 826/// in a call to a C++ method. This region doesn't represent the object 827/// referred to by 'this', but rather 'this' itself. 828class CXXThisRegion : public TypedValueRegion { 829 friend class MemRegionManager; 830 CXXThisRegion(const PointerType *thisPointerTy, 831 const MemRegion *sReg) 832 : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {} 833 834 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 835 const PointerType *PT, 836 const MemRegion *sReg); 837 838 void Profile(llvm::FoldingSetNodeID &ID) const; 839 840public: 841 QualType getValueType() const { 842 return QualType(ThisPointerTy, 0); 843 } 844 845 void dumpToStream(raw_ostream &os) const; 846 847 static bool classof(const MemRegion* R) { 848 return R->getKind() == CXXThisRegionKind; 849 } 850 851private: 852 const PointerType *ThisPointerTy; 853}; 854 855class FieldRegion : public DeclRegion { 856 friend class MemRegionManager; 857 858 FieldRegion(const FieldDecl *fd, const MemRegion* sReg) 859 : DeclRegion(fd, sReg, FieldRegionKind) {} 860 861public: 862 const FieldDecl *getDecl() const { return cast<FieldDecl>(D); } 863 864 QualType getValueType() const { 865 // FIXME: We can cache this if needed. 866 return getDecl()->getType(); 867 } 868 869 DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 870 871 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD, 872 const MemRegion* superRegion) { 873 DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind); 874 } 875 876 static bool classof(const MemRegion* R) { 877 return R->getKind() == FieldRegionKind; 878 } 879 880 void dumpToStream(raw_ostream &os) const; 881 void dumpPretty(raw_ostream &os) const; 882}; 883 884class ObjCIvarRegion : public DeclRegion { 885 886 friend class MemRegionManager; 887 888 ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg); 889 890 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd, 891 const MemRegion* superRegion); 892 893public: 894 const ObjCIvarDecl *getDecl() const; 895 QualType getValueType() const; 896 897 void dumpToStream(raw_ostream &os) const; 898 899 static bool classof(const MemRegion* R) { 900 return R->getKind() == ObjCIvarRegionKind; 901 } 902}; 903//===----------------------------------------------------------------------===// 904// Auxiliary data classes for use with MemRegions. 905//===----------------------------------------------------------------------===// 906 907class ElementRegion; 908 909class RegionRawOffset { 910private: 911 friend class ElementRegion; 912 913 const MemRegion *Region; 914 CharUnits Offset; 915 916 RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero()) 917 : Region(reg), Offset(offset) {} 918 919public: 920 // FIXME: Eventually support symbolic offsets. 921 CharUnits getOffset() const { return Offset; } 922 const MemRegion *getRegion() const { return Region; } 923 924 void dumpToStream(raw_ostream &os) const; 925 void dump() const; 926}; 927 928/// \brief ElementRegin is used to represent both array elements and casts. 929class ElementRegion : public TypedValueRegion { 930 friend class MemRegionManager; 931 932 QualType ElementType; 933 NonLoc Index; 934 935 ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg) 936 : TypedValueRegion(sReg, ElementRegionKind), 937 ElementType(elementType), Index(Idx) { 938 assert((!isa<nonloc::ConcreteInt>(&Idx) || 939 cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) && 940 "The index must be signed"); 941 } 942 943 static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType, 944 SVal Idx, const MemRegion* superRegion); 945 946public: 947 948 NonLoc getIndex() const { return Index; } 949 950 QualType getValueType() const { 951 return ElementType; 952 } 953 954 QualType getElementType() const { 955 return ElementType; 956 } 957 /// Compute the offset within the array. The array might also be a subobject. 958 RegionRawOffset getAsArrayOffset() const; 959 960 void dumpToStream(raw_ostream &os) const; 961 962 void Profile(llvm::FoldingSetNodeID& ID) const; 963 964 static bool classof(const MemRegion* R) { 965 return R->getKind() == ElementRegionKind; 966 } 967}; 968 969// C++ temporary object associated with an expression. 970class CXXTempObjectRegion : public TypedValueRegion { 971 friend class MemRegionManager; 972 973 Expr const *Ex; 974 975 CXXTempObjectRegion(Expr const *E, MemRegion const *sReg) 976 : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {} 977 978 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 979 Expr const *E, const MemRegion *sReg); 980 981public: 982 const Expr *getExpr() const { return Ex; } 983 984 QualType getValueType() const { 985 return Ex->getType(); 986 } 987 988 void dumpToStream(raw_ostream &os) const; 989 990 void Profile(llvm::FoldingSetNodeID &ID) const; 991 992 static bool classof(const MemRegion* R) { 993 return R->getKind() == CXXTempObjectRegionKind; 994 } 995}; 996 997// CXXBaseObjectRegion represents a base object within a C++ object. It is 998// identified by the base class declaration and the region of its parent object. 999class CXXBaseObjectRegion : public TypedValueRegion { 1000 friend class MemRegionManager; 1001 1002 const CXXRecordDecl *decl; 1003 1004 CXXBaseObjectRegion(const CXXRecordDecl *d, const MemRegion *sReg) 1005 : TypedValueRegion(sReg, CXXBaseObjectRegionKind), decl(d) {} 1006 1007 static void ProfileRegion(llvm::FoldingSetNodeID &ID, 1008 const CXXRecordDecl *decl, const MemRegion *sReg); 1009 1010public: 1011 const CXXRecordDecl *getDecl() const { return decl; } 1012 1013 QualType getValueType() const; 1014 1015 void dumpToStream(raw_ostream &os) const; 1016 1017 void Profile(llvm::FoldingSetNodeID &ID) const; 1018 1019 static bool classof(const MemRegion *region) { 1020 return region->getKind() == CXXBaseObjectRegionKind; 1021 } 1022}; 1023 1024template<typename RegionTy> 1025const RegionTy* MemRegion::getAs() const { 1026 if (const RegionTy* RT = dyn_cast<RegionTy>(this)) 1027 return RT; 1028 1029 return NULL; 1030} 1031 1032//===----------------------------------------------------------------------===// 1033// MemRegionManager - Factory object for creating regions. 1034//===----------------------------------------------------------------------===// 1035 1036class MemRegionManager { 1037 ASTContext &C; 1038 llvm::BumpPtrAllocator& A; 1039 llvm::FoldingSet<MemRegion> Regions; 1040 1041 GlobalInternalSpaceRegion *InternalGlobals; 1042 GlobalSystemSpaceRegion *SystemGlobals; 1043 GlobalImmutableSpaceRegion *ImmutableGlobals; 1044 1045 1046 llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *> 1047 StackLocalsSpaceRegions; 1048 llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *> 1049 StackArgumentsSpaceRegions; 1050 llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *> 1051 StaticsGlobalSpaceRegions; 1052 1053 HeapSpaceRegion *heap; 1054 UnknownSpaceRegion *unknown; 1055 MemSpaceRegion *code; 1056 1057public: 1058 MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a) 1059 : C(c), A(a), InternalGlobals(0), SystemGlobals(0), ImmutableGlobals(0), 1060 heap(0), unknown(0), code(0) {} 1061 1062 ~MemRegionManager(); 1063 1064 ASTContext &getContext() { return C; } 1065 1066 llvm::BumpPtrAllocator &getAllocator() { return A; } 1067 1068 /// getStackLocalsRegion - Retrieve the memory region associated with the 1069 /// specified stack frame. 1070 const StackLocalsSpaceRegion * 1071 getStackLocalsRegion(const StackFrameContext *STC); 1072 1073 /// getStackArgumentsRegion - Retrieve the memory region associated with 1074 /// function/method arguments of the specified stack frame. 1075 const StackArgumentsSpaceRegion * 1076 getStackArgumentsRegion(const StackFrameContext *STC); 1077 1078 /// getGlobalsRegion - Retrieve the memory region associated with 1079 /// global variables. 1080 const GlobalsSpaceRegion *getGlobalsRegion( 1081 MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind, 1082 const CodeTextRegion *R = 0); 1083 1084 /// getHeapRegion - Retrieve the memory region associated with the 1085 /// generic "heap". 1086 const HeapSpaceRegion *getHeapRegion(); 1087 1088 /// getUnknownRegion - Retrieve the memory region associated with unknown 1089 /// memory space. 1090 const MemSpaceRegion *getUnknownRegion(); 1091 1092 const MemSpaceRegion *getCodeRegion(); 1093 1094 /// getAllocaRegion - Retrieve a region associated with a call to alloca(). 1095 const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt, 1096 const LocationContext *LC); 1097 1098 /// getCompoundLiteralRegion - Retrieve the region associated with a 1099 /// given CompoundLiteral. 1100 const CompoundLiteralRegion* 1101 getCompoundLiteralRegion(const CompoundLiteralExpr *CL, 1102 const LocationContext *LC); 1103 1104 /// getCXXThisRegion - Retrieve the [artificial] region associated with the 1105 /// parameter 'this'. 1106 const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy, 1107 const LocationContext *LC); 1108 1109 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region. 1110 const SymbolicRegion* getSymbolicRegion(SymbolRef sym); 1111 1112 const StringRegion *getStringRegion(const StringLiteral* Str); 1113 1114 const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str); 1115 1116 /// getVarRegion - Retrieve or create the memory region associated with 1117 /// a specified VarDecl and LocationContext. 1118 const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC); 1119 1120 /// getVarRegion - Retrieve or create the memory region associated with 1121 /// a specified VarDecl and super region. 1122 const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR); 1123 1124 /// getElementRegion - Retrieve the memory region associated with the 1125 /// associated element type, index, and super region. 1126 const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx, 1127 const MemRegion *superRegion, 1128 ASTContext &Ctx); 1129 1130 const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER, 1131 const MemRegion *superRegion) { 1132 return getElementRegion(ER->getElementType(), ER->getIndex(), 1133 superRegion, ER->getContext()); 1134 } 1135 1136 /// getFieldRegion - Retrieve or create the memory region associated with 1137 /// a specified FieldDecl. 'superRegion' corresponds to the containing 1138 /// memory region (which typically represents the memory representing 1139 /// a structure or class). 1140 const FieldRegion *getFieldRegion(const FieldDecl *fd, 1141 const MemRegion* superRegion); 1142 1143 const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR, 1144 const MemRegion *superRegion) { 1145 return getFieldRegion(FR->getDecl(), superRegion); 1146 } 1147 1148 /// getObjCIvarRegion - Retrieve or create the memory region associated with 1149 /// a specified Objective-c instance variable. 'superRegion' corresponds 1150 /// to the containing region (which typically represents the Objective-C 1151 /// object). 1152 const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd, 1153 const MemRegion* superRegion); 1154 1155 const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex, 1156 LocationContext const *LC); 1157 1158 const CXXBaseObjectRegion *getCXXBaseObjectRegion(const CXXRecordDecl *decl, 1159 const MemRegion *superRegion); 1160 1161 /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different 1162 /// super region. 1163 const CXXBaseObjectRegion * 1164 getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg, 1165 const MemRegion *superRegion) { 1166 return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion); 1167 } 1168 1169 const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD); 1170 const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, 1171 CanQualType locTy, 1172 AnalysisDeclContext *AC); 1173 1174 /// getBlockDataRegion - Get the memory region associated with an instance 1175 /// of a block. Unlike many other MemRegions, the LocationContext* 1176 /// argument is allowed to be NULL for cases where we have no known 1177 /// context. 1178 const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc, 1179 const LocationContext *lc = NULL); 1180 1181private: 1182 template <typename RegionTy, typename A1> 1183 RegionTy* getRegion(const A1 a1); 1184 1185 template <typename RegionTy, typename A1> 1186 RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion); 1187 1188 template <typename RegionTy, typename A1, typename A2> 1189 RegionTy* getRegion(const A1 a1, const A2 a2); 1190 1191 template <typename RegionTy, typename A1, typename A2> 1192 RegionTy* getSubRegion(const A1 a1, const A2 a2, 1193 const MemRegion* superRegion); 1194 1195 template <typename RegionTy, typename A1, typename A2, typename A3> 1196 RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3, 1197 const MemRegion* superRegion); 1198 1199 template <typename REG> 1200 const REG* LazyAllocate(REG*& region); 1201 1202 template <typename REG, typename ARG> 1203 const REG* LazyAllocate(REG*& region, ARG a); 1204}; 1205 1206//===----------------------------------------------------------------------===// 1207// Out-of-line member definitions. 1208//===----------------------------------------------------------------------===// 1209 1210inline ASTContext &MemRegion::getContext() const { 1211 return getMemRegionManager()->getContext(); 1212} 1213 1214} // end GR namespace 1215 1216} // end clang namespace 1217 1218//===----------------------------------------------------------------------===// 1219// Pretty-printing regions. 1220//===----------------------------------------------------------------------===// 1221 1222namespace llvm { 1223static inline raw_ostream &operator<<(raw_ostream &os, 1224 const clang::ento::MemRegion* R) { 1225 R->dumpToStream(os); 1226 return os; 1227} 1228} // end llvm namespace 1229 1230#endif 1231