Home | History | Annotate | Download | only in PathSensitive
      1 //== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file defines MemRegion and its subclasses.  MemRegion defines a
     11 //  partially-typed abstraction of memory useful for path-sensitive dataflow
     12 //  analyses.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #ifndef LLVM_CLANG_GR_MEMREGION_H
     17 #define LLVM_CLANG_GR_MEMREGION_H
     18 
     19 #include "clang/AST/ASTContext.h"
     20 #include "clang/AST/CharUnits.h"
     21 #include "clang/AST/Decl.h"
     22 #include "clang/AST/ExprObjC.h"
     23 #include "clang/Basic/LLVM.h"
     24 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
     25 #include "llvm/ADT/FoldingSet.h"
     26 #include "llvm/Support/ErrorHandling.h"
     27 #include <string>
     28 
     29 namespace llvm {
     30 class BumpPtrAllocator;
     31 }
     32 
     33 namespace clang {
     34 
     35 class LocationContext;
     36 class StackFrameContext;
     37 
     38 namespace ento {
     39 
     40 class CodeTextRegion;
     41 class MemRegionManager;
     42 class MemSpaceRegion;
     43 class SValBuilder;
     44 class SymbolicRegion;
     45 class VarRegion;
     46 
     47 /// Represent a region's offset within the top level base region.
     48 class RegionOffset {
     49   /// The base region.
     50   const MemRegion *R;
     51 
     52   /// The bit offset within the base region. It shouldn't be negative.
     53   int64_t Offset;
     54 
     55 public:
     56   // We're using a const instead of an enumeration due to the size required;
     57   // Visual Studio will only create enumerations of size int, not long long.
     58   static const int64_t Symbolic = INT64_MAX;
     59 
     60   RegionOffset() : R(0) {}
     61   RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
     62 
     63   const MemRegion *getRegion() const { return R; }
     64 
     65   bool hasSymbolicOffset() const { return Offset == Symbolic; }
     66 
     67   int64_t getOffset() const {
     68     assert(!hasSymbolicOffset());
     69     return Offset;
     70   }
     71 
     72   bool isValid() const { return R; }
     73 };
     74 
     75 //===----------------------------------------------------------------------===//
     76 // Base region classes.
     77 //===----------------------------------------------------------------------===//
     78 
     79 /// MemRegion - The root abstract class for all memory regions.
     80 class MemRegion : public llvm::FoldingSetNode {
     81   friend class MemRegionManager;
     82 public:
     83   enum Kind {
     84     // Memory spaces.
     85     GenericMemSpaceRegionKind,
     86     StackLocalsSpaceRegionKind,
     87     StackArgumentsSpaceRegionKind,
     88     HeapSpaceRegionKind,
     89     UnknownSpaceRegionKind,
     90     StaticGlobalSpaceRegionKind,
     91     GlobalInternalSpaceRegionKind,
     92     GlobalSystemSpaceRegionKind,
     93     GlobalImmutableSpaceRegionKind,
     94     BEG_NON_STATIC_GLOBAL_MEMSPACES = GlobalInternalSpaceRegionKind,
     95     END_NON_STATIC_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
     96     BEG_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind,
     97     END_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
     98     BEG_MEMSPACES = GenericMemSpaceRegionKind,
     99     END_MEMSPACES = GlobalImmutableSpaceRegionKind,
    100     // Untyped regions.
    101     SymbolicRegionKind,
    102     AllocaRegionKind,
    103     // Typed regions.
    104     BEG_TYPED_REGIONS,
    105     FunctionTextRegionKind = BEG_TYPED_REGIONS,
    106     BlockTextRegionKind,
    107     BlockDataRegionKind,
    108     BEG_TYPED_VALUE_REGIONS,
    109     CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS,
    110     CXXThisRegionKind,
    111     StringRegionKind,
    112     ObjCStringRegionKind,
    113     ElementRegionKind,
    114     // Decl Regions.
    115     BEG_DECL_REGIONS,
    116     VarRegionKind = BEG_DECL_REGIONS,
    117     FieldRegionKind,
    118     ObjCIvarRegionKind,
    119     END_DECL_REGIONS = ObjCIvarRegionKind,
    120     CXXTempObjectRegionKind,
    121     CXXBaseObjectRegionKind,
    122     END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind,
    123     END_TYPED_REGIONS = CXXBaseObjectRegionKind
    124   };
    125 
    126 private:
    127   const Kind kind;
    128 
    129 protected:
    130   MemRegion(Kind k) : kind(k) {}
    131   virtual ~MemRegion();
    132 
    133 public:
    134   ASTContext &getContext() const;
    135 
    136   virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
    137 
    138   virtual MemRegionManager* getMemRegionManager() const = 0;
    139 
    140   const MemSpaceRegion *getMemorySpace() const;
    141 
    142   const MemRegion *getBaseRegion() const;
    143 
    144   /// Check if the region is a subregion of the given region.
    145   virtual bool isSubRegionOf(const MemRegion *R) const;
    146 
    147   const MemRegion *StripCasts(bool StripBaseCasts = true) const;
    148 
    149   /// \brief If this is a symbolic region, returns the region. Otherwise,
    150   /// goes up the base chain looking for the first symbolic base region.
    151   const SymbolicRegion *getSymbolicBase() const;
    152 
    153   bool hasGlobalsOrParametersStorage() const;
    154 
    155   bool hasStackStorage() const;
    156 
    157   bool hasStackNonParametersStorage() const;
    158 
    159   bool hasStackParametersStorage() const;
    160 
    161   /// Compute the offset within the top level memory object.
    162   RegionOffset getAsOffset() const;
    163 
    164   /// \brief Get a string representation of a region for debug use.
    165   std::string getString() const;
    166 
    167   virtual void dumpToStream(raw_ostream &os) const;
    168 
    169   void dump() const;
    170 
    171   /// \brief Returns true if this region can be printed in a user-friendly way.
    172   virtual bool canPrintPretty() const;
    173 
    174   /// \brief Print the region for use in diagnostics.
    175   virtual void printPretty(raw_ostream &os) const;
    176 
    177   /// \brief Returns true if this region's textual representation can be used
    178   /// as part of a larger expression.
    179   virtual bool canPrintPrettyAsExpr() const;
    180 
    181   /// \brief Print the region as expression.
    182   ///
    183   /// When this region represents a subexpression, the method is for printing
    184   /// an expression containing it.
    185   virtual void printPrettyAsExpr(raw_ostream &os) const;
    186 
    187   Kind getKind() const { return kind; }
    188 
    189   template<typename RegionTy> const RegionTy* getAs() const;
    190 
    191   virtual bool isBoundable() const { return false; }
    192 };
    193 
    194 /// MemSpaceRegion - A memory region that represents a "memory space";
    195 ///  for example, the set of global variables, the stack frame, etc.
    196 class MemSpaceRegion : public MemRegion {
    197 protected:
    198   friend class MemRegionManager;
    199 
    200   MemRegionManager *Mgr;
    201 
    202   MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind)
    203     : MemRegion(k), Mgr(mgr) {
    204     assert(classof(this));
    205   }
    206 
    207   MemRegionManager* getMemRegionManager() const { return Mgr; }
    208 
    209 public:
    210   bool isBoundable() const { return false; }
    211 
    212   void Profile(llvm::FoldingSetNodeID &ID) const;
    213 
    214   static bool classof(const MemRegion *R) {
    215     Kind k = R->getKind();
    216     return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
    217   }
    218 };
    219 
    220 class GlobalsSpaceRegion : public MemSpaceRegion {
    221   virtual void anchor();
    222 protected:
    223   GlobalsSpaceRegion(MemRegionManager *mgr, Kind k)
    224     : MemSpaceRegion(mgr, k) {}
    225 public:
    226   static bool classof(const MemRegion *R) {
    227     Kind k = R->getKind();
    228     return k >= BEG_GLOBAL_MEMSPACES && k <= END_GLOBAL_MEMSPACES;
    229   }
    230 };
    231 
    232 /// \brief The region of the static variables within the current CodeTextRegion
    233 /// scope.
    234 ///
    235 /// Currently, only the static locals are placed there, so we know that these
    236 /// variables do not get invalidated by calls to other functions.
    237 class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
    238   friend class MemRegionManager;
    239 
    240   const CodeTextRegion *CR;
    241 
    242   StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
    243     : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
    244 
    245 public:
    246   void Profile(llvm::FoldingSetNodeID &ID) const;
    247 
    248   void dumpToStream(raw_ostream &os) const;
    249 
    250   const CodeTextRegion *getCodeRegion() const { return CR; }
    251 
    252   static bool classof(const MemRegion *R) {
    253     return R->getKind() == StaticGlobalSpaceRegionKind;
    254   }
    255 };
    256 
    257 /// \brief The region for all the non-static global variables.
    258 ///
    259 /// This class is further split into subclasses for efficient implementation of
    260 /// invalidating a set of related global values as is done in
    261 /// RegionStoreManager::invalidateRegions (instead of finding all the dependent
    262 /// globals, we invalidate the whole parent region).
    263 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
    264   friend class MemRegionManager;
    265 
    266 protected:
    267   NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
    268     : GlobalsSpaceRegion(mgr, k) {}
    269 
    270 public:
    271 
    272   static bool classof(const MemRegion *R) {
    273     Kind k = R->getKind();
    274     return k >= BEG_NON_STATIC_GLOBAL_MEMSPACES &&
    275            k <= END_NON_STATIC_GLOBAL_MEMSPACES;
    276   }
    277 };
    278 
    279 /// \brief The region containing globals which are defined in system/external
    280 /// headers and are considered modifiable by system calls (ex: errno).
    281 class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
    282   friend class MemRegionManager;
    283 
    284   GlobalSystemSpaceRegion(MemRegionManager *mgr)
    285     : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
    286 
    287 public:
    288 
    289   void dumpToStream(raw_ostream &os) const;
    290 
    291   static bool classof(const MemRegion *R) {
    292     return R->getKind() == GlobalSystemSpaceRegionKind;
    293   }
    294 };
    295 
    296 /// \brief The region containing globals which are considered not to be modified
    297 /// or point to data which could be modified as a result of a function call
    298 /// (system or internal). Ex: Const global scalars would be modeled as part of
    299 /// this region. This region also includes most system globals since they have
    300 /// low chance of being modified.
    301 class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
    302   friend class MemRegionManager;
    303 
    304   GlobalImmutableSpaceRegion(MemRegionManager *mgr)
    305     : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
    306 
    307 public:
    308 
    309   void dumpToStream(raw_ostream &os) const;
    310 
    311   static bool classof(const MemRegion *R) {
    312     return R->getKind() == GlobalImmutableSpaceRegionKind;
    313   }
    314 };
    315 
    316 /// \brief The region containing globals which can be modified by calls to
    317 /// "internally" defined functions - (for now just) functions other then system
    318 /// calls.
    319 class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
    320   friend class MemRegionManager;
    321 
    322   GlobalInternalSpaceRegion(MemRegionManager *mgr)
    323     : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
    324 
    325 public:
    326 
    327   void dumpToStream(raw_ostream &os) const;
    328 
    329   static bool classof(const MemRegion *R) {
    330     return R->getKind() == GlobalInternalSpaceRegionKind;
    331   }
    332 };
    333 
    334 class HeapSpaceRegion : public MemSpaceRegion {
    335   virtual void anchor();
    336   friend class MemRegionManager;
    337 
    338   HeapSpaceRegion(MemRegionManager *mgr)
    339     : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
    340 public:
    341 
    342   void dumpToStream(raw_ostream &os) const;
    343 
    344   static bool classof(const MemRegion *R) {
    345     return R->getKind() == HeapSpaceRegionKind;
    346   }
    347 };
    348 
    349 class UnknownSpaceRegion : public MemSpaceRegion {
    350   virtual void anchor();
    351   friend class MemRegionManager;
    352   UnknownSpaceRegion(MemRegionManager *mgr)
    353     : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
    354 public:
    355 
    356   void dumpToStream(raw_ostream &os) const;
    357 
    358   static bool classof(const MemRegion *R) {
    359     return R->getKind() == UnknownSpaceRegionKind;
    360   }
    361 };
    362 
    363 class StackSpaceRegion : public MemSpaceRegion {
    364 private:
    365   const StackFrameContext *SFC;
    366 
    367 protected:
    368   StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
    369     : MemSpaceRegion(mgr, k), SFC(sfc) {
    370     assert(classof(this));
    371   }
    372 
    373 public:
    374   const StackFrameContext *getStackFrame() const { return SFC; }
    375 
    376   void Profile(llvm::FoldingSetNodeID &ID) const;
    377 
    378   static bool classof(const MemRegion *R) {
    379     Kind k = R->getKind();
    380     return k >= StackLocalsSpaceRegionKind &&
    381            k <= StackArgumentsSpaceRegionKind;
    382   }
    383 };
    384 
    385 class StackLocalsSpaceRegion : public StackSpaceRegion {
    386   virtual void anchor();
    387   friend class MemRegionManager;
    388   StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
    389     : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
    390 public:
    391 
    392   void dumpToStream(raw_ostream &os) const;
    393 
    394   static bool classof(const MemRegion *R) {
    395     return R->getKind() == StackLocalsSpaceRegionKind;
    396   }
    397 };
    398 
    399 class StackArgumentsSpaceRegion : public StackSpaceRegion {
    400 private:
    401   virtual void anchor();
    402   friend class MemRegionManager;
    403   StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
    404     : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
    405 public:
    406 
    407   void dumpToStream(raw_ostream &os) const;
    408 
    409   static bool classof(const MemRegion *R) {
    410     return R->getKind() == StackArgumentsSpaceRegionKind;
    411   }
    412 };
    413 
    414 
    415 /// SubRegion - A region that subsets another larger region.  Most regions
    416 ///  are subclasses of SubRegion.
    417 class SubRegion : public MemRegion {
    418 private:
    419   virtual void anchor();
    420 protected:
    421   const MemRegion* superRegion;
    422   SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
    423 public:
    424   const MemRegion* getSuperRegion() const {
    425     return superRegion;
    426   }
    427 
    428   /// getExtent - Returns the size of the region in bytes.
    429   virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const {
    430     return UnknownVal();
    431   }
    432 
    433   MemRegionManager* getMemRegionManager() const;
    434 
    435   virtual bool isSubRegionOf(const MemRegion* R) const;
    436 
    437   static bool classof(const MemRegion* R) {
    438     return R->getKind() > END_MEMSPACES;
    439   }
    440 };
    441 
    442 //===----------------------------------------------------------------------===//
    443 // MemRegion subclasses.
    444 //===----------------------------------------------------------------------===//
    445 
    446 /// AllocaRegion - A region that represents an untyped blob of bytes created
    447 ///  by a call to 'alloca'.
    448 class AllocaRegion : public SubRegion {
    449   friend class MemRegionManager;
    450 protected:
    451   unsigned Cnt; // Block counter.  Used to distinguish different pieces of
    452                 // memory allocated by alloca at the same call site.
    453   const Expr *Ex;
    454 
    455   AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion)
    456     : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
    457 
    458 public:
    459 
    460   const Expr *getExpr() const { return Ex; }
    461 
    462   bool isBoundable() const { return true; }
    463 
    464   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
    465 
    466   void Profile(llvm::FoldingSetNodeID& ID) const;
    467 
    468   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
    469                             unsigned Cnt, const MemRegion *superRegion);
    470 
    471   void dumpToStream(raw_ostream &os) const;
    472 
    473   static bool classof(const MemRegion* R) {
    474     return R->getKind() == AllocaRegionKind;
    475   }
    476 };
    477 
    478 /// TypedRegion - An abstract class representing regions that are typed.
    479 class TypedRegion : public SubRegion {
    480 public:
    481   virtual void anchor();
    482 protected:
    483   TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
    484 
    485 public:
    486   virtual QualType getLocationType() const = 0;
    487 
    488   QualType getDesugaredLocationType(ASTContext &Context) const {
    489     return getLocationType().getDesugaredType(Context);
    490   }
    491 
    492   bool isBoundable() const { return true; }
    493 
    494   static bool classof(const MemRegion* R) {
    495     unsigned k = R->getKind();
    496     return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
    497   }
    498 };
    499 
    500 /// TypedValueRegion - An abstract class representing regions having a typed value.
    501 class TypedValueRegion : public TypedRegion {
    502 public:
    503   virtual void anchor();
    504 protected:
    505   TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {}
    506 
    507 public:
    508   virtual QualType getValueType() const = 0;
    509 
    510   virtual QualType getLocationType() const {
    511     // FIXME: We can possibly optimize this later to cache this value.
    512     QualType T = getValueType();
    513     ASTContext &ctx = getContext();
    514     if (T->getAs<ObjCObjectType>())
    515       return ctx.getObjCObjectPointerType(T);
    516     return ctx.getPointerType(getValueType());
    517   }
    518 
    519   QualType getDesugaredValueType(ASTContext &Context) const {
    520     QualType T = getValueType();
    521     return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
    522   }
    523 
    524   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
    525 
    526   static bool classof(const MemRegion* R) {
    527     unsigned k = R->getKind();
    528     return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
    529   }
    530 };
    531 
    532 
    533 class CodeTextRegion : public TypedRegion {
    534 public:
    535   virtual void anchor();
    536 protected:
    537   CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
    538 public:
    539   bool isBoundable() const { return false; }
    540 
    541   static bool classof(const MemRegion* R) {
    542     Kind k = R->getKind();
    543     return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
    544   }
    545 };
    546 
    547 /// FunctionTextRegion - A region that represents code texts of function.
    548 class FunctionTextRegion : public CodeTextRegion {
    549   const NamedDecl *FD;
    550 public:
    551   FunctionTextRegion(const NamedDecl *fd, const MemRegion* sreg)
    552     : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {
    553     assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
    554   }
    555 
    556   QualType getLocationType() const {
    557     const ASTContext &Ctx = getContext();
    558     if (const FunctionDecl *D = dyn_cast<FunctionDecl>(FD)) {
    559       return Ctx.getPointerType(D->getType());
    560     }
    561 
    562     assert(isa<ObjCMethodDecl>(FD));
    563     assert(false && "Getting the type of ObjCMethod is not supported yet");
    564 
    565     // TODO: We might want to return a different type here (ex: id (*ty)(...))
    566     //       depending on how it is used.
    567     return QualType();
    568   }
    569 
    570   const NamedDecl *getDecl() const {
    571     return FD;
    572   }
    573 
    574   virtual void dumpToStream(raw_ostream &os) const;
    575 
    576   void Profile(llvm::FoldingSetNodeID& ID) const;
    577 
    578   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
    579                             const MemRegion*);
    580 
    581   static bool classof(const MemRegion* R) {
    582     return R->getKind() == FunctionTextRegionKind;
    583   }
    584 };
    585 
    586 
    587 /// BlockTextRegion - A region that represents code texts of blocks (closures).
    588 ///  Blocks are represented with two kinds of regions.  BlockTextRegions
    589 ///  represent the "code", while BlockDataRegions represent instances of blocks,
    590 ///  which correspond to "code+data".  The distinction is important, because
    591 ///  like a closure a block captures the values of externally referenced
    592 ///  variables.
    593 class BlockTextRegion : public CodeTextRegion {
    594   friend class MemRegionManager;
    595 
    596   const BlockDecl *BD;
    597   AnalysisDeclContext *AC;
    598   CanQualType locTy;
    599 
    600   BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
    601                   AnalysisDeclContext *ac, const MemRegion* sreg)
    602     : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
    603 
    604 public:
    605   QualType getLocationType() const {
    606     return locTy;
    607   }
    608 
    609   const BlockDecl *getDecl() const {
    610     return BD;
    611   }
    612 
    613   AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
    614 
    615   virtual void dumpToStream(raw_ostream &os) const;
    616 
    617   void Profile(llvm::FoldingSetNodeID& ID) const;
    618 
    619   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
    620                             CanQualType, const AnalysisDeclContext*,
    621                             const MemRegion*);
    622 
    623   static bool classof(const MemRegion* R) {
    624     return R->getKind() == BlockTextRegionKind;
    625   }
    626 };
    627 
    628 /// BlockDataRegion - A region that represents a block instance.
    629 ///  Blocks are represented with two kinds of regions.  BlockTextRegions
    630 ///  represent the "code", while BlockDataRegions represent instances of blocks,
    631 ///  which correspond to "code+data".  The distinction is important, because
    632 ///  like a closure a block captures the values of externally referenced
    633 ///  variables.
    634 class BlockDataRegion : public TypedRegion {
    635   friend class MemRegionManager;
    636   const BlockTextRegion *BC;
    637   const LocationContext *LC; // Can be null */
    638   void *ReferencedVars;
    639   void *OriginalVars;
    640 
    641   BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
    642                   const MemRegion *sreg)
    643   : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
    644     ReferencedVars(0), OriginalVars(0) {}
    645 
    646 public:
    647   const BlockTextRegion *getCodeRegion() const { return BC; }
    648 
    649   const BlockDecl *getDecl() const { return BC->getDecl(); }
    650 
    651   QualType getLocationType() const { return BC->getLocationType(); }
    652 
    653   class referenced_vars_iterator {
    654     const MemRegion * const *R;
    655     const MemRegion * const *OriginalR;
    656   public:
    657     explicit referenced_vars_iterator(const MemRegion * const *r,
    658                                       const MemRegion * const *originalR)
    659       : R(r), OriginalR(originalR) {}
    660 
    661     const VarRegion *getCapturedRegion() const {
    662       return cast<VarRegion>(*R);
    663     }
    664     const VarRegion *getOriginalRegion() const {
    665       return cast<VarRegion>(*OriginalR);
    666     }
    667 
    668     bool operator==(const referenced_vars_iterator &I) const {
    669       assert((R == 0) == (I.R == 0));
    670       return I.R == R;
    671     }
    672     bool operator!=(const referenced_vars_iterator &I) const {
    673       assert((R == 0) == (I.R == 0));
    674       return I.R != R;
    675     }
    676     referenced_vars_iterator &operator++() {
    677       ++R;
    678       ++OriginalR;
    679       return *this;
    680     }
    681   };
    682 
    683   /// Return the original region for a captured region, if
    684   /// one exists.
    685   const VarRegion *getOriginalRegion(const VarRegion *VR) const;
    686 
    687   referenced_vars_iterator referenced_vars_begin() const;
    688   referenced_vars_iterator referenced_vars_end() const;
    689 
    690   virtual void dumpToStream(raw_ostream &os) const;
    691 
    692   void Profile(llvm::FoldingSetNodeID& ID) const;
    693 
    694   static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
    695                             const LocationContext *, const MemRegion *);
    696 
    697   static bool classof(const MemRegion* R) {
    698     return R->getKind() == BlockDataRegionKind;
    699   }
    700 private:
    701   void LazyInitializeReferencedVars();
    702   std::pair<const VarRegion *, const VarRegion *>
    703   getCaptureRegions(const VarDecl *VD);
    704 };
    705 
    706 /// SymbolicRegion - A special, "non-concrete" region. Unlike other region
    707 ///  clases, SymbolicRegion represents a region that serves as an alias for
    708 ///  either a real region, a NULL pointer, etc.  It essentially is used to
    709 ///  map the concept of symbolic values into the domain of regions.  Symbolic
    710 ///  regions do not need to be typed.
    711 class SymbolicRegion : public SubRegion {
    712 protected:
    713   const SymbolRef sym;
    714 
    715 public:
    716   SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
    717     : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
    718 
    719   SymbolRef getSymbol() const {
    720     return sym;
    721   }
    722 
    723   bool isBoundable() const { return true; }
    724 
    725   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
    726 
    727   void Profile(llvm::FoldingSetNodeID& ID) const;
    728 
    729   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
    730                             SymbolRef sym,
    731                             const MemRegion* superRegion);
    732 
    733   void dumpToStream(raw_ostream &os) const;
    734 
    735   static bool classof(const MemRegion* R) {
    736     return R->getKind() == SymbolicRegionKind;
    737   }
    738 };
    739 
    740 /// StringRegion - Region associated with a StringLiteral.
    741 class StringRegion : public TypedValueRegion {
    742   friend class MemRegionManager;
    743   const StringLiteral* Str;
    744 protected:
    745 
    746   StringRegion(const StringLiteral* str, const MemRegion* sreg)
    747     : TypedValueRegion(sreg, StringRegionKind), Str(str) {}
    748 
    749   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
    750                             const StringLiteral* Str,
    751                             const MemRegion* superRegion);
    752 
    753 public:
    754 
    755   const StringLiteral* getStringLiteral() const { return Str; }
    756 
    757   QualType getValueType() const {
    758     return Str->getType();
    759   }
    760 
    761   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
    762 
    763   bool isBoundable() const { return false; }
    764 
    765   void Profile(llvm::FoldingSetNodeID& ID) const {
    766     ProfileRegion(ID, Str, superRegion);
    767   }
    768 
    769   void dumpToStream(raw_ostream &os) const;
    770 
    771   static bool classof(const MemRegion* R) {
    772     return R->getKind() == StringRegionKind;
    773   }
    774 };
    775 
    776 /// The region associated with an ObjCStringLiteral.
    777 class ObjCStringRegion : public TypedValueRegion {
    778   friend class MemRegionManager;
    779   const ObjCStringLiteral* Str;
    780 protected:
    781 
    782   ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg)
    783   : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {}
    784 
    785   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
    786                             const ObjCStringLiteral* Str,
    787                             const MemRegion* superRegion);
    788 
    789 public:
    790 
    791   const ObjCStringLiteral* getObjCStringLiteral() const { return Str; }
    792 
    793   QualType getValueType() const {
    794     return Str->getType();
    795   }
    796 
    797   bool isBoundable() const { return false; }
    798 
    799   void Profile(llvm::FoldingSetNodeID& ID) const {
    800     ProfileRegion(ID, Str, superRegion);
    801   }
    802 
    803   void dumpToStream(raw_ostream &os) const;
    804 
    805   static bool classof(const MemRegion* R) {
    806     return R->getKind() == ObjCStringRegionKind;
    807   }
    808 };
    809 
    810 /// CompoundLiteralRegion - A memory region representing a compound literal.
    811 ///   Compound literals are essentially temporaries that are stack allocated
    812 ///   or in the global constant pool.
    813 class CompoundLiteralRegion : public TypedValueRegion {
    814 private:
    815   friend class MemRegionManager;
    816   const CompoundLiteralExpr *CL;
    817 
    818   CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg)
    819     : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
    820 
    821   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
    822                             const CompoundLiteralExpr *CL,
    823                             const MemRegion* superRegion);
    824 public:
    825   QualType getValueType() const {
    826     return CL->getType();
    827   }
    828 
    829   bool isBoundable() const { return !CL->isFileScope(); }
    830 
    831   void Profile(llvm::FoldingSetNodeID& ID) const;
    832 
    833   void dumpToStream(raw_ostream &os) const;
    834 
    835   const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
    836 
    837   static bool classof(const MemRegion* R) {
    838     return R->getKind() == CompoundLiteralRegionKind;
    839   }
    840 };
    841 
    842 class DeclRegion : public TypedValueRegion {
    843 protected:
    844   const Decl *D;
    845 
    846   DeclRegion(const Decl *d, const MemRegion* sReg, Kind k)
    847     : TypedValueRegion(sReg, k), D(d) {}
    848 
    849   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
    850                       const MemRegion* superRegion, Kind k);
    851 
    852 public:
    853   const Decl *getDecl() const { return D; }
    854   void Profile(llvm::FoldingSetNodeID& ID) const;
    855 
    856   static bool classof(const MemRegion* R) {
    857     unsigned k = R->getKind();
    858     return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
    859   }
    860 };
    861 
    862 class VarRegion : public DeclRegion {
    863   friend class MemRegionManager;
    864 
    865   // Constructors and private methods.
    866   VarRegion(const VarDecl *vd, const MemRegion* sReg)
    867     : DeclRegion(vd, sReg, VarRegionKind) {}
    868 
    869   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
    870                             const MemRegion *superRegion) {
    871     DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
    872   }
    873 
    874   void Profile(llvm::FoldingSetNodeID& ID) const;
    875 
    876 public:
    877   const VarDecl *getDecl() const { return cast<VarDecl>(D); }
    878 
    879   const StackFrameContext *getStackFrame() const;
    880 
    881   QualType getValueType() const {
    882     // FIXME: We can cache this if needed.
    883     return getDecl()->getType();
    884   }
    885 
    886   void dumpToStream(raw_ostream &os) const;
    887 
    888   static bool classof(const MemRegion* R) {
    889     return R->getKind() == VarRegionKind;
    890   }
    891 
    892   bool canPrintPrettyAsExpr() const;
    893 
    894   void printPrettyAsExpr(raw_ostream &os) const;
    895 };
    896 
    897 /// CXXThisRegion - Represents the region for the implicit 'this' parameter
    898 ///  in a call to a C++ method.  This region doesn't represent the object
    899 ///  referred to by 'this', but rather 'this' itself.
    900 class CXXThisRegion : public TypedValueRegion {
    901   friend class MemRegionManager;
    902   CXXThisRegion(const PointerType *thisPointerTy,
    903                 const MemRegion *sReg)
    904     : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
    905 
    906   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
    907                             const PointerType *PT,
    908                             const MemRegion *sReg);
    909 
    910   void Profile(llvm::FoldingSetNodeID &ID) const;
    911 
    912 public:
    913   QualType getValueType() const {
    914     return QualType(ThisPointerTy, 0);
    915   }
    916 
    917   void dumpToStream(raw_ostream &os) const;
    918 
    919   static bool classof(const MemRegion* R) {
    920     return R->getKind() == CXXThisRegionKind;
    921   }
    922 
    923 private:
    924   const PointerType *ThisPointerTy;
    925 };
    926 
    927 class FieldRegion : public DeclRegion {
    928   friend class MemRegionManager;
    929 
    930   FieldRegion(const FieldDecl *fd, const MemRegion* sReg)
    931     : DeclRegion(fd, sReg, FieldRegionKind) {}
    932 
    933 public:
    934   const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
    935 
    936   QualType getValueType() const {
    937     // FIXME: We can cache this if needed.
    938     return getDecl()->getType();
    939   }
    940 
    941   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
    942 
    943   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
    944                             const MemRegion* superRegion) {
    945     DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
    946   }
    947 
    948   static bool classof(const MemRegion* R) {
    949     return R->getKind() == FieldRegionKind;
    950   }
    951 
    952   void dumpToStream(raw_ostream &os) const;
    953 
    954   bool canPrintPretty() const;
    955   void printPretty(raw_ostream &os) const;
    956   bool canPrintPrettyAsExpr() const;
    957   void printPrettyAsExpr(raw_ostream &os) const;
    958 };
    959 
    960 class ObjCIvarRegion : public DeclRegion {
    961 
    962   friend class MemRegionManager;
    963 
    964   ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg);
    965 
    966   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
    967                             const MemRegion* superRegion);
    968 
    969 public:
    970   const ObjCIvarDecl *getDecl() const;
    971   QualType getValueType() const;
    972 
    973   bool canPrintPrettyAsExpr() const;
    974   void printPrettyAsExpr(raw_ostream &os) const;
    975 
    976   void dumpToStream(raw_ostream &os) const;
    977 
    978   static bool classof(const MemRegion* R) {
    979     return R->getKind() == ObjCIvarRegionKind;
    980   }
    981 };
    982 //===----------------------------------------------------------------------===//
    983 // Auxiliary data classes for use with MemRegions.
    984 //===----------------------------------------------------------------------===//
    985 
    986 class ElementRegion;
    987 
    988 class RegionRawOffset {
    989 private:
    990   friend class ElementRegion;
    991 
    992   const MemRegion *Region;
    993   CharUnits Offset;
    994 
    995   RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero())
    996     : Region(reg), Offset(offset) {}
    997 
    998 public:
    999   // FIXME: Eventually support symbolic offsets.
   1000   CharUnits getOffset() const { return Offset; }
   1001   const MemRegion *getRegion() const { return Region; }
   1002 
   1003   void dumpToStream(raw_ostream &os) const;
   1004   void dump() const;
   1005 };
   1006 
   1007 /// \brief ElementRegin is used to represent both array elements and casts.
   1008 class ElementRegion : public TypedValueRegion {
   1009   friend class MemRegionManager;
   1010 
   1011   QualType ElementType;
   1012   NonLoc Index;
   1013 
   1014   ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
   1015     : TypedValueRegion(sReg, ElementRegionKind),
   1016       ElementType(elementType), Index(Idx) {
   1017     assert((!Idx.getAs<nonloc::ConcreteInt>() ||
   1018             Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
   1019            "The index must be signed");
   1020   }
   1021 
   1022   static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType,
   1023                             SVal Idx, const MemRegion* superRegion);
   1024 
   1025 public:
   1026 
   1027   NonLoc getIndex() const { return Index; }
   1028 
   1029   QualType getValueType() const {
   1030     return ElementType;
   1031   }
   1032 
   1033   QualType getElementType() const {
   1034     return ElementType;
   1035   }
   1036   /// Compute the offset within the array. The array might also be a subobject.
   1037   RegionRawOffset getAsArrayOffset() const;
   1038 
   1039   void dumpToStream(raw_ostream &os) const;
   1040 
   1041   void Profile(llvm::FoldingSetNodeID& ID) const;
   1042 
   1043   static bool classof(const MemRegion* R) {
   1044     return R->getKind() == ElementRegionKind;
   1045   }
   1046 };
   1047 
   1048 // C++ temporary object associated with an expression.
   1049 class CXXTempObjectRegion : public TypedValueRegion {
   1050   friend class MemRegionManager;
   1051 
   1052   Expr const *Ex;
   1053 
   1054   CXXTempObjectRegion(Expr const *E, MemRegion const *sReg)
   1055     : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {}
   1056 
   1057   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
   1058                             Expr const *E, const MemRegion *sReg);
   1059 
   1060 public:
   1061   const Expr *getExpr() const { return Ex; }
   1062 
   1063   QualType getValueType() const {
   1064     return Ex->getType();
   1065   }
   1066 
   1067   void dumpToStream(raw_ostream &os) const;
   1068 
   1069   void Profile(llvm::FoldingSetNodeID &ID) const;
   1070 
   1071   static bool classof(const MemRegion* R) {
   1072     return R->getKind() == CXXTempObjectRegionKind;
   1073   }
   1074 };
   1075 
   1076 // CXXBaseObjectRegion represents a base object within a C++ object. It is
   1077 // identified by the base class declaration and the region of its parent object.
   1078 class CXXBaseObjectRegion : public TypedValueRegion {
   1079   friend class MemRegionManager;
   1080 
   1081   llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
   1082 
   1083   CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
   1084                       const MemRegion *SReg)
   1085     : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {}
   1086 
   1087   static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
   1088                             bool IsVirtual, const MemRegion *SReg);
   1089 
   1090 public:
   1091   const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
   1092   bool isVirtual() const { return Data.getInt(); }
   1093 
   1094   QualType getValueType() const;
   1095 
   1096   void dumpToStream(raw_ostream &os) const;
   1097 
   1098   void Profile(llvm::FoldingSetNodeID &ID) const;
   1099 
   1100   static bool classof(const MemRegion *region) {
   1101     return region->getKind() == CXXBaseObjectRegionKind;
   1102   }
   1103 
   1104   bool canPrintPrettyAsExpr() const;
   1105 
   1106   void printPrettyAsExpr(raw_ostream &os) const;
   1107 };
   1108 
   1109 template<typename RegionTy>
   1110 const RegionTy* MemRegion::getAs() const {
   1111   if (const RegionTy* RT = dyn_cast<RegionTy>(this))
   1112     return RT;
   1113 
   1114   return NULL;
   1115 }
   1116 
   1117 //===----------------------------------------------------------------------===//
   1118 // MemRegionManager - Factory object for creating regions.
   1119 //===----------------------------------------------------------------------===//
   1120 
   1121 class MemRegionManager {
   1122   ASTContext &C;
   1123   llvm::BumpPtrAllocator& A;
   1124   llvm::FoldingSet<MemRegion> Regions;
   1125 
   1126   GlobalInternalSpaceRegion *InternalGlobals;
   1127   GlobalSystemSpaceRegion *SystemGlobals;
   1128   GlobalImmutableSpaceRegion *ImmutableGlobals;
   1129 
   1130 
   1131   llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *>
   1132     StackLocalsSpaceRegions;
   1133   llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *>
   1134     StackArgumentsSpaceRegions;
   1135   llvm::DenseMap<const CodeTextRegion *, StaticGlobalSpaceRegion *>
   1136     StaticsGlobalSpaceRegions;
   1137 
   1138   HeapSpaceRegion *heap;
   1139   UnknownSpaceRegion *unknown;
   1140   MemSpaceRegion *code;
   1141 
   1142 public:
   1143   MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
   1144     : C(c), A(a), InternalGlobals(0), SystemGlobals(0), ImmutableGlobals(0),
   1145       heap(0), unknown(0), code(0) {}
   1146 
   1147   ~MemRegionManager();
   1148 
   1149   ASTContext &getContext() { return C; }
   1150 
   1151   llvm::BumpPtrAllocator &getAllocator() { return A; }
   1152 
   1153   /// getStackLocalsRegion - Retrieve the memory region associated with the
   1154   ///  specified stack frame.
   1155   const StackLocalsSpaceRegion *
   1156   getStackLocalsRegion(const StackFrameContext *STC);
   1157 
   1158   /// getStackArgumentsRegion - Retrieve the memory region associated with
   1159   ///  function/method arguments of the specified stack frame.
   1160   const StackArgumentsSpaceRegion *
   1161   getStackArgumentsRegion(const StackFrameContext *STC);
   1162 
   1163   /// getGlobalsRegion - Retrieve the memory region associated with
   1164   ///  global variables.
   1165   const GlobalsSpaceRegion *getGlobalsRegion(
   1166       MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
   1167       const CodeTextRegion *R = 0);
   1168 
   1169   /// getHeapRegion - Retrieve the memory region associated with the
   1170   ///  generic "heap".
   1171   const HeapSpaceRegion *getHeapRegion();
   1172 
   1173   /// getUnknownRegion - Retrieve the memory region associated with unknown
   1174   /// memory space.
   1175   const MemSpaceRegion *getUnknownRegion();
   1176 
   1177   const MemSpaceRegion *getCodeRegion();
   1178 
   1179   /// getAllocaRegion - Retrieve a region associated with a call to alloca().
   1180   const AllocaRegion *getAllocaRegion(const Expr *Ex, unsigned Cnt,
   1181                                       const LocationContext *LC);
   1182 
   1183   /// getCompoundLiteralRegion - Retrieve the region associated with a
   1184   ///  given CompoundLiteral.
   1185   const CompoundLiteralRegion*
   1186   getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
   1187                            const LocationContext *LC);
   1188 
   1189   /// getCXXThisRegion - Retrieve the [artificial] region associated with the
   1190   ///  parameter 'this'.
   1191   const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy,
   1192                                         const LocationContext *LC);
   1193 
   1194   /// \brief Retrieve or create a "symbolic" memory region.
   1195   const SymbolicRegion* getSymbolicRegion(SymbolRef Sym);
   1196 
   1197   /// \brief Return a unique symbolic region belonging to heap memory space.
   1198   const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
   1199 
   1200   const StringRegion *getStringRegion(const StringLiteral* Str);
   1201 
   1202   const ObjCStringRegion *getObjCStringRegion(const ObjCStringLiteral *Str);
   1203 
   1204   /// getVarRegion - Retrieve or create the memory region associated with
   1205   ///  a specified VarDecl and LocationContext.
   1206   const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
   1207 
   1208   /// getVarRegion - Retrieve or create the memory region associated with
   1209   ///  a specified VarDecl and super region.
   1210   const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
   1211 
   1212   /// getElementRegion - Retrieve the memory region associated with the
   1213   ///  associated element type, index, and super region.
   1214   const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
   1215                                         const MemRegion *superRegion,
   1216                                         ASTContext &Ctx);
   1217 
   1218   const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
   1219                                                  const MemRegion *superRegion) {
   1220     return getElementRegion(ER->getElementType(), ER->getIndex(),
   1221                             superRegion, ER->getContext());
   1222   }
   1223 
   1224   /// getFieldRegion - Retrieve or create the memory region associated with
   1225   ///  a specified FieldDecl.  'superRegion' corresponds to the containing
   1226   ///  memory region (which typically represents the memory representing
   1227   ///  a structure or class).
   1228   const FieldRegion *getFieldRegion(const FieldDecl *fd,
   1229                                     const MemRegion* superRegion);
   1230 
   1231   const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
   1232                                              const MemRegion *superRegion) {
   1233     return getFieldRegion(FR->getDecl(), superRegion);
   1234   }
   1235 
   1236   /// getObjCIvarRegion - Retrieve or create the memory region associated with
   1237   ///   a specified Objective-c instance variable.  'superRegion' corresponds
   1238   ///   to the containing region (which typically represents the Objective-C
   1239   ///   object).
   1240   const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
   1241                                           const MemRegion* superRegion);
   1242 
   1243   const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
   1244                                                     LocationContext const *LC);
   1245 
   1246   /// Create a CXXBaseObjectRegion with the given base class for region
   1247   /// \p Super.
   1248   ///
   1249   /// The type of \p Super is assumed be a class deriving from \p BaseClass.
   1250   const CXXBaseObjectRegion *
   1251   getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const MemRegion *Super,
   1252                          bool IsVirtual);
   1253 
   1254   /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
   1255   /// super region.
   1256   const CXXBaseObjectRegion *
   1257   getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
   1258                                   const MemRegion *superRegion) {
   1259     return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
   1260                                   baseReg->isVirtual());
   1261   }
   1262 
   1263   const FunctionTextRegion *getFunctionTextRegion(const NamedDecl *FD);
   1264   const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
   1265                                             CanQualType locTy,
   1266                                             AnalysisDeclContext *AC);
   1267 
   1268   /// getBlockDataRegion - Get the memory region associated with an instance
   1269   ///  of a block.  Unlike many other MemRegions, the LocationContext*
   1270   ///  argument is allowed to be NULL for cases where we have no known
   1271   ///  context.
   1272   const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
   1273                                             const LocationContext *lc = NULL);
   1274 
   1275   /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
   1276   /// by static references. This differs from getCXXTempObjectRegion in the
   1277   /// super-region used.
   1278   const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
   1279 
   1280 private:
   1281   template <typename RegionTy, typename A1>
   1282   RegionTy* getRegion(const A1 a1);
   1283 
   1284   template <typename RegionTy, typename A1>
   1285   RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
   1286 
   1287   template <typename RegionTy, typename A1, typename A2>
   1288   RegionTy* getRegion(const A1 a1, const A2 a2);
   1289 
   1290   template <typename RegionTy, typename A1, typename A2>
   1291   RegionTy* getSubRegion(const A1 a1, const A2 a2,
   1292                          const MemRegion* superRegion);
   1293 
   1294   template <typename RegionTy, typename A1, typename A2, typename A3>
   1295   RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
   1296                          const MemRegion* superRegion);
   1297 
   1298   template <typename REG>
   1299   const REG* LazyAllocate(REG*& region);
   1300 
   1301   template <typename REG, typename ARG>
   1302   const REG* LazyAllocate(REG*& region, ARG a);
   1303 };
   1304 
   1305 //===----------------------------------------------------------------------===//
   1306 // Out-of-line member definitions.
   1307 //===----------------------------------------------------------------------===//
   1308 
   1309 inline ASTContext &MemRegion::getContext() const {
   1310   return getMemRegionManager()->getContext();
   1311 }
   1312 
   1313 } // end GR namespace
   1314 
   1315 } // end clang namespace
   1316 
   1317 //===----------------------------------------------------------------------===//
   1318 // Pretty-printing regions.
   1319 //===----------------------------------------------------------------------===//
   1320 
   1321 namespace llvm {
   1322 static inline raw_ostream &operator<<(raw_ostream &os,
   1323                                       const clang::ento::MemRegion* R) {
   1324   R->dumpToStream(os);
   1325   return os;
   1326 }
   1327 } // end llvm namespace
   1328 
   1329 #endif
   1330