1218887Sdim//== MemRegion.h - 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#ifndef LLVM_CLANG_GR_MEMREGION_H 17218887Sdim#define LLVM_CLANG_GR_MEMREGION_H 18218887Sdim 19239462Sdim#include "clang/AST/ASTContext.h" 20218887Sdim#include "clang/AST/CharUnits.h" 21218887Sdim#include "clang/AST/Decl.h" 22234353Sdim#include "clang/AST/ExprObjC.h" 23226633Sdim#include "clang/Basic/LLVM.h" 24218887Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 25249423Sdim#include "llvm/ADT/FoldingSet.h" 26218887Sdim#include "llvm/Support/ErrorHandling.h" 27218887Sdim#include <string> 28218887Sdim 29218887Sdimnamespace llvm { 30218887Sdimclass BumpPtrAllocator; 31218887Sdim} 32218887Sdim 33218887Sdimnamespace clang { 34218887Sdim 35218887Sdimclass LocationContext; 36218887Sdimclass StackFrameContext; 37218887Sdim 38218887Sdimnamespace ento { 39218887Sdim 40251662Sdimclass CodeTextRegion; 41218887Sdimclass MemRegionManager; 42218887Sdimclass MemSpaceRegion; 43218887Sdimclass SValBuilder; 44251662Sdimclass SymbolicRegion; 45218887Sdimclass VarRegion; 46218887Sdim 47218887Sdim/// Represent a region's offset within the top level base region. 48218887Sdimclass RegionOffset { 49218887Sdim /// The base region. 50218887Sdim const MemRegion *R; 51218887Sdim 52218887Sdim /// The bit offset within the base region. It shouldn't be negative. 53218887Sdim int64_t Offset; 54218887Sdim 55218887Sdimpublic: 56239462Sdim // We're using a const instead of an enumeration due to the size required; 57239462Sdim // Visual Studio will only create enumerations of size int, not long long. 58239462Sdim static const int64_t Symbolic = INT64_MAX; 59239462Sdim 60239462Sdim RegionOffset() : R(0) {} 61218887Sdim RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {} 62218887Sdim 63218887Sdim const MemRegion *getRegion() const { return R; } 64239462Sdim 65239462Sdim bool hasSymbolicOffset() const { return Offset == Symbolic; } 66239462Sdim 67239462Sdim int64_t getOffset() const { 68239462Sdim assert(!hasSymbolicOffset()); 69239462Sdim return Offset; 70239462Sdim } 71239462Sdim 72239462Sdim bool isValid() const { return R; } 73218887Sdim}; 74218887Sdim 75218887Sdim//===----------------------------------------------------------------------===// 76218887Sdim// Base region classes. 77218887Sdim//===----------------------------------------------------------------------===// 78218887Sdim 79218887Sdim/// MemRegion - The root abstract class for all memory regions. 80218887Sdimclass MemRegion : public llvm::FoldingSetNode { 81218887Sdim friend class MemRegionManager; 82218887Sdimpublic: 83218887Sdim enum Kind { 84218887Sdim // Memory spaces. 85218887Sdim GenericMemSpaceRegionKind, 86218887Sdim StackLocalsSpaceRegionKind, 87218887Sdim StackArgumentsSpaceRegionKind, 88218887Sdim HeapSpaceRegionKind, 89218887Sdim UnknownSpaceRegionKind, 90218887Sdim StaticGlobalSpaceRegionKind, 91234353Sdim GlobalInternalSpaceRegionKind, 92234353Sdim GlobalSystemSpaceRegionKind, 93234353Sdim GlobalImmutableSpaceRegionKind, 94234353Sdim BEG_NON_STATIC_GLOBAL_MEMSPACES = GlobalInternalSpaceRegionKind, 95234353Sdim END_NON_STATIC_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind, 96234353Sdim BEG_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind, 97234353Sdim END_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind, 98218887Sdim BEG_MEMSPACES = GenericMemSpaceRegionKind, 99234353Sdim END_MEMSPACES = GlobalImmutableSpaceRegionKind, 100218887Sdim // Untyped regions. 101218887Sdim SymbolicRegionKind, 102218887Sdim AllocaRegionKind, 103218887Sdim // Typed regions. 104218887Sdim BEG_TYPED_REGIONS, 105218887Sdim FunctionTextRegionKind = BEG_TYPED_REGIONS, 106218887Sdim BlockTextRegionKind, 107243830Sdim BlockDataRegionKind, 108226633Sdim BEG_TYPED_VALUE_REGIONS, 109226633Sdim CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS, 110218887Sdim CXXThisRegionKind, 111218887Sdim StringRegionKind, 112234353Sdim ObjCStringRegionKind, 113218887Sdim ElementRegionKind, 114218887Sdim // Decl Regions. 115218887Sdim BEG_DECL_REGIONS, 116218887Sdim VarRegionKind = BEG_DECL_REGIONS, 117218887Sdim FieldRegionKind, 118218887Sdim ObjCIvarRegionKind, 119218887Sdim END_DECL_REGIONS = ObjCIvarRegionKind, 120218887Sdim CXXTempObjectRegionKind, 121218887Sdim CXXBaseObjectRegionKind, 122226633Sdim END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind, 123218887Sdim END_TYPED_REGIONS = CXXBaseObjectRegionKind 124218887Sdim }; 125218887Sdim 126218887Sdimprivate: 127218887Sdim const Kind kind; 128218887Sdim 129218887Sdimprotected: 130218887Sdim MemRegion(Kind k) : kind(k) {} 131218887Sdim virtual ~MemRegion(); 132218887Sdim 133218887Sdimpublic: 134218887Sdim ASTContext &getContext() const; 135218887Sdim 136218887Sdim virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0; 137218887Sdim 138218887Sdim virtual MemRegionManager* getMemRegionManager() const = 0; 139218887Sdim 140218887Sdim const MemSpaceRegion *getMemorySpace() const; 141218887Sdim 142218887Sdim const MemRegion *getBaseRegion() const; 143218887Sdim 144243830Sdim /// Check if the region is a subregion of the given region. 145243830Sdim virtual bool isSubRegionOf(const MemRegion *R) const; 146243830Sdim 147239462Sdim const MemRegion *StripCasts(bool StripBaseCasts = true) const; 148218887Sdim 149251662Sdim /// \brief If this is a symbolic region, returns the region. Otherwise, 150251662Sdim /// goes up the base chain looking for the first symbolic base region. 151251662Sdim const SymbolicRegion *getSymbolicBase() const; 152251662Sdim 153218887Sdim bool hasGlobalsOrParametersStorage() const; 154218887Sdim 155218887Sdim bool hasStackStorage() const; 156218887Sdim 157218887Sdim bool hasStackNonParametersStorage() const; 158218887Sdim 159218887Sdim bool hasStackParametersStorage() const; 160218887Sdim 161218887Sdim /// Compute the offset within the top level memory object. 162218887Sdim RegionOffset getAsOffset() const; 163218887Sdim 164234353Sdim /// \brief Get a string representation of a region for debug use. 165234353Sdim std::string getString() const; 166234353Sdim 167226633Sdim virtual void dumpToStream(raw_ostream &os) const; 168218887Sdim 169218887Sdim void dump() const; 170218887Sdim 171239462Sdim /// \brief Returns true if this region can be printed in a user-friendly way. 172239462Sdim virtual bool canPrintPretty() const; 173239462Sdim 174234353Sdim /// \brief Print the region for use in diagnostics. 175239462Sdim virtual void printPretty(raw_ostream &os) const; 176234353Sdim 177251662Sdim /// \brief Returns true if this region's textual representation can be used 178251662Sdim /// as part of a larger expression. 179251662Sdim virtual bool canPrintPrettyAsExpr() const; 180251662Sdim 181251662Sdim /// \brief Print the region as expression. 182251662Sdim /// 183251662Sdim /// When this region represents a subexpression, the method is for printing 184251662Sdim /// an expression containing it. 185251662Sdim virtual void printPrettyAsExpr(raw_ostream &os) const; 186251662Sdim 187218887Sdim Kind getKind() const { return kind; } 188218887Sdim 189218887Sdim template<typename RegionTy> const RegionTy* getAs() const; 190218887Sdim 191218887Sdim virtual bool isBoundable() const { return false; } 192218887Sdim}; 193218887Sdim 194234353Sdim/// MemSpaceRegion - A memory region that represents a "memory space"; 195218887Sdim/// for example, the set of global variables, the stack frame, etc. 196218887Sdimclass MemSpaceRegion : public MemRegion { 197218887Sdimprotected: 198218887Sdim friend class MemRegionManager; 199218887Sdim 200218887Sdim MemRegionManager *Mgr; 201218887Sdim 202218887Sdim MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind) 203218887Sdim : MemRegion(k), Mgr(mgr) { 204218887Sdim assert(classof(this)); 205218887Sdim } 206218887Sdim 207218887Sdim MemRegionManager* getMemRegionManager() const { return Mgr; } 208218887Sdim 209218887Sdimpublic: 210218887Sdim bool isBoundable() const { return false; } 211218887Sdim 212218887Sdim void Profile(llvm::FoldingSetNodeID &ID) const; 213218887Sdim 214218887Sdim static bool classof(const MemRegion *R) { 215218887Sdim Kind k = R->getKind(); 216218887Sdim return k >= BEG_MEMSPACES && k <= END_MEMSPACES; 217218887Sdim } 218218887Sdim}; 219218887Sdim 220218887Sdimclass GlobalsSpaceRegion : public MemSpaceRegion { 221234353Sdim virtual void anchor(); 222218887Sdimprotected: 223218887Sdim GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) 224218887Sdim : MemSpaceRegion(mgr, k) {} 225218887Sdimpublic: 226218887Sdim static bool classof(const MemRegion *R) { 227218887Sdim Kind k = R->getKind(); 228218887Sdim return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES; 229218887Sdim } 230218887Sdim}; 231234353Sdim 232239462Sdim/// \brief The region of the static variables within the current CodeTextRegion 233234353Sdim/// scope. 234239462Sdim/// 235234353Sdim/// Currently, only the static locals are placed there, so we know that these 236234353Sdim/// variables do not get invalidated by calls to other functions. 237218887Sdimclass StaticGlobalSpaceRegion : public GlobalsSpaceRegion { 238218887Sdim friend class MemRegionManager; 239218887Sdim 240218887Sdim const CodeTextRegion *CR; 241218887Sdim 242218887Sdim StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr) 243218887Sdim : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {} 244218887Sdim 245218887Sdimpublic: 246218887Sdim void Profile(llvm::FoldingSetNodeID &ID) const; 247218887Sdim 248226633Sdim void dumpToStream(raw_ostream &os) const; 249218887Sdim 250218887Sdim const CodeTextRegion *getCodeRegion() const { return CR; } 251218887Sdim 252218887Sdim static bool classof(const MemRegion *R) { 253218887Sdim return R->getKind() == StaticGlobalSpaceRegionKind; 254218887Sdim } 255218887Sdim}; 256234353Sdim 257239462Sdim/// \brief The region for all the non-static global variables. 258234353Sdim/// 259234353Sdim/// This class is further split into subclasses for efficient implementation of 260234353Sdim/// invalidating a set of related global values as is done in 261234353Sdim/// RegionStoreManager::invalidateRegions (instead of finding all the dependent 262234353Sdim/// globals, we invalidate the whole parent region). 263218887Sdimclass NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion { 264218887Sdim friend class MemRegionManager; 265218887Sdim 266234353Sdimprotected: 267234353Sdim NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k) 268234353Sdim : GlobalsSpaceRegion(mgr, k) {} 269218887Sdim 270218887Sdimpublic: 271218887Sdim 272218887Sdim static bool classof(const MemRegion *R) { 273234353Sdim Kind k = R->getKind(); 274234353Sdim return k >= BEG_NON_STATIC_GLOBAL_MEMSPACES && 275234353Sdim k <= END_NON_STATIC_GLOBAL_MEMSPACES; 276218887Sdim } 277218887Sdim}; 278234353Sdim 279239462Sdim/// \brief The region containing globals which are defined in system/external 280234353Sdim/// headers and are considered modifiable by system calls (ex: errno). 281234353Sdimclass GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion { 282234353Sdim friend class MemRegionManager; 283234353Sdim 284234353Sdim GlobalSystemSpaceRegion(MemRegionManager *mgr) 285234353Sdim : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {} 286234353Sdim 287234353Sdimpublic: 288234353Sdim 289234353Sdim void dumpToStream(raw_ostream &os) const; 290234353Sdim 291234353Sdim static bool classof(const MemRegion *R) { 292234353Sdim return R->getKind() == GlobalSystemSpaceRegionKind; 293234353Sdim } 294234353Sdim}; 295234353Sdim 296239462Sdim/// \brief The region containing globals which are considered not to be modified 297234353Sdim/// or point to data which could be modified as a result of a function call 298234353Sdim/// (system or internal). Ex: Const global scalars would be modeled as part of 299234353Sdim/// this region. This region also includes most system globals since they have 300234353Sdim/// low chance of being modified. 301234353Sdimclass GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion { 302234353Sdim friend class MemRegionManager; 303234353Sdim 304234353Sdim GlobalImmutableSpaceRegion(MemRegionManager *mgr) 305234353Sdim : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {} 306234353Sdim 307234353Sdimpublic: 308234353Sdim 309234353Sdim void dumpToStream(raw_ostream &os) const; 310234353Sdim 311234353Sdim static bool classof(const MemRegion *R) { 312234353Sdim return R->getKind() == GlobalImmutableSpaceRegionKind; 313234353Sdim } 314234353Sdim}; 315234353Sdim 316239462Sdim/// \brief The region containing globals which can be modified by calls to 317234353Sdim/// "internally" defined functions - (for now just) functions other then system 318234353Sdim/// calls. 319234353Sdimclass GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion { 320234353Sdim friend class MemRegionManager; 321234353Sdim 322234353Sdim GlobalInternalSpaceRegion(MemRegionManager *mgr) 323234353Sdim : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {} 324234353Sdim 325234353Sdimpublic: 326234353Sdim 327234353Sdim void dumpToStream(raw_ostream &os) const; 328234353Sdim 329234353Sdim static bool classof(const MemRegion *R) { 330234353Sdim return R->getKind() == GlobalInternalSpaceRegionKind; 331234353Sdim } 332234353Sdim}; 333234353Sdim 334218887Sdimclass HeapSpaceRegion : public MemSpaceRegion { 335234353Sdim virtual void anchor(); 336218887Sdim friend class MemRegionManager; 337218887Sdim 338218887Sdim HeapSpaceRegion(MemRegionManager *mgr) 339218887Sdim : MemSpaceRegion(mgr, HeapSpaceRegionKind) {} 340218887Sdimpublic: 341239462Sdim 342239462Sdim void dumpToStream(raw_ostream &os) const; 343239462Sdim 344218887Sdim static bool classof(const MemRegion *R) { 345218887Sdim return R->getKind() == HeapSpaceRegionKind; 346218887Sdim } 347218887Sdim}; 348218887Sdim 349218887Sdimclass UnknownSpaceRegion : public MemSpaceRegion { 350234353Sdim virtual void anchor(); 351218887Sdim friend class MemRegionManager; 352218887Sdim UnknownSpaceRegion(MemRegionManager *mgr) 353218887Sdim : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {} 354218887Sdimpublic: 355239462Sdim 356239462Sdim void dumpToStream(raw_ostream &os) const; 357239462Sdim 358218887Sdim static bool classof(const MemRegion *R) { 359218887Sdim return R->getKind() == UnknownSpaceRegionKind; 360218887Sdim } 361218887Sdim}; 362218887Sdim 363218887Sdimclass StackSpaceRegion : public MemSpaceRegion { 364218887Sdimprivate: 365218887Sdim const StackFrameContext *SFC; 366218887Sdim 367218887Sdimprotected: 368218887Sdim StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc) 369218887Sdim : MemSpaceRegion(mgr, k), SFC(sfc) { 370218887Sdim assert(classof(this)); 371218887Sdim } 372218887Sdim 373218887Sdimpublic: 374218887Sdim const StackFrameContext *getStackFrame() const { return SFC; } 375218887Sdim 376218887Sdim void Profile(llvm::FoldingSetNodeID &ID) const; 377218887Sdim 378218887Sdim static bool classof(const MemRegion *R) { 379218887Sdim Kind k = R->getKind(); 380218887Sdim return k >= StackLocalsSpaceRegionKind && 381218887Sdim k <= StackArgumentsSpaceRegionKind; 382218887Sdim } 383218887Sdim}; 384218887Sdim 385218887Sdimclass StackLocalsSpaceRegion : public StackSpaceRegion { 386234353Sdim virtual void anchor(); 387218887Sdim friend class MemRegionManager; 388218887Sdim StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) 389218887Sdim : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {} 390218887Sdimpublic: 391239462Sdim 392239462Sdim void dumpToStream(raw_ostream &os) const; 393239462Sdim 394218887Sdim static bool classof(const MemRegion *R) { 395218887Sdim return R->getKind() == StackLocalsSpaceRegionKind; 396218887Sdim } 397218887Sdim}; 398218887Sdim 399218887Sdimclass StackArgumentsSpaceRegion : public StackSpaceRegion { 400218887Sdimprivate: 401234353Sdim virtual void anchor(); 402218887Sdim friend class MemRegionManager; 403218887Sdim StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) 404218887Sdim : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {} 405218887Sdimpublic: 406239462Sdim 407239462Sdim void dumpToStream(raw_ostream &os) const; 408239462Sdim 409218887Sdim static bool classof(const MemRegion *R) { 410218887Sdim return R->getKind() == StackArgumentsSpaceRegionKind; 411218887Sdim } 412218887Sdim}; 413218887Sdim 414218887Sdim 415218887Sdim/// SubRegion - A region that subsets another larger region. Most regions 416218887Sdim/// are subclasses of SubRegion. 417218887Sdimclass SubRegion : public MemRegion { 418234353Sdimprivate: 419234353Sdim virtual void anchor(); 420218887Sdimprotected: 421218887Sdim const MemRegion* superRegion; 422218887Sdim SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {} 423218887Sdimpublic: 424218887Sdim const MemRegion* getSuperRegion() const { 425218887Sdim return superRegion; 426218887Sdim } 427218887Sdim 428218887Sdim /// getExtent - Returns the size of the region in bytes. 429218887Sdim virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const { 430218887Sdim return UnknownVal(); 431218887Sdim } 432218887Sdim 433218887Sdim MemRegionManager* getMemRegionManager() const; 434218887Sdim 435243830Sdim virtual bool isSubRegionOf(const MemRegion* R) const; 436218887Sdim 437218887Sdim static bool classof(const MemRegion* R) { 438218887Sdim return R->getKind() > END_MEMSPACES; 439218887Sdim } 440218887Sdim}; 441218887Sdim 442218887Sdim//===----------------------------------------------------------------------===// 443218887Sdim// MemRegion subclasses. 444218887Sdim//===----------------------------------------------------------------------===// 445218887Sdim 446218887Sdim/// AllocaRegion - A region that represents an untyped blob of bytes created 447218887Sdim/// by a call to 'alloca'. 448218887Sdimclass AllocaRegion : public SubRegion { 449218887Sdim friend class MemRegionManager; 450218887Sdimprotected: 451218887Sdim unsigned Cnt; // Block counter. Used to distinguish different pieces of 452218887Sdim // memory allocated by alloca at the same call site. 453226633Sdim const Expr *Ex; 454218887Sdim 455226633Sdim AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion) 456218887Sdim : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {} 457218887Sdim 458218887Sdimpublic: 459218887Sdim 460226633Sdim const Expr *getExpr() const { return Ex; } 461218887Sdim 462218887Sdim bool isBoundable() const { return true; } 463218887Sdim 464218887Sdim DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 465218887Sdim 466218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 467218887Sdim 468226633Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex, 469218887Sdim unsigned Cnt, const MemRegion *superRegion); 470218887Sdim 471226633Sdim void dumpToStream(raw_ostream &os) const; 472218887Sdim 473218887Sdim static bool classof(const MemRegion* R) { 474218887Sdim return R->getKind() == AllocaRegionKind; 475218887Sdim } 476218887Sdim}; 477218887Sdim 478218887Sdim/// TypedRegion - An abstract class representing regions that are typed. 479218887Sdimclass TypedRegion : public SubRegion { 480234353Sdimpublic: 481234353Sdim virtual void anchor(); 482218887Sdimprotected: 483218887Sdim TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {} 484218887Sdim 485218887Sdimpublic: 486226633Sdim virtual QualType getLocationType() const = 0; 487226633Sdim 488226633Sdim QualType getDesugaredLocationType(ASTContext &Context) const { 489226633Sdim return getLocationType().getDesugaredType(Context); 490226633Sdim } 491226633Sdim 492226633Sdim bool isBoundable() const { return true; } 493226633Sdim 494226633Sdim static bool classof(const MemRegion* R) { 495226633Sdim unsigned k = R->getKind(); 496226633Sdim return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS; 497226633Sdim } 498226633Sdim}; 499226633Sdim 500226633Sdim/// TypedValueRegion - An abstract class representing regions having a typed value. 501226633Sdimclass TypedValueRegion : public TypedRegion { 502234353Sdimpublic: 503234353Sdim virtual void anchor(); 504226633Sdimprotected: 505226633Sdim TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {} 506226633Sdim 507226633Sdimpublic: 508218887Sdim virtual QualType getValueType() const = 0; 509218887Sdim 510218887Sdim virtual QualType getLocationType() const { 511218887Sdim // FIXME: We can possibly optimize this later to cache this value. 512218887Sdim QualType T = getValueType(); 513218887Sdim ASTContext &ctx = getContext(); 514218887Sdim if (T->getAs<ObjCObjectType>()) 515218887Sdim return ctx.getObjCObjectPointerType(T); 516218887Sdim return ctx.getPointerType(getValueType()); 517218887Sdim } 518218887Sdim 519218887Sdim QualType getDesugaredValueType(ASTContext &Context) const { 520218887Sdim QualType T = getValueType(); 521218887Sdim return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T; 522218887Sdim } 523218887Sdim 524239462Sdim DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 525239462Sdim 526218887Sdim static bool classof(const MemRegion* R) { 527218887Sdim unsigned k = R->getKind(); 528226633Sdim return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS; 529218887Sdim } 530218887Sdim}; 531218887Sdim 532218887Sdim 533218887Sdimclass CodeTextRegion : public TypedRegion { 534234353Sdimpublic: 535234353Sdim virtual void anchor(); 536218887Sdimprotected: 537218887Sdim CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {} 538218887Sdimpublic: 539218887Sdim bool isBoundable() const { return false; } 540218887Sdim 541218887Sdim static bool classof(const MemRegion* R) { 542218887Sdim Kind k = R->getKind(); 543218887Sdim return k >= FunctionTextRegionKind && k <= BlockTextRegionKind; 544218887Sdim } 545218887Sdim}; 546218887Sdim 547218887Sdim/// FunctionTextRegion - A region that represents code texts of function. 548218887Sdimclass FunctionTextRegion : public CodeTextRegion { 549243830Sdim const NamedDecl *FD; 550218887Sdimpublic: 551243830Sdim FunctionTextRegion(const NamedDecl *fd, const MemRegion* sreg) 552243830Sdim : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) { 553243830Sdim assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd)); 554243830Sdim } 555218887Sdim 556218887Sdim QualType getLocationType() const { 557243830Sdim const ASTContext &Ctx = getContext(); 558243830Sdim if (const FunctionDecl *D = dyn_cast<FunctionDecl>(FD)) { 559243830Sdim return Ctx.getPointerType(D->getType()); 560243830Sdim } 561243830Sdim 562243830Sdim assert(isa<ObjCMethodDecl>(FD)); 563243830Sdim assert(false && "Getting the type of ObjCMethod is not supported yet"); 564243830Sdim 565243830Sdim // TODO: We might want to return a different type here (ex: id (*ty)(...)) 566243830Sdim // depending on how it is used. 567243830Sdim return QualType(); 568218887Sdim } 569243830Sdim 570243830Sdim const NamedDecl *getDecl() const { 571218887Sdim return FD; 572218887Sdim } 573218887Sdim 574226633Sdim virtual void dumpToStream(raw_ostream &os) const; 575218887Sdim 576218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 577218887Sdim 578243830Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD, 579218887Sdim const MemRegion*); 580218887Sdim 581218887Sdim static bool classof(const MemRegion* R) { 582218887Sdim return R->getKind() == FunctionTextRegionKind; 583218887Sdim } 584218887Sdim}; 585218887Sdim 586218887Sdim 587218887Sdim/// BlockTextRegion - A region that represents code texts of blocks (closures). 588218887Sdim/// Blocks are represented with two kinds of regions. BlockTextRegions 589218887Sdim/// represent the "code", while BlockDataRegions represent instances of blocks, 590218887Sdim/// which correspond to "code+data". The distinction is important, because 591218887Sdim/// like a closure a block captures the values of externally referenced 592218887Sdim/// variables. 593218887Sdimclass BlockTextRegion : public CodeTextRegion { 594218887Sdim friend class MemRegionManager; 595218887Sdim 596218887Sdim const BlockDecl *BD; 597234353Sdim AnalysisDeclContext *AC; 598218887Sdim CanQualType locTy; 599218887Sdim 600218887Sdim BlockTextRegion(const BlockDecl *bd, CanQualType lTy, 601234353Sdim AnalysisDeclContext *ac, const MemRegion* sreg) 602218887Sdim : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {} 603218887Sdim 604218887Sdimpublic: 605218887Sdim QualType getLocationType() const { 606218887Sdim return locTy; 607218887Sdim } 608218887Sdim 609218887Sdim const BlockDecl *getDecl() const { 610218887Sdim return BD; 611218887Sdim } 612218887Sdim 613234353Sdim AnalysisDeclContext *getAnalysisDeclContext() const { return AC; } 614218887Sdim 615226633Sdim virtual void dumpToStream(raw_ostream &os) const; 616218887Sdim 617218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 618218887Sdim 619218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD, 620234353Sdim CanQualType, const AnalysisDeclContext*, 621218887Sdim const MemRegion*); 622218887Sdim 623218887Sdim static bool classof(const MemRegion* R) { 624218887Sdim return R->getKind() == BlockTextRegionKind; 625218887Sdim } 626218887Sdim}; 627218887Sdim 628218887Sdim/// BlockDataRegion - A region that represents a block instance. 629218887Sdim/// Blocks are represented with two kinds of regions. BlockTextRegions 630218887Sdim/// represent the "code", while BlockDataRegions represent instances of blocks, 631218887Sdim/// which correspond to "code+data". The distinction is important, because 632218887Sdim/// like a closure a block captures the values of externally referenced 633218887Sdim/// variables. 634243830Sdimclass BlockDataRegion : public TypedRegion { 635218887Sdim friend class MemRegionManager; 636218887Sdim const BlockTextRegion *BC; 637218887Sdim const LocationContext *LC; // Can be null */ 638218887Sdim void *ReferencedVars; 639239462Sdim void *OriginalVars; 640218887Sdim 641218887Sdim BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc, 642218887Sdim const MemRegion *sreg) 643243830Sdim : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), 644239462Sdim ReferencedVars(0), OriginalVars(0) {} 645218887Sdim 646239462Sdimpublic: 647218887Sdim const BlockTextRegion *getCodeRegion() const { return BC; } 648218887Sdim 649218887Sdim const BlockDecl *getDecl() const { return BC->getDecl(); } 650243830Sdim 651243830Sdim QualType getLocationType() const { return BC->getLocationType(); } 652218887Sdim 653218887Sdim class referenced_vars_iterator { 654218887Sdim const MemRegion * const *R; 655239462Sdim const MemRegion * const *OriginalR; 656218887Sdim public: 657239462Sdim explicit referenced_vars_iterator(const MemRegion * const *r, 658239462Sdim const MemRegion * const *originalR) 659239462Sdim : R(r), OriginalR(originalR) {} 660249423Sdim 661249423Sdim const VarRegion *getCapturedRegion() const { 662249423Sdim return cast<VarRegion>(*R); 663218887Sdim } 664249423Sdim const VarRegion *getOriginalRegion() const { 665249423Sdim return cast<VarRegion>(*OriginalR); 666239462Sdim } 667239462Sdim 668218887Sdim bool operator==(const referenced_vars_iterator &I) const { 669249423Sdim assert((R == 0) == (I.R == 0)); 670218887Sdim return I.R == R; 671218887Sdim } 672218887Sdim bool operator!=(const referenced_vars_iterator &I) const { 673249423Sdim assert((R == 0) == (I.R == 0)); 674218887Sdim return I.R != R; 675218887Sdim } 676226633Sdim referenced_vars_iterator &operator++() { 677218887Sdim ++R; 678239462Sdim ++OriginalR; 679218887Sdim return *this; 680218887Sdim } 681218887Sdim }; 682249423Sdim 683249423Sdim /// Return the original region for a captured region, if 684249423Sdim /// one exists. 685249423Sdim const VarRegion *getOriginalRegion(const VarRegion *VR) const; 686218887Sdim 687218887Sdim referenced_vars_iterator referenced_vars_begin() const; 688218887Sdim referenced_vars_iterator referenced_vars_end() const; 689218887Sdim 690226633Sdim virtual void dumpToStream(raw_ostream &os) const; 691218887Sdim 692218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 693218887Sdim 694218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *, 695218887Sdim const LocationContext *, const MemRegion *); 696218887Sdim 697218887Sdim static bool classof(const MemRegion* R) { 698218887Sdim return R->getKind() == BlockDataRegionKind; 699218887Sdim } 700218887Sdimprivate: 701218887Sdim void LazyInitializeReferencedVars(); 702249423Sdim std::pair<const VarRegion *, const VarRegion *> 703249423Sdim getCaptureRegions(const VarDecl *VD); 704218887Sdim}; 705218887Sdim 706218887Sdim/// SymbolicRegion - A special, "non-concrete" region. Unlike other region 707218887Sdim/// clases, SymbolicRegion represents a region that serves as an alias for 708218887Sdim/// either a real region, a NULL pointer, etc. It essentially is used to 709218887Sdim/// map the concept of symbolic values into the domain of regions. Symbolic 710218887Sdim/// regions do not need to be typed. 711218887Sdimclass SymbolicRegion : public SubRegion { 712218887Sdimprotected: 713218887Sdim const SymbolRef sym; 714218887Sdim 715218887Sdimpublic: 716218887Sdim SymbolicRegion(const SymbolRef s, const MemRegion* sreg) 717218887Sdim : SubRegion(sreg, SymbolicRegionKind), sym(s) {} 718218887Sdim 719218887Sdim SymbolRef getSymbol() const { 720218887Sdim return sym; 721218887Sdim } 722218887Sdim 723218887Sdim bool isBoundable() const { return true; } 724218887Sdim 725218887Sdim DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 726218887Sdim 727218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 728218887Sdim 729218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, 730218887Sdim SymbolRef sym, 731218887Sdim const MemRegion* superRegion); 732218887Sdim 733226633Sdim void dumpToStream(raw_ostream &os) const; 734218887Sdim 735218887Sdim static bool classof(const MemRegion* R) { 736218887Sdim return R->getKind() == SymbolicRegionKind; 737218887Sdim } 738218887Sdim}; 739218887Sdim 740218887Sdim/// StringRegion - Region associated with a StringLiteral. 741226633Sdimclass StringRegion : public TypedValueRegion { 742218887Sdim friend class MemRegionManager; 743218887Sdim const StringLiteral* Str; 744218887Sdimprotected: 745218887Sdim 746218887Sdim StringRegion(const StringLiteral* str, const MemRegion* sreg) 747226633Sdim : TypedValueRegion(sreg, StringRegionKind), Str(str) {} 748218887Sdim 749218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, 750218887Sdim const StringLiteral* Str, 751218887Sdim const MemRegion* superRegion); 752218887Sdim 753218887Sdimpublic: 754218887Sdim 755218887Sdim const StringLiteral* getStringLiteral() const { return Str; } 756218887Sdim 757218887Sdim QualType getValueType() const { 758218887Sdim return Str->getType(); 759218887Sdim } 760218887Sdim 761218887Sdim DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 762218887Sdim 763218887Sdim bool isBoundable() const { return false; } 764218887Sdim 765218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const { 766218887Sdim ProfileRegion(ID, Str, superRegion); 767218887Sdim } 768218887Sdim 769226633Sdim void dumpToStream(raw_ostream &os) const; 770218887Sdim 771218887Sdim static bool classof(const MemRegion* R) { 772218887Sdim return R->getKind() == StringRegionKind; 773218887Sdim } 774218887Sdim}; 775234353Sdim 776234353Sdim/// The region associated with an ObjCStringLiteral. 777234353Sdimclass ObjCStringRegion : public TypedValueRegion { 778234353Sdim friend class MemRegionManager; 779234353Sdim const ObjCStringLiteral* Str; 780234353Sdimprotected: 781234353Sdim 782234353Sdim ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg) 783234353Sdim : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {} 784234353Sdim 785234353Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, 786234353Sdim const ObjCStringLiteral* Str, 787234353Sdim const MemRegion* superRegion); 788234353Sdim 789234353Sdimpublic: 790234353Sdim 791234353Sdim const ObjCStringLiteral* getObjCStringLiteral() const { return Str; } 792234353Sdim 793234353Sdim QualType getValueType() const { 794234353Sdim return Str->getType(); 795234353Sdim } 796234353Sdim 797234353Sdim bool isBoundable() const { return false; } 798234353Sdim 799234353Sdim void Profile(llvm::FoldingSetNodeID& ID) const { 800234353Sdim ProfileRegion(ID, Str, superRegion); 801234353Sdim } 802234353Sdim 803234353Sdim void dumpToStream(raw_ostream &os) const; 804234353Sdim 805234353Sdim static bool classof(const MemRegion* R) { 806234353Sdim return R->getKind() == ObjCStringRegionKind; 807234353Sdim } 808234353Sdim}; 809218887Sdim 810218887Sdim/// CompoundLiteralRegion - A memory region representing a compound literal. 811218887Sdim/// Compound literals are essentially temporaries that are stack allocated 812218887Sdim/// or in the global constant pool. 813226633Sdimclass CompoundLiteralRegion : public TypedValueRegion { 814218887Sdimprivate: 815218887Sdim friend class MemRegionManager; 816226633Sdim const CompoundLiteralExpr *CL; 817218887Sdim 818226633Sdim CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg) 819226633Sdim : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {} 820218887Sdim 821218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, 822226633Sdim const CompoundLiteralExpr *CL, 823218887Sdim const MemRegion* superRegion); 824218887Sdimpublic: 825218887Sdim QualType getValueType() const { 826218887Sdim return CL->getType(); 827218887Sdim } 828218887Sdim 829218887Sdim bool isBoundable() const { return !CL->isFileScope(); } 830218887Sdim 831218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 832218887Sdim 833226633Sdim void dumpToStream(raw_ostream &os) const; 834218887Sdim 835226633Sdim const CompoundLiteralExpr *getLiteralExpr() const { return CL; } 836218887Sdim 837218887Sdim static bool classof(const MemRegion* R) { 838218887Sdim return R->getKind() == CompoundLiteralRegionKind; 839218887Sdim } 840218887Sdim}; 841218887Sdim 842226633Sdimclass DeclRegion : public TypedValueRegion { 843218887Sdimprotected: 844226633Sdim const Decl *D; 845218887Sdim 846226633Sdim DeclRegion(const Decl *d, const MemRegion* sReg, Kind k) 847226633Sdim : TypedValueRegion(sReg, k), D(d) {} 848218887Sdim 849226633Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D, 850218887Sdim const MemRegion* superRegion, Kind k); 851218887Sdim 852218887Sdimpublic: 853226633Sdim const Decl *getDecl() const { return D; } 854218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 855218887Sdim 856218887Sdim static bool classof(const MemRegion* R) { 857218887Sdim unsigned k = R->getKind(); 858218887Sdim return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS; 859218887Sdim } 860218887Sdim}; 861218887Sdim 862218887Sdimclass VarRegion : public DeclRegion { 863218887Sdim friend class MemRegionManager; 864218887Sdim 865218887Sdim // Constructors and private methods. 866226633Sdim VarRegion(const VarDecl *vd, const MemRegion* sReg) 867218887Sdim : DeclRegion(vd, sReg, VarRegionKind) {} 868218887Sdim 869226633Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD, 870218887Sdim const MemRegion *superRegion) { 871218887Sdim DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind); 872218887Sdim } 873218887Sdim 874218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 875218887Sdim 876218887Sdimpublic: 877218887Sdim const VarDecl *getDecl() const { return cast<VarDecl>(D); } 878218887Sdim 879218887Sdim const StackFrameContext *getStackFrame() const; 880218887Sdim 881218887Sdim QualType getValueType() const { 882218887Sdim // FIXME: We can cache this if needed. 883218887Sdim return getDecl()->getType(); 884218887Sdim } 885218887Sdim 886226633Sdim void dumpToStream(raw_ostream &os) const; 887218887Sdim 888218887Sdim static bool classof(const MemRegion* R) { 889218887Sdim return R->getKind() == VarRegionKind; 890218887Sdim } 891234353Sdim 892251662Sdim bool canPrintPrettyAsExpr() const; 893251662Sdim 894251662Sdim void printPrettyAsExpr(raw_ostream &os) const; 895218887Sdim}; 896218887Sdim 897218887Sdim/// CXXThisRegion - Represents the region for the implicit 'this' parameter 898218887Sdim/// in a call to a C++ method. This region doesn't represent the object 899218887Sdim/// referred to by 'this', but rather 'this' itself. 900226633Sdimclass CXXThisRegion : public TypedValueRegion { 901218887Sdim friend class MemRegionManager; 902218887Sdim CXXThisRegion(const PointerType *thisPointerTy, 903218887Sdim const MemRegion *sReg) 904226633Sdim : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {} 905218887Sdim 906218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID &ID, 907218887Sdim const PointerType *PT, 908218887Sdim const MemRegion *sReg); 909218887Sdim 910218887Sdim void Profile(llvm::FoldingSetNodeID &ID) const; 911218887Sdim 912218887Sdimpublic: 913218887Sdim QualType getValueType() const { 914218887Sdim return QualType(ThisPointerTy, 0); 915218887Sdim } 916218887Sdim 917226633Sdim void dumpToStream(raw_ostream &os) const; 918218887Sdim 919218887Sdim static bool classof(const MemRegion* R) { 920218887Sdim return R->getKind() == CXXThisRegionKind; 921218887Sdim } 922218887Sdim 923218887Sdimprivate: 924218887Sdim const PointerType *ThisPointerTy; 925218887Sdim}; 926218887Sdim 927218887Sdimclass FieldRegion : public DeclRegion { 928218887Sdim friend class MemRegionManager; 929218887Sdim 930226633Sdim FieldRegion(const FieldDecl *fd, const MemRegion* sReg) 931218887Sdim : DeclRegion(fd, sReg, FieldRegionKind) {} 932218887Sdim 933218887Sdimpublic: 934226633Sdim const FieldDecl *getDecl() const { return cast<FieldDecl>(D); } 935218887Sdim 936218887Sdim QualType getValueType() const { 937218887Sdim // FIXME: We can cache this if needed. 938218887Sdim return getDecl()->getType(); 939218887Sdim } 940218887Sdim 941218887Sdim DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 942218887Sdim 943226633Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD, 944218887Sdim const MemRegion* superRegion) { 945218887Sdim DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind); 946218887Sdim } 947218887Sdim 948218887Sdim static bool classof(const MemRegion* R) { 949218887Sdim return R->getKind() == FieldRegionKind; 950218887Sdim } 951234353Sdim 952234353Sdim void dumpToStream(raw_ostream &os) const; 953239462Sdim 954239462Sdim bool canPrintPretty() const; 955239462Sdim void printPretty(raw_ostream &os) const; 956251662Sdim bool canPrintPrettyAsExpr() const; 957251662Sdim void printPrettyAsExpr(raw_ostream &os) const; 958218887Sdim}; 959218887Sdim 960218887Sdimclass ObjCIvarRegion : public DeclRegion { 961218887Sdim 962218887Sdim friend class MemRegionManager; 963218887Sdim 964234353Sdim ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg); 965218887Sdim 966226633Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd, 967234353Sdim const MemRegion* superRegion); 968218887Sdim 969218887Sdimpublic: 970234353Sdim const ObjCIvarDecl *getDecl() const; 971234353Sdim QualType getValueType() const; 972218887Sdim 973251662Sdim bool canPrintPrettyAsExpr() const; 974251662Sdim void printPrettyAsExpr(raw_ostream &os) const; 975249423Sdim 976226633Sdim void dumpToStream(raw_ostream &os) const; 977218887Sdim 978218887Sdim static bool classof(const MemRegion* R) { 979218887Sdim return R->getKind() == ObjCIvarRegionKind; 980218887Sdim } 981218887Sdim}; 982218887Sdim//===----------------------------------------------------------------------===// 983221345Sdim// Auxiliary data classes for use with MemRegions. 984218887Sdim//===----------------------------------------------------------------------===// 985218887Sdim 986218887Sdimclass ElementRegion; 987218887Sdim 988218887Sdimclass RegionRawOffset { 989218887Sdimprivate: 990218887Sdim friend class ElementRegion; 991218887Sdim 992218887Sdim const MemRegion *Region; 993218887Sdim CharUnits Offset; 994218887Sdim 995218887Sdim RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero()) 996218887Sdim : Region(reg), Offset(offset) {} 997218887Sdim 998218887Sdimpublic: 999218887Sdim // FIXME: Eventually support symbolic offsets. 1000218887Sdim CharUnits getOffset() const { return Offset; } 1001218887Sdim const MemRegion *getRegion() const { return Region; } 1002218887Sdim 1003226633Sdim void dumpToStream(raw_ostream &os) const; 1004218887Sdim void dump() const; 1005218887Sdim}; 1006218887Sdim 1007234353Sdim/// \brief ElementRegin is used to represent both array elements and casts. 1008226633Sdimclass ElementRegion : public TypedValueRegion { 1009218887Sdim friend class MemRegionManager; 1010218887Sdim 1011218887Sdim QualType ElementType; 1012218887Sdim NonLoc Index; 1013218887Sdim 1014218887Sdim ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg) 1015226633Sdim : TypedValueRegion(sReg, ElementRegionKind), 1016218887Sdim ElementType(elementType), Index(Idx) { 1017249423Sdim assert((!Idx.getAs<nonloc::ConcreteInt>() || 1018249423Sdim Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) && 1019218887Sdim "The index must be signed"); 1020218887Sdim } 1021218887Sdim 1022218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType, 1023218887Sdim SVal Idx, const MemRegion* superRegion); 1024218887Sdim 1025218887Sdimpublic: 1026218887Sdim 1027218887Sdim NonLoc getIndex() const { return Index; } 1028218887Sdim 1029218887Sdim QualType getValueType() const { 1030218887Sdim return ElementType; 1031218887Sdim } 1032218887Sdim 1033218887Sdim QualType getElementType() const { 1034218887Sdim return ElementType; 1035218887Sdim } 1036218887Sdim /// Compute the offset within the array. The array might also be a subobject. 1037218887Sdim RegionRawOffset getAsArrayOffset() const; 1038218887Sdim 1039226633Sdim void dumpToStream(raw_ostream &os) const; 1040218887Sdim 1041218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 1042218887Sdim 1043218887Sdim static bool classof(const MemRegion* R) { 1044218887Sdim return R->getKind() == ElementRegionKind; 1045218887Sdim } 1046218887Sdim}; 1047218887Sdim 1048218887Sdim// C++ temporary object associated with an expression. 1049226633Sdimclass CXXTempObjectRegion : public TypedValueRegion { 1050218887Sdim friend class MemRegionManager; 1051218887Sdim 1052218887Sdim Expr const *Ex; 1053218887Sdim 1054218887Sdim CXXTempObjectRegion(Expr const *E, MemRegion const *sReg) 1055226633Sdim : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {} 1056218887Sdim 1057218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID &ID, 1058218887Sdim Expr const *E, const MemRegion *sReg); 1059218887Sdim 1060218887Sdimpublic: 1061226633Sdim const Expr *getExpr() const { return Ex; } 1062226633Sdim 1063218887Sdim QualType getValueType() const { 1064218887Sdim return Ex->getType(); 1065218887Sdim } 1066218887Sdim 1067226633Sdim void dumpToStream(raw_ostream &os) const; 1068218887Sdim 1069218887Sdim void Profile(llvm::FoldingSetNodeID &ID) const; 1070218887Sdim 1071218887Sdim static bool classof(const MemRegion* R) { 1072218887Sdim return R->getKind() == CXXTempObjectRegionKind; 1073218887Sdim } 1074218887Sdim}; 1075218887Sdim 1076218887Sdim// CXXBaseObjectRegion represents a base object within a C++ object. It is 1077218887Sdim// identified by the base class declaration and the region of its parent object. 1078226633Sdimclass CXXBaseObjectRegion : public TypedValueRegion { 1079218887Sdim friend class MemRegionManager; 1080218887Sdim 1081249423Sdim llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data; 1082218887Sdim 1083249423Sdim CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual, 1084249423Sdim const MemRegion *SReg) 1085249423Sdim : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {} 1086218887Sdim 1087249423Sdim static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD, 1088249423Sdim bool IsVirtual, const MemRegion *SReg); 1089218887Sdim 1090218887Sdimpublic: 1091249423Sdim const CXXRecordDecl *getDecl() const { return Data.getPointer(); } 1092249423Sdim bool isVirtual() const { return Data.getInt(); } 1093218887Sdim 1094218887Sdim QualType getValueType() const; 1095218887Sdim 1096226633Sdim void dumpToStream(raw_ostream &os) const; 1097218887Sdim 1098218887Sdim void Profile(llvm::FoldingSetNodeID &ID) const; 1099218887Sdim 1100218887Sdim static bool classof(const MemRegion *region) { 1101218887Sdim return region->getKind() == CXXBaseObjectRegionKind; 1102218887Sdim } 1103251662Sdim 1104251662Sdim bool canPrintPrettyAsExpr() const; 1105251662Sdim 1106251662Sdim void printPrettyAsExpr(raw_ostream &os) const; 1107218887Sdim}; 1108218887Sdim 1109218887Sdimtemplate<typename RegionTy> 1110218887Sdimconst RegionTy* MemRegion::getAs() const { 1111218887Sdim if (const RegionTy* RT = dyn_cast<RegionTy>(this)) 1112218887Sdim return RT; 1113218887Sdim 1114218887Sdim return NULL; 1115218887Sdim} 1116218887Sdim 1117218887Sdim//===----------------------------------------------------------------------===// 1118218887Sdim// MemRegionManager - Factory object for creating regions. 1119218887Sdim//===----------------------------------------------------------------------===// 1120218887Sdim 1121218887Sdimclass MemRegionManager { 1122218887Sdim ASTContext &C; 1123218887Sdim llvm::BumpPtrAllocator& A; 1124218887Sdim llvm::FoldingSet<MemRegion> Regions; 1125218887Sdim 1126234353Sdim GlobalInternalSpaceRegion *InternalGlobals; 1127234353Sdim GlobalSystemSpaceRegion *SystemGlobals; 1128234353Sdim GlobalImmutableSpaceRegion *ImmutableGlobals; 1129234353Sdim 1130218887Sdim 1131218887Sdim llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *> 1132218887Sdim StackLocalsSpaceRegions; 1133218887Sdim llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *> 1134218887Sdim StackArgumentsSpaceRegions; 1135218887Sdim llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *> 1136218887Sdim StaticsGlobalSpaceRegions; 1137218887Sdim 1138218887Sdim HeapSpaceRegion *heap; 1139218887Sdim UnknownSpaceRegion *unknown; 1140218887Sdim MemSpaceRegion *code; 1141218887Sdim 1142218887Sdimpublic: 1143218887Sdim MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a) 1144234353Sdim : C(c), A(a), InternalGlobals(0), SystemGlobals(0), ImmutableGlobals(0), 1145234353Sdim heap(0), unknown(0), code(0) {} 1146218887Sdim 1147218887Sdim ~MemRegionManager(); 1148218887Sdim 1149218887Sdim ASTContext &getContext() { return C; } 1150218887Sdim 1151218887Sdim llvm::BumpPtrAllocator &getAllocator() { return A; } 1152218887Sdim 1153218887Sdim /// getStackLocalsRegion - Retrieve the memory region associated with the 1154218887Sdim /// specified stack frame. 1155218887Sdim const StackLocalsSpaceRegion * 1156218887Sdim getStackLocalsRegion(const StackFrameContext *STC); 1157218887Sdim 1158218887Sdim /// getStackArgumentsRegion - Retrieve the memory region associated with 1159218887Sdim /// function/method arguments of the specified stack frame. 1160218887Sdim const StackArgumentsSpaceRegion * 1161218887Sdim getStackArgumentsRegion(const StackFrameContext *STC); 1162218887Sdim 1163218887Sdim /// getGlobalsRegion - Retrieve the memory region associated with 1164218887Sdim /// global variables. 1165234353Sdim const GlobalsSpaceRegion *getGlobalsRegion( 1166234353Sdim MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind, 1167234353Sdim const CodeTextRegion *R = 0); 1168218887Sdim 1169218887Sdim /// getHeapRegion - Retrieve the memory region associated with the 1170218887Sdim /// generic "heap". 1171218887Sdim const HeapSpaceRegion *getHeapRegion(); 1172218887Sdim 1173218887Sdim /// getUnknownRegion - Retrieve the memory region associated with unknown 1174218887Sdim /// memory space. 1175218887Sdim const MemSpaceRegion *getUnknownRegion(); 1176218887Sdim 1177218887Sdim const MemSpaceRegion *getCodeRegion(); 1178218887Sdim 1179218887Sdim /// getAllocaRegion - Retrieve a region associated with a call to alloca(). 1180226633Sdim const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt, 1181218887Sdim const LocationContext *LC); 1182218887Sdim 1183218887Sdim /// getCompoundLiteralRegion - Retrieve the region associated with a 1184218887Sdim /// given CompoundLiteral. 1185218887Sdim const CompoundLiteralRegion* 1186226633Sdim getCompoundLiteralRegion(const CompoundLiteralExpr *CL, 1187218887Sdim const LocationContext *LC); 1188218887Sdim 1189221345Sdim /// getCXXThisRegion - Retrieve the [artificial] region associated with the 1190218887Sdim /// parameter 'this'. 1191218887Sdim const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy, 1192218887Sdim const LocationContext *LC); 1193218887Sdim 1194239462Sdim /// \brief Retrieve or create a "symbolic" memory region. 1195239462Sdim const SymbolicRegion* getSymbolicRegion(SymbolRef Sym); 1196218887Sdim 1197239462Sdim /// \brief Return a unique symbolic region belonging to heap memory space. 1198239462Sdim const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym); 1199239462Sdim 1200234353Sdim const StringRegion *getStringRegion(const StringLiteral* Str); 1201218887Sdim 1202234353Sdim const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str); 1203234353Sdim 1204218887Sdim /// getVarRegion - Retrieve or create the memory region associated with 1205218887Sdim /// a specified VarDecl and LocationContext. 1206218887Sdim const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC); 1207218887Sdim 1208218887Sdim /// getVarRegion - Retrieve or create the memory region associated with 1209218887Sdim /// a specified VarDecl and super region. 1210218887Sdim const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR); 1211218887Sdim 1212218887Sdim /// getElementRegion - Retrieve the memory region associated with the 1213218887Sdim /// associated element type, index, and super region. 1214218887Sdim const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx, 1215218887Sdim const MemRegion *superRegion, 1216218887Sdim ASTContext &Ctx); 1217218887Sdim 1218218887Sdim const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER, 1219218887Sdim const MemRegion *superRegion) { 1220218887Sdim return getElementRegion(ER->getElementType(), ER->getIndex(), 1221218887Sdim superRegion, ER->getContext()); 1222218887Sdim } 1223218887Sdim 1224218887Sdim /// getFieldRegion - Retrieve or create the memory region associated with 1225218887Sdim /// a specified FieldDecl. 'superRegion' corresponds to the containing 1226218887Sdim /// memory region (which typically represents the memory representing 1227218887Sdim /// a structure or class). 1228226633Sdim const FieldRegion *getFieldRegion(const FieldDecl *fd, 1229218887Sdim const MemRegion* superRegion); 1230218887Sdim 1231218887Sdim const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR, 1232218887Sdim const MemRegion *superRegion) { 1233218887Sdim return getFieldRegion(FR->getDecl(), superRegion); 1234218887Sdim } 1235218887Sdim 1236218887Sdim /// getObjCIvarRegion - Retrieve or create the memory region associated with 1237218887Sdim /// a specified Objective-c instance variable. 'superRegion' corresponds 1238218887Sdim /// to the containing region (which typically represents the Objective-C 1239218887Sdim /// object). 1240226633Sdim const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd, 1241218887Sdim const MemRegion* superRegion); 1242218887Sdim 1243218887Sdim const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex, 1244218887Sdim LocationContext const *LC); 1245218887Sdim 1246249423Sdim /// Create a CXXBaseObjectRegion with the given base class for region 1247249423Sdim /// \p Super. 1248249423Sdim /// 1249249423Sdim /// The type of \p Super is assumed be a class deriving from \p BaseClass. 1250249423Sdim const CXXBaseObjectRegion * 1251249423Sdim getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const MemRegion *Super, 1252249423Sdim bool IsVirtual); 1253218887Sdim 1254218887Sdim /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different 1255218887Sdim /// super region. 1256218887Sdim const CXXBaseObjectRegion * 1257218887Sdim getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg, 1258218887Sdim const MemRegion *superRegion) { 1259249423Sdim return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion, 1260249423Sdim baseReg->isVirtual()); 1261218887Sdim } 1262218887Sdim 1263243830Sdim const FunctionTextRegion *getFunctionTextRegion(const NamedDecl *FD); 1264218887Sdim const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, 1265218887Sdim CanQualType locTy, 1266234353Sdim AnalysisDeclContext *AC); 1267218887Sdim 1268218887Sdim /// getBlockDataRegion - Get the memory region associated with an instance 1269218887Sdim /// of a block. Unlike many other MemRegions, the LocationContext* 1270218887Sdim /// argument is allowed to be NULL for cases where we have no known 1271218887Sdim /// context. 1272218887Sdim const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc, 1273218887Sdim const LocationContext *lc = NULL); 1274218887Sdim 1275218887Sdimprivate: 1276218887Sdim template <typename RegionTy, typename A1> 1277218887Sdim RegionTy* getRegion(const A1 a1); 1278218887Sdim 1279218887Sdim template <typename RegionTy, typename A1> 1280218887Sdim RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion); 1281218887Sdim 1282218887Sdim template <typename RegionTy, typename A1, typename A2> 1283218887Sdim RegionTy* getRegion(const A1 a1, const A2 a2); 1284218887Sdim 1285218887Sdim template <typename RegionTy, typename A1, typename A2> 1286218887Sdim RegionTy* getSubRegion(const A1 a1, const A2 a2, 1287218887Sdim const MemRegion* superRegion); 1288218887Sdim 1289218887Sdim template <typename RegionTy, typename A1, typename A2, typename A3> 1290218887Sdim RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3, 1291218887Sdim const MemRegion* superRegion); 1292218887Sdim 1293218887Sdim template <typename REG> 1294218887Sdim const REG* LazyAllocate(REG*& region); 1295218887Sdim 1296218887Sdim template <typename REG, typename ARG> 1297218887Sdim const REG* LazyAllocate(REG*& region, ARG a); 1298218887Sdim}; 1299218887Sdim 1300218887Sdim//===----------------------------------------------------------------------===// 1301218887Sdim// Out-of-line member definitions. 1302218887Sdim//===----------------------------------------------------------------------===// 1303218887Sdim 1304226633Sdiminline ASTContext &MemRegion::getContext() const { 1305218887Sdim return getMemRegionManager()->getContext(); 1306218887Sdim} 1307218887Sdim 1308218887Sdim} // end GR namespace 1309218887Sdim 1310218887Sdim} // end clang namespace 1311218887Sdim 1312218887Sdim//===----------------------------------------------------------------------===// 1313218887Sdim// Pretty-printing regions. 1314218887Sdim//===----------------------------------------------------------------------===// 1315218887Sdim 1316218887Sdimnamespace llvm { 1317226633Sdimstatic inline raw_ostream &operator<<(raw_ostream &os, 1318218887Sdim const clang::ento::MemRegion* R) { 1319218887Sdim R->dumpToStream(os); 1320218887Sdim return os; 1321218887Sdim} 1322218887Sdim} // end llvm namespace 1323218887Sdim 1324218887Sdim#endif 1325