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 */ 638263508Sdim unsigned BlockCount; 639218887Sdim void *ReferencedVars; 640239462Sdim void *OriginalVars; 641218887Sdim 642218887Sdim BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc, 643263508Sdim unsigned count, const MemRegion *sreg) 644243830Sdim : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), 645263508Sdim BlockCount(count), 646239462Sdim ReferencedVars(0), OriginalVars(0) {} 647218887Sdim 648239462Sdimpublic: 649218887Sdim const BlockTextRegion *getCodeRegion() const { return BC; } 650218887Sdim 651218887Sdim const BlockDecl *getDecl() const { return BC->getDecl(); } 652243830Sdim 653243830Sdim QualType getLocationType() const { return BC->getLocationType(); } 654218887Sdim 655218887Sdim class referenced_vars_iterator { 656218887Sdim const MemRegion * const *R; 657239462Sdim const MemRegion * const *OriginalR; 658218887Sdim public: 659239462Sdim explicit referenced_vars_iterator(const MemRegion * const *r, 660239462Sdim const MemRegion * const *originalR) 661239462Sdim : R(r), OriginalR(originalR) {} 662249423Sdim 663249423Sdim const VarRegion *getCapturedRegion() const { 664249423Sdim return cast<VarRegion>(*R); 665218887Sdim } 666249423Sdim const VarRegion *getOriginalRegion() const { 667249423Sdim return cast<VarRegion>(*OriginalR); 668239462Sdim } 669239462Sdim 670218887Sdim bool operator==(const referenced_vars_iterator &I) const { 671249423Sdim assert((R == 0) == (I.R == 0)); 672218887Sdim return I.R == R; 673218887Sdim } 674218887Sdim bool operator!=(const referenced_vars_iterator &I) const { 675249423Sdim assert((R == 0) == (I.R == 0)); 676218887Sdim return I.R != R; 677218887Sdim } 678226633Sdim referenced_vars_iterator &operator++() { 679218887Sdim ++R; 680239462Sdim ++OriginalR; 681218887Sdim return *this; 682218887Sdim } 683218887Sdim }; 684249423Sdim 685249423Sdim /// Return the original region for a captured region, if 686249423Sdim /// one exists. 687249423Sdim const VarRegion *getOriginalRegion(const VarRegion *VR) const; 688218887Sdim 689218887Sdim referenced_vars_iterator referenced_vars_begin() const; 690218887Sdim referenced_vars_iterator referenced_vars_end() const; 691218887Sdim 692226633Sdim virtual void dumpToStream(raw_ostream &os) const; 693218887Sdim 694218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 695218887Sdim 696218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *, 697263508Sdim const LocationContext *, unsigned, 698263508Sdim const MemRegion *); 699218887Sdim 700218887Sdim static bool classof(const MemRegion* R) { 701218887Sdim return R->getKind() == BlockDataRegionKind; 702218887Sdim } 703218887Sdimprivate: 704218887Sdim void LazyInitializeReferencedVars(); 705249423Sdim std::pair<const VarRegion *, const VarRegion *> 706249423Sdim getCaptureRegions(const VarDecl *VD); 707218887Sdim}; 708218887Sdim 709218887Sdim/// SymbolicRegion - A special, "non-concrete" region. Unlike other region 710218887Sdim/// clases, SymbolicRegion represents a region that serves as an alias for 711218887Sdim/// either a real region, a NULL pointer, etc. It essentially is used to 712218887Sdim/// map the concept of symbolic values into the domain of regions. Symbolic 713218887Sdim/// regions do not need to be typed. 714218887Sdimclass SymbolicRegion : public SubRegion { 715218887Sdimprotected: 716218887Sdim const SymbolRef sym; 717218887Sdim 718218887Sdimpublic: 719218887Sdim SymbolicRegion(const SymbolRef s, const MemRegion* sreg) 720218887Sdim : SubRegion(sreg, SymbolicRegionKind), sym(s) {} 721218887Sdim 722218887Sdim SymbolRef getSymbol() const { 723218887Sdim return sym; 724218887Sdim } 725218887Sdim 726218887Sdim bool isBoundable() const { return true; } 727218887Sdim 728218887Sdim DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 729218887Sdim 730218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 731218887Sdim 732218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, 733218887Sdim SymbolRef sym, 734218887Sdim const MemRegion* superRegion); 735218887Sdim 736226633Sdim void dumpToStream(raw_ostream &os) const; 737218887Sdim 738218887Sdim static bool classof(const MemRegion* R) { 739218887Sdim return R->getKind() == SymbolicRegionKind; 740218887Sdim } 741218887Sdim}; 742218887Sdim 743218887Sdim/// StringRegion - Region associated with a StringLiteral. 744226633Sdimclass StringRegion : public TypedValueRegion { 745218887Sdim friend class MemRegionManager; 746218887Sdim const StringLiteral* Str; 747218887Sdimprotected: 748218887Sdim 749218887Sdim StringRegion(const StringLiteral* str, const MemRegion* sreg) 750226633Sdim : TypedValueRegion(sreg, StringRegionKind), Str(str) {} 751218887Sdim 752218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, 753218887Sdim const StringLiteral* Str, 754218887Sdim const MemRegion* superRegion); 755218887Sdim 756218887Sdimpublic: 757218887Sdim 758218887Sdim const StringLiteral* getStringLiteral() const { return Str; } 759218887Sdim 760218887Sdim QualType getValueType() const { 761218887Sdim return Str->getType(); 762218887Sdim } 763218887Sdim 764218887Sdim DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 765218887Sdim 766218887Sdim bool isBoundable() const { return false; } 767218887Sdim 768218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const { 769218887Sdim ProfileRegion(ID, Str, superRegion); 770218887Sdim } 771218887Sdim 772226633Sdim void dumpToStream(raw_ostream &os) const; 773218887Sdim 774218887Sdim static bool classof(const MemRegion* R) { 775218887Sdim return R->getKind() == StringRegionKind; 776218887Sdim } 777218887Sdim}; 778234353Sdim 779234353Sdim/// The region associated with an ObjCStringLiteral. 780234353Sdimclass ObjCStringRegion : public TypedValueRegion { 781234353Sdim friend class MemRegionManager; 782234353Sdim const ObjCStringLiteral* Str; 783234353Sdimprotected: 784234353Sdim 785234353Sdim ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg) 786234353Sdim : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {} 787234353Sdim 788234353Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, 789234353Sdim const ObjCStringLiteral* Str, 790234353Sdim const MemRegion* superRegion); 791234353Sdim 792234353Sdimpublic: 793234353Sdim 794234353Sdim const ObjCStringLiteral* getObjCStringLiteral() const { return Str; } 795234353Sdim 796234353Sdim QualType getValueType() const { 797234353Sdim return Str->getType(); 798234353Sdim } 799234353Sdim 800234353Sdim bool isBoundable() const { return false; } 801234353Sdim 802234353Sdim void Profile(llvm::FoldingSetNodeID& ID) const { 803234353Sdim ProfileRegion(ID, Str, superRegion); 804234353Sdim } 805234353Sdim 806234353Sdim void dumpToStream(raw_ostream &os) const; 807234353Sdim 808234353Sdim static bool classof(const MemRegion* R) { 809234353Sdim return R->getKind() == ObjCStringRegionKind; 810234353Sdim } 811234353Sdim}; 812218887Sdim 813218887Sdim/// CompoundLiteralRegion - A memory region representing a compound literal. 814218887Sdim/// Compound literals are essentially temporaries that are stack allocated 815218887Sdim/// or in the global constant pool. 816226633Sdimclass CompoundLiteralRegion : public TypedValueRegion { 817218887Sdimprivate: 818218887Sdim friend class MemRegionManager; 819226633Sdim const CompoundLiteralExpr *CL; 820218887Sdim 821226633Sdim CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg) 822226633Sdim : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {} 823218887Sdim 824218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, 825226633Sdim const CompoundLiteralExpr *CL, 826218887Sdim const MemRegion* superRegion); 827218887Sdimpublic: 828218887Sdim QualType getValueType() const { 829218887Sdim return CL->getType(); 830218887Sdim } 831218887Sdim 832218887Sdim bool isBoundable() const { return !CL->isFileScope(); } 833218887Sdim 834218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 835218887Sdim 836226633Sdim void dumpToStream(raw_ostream &os) const; 837218887Sdim 838226633Sdim const CompoundLiteralExpr *getLiteralExpr() const { return CL; } 839218887Sdim 840218887Sdim static bool classof(const MemRegion* R) { 841218887Sdim return R->getKind() == CompoundLiteralRegionKind; 842218887Sdim } 843218887Sdim}; 844218887Sdim 845226633Sdimclass DeclRegion : public TypedValueRegion { 846218887Sdimprotected: 847226633Sdim const Decl *D; 848218887Sdim 849226633Sdim DeclRegion(const Decl *d, const MemRegion* sReg, Kind k) 850226633Sdim : TypedValueRegion(sReg, k), D(d) {} 851218887Sdim 852226633Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D, 853218887Sdim const MemRegion* superRegion, Kind k); 854218887Sdim 855218887Sdimpublic: 856226633Sdim const Decl *getDecl() const { return D; } 857218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 858218887Sdim 859218887Sdim static bool classof(const MemRegion* R) { 860218887Sdim unsigned k = R->getKind(); 861218887Sdim return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS; 862218887Sdim } 863218887Sdim}; 864218887Sdim 865218887Sdimclass VarRegion : public DeclRegion { 866218887Sdim friend class MemRegionManager; 867218887Sdim 868218887Sdim // Constructors and private methods. 869226633Sdim VarRegion(const VarDecl *vd, const MemRegion* sReg) 870218887Sdim : DeclRegion(vd, sReg, VarRegionKind) {} 871218887Sdim 872226633Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD, 873218887Sdim const MemRegion *superRegion) { 874218887Sdim DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind); 875218887Sdim } 876218887Sdim 877218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 878218887Sdim 879218887Sdimpublic: 880218887Sdim const VarDecl *getDecl() const { return cast<VarDecl>(D); } 881218887Sdim 882218887Sdim const StackFrameContext *getStackFrame() const; 883218887Sdim 884218887Sdim QualType getValueType() const { 885218887Sdim // FIXME: We can cache this if needed. 886218887Sdim return getDecl()->getType(); 887218887Sdim } 888218887Sdim 889226633Sdim void dumpToStream(raw_ostream &os) const; 890218887Sdim 891218887Sdim static bool classof(const MemRegion* R) { 892218887Sdim return R->getKind() == VarRegionKind; 893218887Sdim } 894234353Sdim 895251662Sdim bool canPrintPrettyAsExpr() const; 896251662Sdim 897251662Sdim void printPrettyAsExpr(raw_ostream &os) const; 898218887Sdim}; 899218887Sdim 900218887Sdim/// CXXThisRegion - Represents the region for the implicit 'this' parameter 901218887Sdim/// in a call to a C++ method. This region doesn't represent the object 902218887Sdim/// referred to by 'this', but rather 'this' itself. 903226633Sdimclass CXXThisRegion : public TypedValueRegion { 904218887Sdim friend class MemRegionManager; 905218887Sdim CXXThisRegion(const PointerType *thisPointerTy, 906218887Sdim const MemRegion *sReg) 907226633Sdim : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {} 908218887Sdim 909218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID &ID, 910218887Sdim const PointerType *PT, 911218887Sdim const MemRegion *sReg); 912218887Sdim 913218887Sdim void Profile(llvm::FoldingSetNodeID &ID) const; 914218887Sdim 915218887Sdimpublic: 916218887Sdim QualType getValueType() const { 917218887Sdim return QualType(ThisPointerTy, 0); 918218887Sdim } 919218887Sdim 920226633Sdim void dumpToStream(raw_ostream &os) const; 921218887Sdim 922218887Sdim static bool classof(const MemRegion* R) { 923218887Sdim return R->getKind() == CXXThisRegionKind; 924218887Sdim } 925218887Sdim 926218887Sdimprivate: 927218887Sdim const PointerType *ThisPointerTy; 928218887Sdim}; 929218887Sdim 930218887Sdimclass FieldRegion : public DeclRegion { 931218887Sdim friend class MemRegionManager; 932218887Sdim 933226633Sdim FieldRegion(const FieldDecl *fd, const MemRegion* sReg) 934218887Sdim : DeclRegion(fd, sReg, FieldRegionKind) {} 935218887Sdim 936218887Sdimpublic: 937226633Sdim const FieldDecl *getDecl() const { return cast<FieldDecl>(D); } 938218887Sdim 939218887Sdim QualType getValueType() const { 940218887Sdim // FIXME: We can cache this if needed. 941218887Sdim return getDecl()->getType(); 942218887Sdim } 943218887Sdim 944218887Sdim DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const; 945218887Sdim 946226633Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD, 947218887Sdim const MemRegion* superRegion) { 948218887Sdim DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind); 949218887Sdim } 950218887Sdim 951218887Sdim static bool classof(const MemRegion* R) { 952218887Sdim return R->getKind() == FieldRegionKind; 953218887Sdim } 954234353Sdim 955234353Sdim void dumpToStream(raw_ostream &os) const; 956239462Sdim 957239462Sdim bool canPrintPretty() const; 958239462Sdim void printPretty(raw_ostream &os) const; 959251662Sdim bool canPrintPrettyAsExpr() const; 960251662Sdim void printPrettyAsExpr(raw_ostream &os) const; 961218887Sdim}; 962218887Sdim 963218887Sdimclass ObjCIvarRegion : public DeclRegion { 964218887Sdim 965218887Sdim friend class MemRegionManager; 966218887Sdim 967234353Sdim ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg); 968218887Sdim 969226633Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd, 970234353Sdim const MemRegion* superRegion); 971218887Sdim 972218887Sdimpublic: 973234353Sdim const ObjCIvarDecl *getDecl() const; 974234353Sdim QualType getValueType() const; 975218887Sdim 976251662Sdim bool canPrintPrettyAsExpr() const; 977251662Sdim void printPrettyAsExpr(raw_ostream &os) const; 978249423Sdim 979226633Sdim void dumpToStream(raw_ostream &os) const; 980218887Sdim 981218887Sdim static bool classof(const MemRegion* R) { 982218887Sdim return R->getKind() == ObjCIvarRegionKind; 983218887Sdim } 984218887Sdim}; 985218887Sdim//===----------------------------------------------------------------------===// 986221345Sdim// Auxiliary data classes for use with MemRegions. 987218887Sdim//===----------------------------------------------------------------------===// 988218887Sdim 989218887Sdimclass ElementRegion; 990218887Sdim 991218887Sdimclass RegionRawOffset { 992218887Sdimprivate: 993218887Sdim friend class ElementRegion; 994218887Sdim 995218887Sdim const MemRegion *Region; 996218887Sdim CharUnits Offset; 997218887Sdim 998218887Sdim RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero()) 999218887Sdim : Region(reg), Offset(offset) {} 1000218887Sdim 1001218887Sdimpublic: 1002218887Sdim // FIXME: Eventually support symbolic offsets. 1003218887Sdim CharUnits getOffset() const { return Offset; } 1004218887Sdim const MemRegion *getRegion() const { return Region; } 1005218887Sdim 1006226633Sdim void dumpToStream(raw_ostream &os) const; 1007218887Sdim void dump() const; 1008218887Sdim}; 1009218887Sdim 1010234353Sdim/// \brief ElementRegin is used to represent both array elements and casts. 1011226633Sdimclass ElementRegion : public TypedValueRegion { 1012218887Sdim friend class MemRegionManager; 1013218887Sdim 1014218887Sdim QualType ElementType; 1015218887Sdim NonLoc Index; 1016218887Sdim 1017218887Sdim ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg) 1018226633Sdim : TypedValueRegion(sReg, ElementRegionKind), 1019218887Sdim ElementType(elementType), Index(Idx) { 1020249423Sdim assert((!Idx.getAs<nonloc::ConcreteInt>() || 1021249423Sdim Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) && 1022218887Sdim "The index must be signed"); 1023218887Sdim } 1024218887Sdim 1025218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType, 1026218887Sdim SVal Idx, const MemRegion* superRegion); 1027218887Sdim 1028218887Sdimpublic: 1029218887Sdim 1030218887Sdim NonLoc getIndex() const { return Index; } 1031218887Sdim 1032218887Sdim QualType getValueType() const { 1033218887Sdim return ElementType; 1034218887Sdim } 1035218887Sdim 1036218887Sdim QualType getElementType() const { 1037218887Sdim return ElementType; 1038218887Sdim } 1039218887Sdim /// Compute the offset within the array. The array might also be a subobject. 1040218887Sdim RegionRawOffset getAsArrayOffset() const; 1041218887Sdim 1042226633Sdim void dumpToStream(raw_ostream &os) const; 1043218887Sdim 1044218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const; 1045218887Sdim 1046218887Sdim static bool classof(const MemRegion* R) { 1047218887Sdim return R->getKind() == ElementRegionKind; 1048218887Sdim } 1049218887Sdim}; 1050218887Sdim 1051218887Sdim// C++ temporary object associated with an expression. 1052226633Sdimclass CXXTempObjectRegion : public TypedValueRegion { 1053218887Sdim friend class MemRegionManager; 1054218887Sdim 1055218887Sdim Expr const *Ex; 1056218887Sdim 1057218887Sdim CXXTempObjectRegion(Expr const *E, MemRegion const *sReg) 1058226633Sdim : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {} 1059218887Sdim 1060218887Sdim static void ProfileRegion(llvm::FoldingSetNodeID &ID, 1061218887Sdim Expr const *E, const MemRegion *sReg); 1062218887Sdim 1063218887Sdimpublic: 1064226633Sdim const Expr *getExpr() const { return Ex; } 1065226633Sdim 1066218887Sdim QualType getValueType() const { 1067218887Sdim return Ex->getType(); 1068218887Sdim } 1069218887Sdim 1070226633Sdim void dumpToStream(raw_ostream &os) const; 1071218887Sdim 1072218887Sdim void Profile(llvm::FoldingSetNodeID &ID) const; 1073218887Sdim 1074218887Sdim static bool classof(const MemRegion* R) { 1075218887Sdim return R->getKind() == CXXTempObjectRegionKind; 1076218887Sdim } 1077218887Sdim}; 1078218887Sdim 1079218887Sdim// CXXBaseObjectRegion represents a base object within a C++ object. It is 1080218887Sdim// identified by the base class declaration and the region of its parent object. 1081226633Sdimclass CXXBaseObjectRegion : public TypedValueRegion { 1082218887Sdim friend class MemRegionManager; 1083218887Sdim 1084249423Sdim llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data; 1085218887Sdim 1086249423Sdim CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual, 1087249423Sdim const MemRegion *SReg) 1088249423Sdim : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {} 1089218887Sdim 1090249423Sdim static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD, 1091249423Sdim bool IsVirtual, const MemRegion *SReg); 1092218887Sdim 1093218887Sdimpublic: 1094249423Sdim const CXXRecordDecl *getDecl() const { return Data.getPointer(); } 1095249423Sdim bool isVirtual() const { return Data.getInt(); } 1096218887Sdim 1097218887Sdim QualType getValueType() const; 1098218887Sdim 1099226633Sdim void dumpToStream(raw_ostream &os) const; 1100218887Sdim 1101218887Sdim void Profile(llvm::FoldingSetNodeID &ID) const; 1102218887Sdim 1103218887Sdim static bool classof(const MemRegion *region) { 1104218887Sdim return region->getKind() == CXXBaseObjectRegionKind; 1105218887Sdim } 1106251662Sdim 1107251662Sdim bool canPrintPrettyAsExpr() const; 1108251662Sdim 1109251662Sdim void printPrettyAsExpr(raw_ostream &os) const; 1110218887Sdim}; 1111218887Sdim 1112218887Sdimtemplate<typename RegionTy> 1113218887Sdimconst RegionTy* MemRegion::getAs() const { 1114218887Sdim if (const RegionTy* RT = dyn_cast<RegionTy>(this)) 1115218887Sdim return RT; 1116218887Sdim 1117218887Sdim return NULL; 1118218887Sdim} 1119218887Sdim 1120218887Sdim//===----------------------------------------------------------------------===// 1121218887Sdim// MemRegionManager - Factory object for creating regions. 1122218887Sdim//===----------------------------------------------------------------------===// 1123218887Sdim 1124218887Sdimclass MemRegionManager { 1125218887Sdim ASTContext &C; 1126218887Sdim llvm::BumpPtrAllocator& A; 1127218887Sdim llvm::FoldingSet<MemRegion> Regions; 1128218887Sdim 1129234353Sdim GlobalInternalSpaceRegion *InternalGlobals; 1130234353Sdim GlobalSystemSpaceRegion *SystemGlobals; 1131234353Sdim GlobalImmutableSpaceRegion *ImmutableGlobals; 1132234353Sdim 1133218887Sdim 1134218887Sdim llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *> 1135218887Sdim StackLocalsSpaceRegions; 1136218887Sdim llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *> 1137218887Sdim StackArgumentsSpaceRegions; 1138218887Sdim llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *> 1139218887Sdim StaticsGlobalSpaceRegions; 1140218887Sdim 1141218887Sdim HeapSpaceRegion *heap; 1142218887Sdim UnknownSpaceRegion *unknown; 1143218887Sdim MemSpaceRegion *code; 1144218887Sdim 1145218887Sdimpublic: 1146218887Sdim MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a) 1147234353Sdim : C(c), A(a), InternalGlobals(0), SystemGlobals(0), ImmutableGlobals(0), 1148234353Sdim heap(0), unknown(0), code(0) {} 1149218887Sdim 1150218887Sdim ~MemRegionManager(); 1151218887Sdim 1152218887Sdim ASTContext &getContext() { return C; } 1153218887Sdim 1154218887Sdim llvm::BumpPtrAllocator &getAllocator() { return A; } 1155218887Sdim 1156218887Sdim /// getStackLocalsRegion - Retrieve the memory region associated with the 1157218887Sdim /// specified stack frame. 1158218887Sdim const StackLocalsSpaceRegion * 1159218887Sdim getStackLocalsRegion(const StackFrameContext *STC); 1160218887Sdim 1161218887Sdim /// getStackArgumentsRegion - Retrieve the memory region associated with 1162218887Sdim /// function/method arguments of the specified stack frame. 1163218887Sdim const StackArgumentsSpaceRegion * 1164218887Sdim getStackArgumentsRegion(const StackFrameContext *STC); 1165218887Sdim 1166218887Sdim /// getGlobalsRegion - Retrieve the memory region associated with 1167218887Sdim /// global variables. 1168234353Sdim const GlobalsSpaceRegion *getGlobalsRegion( 1169234353Sdim MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind, 1170234353Sdim const CodeTextRegion *R = 0); 1171218887Sdim 1172218887Sdim /// getHeapRegion - Retrieve the memory region associated with the 1173218887Sdim /// generic "heap". 1174218887Sdim const HeapSpaceRegion *getHeapRegion(); 1175218887Sdim 1176218887Sdim /// getUnknownRegion - Retrieve the memory region associated with unknown 1177218887Sdim /// memory space. 1178218887Sdim const MemSpaceRegion *getUnknownRegion(); 1179218887Sdim 1180218887Sdim const MemSpaceRegion *getCodeRegion(); 1181218887Sdim 1182218887Sdim /// getAllocaRegion - Retrieve a region associated with a call to alloca(). 1183226633Sdim const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt, 1184218887Sdim const LocationContext *LC); 1185218887Sdim 1186218887Sdim /// getCompoundLiteralRegion - Retrieve the region associated with a 1187218887Sdim /// given CompoundLiteral. 1188218887Sdim const CompoundLiteralRegion* 1189226633Sdim getCompoundLiteralRegion(const CompoundLiteralExpr *CL, 1190218887Sdim const LocationContext *LC); 1191218887Sdim 1192221345Sdim /// getCXXThisRegion - Retrieve the [artificial] region associated with the 1193218887Sdim /// parameter 'this'. 1194218887Sdim const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy, 1195218887Sdim const LocationContext *LC); 1196218887Sdim 1197239462Sdim /// \brief Retrieve or create a "symbolic" memory region. 1198239462Sdim const SymbolicRegion* getSymbolicRegion(SymbolRef Sym); 1199218887Sdim 1200239462Sdim /// \brief Return a unique symbolic region belonging to heap memory space. 1201239462Sdim const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym); 1202239462Sdim 1203234353Sdim const StringRegion *getStringRegion(const StringLiteral* Str); 1204218887Sdim 1205234353Sdim const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str); 1206234353Sdim 1207218887Sdim /// getVarRegion - Retrieve or create the memory region associated with 1208218887Sdim /// a specified VarDecl and LocationContext. 1209218887Sdim const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC); 1210218887Sdim 1211218887Sdim /// getVarRegion - Retrieve or create the memory region associated with 1212218887Sdim /// a specified VarDecl and super region. 1213218887Sdim const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR); 1214218887Sdim 1215218887Sdim /// getElementRegion - Retrieve the memory region associated with the 1216218887Sdim /// associated element type, index, and super region. 1217218887Sdim const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx, 1218218887Sdim const MemRegion *superRegion, 1219218887Sdim ASTContext &Ctx); 1220218887Sdim 1221218887Sdim const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER, 1222218887Sdim const MemRegion *superRegion) { 1223218887Sdim return getElementRegion(ER->getElementType(), ER->getIndex(), 1224218887Sdim superRegion, ER->getContext()); 1225218887Sdim } 1226218887Sdim 1227218887Sdim /// getFieldRegion - Retrieve or create the memory region associated with 1228218887Sdim /// a specified FieldDecl. 'superRegion' corresponds to the containing 1229218887Sdim /// memory region (which typically represents the memory representing 1230218887Sdim /// a structure or class). 1231226633Sdim const FieldRegion *getFieldRegion(const FieldDecl *fd, 1232218887Sdim const MemRegion* superRegion); 1233218887Sdim 1234218887Sdim const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR, 1235218887Sdim const MemRegion *superRegion) { 1236218887Sdim return getFieldRegion(FR->getDecl(), superRegion); 1237218887Sdim } 1238218887Sdim 1239218887Sdim /// getObjCIvarRegion - Retrieve or create the memory region associated with 1240218887Sdim /// a specified Objective-c instance variable. 'superRegion' corresponds 1241218887Sdim /// to the containing region (which typically represents the Objective-C 1242218887Sdim /// object). 1243226633Sdim const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd, 1244218887Sdim const MemRegion* superRegion); 1245218887Sdim 1246218887Sdim const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex, 1247218887Sdim LocationContext const *LC); 1248218887Sdim 1249249423Sdim /// Create a CXXBaseObjectRegion with the given base class for region 1250249423Sdim /// \p Super. 1251249423Sdim /// 1252249423Sdim /// The type of \p Super is assumed be a class deriving from \p BaseClass. 1253249423Sdim const CXXBaseObjectRegion * 1254249423Sdim getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const MemRegion *Super, 1255249423Sdim bool IsVirtual); 1256218887Sdim 1257218887Sdim /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different 1258218887Sdim /// super region. 1259218887Sdim const CXXBaseObjectRegion * 1260218887Sdim getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg, 1261218887Sdim const MemRegion *superRegion) { 1262249423Sdim return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion, 1263249423Sdim baseReg->isVirtual()); 1264218887Sdim } 1265218887Sdim 1266243830Sdim const FunctionTextRegion *getFunctionTextRegion(const NamedDecl *FD); 1267218887Sdim const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, 1268218887Sdim CanQualType locTy, 1269234353Sdim AnalysisDeclContext *AC); 1270218887Sdim 1271218887Sdim /// getBlockDataRegion - Get the memory region associated with an instance 1272218887Sdim /// of a block. Unlike many other MemRegions, the LocationContext* 1273218887Sdim /// argument is allowed to be NULL for cases where we have no known 1274218887Sdim /// context. 1275218887Sdim const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc, 1276263508Sdim const LocationContext *lc, 1277263508Sdim unsigned blockCount); 1278218887Sdim 1279263508Sdim /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended 1280263508Sdim /// by static references. This differs from getCXXTempObjectRegion in the 1281263508Sdim /// super-region used. 1282263508Sdim const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex); 1283263508Sdim 1284218887Sdimprivate: 1285218887Sdim template <typename RegionTy, typename A1> 1286218887Sdim RegionTy* getRegion(const A1 a1); 1287218887Sdim 1288218887Sdim template <typename RegionTy, typename A1> 1289218887Sdim RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion); 1290218887Sdim 1291218887Sdim template <typename RegionTy, typename A1, typename A2> 1292218887Sdim RegionTy* getRegion(const A1 a1, const A2 a2); 1293218887Sdim 1294218887Sdim template <typename RegionTy, typename A1, typename A2> 1295218887Sdim RegionTy* getSubRegion(const A1 a1, const A2 a2, 1296218887Sdim const MemRegion* superRegion); 1297218887Sdim 1298218887Sdim template <typename RegionTy, typename A1, typename A2, typename A3> 1299218887Sdim RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3, 1300218887Sdim const MemRegion* superRegion); 1301218887Sdim 1302218887Sdim template <typename REG> 1303218887Sdim const REG* LazyAllocate(REG*& region); 1304218887Sdim 1305218887Sdim template <typename REG, typename ARG> 1306218887Sdim const REG* LazyAllocate(REG*& region, ARG a); 1307218887Sdim}; 1308218887Sdim 1309218887Sdim//===----------------------------------------------------------------------===// 1310218887Sdim// Out-of-line member definitions. 1311218887Sdim//===----------------------------------------------------------------------===// 1312218887Sdim 1313226633Sdiminline ASTContext &MemRegion::getContext() const { 1314218887Sdim return getMemRegionManager()->getContext(); 1315218887Sdim} 1316263508Sdim 1317263508Sdim//===----------------------------------------------------------------------===// 1318263508Sdim// Means for storing region/symbol handling traits. 1319263508Sdim//===----------------------------------------------------------------------===// 1320263508Sdim 1321263508Sdim/// Information about invalidation for a particular region/symbol. 1322263508Sdimclass RegionAndSymbolInvalidationTraits { 1323263508Sdim typedef unsigned char StorageTypeForKinds; 1324263508Sdim llvm::DenseMap<const MemRegion *, StorageTypeForKinds> MRTraitsMap; 1325263508Sdim llvm::DenseMap<SymbolRef, StorageTypeForKinds> SymTraitsMap; 1326263508Sdim 1327263508Sdim typedef llvm::DenseMap<const MemRegion *, StorageTypeForKinds>::const_iterator 1328263508Sdim const_region_iterator; 1329263508Sdim typedef llvm::DenseMap<SymbolRef, StorageTypeForKinds>::const_iterator 1330263508Sdim const_symbol_iterator; 1331263508Sdim 1332263508Sdimpublic: 1333263508Sdim /// \brief Describes different invalidation traits. 1334263508Sdim enum InvalidationKinds { 1335263508Sdim /// Tells that a region's contents is not changed. 1336263508Sdim TK_PreserveContents = 0x1, 1337263508Sdim /// Suppress pointer-escaping of a region. 1338263508Sdim TK_SuppressEscape = 0x2 1339263508Sdim 1340263508Sdim // Do not forget to extend StorageTypeForKinds if number of traits exceed 1341263508Sdim // the number of bits StorageTypeForKinds can store. 1342263508Sdim }; 1343263508Sdim 1344263508Sdim void setTrait(SymbolRef Sym, InvalidationKinds IK); 1345263508Sdim void setTrait(const MemRegion *MR, InvalidationKinds IK); 1346263508Sdim bool hasTrait(SymbolRef Sym, InvalidationKinds IK); 1347263508Sdim bool hasTrait(const MemRegion *MR, InvalidationKinds IK); 1348263508Sdim}; 1349218887Sdim 1350218887Sdim} // end GR namespace 1351218887Sdim 1352218887Sdim} // end clang namespace 1353218887Sdim 1354218887Sdim//===----------------------------------------------------------------------===// 1355218887Sdim// Pretty-printing regions. 1356218887Sdim//===----------------------------------------------------------------------===// 1357218887Sdim 1358218887Sdimnamespace llvm { 1359226633Sdimstatic inline raw_ostream &operator<<(raw_ostream &os, 1360218887Sdim const clang::ento::MemRegion* R) { 1361218887Sdim R->dumpToStream(os); 1362218887Sdim return os; 1363218887Sdim} 1364218887Sdim} // end llvm namespace 1365218887Sdim 1366218887Sdim#endif 1367